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-2007 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.96 2007/12/03 20:59:15 quipo 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.         if (!$db->options['emulate_database']{
  77.             return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  78.                 'database creation is only supported if the "emulate_database" option is enabled'__FUNCTION__);
  79.         }
  80.  
  81.         $username $db->options['database_name_prefix'].$name;
  82.         $password $db->dsn['password'$db->dsn['password'$name;
  83.         $tablespace $db->options['default_tablespace']
  84.             ? ' DEFAULT TABLESPACE '.$db->options['default_tablespace''';
  85.  
  86.         $query 'CREATE USER '.$username.' IDENTIFIED BY '.$password.$tablespace;
  87.         $result $db->standaloneQuery($querynulltrue);
  88.         if (PEAR::isError($result)) {
  89.             return $result;
  90.         }
  91.         $query 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO '.$username;
  92.         $result $db->standaloneQuery($querynulltrue);
  93.         if (PEAR::isError($result)) {
  94.             $query 'DROP USER '.$username.' CASCADE';
  95.             $result2 $db->standaloneQuery($querynulltrue);
  96.             if (PEAR::isError($result2)) {
  97.                 return $db->raiseError($result2nullnull,
  98.                     'could not setup the database user'__FUNCTION__);
  99.             }
  100.             return $result;
  101.         }
  102.         return MDB2_OK;
  103.     }
  104.  
  105.     // }}}
  106.     // {{{ dropDatabase()
  107.  
  108.     /**
  109.      * drop an existing database
  110.      *
  111.      * @param object $db database object that is extended by this class
  112.      * @param string $name name of the database that should be dropped
  113.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  114.      * @access public
  115.      */
  116.     function dropDatabase($name)
  117.     {
  118.         $db =$this->getDBInstance();
  119.         if (PEAR::isError($db)) {
  120.             return $db;
  121.         }
  122.  
  123.         if (!$db->options['emulate_database']{
  124.             return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  125.                 'database dropping is only supported if the "emulate_database" option is enabled'__FUNCTION__);
  126.         }
  127.  
  128.         $username $db->options['database_name_prefix'].$name;
  129.         return $db->standaloneQuery('DROP USER '.$username.' CASCADE'nulltrue);
  130.     }
  131.  
  132.  
  133.     // }}}
  134.     // {{{ _makeAutoincrement()
  135.  
  136.     /**
  137.      * add an autoincrement sequence + trigger
  138.      *
  139.      * @param string $name  name of the PK field
  140.      * @param string $table name of the table
  141.      * @param string $start start value for the sequence
  142.      * @return mixed        MDB2_OK on success, a MDB2 error on failure
  143.      * @access private
  144.      */
  145.     function _makeAutoincrement($name$table$start = 1)
  146.     {
  147.         $db =$this->getDBInstance();
  148.         if (PEAR::isError($db)) {
  149.             return $db;
  150.         }
  151.  
  152.         $table strtoupper($table);
  153.         $index_name  $table '_AI_PK';
  154.         $definition = array(
  155.             'primary' => true,
  156.             'fields' => array($name => true),
  157.         );
  158.         $result $this->createConstraint($table$index_name$definition);
  159.         if (PEAR::isError($result)) {
  160.             return $db->raiseError($resultnullnull,
  161.                 'primary key for autoincrement PK could not be created'__FUNCTION__);
  162.         }
  163.  
  164.         if (is_null($start)) {
  165.             $db->beginTransaction();
  166.             $query 'SELECT MAX(' $db->quoteIdentifier($nametrue') FROM ' $db->quoteIdentifier($tabletrue);
  167.             $start $this->db->queryOne($query'integer');
  168.             if (PEAR::isError($start)) {
  169.                 return $start;
  170.             }
  171.             ++$start;
  172.             $result $this->createSequence($table$start);
  173.             $db->commit();
  174.         else {
  175.             $result $this->createSequence($table$start);
  176.         }
  177.         if (PEAR::isError($result)) {
  178.             return $db->raiseError($resultnullnull,
  179.                 'sequence for autoincrement PK could not be created'__FUNCTION__);
  180.         }
  181.         $sequence_name         $db->getSequenceName($table);
  182.         $trigger_name          $db->quoteIdentifier($table '_AI_PK'true);
  183.         $sequence_name_quoted  $db->quoteIdentifier($sequence_nametrue);
  184.         $table $db->quoteIdentifier($tabletrue);
  185.         $name  $db->quoteIdentifier($nametrue);
  186.         $trigger_sql '
  187. CREATE TRIGGER '.$trigger_name.'
  188.    BEFORE INSERT
  189.    ON '.$table.'
  190.    FOR EACH ROW
  191. DECLARE
  192.    last_Sequence NUMBER;
  193.    last_InsertID NUMBER;
  194. BEGIN
  195.    SELECT '.$sequence_name_quoted.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL;
  196.    IF (:NEW.'.$name.' IS NULL OR :NEW.'.$name.' = 0) THEN
  197.       SELECT '.$sequence_name_quoted.'.NEXTVAL INTO :NEW.'.$name.' FROM DUAL;
  198.    ELSE
  199.       SELECT NVL(Last_Number, 0) INTO last_Sequence
  200.         FROM User_Sequences
  201.        WHERE UPPER(Sequence_Name) = UPPER(\''.$sequence_name.'\');
  202.       SELECT :NEW.'.$name.' INTO last_InsertID FROM DUAL;
  203.       WHILE (last_InsertID > last_Sequence) LOOP
  204.          SELECT '.$sequence_name_quoted.'.NEXTVAL INTO last_Sequence FROM DUAL;
  205.       END LOOP;
  206.    END IF;
  207. END;
  208. ';
  209.         $result $db->exec($trigger_sql);
  210.         if (PEAR::isError($result)) {
  211.             return $result;
  212.         }
  213.         return MDB2_OK;
  214.     }
  215.  
  216.     // }}}
  217.     // {{{ _dropAutoincrement()
  218.  
  219.     /**
  220.      * drop an existing autoincrement sequence + trigger
  221.      *
  222.      * @param string $table name of the table
  223.      * @return mixed        MDB2_OK on success, a MDB2 error on failure
  224.      * @access private
  225.      */
  226.     function _dropAutoincrement($table)
  227.     {
  228.         $db =$this->getDBInstance();
  229.         if (PEAR::isError($db)) {
  230.             return $db;
  231.         }
  232.  
  233.         $table strtoupper($table);
  234.         $trigger_name $table '_AI_PK';
  235.         $trigger_name_quoted $db->quote($trigger_name'text');
  236.         $query 'SELECT trigger_name FROM user_triggers';
  237.         $query.= ' WHERE trigger_name='.$trigger_name_quoted.' OR trigger_name='.strtoupper($trigger_name_quoted);
  238.         $trigger $db->queryOne($query);
  239.         if (PEAR::isError($trigger)) {
  240.             return $trigger;
  241.         }
  242.  
  243.         if ($trigger{
  244.             $trigger_name  $db->quoteIdentifier($table '_AI_PK'true);
  245.             $trigger_sql 'DROP TRIGGER ' $trigger_name;
  246.             $result $db->exec($trigger_sql);
  247.             if (PEAR::isError($result)) {
  248.                 return $db->raiseError($resultnullnull,
  249.                     'trigger for autoincrement PK could not be dropped'__FUNCTION__);
  250.             }
  251.  
  252.             $result $this->dropSequence($table);
  253.             if (PEAR::isError($result)) {
  254.                 return $db->raiseError($resultnullnull,
  255.                     'sequence for autoincrement PK could not be dropped'__FUNCTION__);
  256.             }
  257.  
  258.             $index_name $table '_AI_PK';
  259.             $result $this->dropConstraint($table$index_name);
  260.             if (PEAR::isError($result)) {
  261.                 return $db->raiseError($resultnullnull,
  262.                     'primary key for autoincrement PK could not be dropped'__FUNCTION__);
  263.             }
  264.         }
  265.  
  266.         return MDB2_OK;
  267.     }
  268.  
  269.     // }}}
  270.     // {{{ _getTemporaryTableQuery()
  271.  
  272.     /**
  273.      * A method to return the required SQL string that fits between CREATE ... TABLE
  274.      * to create the table as a temporary table.
  275.      *
  276.      * @return string The string required to be placed between "CREATE" and "TABLE"
  277.      *                 to generate a temporary table, if possible.
  278.      */
  279.     function _getTemporaryTableQuery()
  280.     {
  281.         return 'GLOBAL TEMPORARY';
  282.     }
  283.  
  284.     // }}}
  285.     // {{{ _getAdvancedFKOptions()
  286.  
  287.     /**
  288.      * Return the FOREIGN KEY query section dealing with non-standard options
  289.      * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
  290.      *
  291.      * @param array $definition 
  292.      * @return string 
  293.      * @access protected
  294.      */
  295.     function _getAdvancedFKOptions($definition)
  296.     {
  297.         $query '';
  298.         if (!empty($definition['ondelete']&& (strtoupper($definition['ondelete']!= 'NO ACTION')) {
  299.             $query .= ' ON DELETE '.$definition['ondelete'];
  300.         }
  301.         if (!empty($definition['deferrable'])) {
  302.             $query .= ' DEFERRABLE';
  303.         else {
  304.             $query .= ' NOT DEFERRABLE';
  305.         }
  306.         if (!empty($definition['initiallydeferred'])) {
  307.             $query .= ' INITIALLY DEFERRED';
  308.         else {
  309.             $query .= ' INITIALLY IMMEDIATE';
  310.         }
  311.         return $query;
  312.     }
  313.  
  314.     // }}}
  315.     // {{{ createTable()
  316.  
  317.     /**
  318.      * create a new table
  319.      *
  320.      * @param string $name     Name of the database that should be created
  321.      * @param array $fields Associative array that contains the definition of each field of the new table
  322.      *                         The indexes of the array entries are the names of the fields of the table an
  323.      *                         the array entry values are associative arrays like those that are meant to be
  324.      *                          passed with the field definitions to get[Type]Declaration() functions.
  325.      *
  326.      *                         Example
  327.      *                         array(
  328.      *
  329.      *                             'id' => array(
  330.      *                                 'type' => 'integer',
  331.      *                                 'unsigned' => 1
  332.      *                                 'notnull' => 1
  333.      *                                 'default' => 0
  334.      *                             ),
  335.      *                             'name' => array(
  336.      *                                 'type' => 'text',
  337.      *                                 'length' => 12
  338.      *                             ),
  339.      *                             'password' => array(
  340.      *                                 'type' => 'text',
  341.      *                                 'length' => 12
  342.      *                             )
  343.      *                         );
  344.      * @param array $options  An associative array of table options:
  345.      *                           array(
  346.      *                               'comment' => 'Foo',
  347.      *                               'temporary' => true|false,
  348.      *                           );
  349.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  350.      * @access public
  351.      */
  352.     function createTable($name$fields$options = array())
  353.     {
  354.         $db =$this->getDBInstance();
  355.         if (PEAR::isError($db)) {
  356.             return $db;
  357.         }
  358.         $db->beginNestedTransaction();
  359.         $result = parent::createTable($name$fields$options);
  360.         if (!PEAR::isError($result)) {
  361.             foreach ($fields as $field_name => $field{
  362.                 if (!empty($field['autoincrement'])) {
  363.                     $result $this->_makeAutoincrement($field_name$name);
  364.                 }
  365.             }
  366.         }
  367.         $db->completeNestedTransaction();
  368.         return $result;
  369.     }
  370.  
  371.     // }}}
  372.     // {{{ dropTable()
  373.  
  374.     /**
  375.      * drop an existing table
  376.      *
  377.      * @param string $name name of the table that should be dropped
  378.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  379.      * @access public
  380.      */
  381.     function dropTable($name)
  382.     {
  383.         $db =$this->getDBInstance();
  384.         if (PEAR::isError($db)) {
  385.             return $db;
  386.         }
  387.         $db->beginNestedTransaction();
  388.         $result $this->_dropAutoincrement($name);
  389.         if (!PEAR::isError($result)) {
  390.             $result = parent::dropTable($name);
  391.         }
  392.         $db->completeNestedTransaction();
  393.         return $result;
  394.     }
  395.  
  396.     // }}}
  397.     // {{{ alterTable()
  398.  
  399.     /**
  400.      * alter an existing table
  401.      *
  402.      * @param string $name         name of the table that is intended to be changed.
  403.      * @param array $changes     associative array that contains the details of each type
  404.      *                              of change that is intended to be performed. The types of
  405.      *                              changes that are currently supported are defined as follows:
  406.      *
  407.      *                              name
  408.      *
  409.      *                                 New name for the table.
  410.      *
  411.      *                             add
  412.      *
  413.      *                                 Associative array with the names of fields to be added as
  414.      *                                  indexes of the array. The value of each entry of the array
  415.      *                                  should be set to another associative array with the properties
  416.      *                                  of the fields to be added. The properties of the fields should
  417.      *                                  be the same as defined by the MDB2 parser.
  418.      *
  419.      *
  420.      *                             remove
  421.      *
  422.      *                                 Associative array with the names of fields to be removed as indexes
  423.      *                                  of the array. Currently the values assigned to each entry are ignored.
  424.      *                                  An empty array should be used for future compatibility.
  425.      *
  426.      *                             rename
  427.      *
  428.      *                                 Associative array with the names of fields to be renamed as indexes
  429.      *                                  of the array. The value of each entry of the array should be set to
  430.      *                                  another associative array with the entry named name with the new
  431.      *                                  field name and the entry named Declaration that is expected to contain
  432.      *                                  the portion of the field declaration already in DBMS specific SQL code
  433.      *                                  as it is used in the CREATE TABLE statement.
  434.      *
  435.      *                             change
  436.      *
  437.      *                                 Associative array with the names of the fields to be changed as indexes
  438.      *                                  of the array. Keep in mind that if it is intended to change either the
  439.      *                                  name of a field and any other properties, the change array entries
  440.      *                                  should have the new names of the fields as array indexes.
  441.      *
  442.      *                                 The value of each entry of the array should be set to another associative
  443.      *                                  array with the properties of the fields to that are meant to be changed as
  444.      *                                  array entries. These entries should be assigned to the new values of the
  445.      *                                  respective properties. The properties of the fields should be the same
  446.      *                                  as defined by the MDB2 parser.
  447.      *
  448.      *                             Example
  449.      *                                 array(
  450.      *                                     'name' => 'userlist',
  451.      *                                     'add' => array(
  452.      *                                         'quota' => array(
  453.      *                                             'type' => 'integer',
  454.      *                                             'unsigned' => 1
  455.      *                                         )
  456.      *                                     ),
  457.      *                                     'remove' => array(
  458.      *                                         'file_limit' => array(),
  459.      *                                         'time_limit' => array()
  460.      *                                     ),
  461.      *                                     'change' => array(
  462.      *                                         'name' => array(
  463.      *                                             'length' => '20',
  464.      *                                             'definition' => array(
  465.      *                                                 'type' => 'text',
  466.      *                                                 'length' => 20,
  467.      *                                             ),
  468.      *                                         )
  469.      *                                     ),
  470.      *                                     'rename' => array(
  471.      *                                         'sex' => array(
  472.      *                                             'name' => 'gender',
  473.      *                                             'definition' => array(
  474.      *                                                 'type' => 'text',
  475.      *                                                 'length' => 1,
  476.      *                                                 'default' => 'M',
  477.      *                                             ),
  478.      *                                         )
  479.      *                                     )
  480.      *                                 )
  481.      *
  482.      * @param boolean $check     indicates whether the function should just check if the DBMS driver
  483.      *                              can perform the requested table alterations if the value is true or
  484.      *                              actually perform them otherwise.
  485.      * @access public
  486.      *
  487.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  488.      */
  489.     function alterTable($name$changes$check)
  490.     {
  491.         $db =$this->getDBInstance();
  492.         if (PEAR::isError($db)) {
  493.             return $db;
  494.         }
  495.  
  496.         foreach ($changes as $change_name => $change{
  497.             switch ($change_name{
  498.             case 'add':
  499.             case 'remove':
  500.             case 'change':
  501.             case 'name':
  502.             case 'rename':
  503.                 break;
  504.             default:
  505.                 return $db->raiseError(MDB2_ERROR_CANNOT_ALTERnullnull,
  506.                     'change type "'.$change_name.'" not yet supported'__FUNCTION__);
  507.             }
  508.         }
  509.  
  510.         if ($check{
  511.             return MDB2_OK;
  512.         }
  513.  
  514.         $name $db->quoteIdentifier($nametrue);
  515.  
  516.         if (!empty($changes['add']&& is_array($changes['add'])) {
  517.             $fields = array();
  518.             foreach ($changes['add'as $field_name => $field{
  519.                 $fields[$db->getDeclaration($field['type']$field_name$field);
  520.             }
  521.             $result $db->exec("ALTER TABLE $name ADD (". implode(', '$fields).')');
  522.             if (PEAR::isError($result)) {
  523.                 return $result;
  524.             }
  525.         }
  526.  
  527.         if (!empty($changes['change']&& is_array($changes['change'])) {
  528.             $fields = array();
  529.             foreach ($changes['change'as $field_name => $field{
  530.                 $fields[$field_name' ' $db->getDeclaration($field['definition']['type']''$field['definition']);
  531.             }
  532.             $result $db->exec("ALTER TABLE $name MODIFY (". implode(', '$fields).')');
  533.             if (PEAR::isError($result)) {
  534.                 return $result;
  535.             }
  536.         }
  537.  
  538.         if (!empty($changes['rename']&& is_array($changes['rename'])) {
  539.             foreach ($changes['rename'as $field_name => $field{
  540.                 $field_name $db->quoteIdentifier($field_nametrue);
  541.                 $query = "ALTER TABLE $name RENAME COLUMN $field_name TO ".$db->quoteIdentifier($field['name']);
  542.                 $result $db->exec($query);
  543.                 if (PEAR::isError($result)) {
  544.                     return $result;
  545.                 }
  546.             }
  547.         }
  548.  
  549.         if (!empty($changes['remove']&& is_array($changes['remove'])) {
  550.             $fields = array();
  551.             foreach ($changes['remove'as $field_name => $field{
  552.                 $fields[$db->quoteIdentifier($field_nametrue);
  553.             }
  554.             $result $db->exec("ALTER TABLE $name DROP COLUMN ". implode(', '$fields));
  555.             if (PEAR::isError($result)) {
  556.                 return $result;
  557.             }
  558.         }
  559.  
  560.         if (!empty($changes['name'])) {
  561.             $change_name $db->quoteIdentifier($changes['name']true);
  562.             $result $db->exec("ALTER TABLE $name RENAME TO ".$change_name);
  563.             if (PEAR::isError($result)) {
  564.                 return $result;
  565.             }
  566.         }
  567.  
  568.         return MDB2_OK;
  569.     }
  570.  
  571.     // }}}
  572.     // {{{ _fetchCol()
  573.  
  574.     /**
  575.      * Utility method to fetch and format a column from a resultset
  576.      *
  577.      * @param resource $result 
  578.      * @param boolean $fixname (used when listing indices or constraints)
  579.      * @return mixed array of names on success, a MDB2 error on failure
  580.      * @access private
  581.      */
  582.     function _fetchCol($result$fixname = false)
  583.     {
  584.         if (PEAR::isError($result)) {
  585.             return $result;
  586.         }
  587.         $col $result->fetchCol();
  588.         if (PEAR::isError($col)) {
  589.             return $col;
  590.         }
  591.         $result->free();
  592.         
  593.         $db =$this->getDBInstance();
  594.         if (PEAR::isError($db)) {
  595.             return $db;
  596.         }
  597.         
  598.         if ($fixname{
  599.             foreach ($col as $k => $v{
  600.                 $col[$k$this->_fixIndexName($v);
  601.             }
  602.         }
  603.         
  604.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE
  605.             && $db->options['field_case'== CASE_LOWER
  606.         {
  607.             $col array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$col);
  608.         }
  609.         return $col;
  610.     }
  611.  
  612.     // }}}
  613.     // {{{ listDatabases()
  614.  
  615.     /**
  616.      * list all databases
  617.      *
  618.      * @return mixed array of database names on success, a MDB2 error on failure
  619.      * @access public
  620.      */
  621.     function listDatabases()
  622.     {
  623.         $db =$this->getDBInstance();
  624.         if (PEAR::isError($db)) {
  625.             return $db;
  626.         }
  627.  
  628.         if (!$db->options['emulate_database']{
  629.             return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  630.                 'database listing is only supported if the "emulate_database" option is enabled'__FUNCTION__);
  631.         }
  632.  
  633.         if ($db->options['database_name_prefix']{
  634.             $query 'SELECT SUBSTR(username, ';
  635.             $query.= (strlen($db->options['database_name_prefix'])+1);
  636.             $query.= ") FROM sys.dba_users WHERE username LIKE '";
  637.             $query.= $db->options['database_name_prefix']."%'";
  638.         else {
  639.             $query 'SELECT username FROM sys.dba_users';
  640.         }
  641.         $result $db->standaloneQuery($queryarray('text')false);
  642.         return $this->_fetchCol($result);
  643.     }
  644.  
  645.     // }}}
  646.     // {{{ listUsers()
  647.  
  648.     /**
  649.      * list all users
  650.      *
  651.      * @return mixed array of user names on success, a MDB2 error on failure
  652.      * @access public
  653.      */
  654.     function listUsers()
  655.     {
  656.         $db =$this->getDBInstance();
  657.         if (PEAR::isError($db)) {
  658.             return $db;
  659.         }
  660.  
  661.         if ($db->options['emulate_database'&& $db->options['database_name_prefix']{
  662.             $query 'SELECT SUBSTR(username, ';
  663.             $query.= (strlen($db->options['database_name_prefix'])+1);
  664.             $query.= ") FROM sys.dba_users WHERE username NOT LIKE '";
  665.             $query.= $db->options['database_name_prefix']."%'";
  666.         else {
  667.             $query 'SELECT username FROM sys.dba_users';
  668.         }
  669.         return $db->queryCol($query);
  670.     }
  671.  
  672.     // }}}
  673.     // {{{ listViews()
  674.  
  675.     /**
  676.      * list all views in the current database
  677.      *
  678.      * @param string owner, the current is default
  679.      * @return mixed array of view names on success, a MDB2 error on failure
  680.      * @access public
  681.      */
  682.     function listViews($owner = null)
  683.     {
  684.         $db =$this->getDBInstance();
  685.         if (PEAR::isError($db)) {
  686.             return $db;
  687.         }
  688.         
  689.         if (empty($owner)) {
  690.             $owner $db->dsn['username'];
  691.         }
  692.  
  693.         $query 'SELECT view_name
  694.                     FROM sys.all_views
  695.                    WHERE owner=? OR owner=?';
  696.         $stmt $db->prepare($query);
  697.         if (PEAR::isError($stmt)) {
  698.             return $stmt;
  699.         }
  700.         $result $stmt->execute(array($ownerstrtoupper($owner)));
  701.         return $this->_fetchCol($result);
  702.     }
  703.  
  704.     // }}}
  705.     // {{{ listFunctions()
  706.  
  707.     /**
  708.      * list all functions in the current database
  709.      *
  710.      * @param string owner, the current is default
  711.      * @return mixed array of function names on success, a MDB2 error on failure
  712.      * @access public
  713.      */
  714.     function listFunctions($owner = null)
  715.     {
  716.         $db =$this->getDBInstance();
  717.         if (PEAR::isError($db)) {
  718.             return $db;
  719.         }
  720.  
  721.         if (empty($owner)) {
  722.             $owner $db->dsn['username'];
  723.         }
  724.  
  725.         $query "SELECT name
  726.                     FROM sys.all_source
  727.                    WHERE line = 1
  728.                      AND type = 'FUNCTION'
  729.                      AND (owner=? OR owner=?)";
  730.         $stmt $db->prepare($query);
  731.         if (PEAR::isError($stmt)) {
  732.             return $stmt;
  733.         }
  734.         $result $stmt->execute(array($ownerstrtoupper($owner)));
  735.         return $this->_fetchCol($result);
  736.     }
  737.  
  738.     // }}}
  739.     // {{{ listTableTriggers()
  740.  
  741.     /**
  742.      * list all triggers in the database that reference a given table
  743.      *
  744.      * @param string table for which all referenced triggers should be found
  745.      * @return mixed array of trigger names on success, a MDB2 error on failure
  746.      * @access public
  747.      */
  748.     function listTableTriggers($table = null)
  749.     {
  750.         $db =$this->getDBInstance();
  751.         if (PEAR::isError($db)) {
  752.             return $db;
  753.         }
  754.  
  755.         if (empty($owner)) {
  756.             $owner $db->dsn['username'];
  757.         }
  758.  
  759.         $query "SELECT trigger_name
  760.                     FROM sys.all_triggers
  761.                    WHERE (table_name=? OR table_name=?)
  762.                      AND (owner=? OR owner=?)";
  763.         $stmt $db->prepare($query);
  764.         if (PEAR::isError($stmt)) {
  765.             return $stmt;
  766.         }
  767.         $args = array(
  768.             $table,
  769.             strtoupper($table),
  770.             $owner,
  771.             strtoupper($owner),
  772.         );
  773.         $result $stmt->execute($args);
  774.         return $this->_fetchCol($result);
  775.     }
  776.  
  777.     // }}}
  778.     // {{{ listTables()
  779.  
  780.     /**
  781.      * list all tables in the database
  782.      *
  783.      * @param string owner, the current is default
  784.      * @return mixed array of table names on success, a MDB2 error on failure
  785.      * @access public
  786.      */
  787.     function listTables($owner = null)
  788.     {
  789.         $db =$this->getDBInstance();
  790.         if (PEAR::isError($db)) {
  791.             return $db;
  792.         }
  793.         
  794.         if (empty($owner)) {
  795.             $owner $db->dsn['username'];
  796.         }
  797.  
  798.         $query 'SELECT table_name
  799.                     FROM sys.all_tables
  800.                    WHERE owner=? OR owner=?';
  801.         $stmt $db->prepare($query);
  802.         if (PEAR::isError($stmt)) {
  803.             return $stmt;
  804.         }
  805.         $result $stmt->execute(array($ownerstrtoupper($owner)));
  806.         return $this->_fetchCol($result);
  807.     }
  808.  
  809.     // }}}
  810.     // {{{ listTableFields()
  811.  
  812.     /**
  813.      * list all fields in a table in the current database
  814.      *
  815.      * @param string $table name of table that should be used in method
  816.      * @return mixed array of field names on success, a MDB2 error on failure
  817.      * @access public
  818.      */
  819.     function listTableFields($table)
  820.     {
  821.         $db =$this->getDBInstance();
  822.         if (PEAR::isError($db)) {
  823.             return $db;
  824.         }
  825.         
  826.         list($owner$table$this->splitTableSchema($table);
  827.         if (empty($owner)) {
  828.             $owner $db->dsn['username'];
  829.         }
  830.  
  831.         $query 'SELECT column_name
  832.                     FROM all_tab_columns
  833.                    WHERE (table_name=? OR table_name=?)
  834.                      AND (owner=? OR owner=?)
  835.                 ORDER BY column_id';
  836.         $stmt $db->prepare($query);
  837.         if (PEAR::isError($stmt)) {
  838.             return $stmt;
  839.         }
  840.         $args = array(
  841.             $table,
  842.             strtoupper($table),
  843.             $owner,
  844.             strtoupper($owner),
  845.         );
  846.         $result $stmt->execute($args);
  847.         return $this->_fetchCol($result);
  848.     }
  849.  
  850.     // }}}
  851.     // {{{ listTableIndexes()
  852.  
  853.     /**
  854.      * list all indexes in a table
  855.      *
  856.      * @param string $table name of table that should be used in method
  857.      * @return mixed array of index names on success, a MDB2 error on failure
  858.      * @access public
  859.      */
  860.     function listTableIndexes($table)
  861.     {
  862.         $db =$this->getDBInstance();
  863.         if (PEAR::isError($db)) {
  864.             return $db;
  865.         }
  866.         
  867.         list($owner$table$this->splitTableSchema($table);
  868.         if (empty($owner)) {
  869.             $owner $db->dsn['username'];
  870.         }
  871.         
  872.         $query 'SELECT i.index_name name
  873.                     FROM all_indexes i
  874.                LEFT JOIN all_constraints c
  875.                       ON c.index_name = i.index_name
  876.                      AND c.owner = i.owner
  877.                      AND c.table_name = i.table_name
  878.                    WHERE (i.table_name=? OR i.table_name=?)
  879.                      AND (i.owner=? OR i.owner=?)
  880.                      AND c.index_name IS NULL
  881.                      AND i.generated=' .$db->quote('N''text');
  882.         $stmt $db->prepare($query);
  883.         if (PEAR::isError($stmt)) {
  884.             return $stmt;
  885.         }
  886.         $args = array(
  887.             $table,
  888.             strtoupper($table),
  889.             $owner,
  890.             strtoupper($owner),
  891.         );
  892.         $result $stmt->execute($args);
  893.         return $this->_fetchCol($resulttrue);
  894.     }
  895.  
  896.     // }}}
  897.     // {{{ listTableConstraints()
  898.  
  899.     /**
  900.      * list all constraints in a table
  901.      *
  902.      * @param string $table name of table that should be used in method
  903.      * @return mixed array of constraint names on success, a MDB2 error on failure
  904.      * @access public
  905.      */
  906.     function listTableConstraints($table)
  907.     {
  908.         $db =$this->getDBInstance();
  909.         if (PEAR::isError($db)) {
  910.             return $db;
  911.         }
  912.  
  913.         list($owner$table$this->splitTableSchema($table);
  914.         if (empty($owner)) {
  915.             $owner $db->dsn['username'];
  916.         }
  917.  
  918.         $query 'SELECT constraint_name
  919.                     FROM all_constraints
  920.                    WHERE (table_name=? OR table_name=?)
  921.                      AND (owner=? OR owner=?)';
  922.         $stmt $db->prepare($query);
  923.         if (PEAR::isError($stmt)) {
  924.             return $stmt;
  925.         }
  926.         $args = array(
  927.             $table,
  928.             strtoupper($table),
  929.             $owner,
  930.             strtoupper($owner),
  931.         );
  932.         $result $stmt->execute($args);
  933.         return $this->_fetchCol($resulttrue);
  934.     }
  935.  
  936.     // }}}
  937.     // {{{ createSequence()
  938.  
  939.     /**
  940.      * create sequence
  941.      *
  942.      * @param object $db database object that is extended by this class
  943.      * @param string $seq_name name of the sequence to be created
  944.      * @param string $start start value of the sequence; default is 1
  945.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  946.      * @access public
  947.      */
  948.     function createSequence($seq_name$start = 1)
  949.     {
  950.         $db =$this->getDBInstance();
  951.         if (PEAR::isError($db)) {
  952.             return $db;
  953.         }
  954.  
  955.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  956.         $query = "CREATE SEQUENCE $sequence_name START WITH $start INCREMENT BY 1 NOCACHE";
  957.         $query.= ($start < 1 ? " MINVALUE $start" : '');
  958.         return $db->exec($query);
  959.     }
  960.  
  961.     // }}}
  962.     // {{{ dropSequence()
  963.  
  964.     /**
  965.      * drop existing sequence
  966.      *
  967.      * @param object $db database object that is extended by this class
  968.      * @param string $seq_name name of the sequence to be dropped
  969.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  970.      * @access public
  971.      */
  972.     function dropSequence($seq_name)
  973.     {
  974.         $db =$this->getDBInstance();
  975.         if (PEAR::isError($db)) {
  976.             return $db;
  977.         }
  978.  
  979.         $sequence_name $db->quoteIdentifier($db->getSequenceName($seq_name)true);
  980.         return $db->exec("DROP SEQUENCE $sequence_name");
  981.     }
  982.  
  983.     // }}}
  984.     // {{{ listSequences()
  985.  
  986.     /**
  987.      * list all sequences in the current database
  988.      *
  989.      * @param string owner, the current is default
  990.      * @return mixed array of sequence names on success, a MDB2 error on failure
  991.      * @access public
  992.      */
  993.     function listSequences($owner = null)
  994.     {
  995.         $db =$this->getDBInstance();
  996.         if (PEAR::isError($db)) {
  997.             return $db;
  998.         }
  999.  
  1000.         if (empty($owner)) {
  1001.             $owner $db->dsn['username'];
  1002.         }
  1003.  
  1004.         $query 'SELECT sequence_name
  1005.                     FROM sys.all_sequences
  1006.                    WHERE (sequence_owner=? OR sequence_owner=?)';
  1007.         $stmt $db->prepare($query);
  1008.         if (PEAR::isError($stmt)) {
  1009.             return $stmt;
  1010.         }
  1011.         $result $stmt->execute(array($ownerstrtoupper($owner)));
  1012.         if (PEAR::isError($result)) {
  1013.             return $result;
  1014.         }
  1015.         $col $result->fetchCol();
  1016.         if (PEAR::isError($col)) {
  1017.             return $col;
  1018.         }
  1019.         $result->free();
  1020.         
  1021.         foreach ($col as $k => $v{
  1022.             $col[$k$this->_fixSequenceName($v);
  1023.         }
  1024.  
  1025.         if ($db->options['portability'MDB2_PORTABILITY_FIX_CASE
  1026.             && $db->options['field_case'== CASE_LOWER
  1027.         {
  1028.             $col array_map(($db->options['field_case'== CASE_LOWER ? 'strtolower' 'strtoupper')$col);
  1029.         }
  1030.         return $col;
  1031.     }
  1032. }
  1033. ?>

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