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

Source for file Common.php

Documentation is available at Common.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: Common.php,v 1.42 2008/01/12 12:50:58 quipo Exp $
  46. //
  47.  
  48. /**
  49.  * @package MDB2
  50.  * @category Database
  51.  */
  52.  
  53. /**
  54.  * These are constants for the tableInfo-function
  55.  * they are bitwised or'ed. so if there are more constants to be defined
  56.  * in the future, adjust MDB2_TABLEINFO_FULL accordingly
  57.  */
  58.  
  59. define('MDB2_TABLEINFO_ORDER',      1);
  60. define('MDB2_TABLEINFO_ORDERTABLE'2);
  61. define('MDB2_TABLEINFO_FULL',       3);
  62.  
  63. /**
  64.  * Base class for the schema reverse engineering module that is extended by each MDB2 driver
  65.  *
  66.  * To load this module in the MDB2 object:
  67.  * $mdb->loadModule('Reverse');
  68.  *
  69.  * @package MDB2
  70.  * @category Database
  71.  * @author  Lukas Smith <smith@pooteeweet.org>
  72.  */
  73. {
  74.     // {{{ splitTableSchema()
  75.  
  76.     /**
  77.      * Split the "[owner|schema].table" notation into an array
  78.      * @access private
  79.      */
  80.     function splitTableSchema($table)
  81.     {
  82.         $ret = array();
  83.         if (strpos($table'.'!== false{
  84.             return explode('.'$table);
  85.         }
  86.         return array(null$table);
  87.     }
  88.  
  89.     // }}}
  90.     // {{{ getTableFieldDefinition()
  91.  
  92.     /**
  93.      * Get the structure of a field into an array
  94.      *
  95.      * @param string    $table     name of table that should be used in method
  96.      * @param string    $field     name of field that should be used in method
  97.      * @return mixed data array on success, a MDB2 error on failure.
  98.      *           The returned array contains an array for each field definition,
  99.      *           with all or some of these indices, depending on the field data type:
  100.      *           [notnull] [nativetype] [length] [fixed] [default] [type] [mdb2type]
  101.      * @access public
  102.      */
  103.     function getTableFieldDefinition($table$field)
  104.     {
  105.         $db =$this->getDBInstance();
  106.         if (PEAR::isError($db)) {
  107.             return $db;
  108.         }
  109.  
  110.         return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  111.             'method not implemented'__FUNCTION__);
  112.     }
  113.  
  114.     // }}}
  115.     // {{{ getTableIndexDefinition()
  116.  
  117.     /**
  118.      * Get the structure of an index into an array
  119.      *
  120.      * @param string    $table      name of table that should be used in method
  121.      * @param string    $index      name of index that should be used in method
  122.      * @return mixed data array on success, a MDB2 error on failure
  123.      *           The returned array has this structure:
  124.      *           </pre>
  125.      *           array (
  126.      *               [fields] => array (
  127.      *                   [field1name] => array() // one entry per each field covered
  128.      *                   [field2name] => array() // by the index
  129.      *                   [field3name] => array(
  130.      *                       [sorting] => ascending
  131.      *                   )
  132.      *               )
  133.      *           );
  134.      *           </pre>
  135.      * @access public
  136.      */
  137.     function getTableIndexDefinition($table$index)
  138.     {
  139.         $db =$this->getDBInstance();
  140.         if (PEAR::isError($db)) {
  141.             return $db;
  142.         }
  143.  
  144.         return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  145.             'method not implemented'__FUNCTION__);
  146.     }
  147.  
  148.     // }}}
  149.     // {{{ getTableConstraintDefinition()
  150.  
  151.     /**
  152.      * Get the structure of an constraints into an array
  153.      *
  154.      * @param string    $table      name of table that should be used in method
  155.      * @param string    $index      name of index that should be used in method
  156.      * @return mixed data array on success, a MDB2 error on failure
  157.      *           The returned array has this structure:
  158.      *           <pre>
  159.      *           array (
  160.      *               [primary] => 0
  161.      *               [unique]  => 0
  162.      *               [foreign] => 1
  163.      *               [check]   => 0
  164.      *               [fields] => array (
  165.      *                   [field1name] => array() // one entry per each field covered
  166.      *                   [field2name] => array() // by the index
  167.      *                   [field3name] => array(
  168.      *                       [sorting]  => ascending
  169.      *                       [position] => 3
  170.      *                   )
  171.      *               )
  172.      *               [references] => array(
  173.      *                   [table] => name
  174.      *                   [fields] => array(
  175.      *                       [field1name] => array(  //one entry per each referenced field
  176.      *                            [position] => 1
  177.      *                       )
  178.      *                   )
  179.      *               )
  180.      *               [deferrable] => 0
  181.      *               [initiallydeferred] => 0
  182.      *               [onupdate] => CASCADE|RESTRICT|SET NULL|SET DEFAULT|NO ACTION
  183.      *               [ondelete] => CASCADE|RESTRICT|SET NULL|SET DEFAULT|NO ACTION
  184.      *               [match] => SIMPLE|PARTIAL|FULL
  185.      *           );
  186.      *           </pre>
  187.      * @access public
  188.      */
  189.     function getTableConstraintDefinition($table$index)
  190.     {
  191.         $db =$this->getDBInstance();
  192.         if (PEAR::isError($db)) {
  193.             return $db;
  194.         }
  195.  
  196.         return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  197.             'method not implemented'__FUNCTION__);
  198.     }
  199.  
  200.     // }}}
  201.     // {{{ getSequenceDefinition()
  202.  
  203.     /**
  204.      * Get the structure of a sequence into an array
  205.      *
  206.      * @param string    $sequence   name of sequence that should be used in method
  207.      * @return mixed data array on success, a MDB2 error on failure
  208.      *           The returned array has this structure:
  209.      *           <pre>
  210.      *           array (
  211.      *               [start] => n
  212.      *           );
  213.      *           </pre>
  214.      * @access public
  215.      */
  216.     function getSequenceDefinition($sequence)
  217.     {
  218.         $db =$this->getDBInstance();
  219.         if (PEAR::isError($db)) {
  220.             return $db;
  221.         }
  222.  
  223.         $start $db->currId($sequence);
  224.         if (PEAR::isError($start)) {
  225.             return $start;
  226.         }
  227.         if ($db->supports('current_id')) {
  228.             $start++;
  229.         else {
  230.             $db->warnings['database does not support getting current
  231.                 sequence value, the sequence value was incremented';
  232.         }
  233.         $definition = array();
  234.         if ($start != 1{
  235.             $definition = array('start' => $start);
  236.         }
  237.         return $definition;
  238.     }
  239.  
  240.     // }}}
  241.     // {{{ getTriggerDefinition()
  242.  
  243.     /**
  244.      * Get the structure of a trigger into an array
  245.      *
  246.      * EXPERIMENTAL
  247.      *
  248.      * WARNING: this function is experimental and may change the returned value
  249.      * at any time until labelled as non-experimental
  250.      *
  251.      * @param string    $trigger    name of trigger that should be used in method
  252.      * @return mixed data array on success, a MDB2 error on failure
  253.      *           The returned array has this structure:
  254.      *           <pre>
  255.      *           array (
  256.      *               [trigger_name]    => 'trigger name',
  257.      *               [table_name]      => 'table name',
  258.      *               [trigger_body]    => 'trigger body definition',
  259.      *               [trigger_type]    => 'BEFORE' | 'AFTER',
  260.      *               [trigger_event]   => 'INSERT' | 'UPDATE' | 'DELETE'
  261.      *                   //or comma separated list of multiple events, when supported
  262.      *               [trigger_enabled] => true|false
  263.      *               [trigger_comment] => 'trigger comment',
  264.      *           );
  265.      *           </pre>
  266.      *           The oci8 driver also returns a [when_clause] index.
  267.      * @access public
  268.      */
  269.     function getTriggerDefinition($trigger)
  270.     {
  271.         $db =$this->getDBInstance();
  272.         if (PEAR::isError($db)) {
  273.             return $db;
  274.         }
  275.  
  276.         return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  277.             'method not implemented'__FUNCTION__);
  278.     }
  279.  
  280.     // }}}
  281.     // {{{ tableInfo()
  282.  
  283.     /**
  284.      * Returns information about a table or a result set
  285.      *
  286.      * The format of the resulting array depends on which <var>$mode</var>
  287.      * you select.  The sample output below is based on this query:
  288.      * <pre>
  289.      *    SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
  290.      *    FROM tblFoo
  291.      *    JOIN tblBar ON tblFoo.fldId = tblBar.fldId
  292.      * </pre>
  293.      *
  294.      * <ul>
  295.      * <li>
  296.      *
  297.      * <kbd>null</kbd> (default)
  298.      *   <pre>
  299.      *   [0] => Array (
  300.      *       [table] => tblFoo
  301.      *       [name] => fldId
  302.      *       [type] => int
  303.      *       [len] => 11
  304.      *       [flags] => primary_key not_null
  305.      *   )
  306.      *   [1] => Array (
  307.      *       [table] => tblFoo
  308.      *       [name] => fldPhone
  309.      *       [type] => string
  310.      *       [len] => 20
  311.      *       [flags] =>
  312.      *   )
  313.      *   [2] => Array (
  314.      *       [table] => tblBar
  315.      *       [name] => fldId
  316.      *       [type] => int
  317.      *       [len] => 11
  318.      *       [flags] => primary_key not_null
  319.      *   )
  320.      *   </pre>
  321.      *
  322.      * </li><li>
  323.      *
  324.      * <kbd>MDB2_TABLEINFO_ORDER</kbd>
  325.      *
  326.      *   <p>In addition to the information found in the default output,
  327.      *   a notation of the number of columns is provided by the
  328.      *   <samp>num_fields</samp> element while the <samp>order</samp>
  329.      *   element provides an array with the column names as the keys and
  330.      *   their location index number (corresponding to the keys in the
  331.      *   the default output) as the values.</p>
  332.      *
  333.      *   <p>If a result set has identical field names, the last one is
  334.      *   used.</p>
  335.      *
  336.      *   <pre>
  337.      *   [num_fields] => 3
  338.      *   [order] => Array (
  339.      *       [fldId] => 2
  340.      *       [fldTrans] => 1
  341.      *   )
  342.      *   </pre>
  343.      *
  344.      * </li><li>
  345.      *
  346.      * <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>
  347.      *
  348.      *   <p>Similar to <kbd>MDB2_TABLEINFO_ORDER</kbd> but adds more
  349.      *   dimensions to the array in which the table names are keys and
  350.      *   the field names are sub-keys.  This is helpful for queries that
  351.      *   join tables which have identical field names.</p>
  352.      *
  353.      *   <pre>
  354.      *   [num_fields] => 3
  355.      *   [ordertable] => Array (
  356.      *       [tblFoo] => Array (
  357.      *           [fldId] => 0
  358.      *           [fldPhone] => 1
  359.      *       )
  360.      *       [tblBar] => Array (
  361.      *           [fldId] => 2
  362.      *       )
  363.      *   )
  364.      *   </pre>
  365.      *
  366.      * </li>
  367.      * </ul>
  368.      *
  369.      * The <samp>flags</samp> element contains a space separated list
  370.      * of extra information about the field.  This data is inconsistent
  371.      * between DBMS's due to the way each DBMS works.
  372.      *   + <samp>primary_key</samp>
  373.      *   + <samp>unique_key</samp>
  374.      *   + <samp>multiple_key</samp>
  375.      *   + <samp>not_null</samp>
  376.      *
  377.      * Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
  378.      * elements if <var>$result</var> is a table name.  The following DBMS's
  379.      * provide full information from queries:
  380.      *   + fbsql
  381.      *   + mysql
  382.      *
  383.      * If the 'portability' option has <samp>MDB2_PORTABILITY_FIX_CASE</samp>
  384.      * turned on, the names of tables and fields will be lower or upper cased.
  385.      *
  386.      * @param object|string $result  MDB2_result object from a query or a
  387.      *                                 string containing the name of a table.
  388.      *                                 While this also accepts a query result
  389.      *                                 resource identifier, this behavior is
  390.      *                                 deprecated.
  391.      * @param int  $mode   either unused or one of the tableInfo modes:
  392.      *                      <kbd>MDB2_TABLEINFO_ORDERTABLE</kbd>,
  393.      *                      <kbd>MDB2_TABLEINFO_ORDER</kbd> or
  394.      *                      <kbd>MDB2_TABLEINFO_FULL</kbd> (which does both).
  395.      *                      These are bitwise, so the first two can be
  396.      *                      combined using <kbd>|</kbd>.
  397.      *
  398.      * @return array  an associative array with the information requested.
  399.      *                  A MDB2_Error object on failure.
  400.      *
  401.      * @see MDB2_Driver_Common::setOption()
  402.      */
  403.     function tableInfo($result$mode = null)
  404.     {
  405.         $db =$this->getDBInstance();
  406.         if (PEAR::isError($db)) {
  407.             return $db;
  408.         }
  409.  
  410.         if (!is_string($result)) {
  411.             return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  412.                 'method not implemented'__FUNCTION__);
  413.         }
  414.  
  415.         $db->loadModule('Manager'nulltrue);
  416.         $fields $db->manager->listTableFields($result);
  417.         if (PEAR::isError($fields)) {
  418.             return $fields;
  419.         }
  420.  
  421.         $flags = array();
  422.  
  423.         $idxname_format $db->getOption('idxname_format');
  424.         $db->setOption('idxname_format''%s');
  425.  
  426.         $indexes $db->manager->listTableIndexes($result);
  427.         if (PEAR::isError($indexes)) {
  428.             $db->setOption('idxname_format'$idxname_format);
  429.             return $indexes;
  430.         }
  431.  
  432.         foreach ($indexes as $index{
  433.             $definition $this->getTableIndexDefinition($result$index);
  434.             if (PEAR::isError($definition)) {
  435.                 $db->setOption('idxname_format'$idxname_format);
  436.                 return $definition;
  437.             }
  438.             if (count($definition['fields']> 1{
  439.                 foreach ($definition['fields'as $field => $sort{
  440.                     $flags[$field'multiple_key';
  441.                 }
  442.             }
  443.         }
  444.  
  445.         $constraints $db->manager->listTableConstraints($result);
  446.         if (PEAR::isError($constraints)) {
  447.             return $constraints;
  448.         }
  449.  
  450.         foreach ($constraints as $constraint{
  451.             $definition $this->getTableConstraintDefinition($result$constraint);
  452.             if (PEAR::isError($definition)) {
  453.                 $db->setOption('idxname_format'$idxname_format);
  454.                 return $definition;
  455.             }
  456.             $flag !empty($definition['primary'])
  457.                 ? 'primary_key' (!empty($definition['unique'])
  458.                     ? 'unique_key' : false);
  459.             if ($flag{
  460.                 foreach ($definition['fields'as $field => $sort{
  461.                     if (empty($flags[$field]|| $flags[$field!= 'primary_key'{
  462.                         $flags[$field$flag;
  463.                     }
  464.                 }
  465.             }
  466.         }
  467.  
  468.         $res = array();
  469.  
  470.         if ($mode{
  471.             $res['num_fields'count($fields);
  472.         }
  473.  
  474.         foreach ($fields as $i => $field{
  475.             $definition $this->getTableFieldDefinition($result$field);
  476.             if (PEAR::isError($definition)) {
  477.                 $db->setOption('idxname_format'$idxname_format);
  478.                 return $definition;
  479.             }
  480.             $res[$i$definition[0];
  481.             $res[$i]['name'$field;
  482.             $res[$i]['table'$result;
  483.             $res[$i]['type'preg_replace('/^([a-z]+).*$/i''\\1'trim($definition[0]['nativetype']));
  484.             // 'primary_key', 'unique_key', 'multiple_key'
  485.             $res[$i]['flags'= empty($flags[$field]'' $flags[$field];
  486.             // not_null', 'unsigned', 'auto_increment', 'default_[rawencodedvalue]'
  487.             if (!empty($res[$i]['notnull'])) {
  488.                 $res[$i]['flags'].= ' not_null';
  489.             }
  490.             if (!empty($res[$i]['unsigned'])) {
  491.                 $res[$i]['flags'].= ' unsigned';
  492.             }
  493.             if (!empty($res[$i]['auto_increment'])) {
  494.                 $res[$i]['flags'].= ' autoincrement';
  495.             }
  496.             if (!empty($res[$i]['default'])) {
  497.                 $res[$i]['flags'].= ' default_'.rawurlencode($res[$i]['default']);
  498.             }
  499.  
  500.             if ($mode MDB2_TABLEINFO_ORDER{
  501.                 $res['order'][$res[$i]['name']] $i;
  502.             }
  503.             if ($mode MDB2_TABLEINFO_ORDERTABLE{
  504.                 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] $i;
  505.             }
  506.         }
  507.  
  508.         $db->setOption('idxname_format'$idxname_format);
  509.         return $res;
  510.     }
  511. }
  512. ?>

Documentation generated on Sat, 15 Mar 2008 05:30:12 -0400 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.