MDB2
[ class tree: MDB2 ] [ index: MDB2 ] [ all elements ]

Source for file oci8.php

Documentation is available at oci8.php

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP versions 4 and 5                                                 |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,                 |
  6. // | Stig. S. Bakken, Lukas Smith                                         |
  7. // | All rights reserved.                                                 |
  8. // +----------------------------------------------------------------------+
  9. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
  10. // | API as well as database abstraction for PHP applications.            |
  11. // | This LICENSE is in the BSD license style.                            |
  12. // |                                                                      |
  13. // | Redistribution and use in source and binary forms, with or without   |
  14. // | modification, are permitted provided that the following conditions   |
  15. // | are met:                                                             |
  16. // |                                                                      |
  17. // | Redistributions of source code must retain the above copyright       |
  18. // | notice, this list of conditions and the following disclaimer.        |
  19. // |                                                                      |
  20. // | Redistributions in binary form must reproduce the above copyright    |
  21. // | notice, this list of conditions and the following disclaimer in the  |
  22. // | documentation and/or other materials provided with the distribution. |
  23. // |                                                                      |
  24. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  25. // | Lukas Smith nor the names of his contributors may be used to endorse |
  26. // | or promote products derived from this software without specific prior|
  27. // | written permission.                                                  |
  28. // |                                                                      |
  29. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  30. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  31. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  32. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  33. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  34. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  35. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  36. // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  37. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  38. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  39. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  40. // | POSSIBILITY OF SUCH DAMAGE.                                          |
  41. // +----------------------------------------------------------------------+
  42. // | Author: Lukas Smith <smith@pooteeweet.org>                           |
  43. // +----------------------------------------------------------------------+
  44.  
  45. // $Id: oci8.php,v 1.111 2009/01/07 09:20:20 afz Exp $
  46.  
  47. require_once 'MDB2/Driver/Manager/Common.php';
  48.  
  49. /**
  50.  * MDB2 oci8 driver for the management modules
  51.  *
  52.  * @package MDB2
  53.  * @category Database
  54.  * @author Lukas Smith <smith@pooteeweet.org>
  55.  */
  56. class MDB2_Driver_Manager_oci8 extends MDB2_Driver_Manager_Common
  57. {
  58.     // {{{ createDatabase()
  59.  
  60.     /**
  61.      * create a new database
  62.      *
  63.      * @param string $name    name of the database that should be created
  64.      * @param array  $options array with charset, collation info
  65.      *
  66.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  67.      * @access public
  68.      */
  69.     function createDatabase($name$options = array())
  70.     {
  71.         $db =$this->getDBInstance();
  72.         if (PEAR::isError($db)) {
  73.             return $db;
  74.         }
  75.  
  76.         $username $db->options['database_name_prefix'].$name;
  77.         $password $db->dsn['password'$db->dsn['password'$name;
  78.         $tablespace $db->options['default_tablespace']
  79.             ? ' DEFAULT TABLESPACE '.$db->options['default_tablespace''';
  80.  
  81.         $query 'CREATE USER '.$username.' IDENTIFIED BY '.$password.$tablespace;
  82.         $result $db->standaloneQuery($querynulltrue);
  83.         if (PEAR::isError($result)) {
  84.             return $result;
  85.         }
  86.         $query 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO '.$username;
  87.         $result $db->standaloneQuery($querynulltrue);
  88.         if (PEAR::isError($result)) {
  89.             $query 'DROP USER '.$username.' CASCADE';
  90.             $result2 $db->standaloneQuery($querynulltrue);
  91.             if (PEAR::isError($result2)) {
  92.                 return $db->raiseError($result2nullnull,
  93.                     'could not setup the database user'__FUNCTION__);
  94.             }
  95.             return $result;
  96.         }
  97.         return MDB2_OK;
  98.     }
  99.  
  100.     // }}}
  101.     // {{{ alterDatabase()
  102.  
  103.     /**
  104.      * alter an existing database
  105.      *
  106.      * IMPORTANT: the safe way to change the db charset is to do a full import/export!
  107.      * If - and only if - the new character set is a strict superset of the current
  108.      * character set, it is possible to use the ALTER DATABASE CHARACTER SET to
  109.      * expedite the change in the database character set.
  110.      *
  111.      * @param string $name    name of the database that is intended to be changed
  112.      * @param array  $options array with name, charset info
  113.      *
  114.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  115.      * @access public
  116.      */
  117.     function alterDatabase($name$options = array())
  118.     {
  119.         //disabled
  120.         //return parent::alterDatabase($name, $options);
  121.  
  122.         $db =$this->getDBInstance();
  123.         if (PEAR::isError($db)) {
  124.             return $db;
  125.         }
  126.  
  127.         if (!empty($options['name'])) {
  128.             $query 'ALTER DATABASE ' $db->quoteIdentifier($nametrue)
  129.                     .' RENAME GLOBAL_NAME TO ' $db->quoteIdentifier($options['name']true);
  130.             $result $db->standaloneQuery($query);
  131.             if (PEAR::isError($result)) {
  132.                 return $result;
  133.             }
  134.         }
  135.  
  136.         if (!empty($options['charset'])) {
  137.             $queries = array();
  138.             $queries['SHUTDOWN IMMEDIATE'//or NORMAL
  139.             $queries['STARTUP MOUNT';
  140.             $queries['ALTER SYSTEM ENABLE RESTRICTED SESSION';
  141.             $queries['ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0';
  142.             $queries['ALTER DATABASE OPEN';
  143.             $queries['ALTER DATABASE CHARACTER SET ' $options['charset'];
  144.             $queries['ALTER DATABASE NATIONAL CHARACTER SET ' $options['charset'];
  145.             $queries['SHUTDOWN IMMEDIATE'//or NORMAL
  146.             $queries['STARTUP';
  147.  
  148.             foreach ($queries as $query{
  149.                 $result $db->standaloneQuery($query);
  150.                 if (PEAR::isError($result)) {
  151.                     return $result;
  152.                 }
  153.             }
  154.         }
  155.  
  156.         return MDB2_OK;
  157.     }
  158.  
  159.     // }}}
  160.     // {{{ dropDatabase()
  161.  
  162.     /**
  163.      * drop an existing database
  164.      *
  165.      * @param object $db database object that is extended by this class
  166.      * @param string $name name of the database that should be dropped
  167.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  168.      * @access public
  169.      */
  170.     function dropDatabase($name)
  171.     {
  172.         $db =$this->getDBInstance();
  173.         if (PEAR::isError($db)) {
  174.             return $db;
  175.         }
  176.  
  177.         $username $db->options['database_name_prefix'].$name;
  178.         return $db->standaloneQuery('DROP USER '.$username.' CASCADE'nulltrue);
  179.     }
  180.  
  181.  
  182.     // }}}
  183.     // {{{ _makeAutoincrement()
  184.  
  185.     /**
  186.      * add an autoincrement sequence + trigger
  187.      *
  188.      * @param string $name  name of the PK field
  189.      * @param string $table name of the table
  190.      * @param string $start start value for the sequence
  191.      * @return mixed        MDB2_OK on success, a MDB2 error on failure
  192.      * @access private
  193.      */
  194.     function _makeAutoincrement($name$table$start = 1)
  195.     {
  196.         $db =$this->getDBInstance();
  197.         if (PEAR::isError($db)) {
  198.             return $db;
  199.         }
  200.  
  201.         $table_uppercase strtoupper($table);
  202.         $index_name  $table_uppercase '_AI_PK';
  203.         $definition = array(
  204.             'primary' => true,
  205.             'fields' => array($name => true),
  206.         );
  207.         $idxname_format $db->getOption('idxname_format');
  208.         $db->setOption('idxname_format''%s');
  209.         $result $this->createConstraint($table$index_name$definition);
  210.         $db->setOption('idxname_format'$idxname_format);
  211.         if (PEAR::isError($result)) {
  212.             return $db->raiseError($resultnullnull,
  213.                 'primary key for autoincrement PK could not be created'__FUNCTION__);
  214.         }
  215.  
  216.         $seq_name $table.'_'.$name;
  217.         if (is_null($start)) {
  218.             $db->beginTransaction();
  219.             $query 'SELECT MAX(' $db->quoteIdentifier($nametrue') FROM ' $db->quoteIdentifier($tabletrue);
  220.             $start $this->db->queryOne($query'integer');
  221.             if (PEAR::isError($start)) {
  222.                 return $start;
  223.             }
  224.             ++$start;
  225.             $result $this->createSequence($seq_name$start);
  226.             $db->commit();
  227.         else {
  228.             $result $this->createSequence($seq_name$start);
  229.         }
  230.         if (PEAR::isError($result)) {
  231.             return $db->raiseError($resultnullnull,
  232.                 'sequence for autoincrement PK could not be created'__FUNCTION__);
  233.         }
  234.         $seq_name        $db->getSequenceName($seq_name);
  235.         $trigger_name    $db->quoteIdentifier($table_uppercase '_AI_PK'true);
  236.         $seq_name_quoted $db->quoteIdentifier($seq_nametrue);
  237.         $table $db->quoteIdentifier($tabletrue);
  238.         $name  $db->quoteIdentifier($nametrue);
  239.         $trigger_sql '
  240. CREATE TRIGGER '.$trigger_name.'
  241.    BEFORE INSERT
  242.    ON '.$table.'
  243.    FOR EACH ROW
  244. DECLARE
  245.    last_Sequence NUMBER;
  246.    last_InsertID NUMBER;
  247. BEGIN
  248.    SELECT '.$seq_name_quoted.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL;
  249.    IF (:NEW.'.$name.' IS NULL OR :NEW.'.$name.' = 0) THEN
  250.       SELECT '.$seq_name_quoted.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL;
  251.    ELSE
  252.       SELECT NVL(Last_Number, 0) INTO last_Sequence
  253.         FROM User_Sequences
  254.        WHERE UPPER(Sequence_Name) = UPPER(\''.$seq_name.'\');
  255.       SELECT :NEW.'.$name.' INTO last_InsertID FROM DUAL;
  256.       WHILE (last_InsertID > last_Sequence) LOOP
  257.          SELECT '.$seq_name_quoted.'.NEXTVAL INTO last_Sequence FROM DUAL;
  258.       END LOOP;
  259.    END IF;
  260. END;
  261. ';
  262.         $result $db->exec($trigger_sql);
  263.         if (PEAR::isError($result)) {
  264.             return $result;
  265.         }
  266.         return MDB2_OK;
  267.     }
  268.  
  269.     // }}}
  270.     // {{{ _dropAutoincrement()
  271.  
  272.     /**
  273.      * drop an existing autoincrement sequence + trigger
  274.      *
  275.      * @param string $table name of the table
  276.      * @return mixed        MDB2_OK on success, a MDB2 error on failure
  277.      * @access private
  278.      */
  279.     function _dropAutoincrement($table)
  280.     {
  281.         $db =$this->getDBInstance();
  282.         if (PEAR::isError($db)) {
  283.             return $db;
  284.         }
  285.  
  286.         $table strtoupper($table);
  287.         $trigger_name $table '_AI_PK';
  288.         $trigger_name_quoted $db->quote($trigger_name'text');
  289.         $query 'SELECT trigger_name FROM user_triggers';
  290.         $query.= ' WHERE trigger_name='.$trigger_name_quoted.' OR trigger_name='.strtoupper($trigger_name_quoted);
  291.         $trigger $db->queryOne($query);
  292.         if (PEAR::isError($trigger)) {
  293.             return $trigger;
  294.         }
  295.  
  296.         if ($trigger{
  297.             $trigger_name  $db->quoteIdentifier($table '_AI_PK'true);
  298.             $trigger_sql 'DROP TRIGGER ' $trigger_name;
  299.             $result $db->exec($trigger_sql);
  300.             if (PEAR::isError($result)) {
  301.                 return $db->raiseError($resultnullnull,
  302.                     'trigger for autoincrement PK could not be dropped'__FUNCTION__);
  303.             }
  304.  
  305.             $result $this->dropSequence($table);
  306.             if (PEAR::isError($result)) {
  307.                 return $db->raiseError($resultnullnull,
  308.                     'sequence for autoincrement PK could not be dropped'__FUNCTION__);
  309.             }
  310.  
  311.             $index_name $table '_AI_PK';
  312.             $idxname_format $db->getOption('idxname_format');
  313.             $db->setOption('idxname_format''%s');
  314.             $result1 $this->dropConstraint($table$index_name);
  315.             $db->setOption('idxname_format'$idxname_format);
  316.             $result2 $this->dropConstraint($table$index_name);
  317.             if (PEAR::isError($result1&& PEAR::isError($result2)) {
  318.                 return $db->raiseError($result1nullnull,
  319.                     'primary key for autoincrement PK could not be dropped'__FUNCTION__);
  320.             }
  321.         }
  322.  
  323.         return MDB2_OK;
  324.     }
  325.  
  326.     // }}}
  327.     // {{{ _getTemporaryTableQuery()
  328.  
  329.     /**
  330.      * A method to return the required SQL string that fits between CREATE ... TABLE
  331.      * to create the table as a temporary table.
  332.      *
  333.      * @return string The string required to be placed between "CREATE" and "TABLE"
  334.      *                 to generate a temporary table, if possible.
  335.      */
  336.     function _getTemporaryTableQuery()
  337.     {
  338.         return 'GLOBAL TEMPORARY';
  339.     }
  340.  
  341.     // }}}
  342.     // {{{ _getAdvancedFKOptions()
  343.  
  344.     /**
  345.      * Return the FOREIGN KEY query section dealing with non-standard options
  346.      * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
  347.      *
  348.      * @param array $definition 
  349.      * @return string 
  350.      * @access protected
  351.      */
  352.     function _getAdvancedFKOptions($definition)
  353.     {
  354.         $query '';
  355.         if (!empty($definition['ondelete']&& (strtoupper($definition['ondelete']!= 'NO ACTION')) {
  356.             $query .= ' ON DELETE '.$definition['ondelete'];
  357.         }
  358.         if (!empty($definition['deferrable'])) {
  359.             $query .= ' DEFERRABLE';
  360.         else {
  361.             $query .= ' NOT DEFERRABLE';
  362.         }
  363.         if (!empty($definition['initiallydeferred'])) {
  364.             $query .= ' INITIALLY DEFERRED';
  365.         else {
  366.             $query .= ' INITIALLY IMMEDIATE';
  367.         }
  368.         return $query;
  369.     }
  370.  
  371.     // }}}
  372.     // {{{ createTable()
  373.  
  374.     /**
  375.      * create a new table
  376.      *
  377.      * @param string $name     Name of the database that should be created
  378.      * @param array $fields Associative array that contains the definition of each field of the new table
  379.      *                         The indexes of the array entries are the names of the fields of the table an
  380.      *                         the array entry values are associative arrays like those that are meant to be
  381.      *                          passed with the field definitions to get[Type]Declaration() functions.
  382.      *
  383.      *                         Example
  384.      *                         array(
  385.      *
  386.      *                             'id' => array(
  387.      *                                 'type' => 'integer',
  388.      *                                 'unsigned' => 1
  389.      *                                 'notnull' => 1
  390.      *                                 'default' => 0
  391.      *                             ),
  392.      *                             'name' => array(
  393.      *                                 'type' => 'text',
  394.      *                                 'length' => 12
  395.      *                             ),
  396.      *                             'password' => array(
  397.      *                                 'type' => 'text',
  398.      *                                 'length' => 12
  399.      *                             )
  400.      *                         );
  401.      * @param array $options  An associative array of table options:
  402.      *                           array(
  403.      *                               'comment' => 'Foo',
  404.      *                               'temporary' => true|false,
  405.      *                           );
  406.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  407.      * @access public
  408.      */
  409.     function createTable($name$fields$options = array())
  410.     {
  411.         $db =$this->getDBInstance();
  412.         if (PEAR::isError($db)) {
  413.             return $db;
  414.         }
  415.         $db->beginNestedTransaction();
  416.         $result = parent::createTable($name$fields$options);
  417.         if (!PEAR::isError($result)) {
  418.             foreach ($fields as $field_name => $field{
  419.                 if (!empty($field['autoincrement'])) {
  420.                     $result $this->_makeAutoincrement($field_name$name);
  421.                 }
  422.             }
  423.         }
  424.         $db->completeNestedTransaction();
  425.         return $result;
  426.     }
  427.  
  428.     // }}}
  429.     // {{{ dropTable()
  430.  
  431.     /**
  432.      * drop an existing table
  433.      *
  434.      * @param string $name name of the table that should be dropped
  435.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  436.      * @access public
  437.      */
  438.     function dropTable($name)
  439.     {
  440.         $db =$this->getDBInstance();
  441.         if (PEAR::isError($db)) {
  442.             return $db;
  443.         }
  444.         $db->beginNestedTransaction();
  445.         $result $this->_dropAutoincrement($name);
  446.         if (!PEAR::isError($result)) {
  447.             $result = parent::dropTable($name);
  448.         }
  449.         $db->completeNestedTransaction();
  450.         return $result;
  451.     }
  452.  
  453.     // }}}
  454.     // {{{ truncateTable()
  455.  
  456.     /**
  457.      * Truncate an existing table (if the TRUNCATE TABLE syntax is not supported,
  458.      * it falls back to a DELETE FROM TABLE query)
  459.      *
  460.      * @param string $name name of the table that should be truncated
  461.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  462.      * @access public
  463.      */
  464.     function truncateTable($name)
  465.     {
  466.         $db =$this->getDBInstance();
  467.         if (PEAR::isError($db)) {
  468.             return $db;
  469.         }
  470.  
  471.         $name $db->quoteIdentifier($nametrue);
  472.         return $db->exec("TRUNCATE TABLE $name");
  473.     }
  474.  
  475.     // }}}
  476.     // {{{ vacuum()
  477.  
  478.     /**
  479.      * Optimize (vacuum) all the tables in the db (or only the specified table)
  480.      * and optionally run ANALYZE.
  481.      *
  482.      * @param string $table table name (all the tables if empty)
  483.      * @param array  $options an array with driver-specific options:
  484.      *                - timeout [int] (in seconds) [mssql-only]
  485.      *                - analyze [boolean] [pgsql and mysql]
  486.      *                - full [boolean] [pgsql-only]
  487.      *                - freeze [boolean] [pgsql-only]
  488.      *
  489.      * @return mixed MDB2_OK success, a MDB2 error on failure
  490.      * @access public
  491.      */
  492.     function vacuum($table = null$options = array())
  493.     {
  494.         // not needed in Oracle
  495.         return MDB2_OK;
  496.     }
  497.  
  498.     // }}}
  499.     // {{{ alterTable()
  500.  
  501.     /**
  502.      * alter an existing table
  503.      *
  504.      * @param string $name         name of the table that is intended to be changed.
  505.      * @param array $changes     associative array that contains the details of each type
  506.      *                              of change that is intended to be performed. The types of
  507.      *                              changes that are currently supported are defined as follows:
  508.      *
  509.      *                              name
  510.      *
  511.      *                                 New name for the table.
  512.      *
  513.      *                             add
  514.      *
  515.      *                                 Associative array with the names of fields to be added as
  516.      *                                  indexes of the array. The value of each entry of the array
  517.      *                                  should be set to another associative array with the properties
  518.      *                                  of the fields to be added. The properties of the fields should
  519.      *                                  be the same as defined by the MDB2 parser.
  520.      *
  521.      *
  522.      *                             remove
  523.      *
  524.      *                                 Associative array with the names of fields to be removed as indexes
  525.      *                                  of the array. Currently the values assigned to each entry are ignored.
  526.      *                                  An empty array should be used for future compatibility.
  527.      *
  528.      *                             rename
  529.      *
  530.      *                                 Associative array with the names of fields to be renamed as indexes
  531.      *                                  of the array. The value of each entry of the array should be set to
  532.      *                                  another associative array with the entry named name with the new
  533.      *                                  field name and the entry named Declaration that is expected to contain
  534.      *                                  the portion of the field declaration already in DBMS specific SQL code
  535.      *                                  as it is used in the CREATE TABLE statement.
  536.      *
  537.      *                             change
  538.      *
  539.      *                                 Associative array with the names of the fields to be changed as indexes
  540.      *                                  of the array. Keep in mind that if it is intended to change either the
  541.      *                                  name of a field and any other properties, the change array entries
  542.      *                                  should have the new names of the fields as array indexes.
  543.      *
  544.      *                                 The value of each entry of the array should be set to another associative
  545.      *                                  array with the properties of the fields to that are meant to be changed as
  546.      *                                  array entries. These entries should be assigned to the new values of the
  547.      *                                  respective properties. The properties of the fields should be the same
  548.      *                                  as defined by the MDB2 parser.
  549.      *
  550.      *                             Example
  551.      *                                 array(
  552.      *                                     'name' => 'userlist',
  553.      *                                     'add' => array(
  554.      *                                         'quota' => array(
  555.      *                                             'type' => 'integer',
  556.      *                                             'unsigned' => 1
  557.      *                                         )
  558.      *                                     ),
  559.      *                                     'remove' => array(
  560.      *                                         'file_limit' => array(),
  561.      *                                         'time_limit' => array()
  562.      *                                     ),
  563.      *                                     'change' => array(
  564.      *                                         'name' => array(
  565.      *                                             'length' => '20',
  566.      *                                             'definition' => array(
  567.      *                                                 'type' => 'text',
  568.      *                                                 'length' => 20,
  569.      *                                             ),
  570.      *                                         )
  571.      *                                     ),
  572.      *                                     'rename' => array(
  573.      *                                         'sex' => array(
  574.      *                                             'name' => 'gender',
  575.      *                                             'definition' => array(
  576.      *                                                 'type' => 'text',
  577.      *                                                 'length' => 1,
  578.      *                                                 'default' => 'M',
  579.      *                                             ),
  580.      *                                         )
  581.      *                                     )
  582.      *                                 )
  583.      *
  584.      * @param boolean $check     indicates whether the function should just check if the DBMS driver
  585.      *                              can perform the requested table alterations if the value is true or
  586.      *                              actually perform them otherwise.
  587.      * @access public
  588.      *
  589.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  590.      */
  591.     function alterTable($name$changes$check)
  592.     {
  593.         $db =$this->getDBInstance();
  594.         if (PEAR::isError($db)) {
  595.             return $db;
  596.         }
  597.  
  598.         foreach ($changes as $change_name => $change{
  599.             switch ($change_name{
  600.             case 'add':
  601.             case 'remove':
  602.             case 'change':
  603.             case 'name':
  604.             case 'rename':
  605.                 break;
  606.             default:
  607.                 return $db->raiseError(MDB2_ERROR_CANNOT_ALTERnullnull,
  608.                     'change type "'.$change_name.'" not yet supported'__FUNCTION__);
  609.             }
  610.         }
  611.  
  612.         if ($check{
  613.             return MDB2_OK;
  614.         }
  615.  
  616.         $name $db->quoteIdentifier($nametrue);
  617.  
  618.         if (!empty($changes['add']&& is_array($changes['add'])) {
  619.             $fields = array();
  620.             foreach ($changes['add'as $field_name => $field{
  621.                 $fields[$db->getDeclaration($field['type']$field_name$field);
  622.             }
  623.             $result $db->exec("ALTER TABLE $name ADD (". implode(', '$fields).')');
  624.             if (PEAR::isError($result)) {
  625.                 return $result;
  626.             }
  627.         }
  628.  
  629.         if (!empty($changes['change']&& is_array($changes['change'])) {
  630.             $fields = array();
  631.             foreach ($changes['change'as $field_name => $field{
  632.                 //fix error "column to be modified to NOT NULL is already NOT NULL" 
  633.                 if (!array_key_exists('notnull'$field)) {
  634.                     unset($field['definition']['notnull']);
  635.                 }
  636.                 $fields[$db->getDeclaration($field['definition']['type']$field_name$field['definition']);
  637.             }
  638.             $result $db->exec("ALTER TABLE $name MODIFY (". implode(', '$fields).')');
  639.             if (PEAR::isError($result)) {
  640.                 return $result;
  641.             }
  642.         }
  643.  
  644.         if (!empty($changes['rename']&& is_array($changes['rename'])) {
  645.             foreach ($changes['rename'as $field_name => $field{
  646.                 $field_name $db->quoteIdentifier($field_nametrue);
  647.                 $query = "ALTER TABLE $name RENAME COLUMN $field_name TO ".$db->quoteIdentifier($field['name']);
  648.                 $result $db->exec($query);
  649.                 if (PEAR::isError($result)) {
  650.                     return $result;
  651.                 }
  652.             }
  653.         }
  654.  
  655.         if (!empty($changes['remove']&& is_array($changes['remove'])) {
  656.             $fields = array();
  657.             foreach ($changes['remove'as $field_name => $field{
  658.                 $fields[$db->quoteIdentifier($field_nametrue);
  659.             }
  660.             $result $db->exec("ALTER TABLE $name DROP COLUMN ". implode(', '$fields));
  661.             if (PEAR::isError($result)) {
  662.                 return $result;
  663.             }
  664.         }
  665.  
  666.         if (!empty($changes['name'])) {
  667.             $change_name $db->quoteIdentifier($changes['name']true);
  668.             $result $db->exec("ALTER TABLE $name RENAME TO ".$change_name);
  669.             if (PEAR::isError($result)) {
  670.                 return $result;
  671.             }
  672.         }
  673.  
  674.         return MDB2_OK;
  675.     }
  676.  
  677.     // }}}
  678.     // {{{ _fetchCol()
  679.  
  680.     /**
  681.      * Utility method to fetch and format a column from a resultset
  682.      *
  683.      * @param resource $result 
  684.      * @param boolean $fixname (used when listing indices or constraints)
  685.      * @return mixed array of names on success, a MDB2 error on failure
  686.      * @access private
  687.      */
  688.     function _fetchCol($result$fixname = false)
  689.     {
  690.         if (PEAR::isError($result)) {
  691.             return $result;
  692.         }
  693.         $col $result->fetchCol();
  694.         if (PEAR::isError($col)) {
  695.             return $col;
  696.         }
  697.         $result->free();
  698.         
  699.         $db =$this->getDBInstance();
  700.         if (PEAR::isError($db)) {
  701.             return $db;
  702.         }
  703.         
  704.         if ($fixname{
  705.             foreach ($col as $k => $v{
  706.                 $col[$k$this->_fixIndexName($v);
  707.             }
  708.         }
  709.         
  710.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE
  711.             && $db->options['field_case'== CASE_LOWER
  712.         {
  713.             $col array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$col);
  714.         }
  715.         return $col;
  716.     }
  717.  
  718.     // }}}
  719.     // {{{ listDatabases()
  720.  
  721.     /**
  722.      * list all databases
  723.      *
  724.      * @return mixed array of database names on success, a MDB2 error on failure
  725.      * @access public
  726.      */
  727.     function listDatabases()
  728.     {
  729.         $db =$this->getDBInstance();
  730.         if (PEAR::isError($db)) {
  731.             return $db;
  732.         }
  733.  
  734.         if (!$db->options['emulate_database']{
  735.             return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  736.                 'database listing is only supported if the "emulate_database" option is enabled'__FUNCTION__);
  737.         }
  738.  
  739.         if ($db->options['database_name_prefix']{
  740.             $query 'SELECT SUBSTR(username, ';
  741.             $query.= (strlen($db->options['database_name_prefix'])+1);
  742.             $query.= ") FROM sys.dba_users WHERE username LIKE '";
  743.             $query.= $db->options['database_name_prefix']."%'";
  744.         else {
  745.             $query 'SELECT username FROM sys.dba_users';
  746.         }
  747.         $result $db->standaloneQuery($queryarray('text')false);
  748.         return $this->_fetchCol($result);
  749.     }
  750.  
  751.     // }}}
  752.     // {{{ listUsers()
  753.  
  754.     /**
  755.      * list all users
  756.      *
  757.      * @return mixed array of user names on success, a MDB2 error on failure
  758.      * @access public
  759.      */
  760.     function listUsers()
  761.     {
  762.         $db =$this->getDBInstance();
  763.         if (PEAR::isError($db)) {
  764.             return $db;
  765.         }
  766.  
  767.         if ($db->options['emulate_database'&& $db->options['database_name_prefix']{
  768.             $query 'SELECT SUBSTR(username, ';
  769.             $query.= (strlen($db->options['database_name_prefix'])+1);
  770.             $query.= ") FROM sys.dba_users WHERE username NOT LIKE '";
  771.             $query.= $db->options['database_name_prefix']."%'";
  772.         else {
  773.             $query 'SELECT username FROM sys.dba_users';
  774.         }
  775.         return $db->queryCol($query);
  776.     }
  777.  
  778.     // }}}
  779.     // {{{ listViews()
  780.  
  781.     /**
  782.      * list all views in the current database
  783.      *
  784.      * @param string owner, the current is default
  785.      * @return mixed array of view names on success, a MDB2 error on failure
  786.      * @access public
  787.      */
  788.     function listViews($owner = null)
  789.     {
  790.         $db =$this->getDBInstance();
  791.         if (PEAR::isError($db)) {
  792.             return $db;
  793.         }
  794.         
  795.         if (empty($owner)) {
  796.             $owner $db->dsn['username'];
  797.         }
  798.  
  799.         $query 'SELECT view_name
  800.                     FROM sys.all_views
  801.                    WHERE owner=? OR owner=?';
  802.         $stmt $db->prepare($query);
  803.         if (PEAR::isError($stmt)) {
  804.             return $stmt;
  805.         }
  806.         $result $stmt->execute(array($ownerstrtoupper($owner)));
  807.         return $this->_fetchCol($result);
  808.     }
  809.  
  810.     // }}}
  811.     // {{{ listFunctions()
  812.  
  813.     /**
  814.      * list all functions in the current database
  815.      *
  816.      * @param string owner, the current is default
  817.      * @return mixed array of function names on success, a MDB2 error on failure
  818.      * @access public
  819.      */
  820.     function listFunctions($owner = null)
  821.     {
  822.         $db =$this->getDBInstance();
  823.         if (PEAR::isError($db)) {
  824.             return $db;
  825.         }
  826.  
  827.         if (empty($owner)) {
  828.             $owner $db->dsn['username'];
  829.         }
  830.  
  831.         $query "SELECT name
  832.                     FROM sys.all_source
  833.                    WHERE line = 1
  834.                      AND type = 'FUNCTION'
  835.                      AND (owner=? OR owner=?)";
  836.         $stmt $db->prepare($query);
  837.         if (PEAR::isError($stmt)) {
  838.             return $stmt;
  839.         }
  840.         $result $stmt->execute(array($ownerstrtoupper($owner)));
  841.         return $this->_fetchCol($result);
  842.     }
  843.  
  844.     // }}}
  845.     // {{{ listTableTriggers()
  846.  
  847.     /**
  848.      * list all triggers in the database that reference a given table
  849.      *
  850.      * @param string table for which all referenced triggers should be found
  851.      * @return mixed array of trigger names on success, a MDB2 error on failure
  852.      * @access public
  853.      */
  854.     function listTableTriggers($table = null)
  855.     {
  856.         $db =$this->getDBInstance();
  857.         if (PEAR::isError($db)) {
  858.             return $db;
  859.         }
  860.  
  861.         if (empty($owner)) {
  862.             $owner $db->dsn['username'];
  863.         }
  864.  
  865.         $query "SELECT trigger_name
  866.                     FROM sys.all_triggers
  867.                    WHERE (table_name=? OR table_name=?)
  868.                      AND (owner=? OR owner=?)";
  869.         $stmt $db->prepare($query);
  870.         if (PEAR::isError($stmt)) {
  871.             return $stmt;
  872.         }
  873.         $args = array(
  874.             $table,
  875.             strtoupper($table),
  876.             $owner,
  877.             strtoupper($owner),
  878.         );
  879.         $result $stmt->execute($args);
  880.         return $this->_fetchCol($result);
  881.     }
  882.  
  883.     // }}}
  884.     // {{{ listTables()
  885.  
  886.     /**
  887.      * list all tables in the database
  888.      *
  889.      * @param string owner, the current is default
  890.      * @return mixed array of table names on success, a MDB2 error on failure
  891.      * @access public
  892.      */
  893.     function listTables($owner = null)
  894.     {
  895.         $db =$this->getDBInstance();
  896.         if (PEAR::isError($db)) {
  897.             return $db;
  898.         }
  899.         
  900.         if (empty($owner)) {
  901.             $owner $db->dsn['username'];
  902.         }
  903.  
  904.         $query 'SELECT table_name
  905.                     FROM sys.all_tables
  906.                    WHERE owner=? OR owner=?';
  907.         $stmt $db->prepare($query);
  908.         if (PEAR::isError($stmt)) {
  909.             return $stmt;
  910.         }
  911.         $result $stmt->execute(array($ownerstrtoupper($owner)));
  912.         return $this->_fetchCol($result);
  913.     }
  914.  
  915.     // }}}
  916.     // {{{ listTableFields()
  917.  
  918.     /**
  919.      * list all fields in a table in the current database
  920.      *
  921.      * @param string $table name of table that should be used in method
  922.      * @return mixed array of field names on success, a MDB2 error on failure
  923.      * @access public
  924.      */
  925.     function listTableFields($table)
  926.     {
  927.         $db =$this->getDBInstance();
  928.         if (PEAR::isError($db)) {
  929.             return $db;
  930.         }
  931.         
  932.         list($owner$table$this->splitTableSchema($table);
  933.         if (empty($owner)) {
  934.             $owner $db->dsn['username'];
  935.         }
  936.  
  937.         $query 'SELECT column_name
  938.                     FROM all_tab_columns
  939.                    WHERE (table_name=? OR table_name=?)
  940.                      AND (owner=? OR owner=?)
  941.                 ORDER BY column_id';
  942.         $stmt $db->prepare($query);
  943.         if (PEAR::isError($stmt)) {
  944.             return $stmt;
  945.         }
  946.         $args = array(
  947.             $table,
  948.             strtoupper($table),
  949.             $owner,
  950.             strtoupper($owner),
  951.         );
  952.         $result $stmt->execute($args);
  953.         return $this->_fetchCol($result);
  954.     }
  955.  
  956.     // }}}
  957.     // {{{ listTableIndexes()
  958.  
  959.     /**
  960.      * list all indexes in a table
  961.      *
  962.      * @param string $table name of table that should be used in method
  963.      * @return mixed array of index names on success, a MDB2 error on failure
  964.      * @access public
  965.      */
  966.     function listTableIndexes($table)
  967.     {
  968.         $db =$this->getDBInstance();
  969.         if (PEAR::isError($db)) {
  970.             return $db;
  971.         }
  972.         
  973.         list($owner$table$this->splitTableSchema($table);
  974.         if (empty($owner)) {
  975.             $owner $db->dsn['username'];
  976.         }
  977.         
  978.         $query 'SELECT i.index_name name
  979.                     FROM all_indexes i
  980.                LEFT JOIN all_constraints c
  981.                       ON c.index_name = i.index_name
  982.                      AND c.owner = i.owner
  983.                      AND c.table_name = i.table_name
  984.                    WHERE (i.table_name=? OR i.table_name=?)
  985.                      AND (i.owner=? OR i.owner=?)
  986.                      AND c.index_name IS NULL
  987.                      AND i.generated=' .$db->quote('N''text');
  988.         $stmt $db->prepare($query);
  989.         if (PEAR::isError($stmt)) {
  990.             return $stmt;
  991.         }
  992.         $args = array(
  993.             $table,
  994.             strtoupper($table),
  995.             $owner,
  996.             strtoupper($owner),
  997.         );
  998.         $result $stmt->execute($args);
  999.         return $this->_fetchCol($resulttrue);
  1000.     }
  1001.  
  1002.     // }}}
  1003.     // {{{ createConstraint()
  1004.  
  1005.     /**
  1006.      * create a constraint on a table
  1007.      *
  1008.      * @param string    $table        name of the table on which the constraint is to be created
  1009.      * @param string    $name         name of the constraint to be created
  1010.      * @param array     $definition   associative array that defines properties of the constraint to be created.
  1011.      *                                 Currently, only one property named FIELDS is supported. This property
  1012.      *                                 is also an associative with the names of the constraint fields as array
  1013.      *                                 constraints. Each entry of this array is set to another type of associative
  1014.      *                                 array that specifies properties of the constraint that are specific to
  1015.      *                                 each field.
  1016.      *
  1017.      *                                 Example
  1018.      *                                    array(
  1019.      *                                        'fields' => array(
  1020.      *                                            'user_name' => array(),
  1021.      *                                            'last_login' => array()
  1022.      *                                        )
  1023.      *                                    )
  1024.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1025.      * @access public
  1026.      */
  1027.     function createConstraint($table$name$definition)
  1028.     {
  1029.         $result = parent::createConstraint($table$name$definition);
  1030.         if (PEAR::isError($result)) {
  1031.             return $result;
  1032.         }
  1033.         if (!empty($definition['foreign'])) {
  1034.             return $this->_createFKTriggers($tablearray($name => $definition));
  1035.         }
  1036.         return MDB2_OK;
  1037.     }
  1038.  
  1039.     // }}}
  1040.     // {{{ dropConstraint()
  1041.  
  1042.     /**
  1043.      * drop existing constraint
  1044.      *
  1045.      * @param string    $table        name of table that should be used in method
  1046.      * @param string    $name         name of the constraint to be dropped
  1047.      * @param string    $primary      hint if the constraint is primary
  1048.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1049.      * @access public
  1050.      */
  1051.     function dropConstraint($table$name$primary = false)
  1052.     {
  1053.         $db =$this->getDBInstance();
  1054.         if (PEAR::isError($db)) {
  1055.             return $db;
  1056.         }
  1057.  
  1058.         //is it a FK constraint? If so, also delete the associated triggers
  1059.         $db->loadModule('Reverse'nulltrue);
  1060.         $definition $db->reverse->getTableConstraintDefinition($table$name);
  1061.         if (!PEAR::isError($definition&& !empty($definition['foreign'])) {
  1062.             //first drop the FK enforcing triggers
  1063.             $result $this->_dropFKTriggers($table$name$definition['references']['table']);
  1064.             if (PEAR::isError($result)) {
  1065.                 return $result;
  1066.             }
  1067.         }
  1068.  
  1069.         return parent::dropConstraint($table$name$primary);
  1070.     }
  1071.  
  1072.     // }}}
  1073.     // {{{ _createFKTriggers()
  1074.  
  1075.     /**
  1076.      * Create triggers to enforce the FOREIGN KEY constraint on the table
  1077.      *
  1078.      * @param string $table        table name
  1079.      * @param array  $foreign_keys FOREIGN KEY definitions
  1080.      *
  1081.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1082.      * @access private
  1083.      */
  1084.     function _createFKTriggers($table$foreign_keys)
  1085.     {
  1086.         $db =$this->getDBInstance();
  1087.         if (PEAR::isError($db)) {
  1088.             return $db;
  1089.         }
  1090.         // create triggers to enforce FOREIGN KEY constraints
  1091.         if ($db->supports('triggers'&& !empty($foreign_keys)) {
  1092.             $table $db->quoteIdentifier($tabletrue);
  1093.             foreach ($foreign_keys as $fkname => $fkdef{
  1094.                 if (empty($fkdef)) {
  1095.                     continue;
  1096.                 }
  1097.                 $fkdef['onupdate'= empty($fkdef['onupdate']$db->options['default_fk_action_onupdate'strtoupper($fkdef['onupdate']);
  1098.                 if ('RESTRICT' == $fkdef['onupdate'|| 'NO ACTION' == $fkdef['onupdate']{
  1099.                     // already handled by default
  1100.                     continue;
  1101.                 }
  1102.  
  1103.                 $trigger_name substr(strtolower($fkname.'_pk_upd_trg')0$db->options['max_identifiers_length']);
  1104.                 $table_fields array_keys($fkdef['fields']);
  1105.                 $referenced_fields array_keys($fkdef['references']['fields']);
  1106.  
  1107.                 //create the ON UPDATE trigger on the primary table
  1108.                 $restrict_action ' IF (SELECT ';
  1109.                 $aliased_fields = array();
  1110.                 foreach ($table_fields as $field{
  1111.                     $aliased_fields[$table .'.'.$field .' AS '.$field;
  1112.                 }
  1113.                 $restrict_action .= implode(','$aliased_fields)
  1114.                        .' FROM '.$table
  1115.                        .' WHERE ';
  1116.                 $conditions  = array();
  1117.                 $new_values  = array();
  1118.                 $null_values = array();
  1119.                 for ($i=0; $i<count($table_fields)$i++{
  1120.                     $conditions[]  $table_fields[$i.' = :OLD.'.$referenced_fields[$i];
  1121.                     $new_values[]  $table_fields[$i.' = :NEW.'.$referenced_fields[$i];
  1122.                     $null_values[$table_fields[$i.' = NULL';
  1123.                 }
  1124.  
  1125.                 $cascade_action 'UPDATE '.$table.' SET '.implode(', '$new_values.' WHERE '.implode(' AND '$conditions)';';
  1126.                 $setnull_action 'UPDATE '.$table.' SET '.implode(', '$null_values).' WHERE '.implode(' AND '$conditions)';';
  1127.  
  1128.                 if ('SET DEFAULT' == $fkdef['onupdate'|| 'SET DEFAULT' == $fkdef['ondelete']{
  1129.                     $db->loadModule('Reverse'nulltrue);
  1130.                     $default_values = array();
  1131.                     foreach ($table_fields as $table_field{
  1132.                         $field_definition $db->reverse->getTableFieldDefinition($table$field);
  1133.                         if (PEAR::isError($field_definition)) {
  1134.                             return $field_definition;
  1135.                         }
  1136.                         $default_values[$table_field .' = '$field_definition[0]['default'];
  1137.                     }
  1138.                     $setdefault_action 'UPDATE '.$table.' SET '.implode(', '$default_values).' WHERE '.implode(' AND '$conditions)';';
  1139.                 }
  1140.  
  1141.                 $query 'CREATE TRIGGER %s'
  1142.                         .' %s ON '.$fkdef['references']['table']
  1143.                         .' FOR EACH ROW '
  1144.                         .' BEGIN ';
  1145.  
  1146.                 if ('CASCADE' == $fkdef['onupdate']{
  1147.                     $sql_update sprintf($query$trigger_name'BEFORE UPDATE',  'update'$cascade_action;
  1148.                 elseif ('SET NULL' == $fkdef['onupdate']{
  1149.                     $sql_update sprintf($query$trigger_name'BEFORE UPDATE''update'$setnull_action;
  1150.                 elseif ('SET DEFAULT' == $fkdef['onupdate']{
  1151.                     $sql_update sprintf($query$trigger_name'BEFORE UPDATE''update'$setdefault_action;
  1152.                 }
  1153.                 $sql_update .= ' END;';
  1154.                 $result $db->exec($sql_update);
  1155.                 if (PEAR::isError($result)) {
  1156.                     return $result;
  1157.                 }
  1158.             }
  1159.         }
  1160.         return MDB2_OK;
  1161.     }
  1162.  
  1163.     // }}}
  1164.     // {{{ _dropFKTriggers()
  1165.  
  1166.     /**
  1167.      * Drop the triggers created to enforce the FOREIGN KEY constraint on the table
  1168.      *
  1169.      * @param string $table            table name
  1170.      * @param string $fkname           FOREIGN KEY constraint name
  1171.      * @param string $referenced_table referenced table name
  1172.      *
  1173.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1174.      * @access private
  1175.      */
  1176.     function _dropFKTriggers($table$fkname$referenced_table)
  1177.     {
  1178.         $db =$this->getDBInstance();
  1179.         if (PEAR::isError($db)) {
  1180.             return $db;
  1181.         }
  1182.  
  1183.         $triggers  $this->listTableTriggers($table);
  1184.         $triggers2 $this->listTableTriggers($referenced_table);
  1185.         if (!PEAR::isError($triggers2&& !PEAR::isError($triggers)) {
  1186.             $triggers array_merge($triggers$triggers2);
  1187.             $trigger_name substr(strtolower($fkname.'_pk_upd_trg')0$db->options['max_identifiers_length']);
  1188.             $pattern '/^'.$trigger_name.'$/i';
  1189.             foreach ($triggers as $trigger{
  1190.                 if (preg_match($pattern$trigger)) {
  1191.                     $result $db->exec('DROP TRIGGER '.$trigger);
  1192.                     if (PEAR::isError($result)) {
  1193.                         return $result;
  1194.                     }
  1195.                 }
  1196.             }
  1197.         }
  1198.         return MDB2_OK;
  1199.     }
  1200.  
  1201.     // }}}
  1202.     // {{{ listTableConstraints()
  1203.  
  1204.     /**
  1205.      * list all constraints in a table
  1206.      *
  1207.      * @param string $table name of table that should be used in method
  1208.      * @return mixed array of constraint names on success, a MDB2 error on failure
  1209.      * @access public
  1210.      */
  1211.     function listTableConstraints($table)
  1212.     {
  1213.         $db =$this->getDBInstance();
  1214.         if (PEAR::isError($db)) {
  1215.             return $db;
  1216.         }
  1217.  
  1218.         list($owner$table$this->splitTableSchema($table);
  1219.         if (empty($owner)) {
  1220.             $owner $db->dsn['username'];
  1221.         }
  1222.  
  1223.         $query 'SELECT constraint_name
  1224.                     FROM all_constraints
  1225.                    WHERE (table_name=? OR table_name=?)
  1226.                      AND (owner=? OR owner=?)';
  1227.         $stmt $db->prepare($query);
  1228.         if (PEAR::isError($stmt)) {
  1229.             return $stmt;
  1230.         }
  1231.         $args = array(
  1232.             $table,
  1233.             strtoupper($table),
  1234.             $owner,
  1235.             strtoupper($owner),
  1236.         );
  1237.         $result $stmt->execute($args);
  1238.         return $this->_fetchCol($resulttrue);
  1239.     }
  1240.  
  1241.     // }}}
  1242.     // {{{ createSequence()
  1243.  
  1244.     /**
  1245.      * create sequence
  1246.      *
  1247.      * @param object $db database object that is extended by this class
  1248.      * @param string $seq_name name of the sequence to be created
  1249.      * @param string $start start value of the sequence; default is 1
  1250.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1251.      * @access public
  1252.      */
  1253.     function createSequence($seq_name$start = 1)
  1254.     {
  1255.         $db =$this->getDBInstance();
  1256.         if (PEAR::isError($db)) {
  1257.             return $db;
  1258.         }
  1259.  
  1260.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  1261.         $query = "CREATE SEQUENCE $sequence_name START WITH $start INCREMENT BY 1 NOCACHE";
  1262.         $query.= ($start < 1 ? " MINVALUE $start" : '');
  1263.         return $db->exec($query);
  1264.     }
  1265.  
  1266.     // }}}
  1267.     // {{{ dropSequence()
  1268.  
  1269.     /**
  1270.      * drop existing sequence
  1271.      *
  1272.      * @param object $db database object that is extended by this class
  1273.      * @param string $seq_name name of the sequence to be dropped
  1274.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1275.      * @access public
  1276.      */
  1277.     function dropSequence($seq_name)
  1278.     {
  1279.         $db =$this->getDBInstance();
  1280.         if (PEAR::isError($db)) {
  1281.             return $db;
  1282.         }
  1283.  
  1284.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  1285.         return $db->exec("DROP SEQUENCE $sequence_name");
  1286.     }
  1287.  
  1288.     // }}}
  1289.     // {{{ listSequences()
  1290.  
  1291.     /**
  1292.      * list all sequences in the current database
  1293.      *
  1294.      * @param string owner, the current is default
  1295.      * @return mixed array of sequence names on success, a MDB2 error on failure
  1296.      * @access public
  1297.      */
  1298.     function listSequences($owner = null)
  1299.     {
  1300.         $db =$this->getDBInstance();
  1301.         if (PEAR::isError($db)) {
  1302.             return $db;
  1303.         }
  1304.  
  1305.         if (empty($owner)) {
  1306.             $owner $db->dsn['username'];
  1307.         }
  1308.  
  1309.         $query 'SELECT sequence_name
  1310.                     FROM sys.all_sequences
  1311.                    WHERE (sequence_owner=? OR sequence_owner=?)';
  1312.         $stmt $db->prepare($query);
  1313.         if (PEAR::isError($stmt)) {
  1314.             return $stmt;
  1315.         }
  1316.         $result $stmt->execute(array($ownerstrtoupper($owner)));
  1317.         if (PEAR::isError($result)) {
  1318.             return $result;
  1319.         }
  1320.         $col $result->fetchCol();
  1321.         if (PEAR::isError($col)) {
  1322.             return $col;
  1323.         }
  1324.         $result->free();
  1325.         
  1326.         foreach ($col as $k => $v{
  1327.             $col[$k$this->_fixSequenceName($v);
  1328.         }
  1329.  
  1330.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE
  1331.             && $db->options['field_case'== CASE_LOWER
  1332.         {
  1333.             $col array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$col);
  1334.         }
  1335.         return $col;
  1336.     }
  1337. }
  1338. ?>

Documentation generated on Mon, 11 Mar 2019 15:28:32 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.