home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / MDB2 / Driver / Reverse / Common.php next >
Encoding:
PHP Script  |  2008-07-02  |  17.4 KB  |  476 lines

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