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 / mysql.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  18.0 KB  |  437 lines

  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: mysql.php,v 1.68 2007/03/29 18:18:06 quipo Exp $
  46. //
  47.  
  48. require_once 'MDB2/Driver/Reverse/Common.php';
  49.  
  50. /**
  51.  * MDB2 MySQL driver for the schema reverse engineering module
  52.  *
  53.  * @package MDB2
  54.  * @category Database
  55.  * @author  Lukas Smith <smith@pooteeweet.org>
  56.  * @author  Lorenzo Alberton <l.alberton@quipo.it>
  57.  */
  58. class MDB2_Driver_Reverse_mysql extends MDB2_Driver_Reverse_Common
  59. {
  60.     // {{{ getTableFieldDefinition()
  61.  
  62.     /**
  63.      * Get the structure of a field into an array
  64.      *
  65.      * @param string    $table       name of table that should be used in method
  66.      * @param string    $field_name  name of field that should be used in method
  67.      * @return mixed data array on success, a MDB2 error on failure
  68.      * @access public
  69.      */
  70.     function getTableFieldDefinition($table, $field_name)
  71.     {
  72.         $db =& $this->getDBInstance();
  73.         if (PEAR::isError($db)) {
  74.             return $db;
  75.         }
  76.  
  77.         $result = $db->loadModule('Datatype', null, true);
  78.         if (PEAR::isError($result)) {
  79.             return $result;
  80.         }
  81.         $table = $db->quoteIdentifier($table, true);
  82.         $query = "SHOW COLUMNS FROM $table LIKE ".$db->quote($field_name);
  83.         $columns = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
  84.         if (PEAR::isError($columns)) {
  85.             return $columns;
  86.         }
  87.         foreach ($columns as $column) {
  88.             $column = array_change_key_case($column, CASE_LOWER);
  89.             $column['name'] = $column['field'];
  90.             unset($column['field']);
  91.             if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
  92.                 if ($db->options['field_case'] == CASE_LOWER) {
  93.                     $column['name'] = strtolower($column['name']);
  94.                 } else {
  95.                     $column['name'] = strtoupper($column['name']);
  96.                 }
  97.             } else {
  98.                 $column = array_change_key_case($column, $db->options['field_case']);
  99.             }
  100.             if ($field_name == $column['name']) {
  101.                 $mapped_datatype = $db->datatype->mapNativeDatatype($column);
  102.                 if (PEAR::IsError($mapped_datatype)) {
  103.                     return $mapped_datatype;
  104.                 }
  105.                 list($types, $length, $unsigned, $fixed) = $mapped_datatype;
  106.                 $notnull = false;
  107.                 if (empty($column['null']) || $column['null'] !== 'YES') {
  108.                     $notnull = true;
  109.                 }
  110.                 $default = false;
  111.                 if (array_key_exists('default', $column)) {
  112.                     $default = $column['default'];
  113.                     if (is_null($default) && $notnull) {
  114.                         $default = '';
  115.                     }
  116.                 }
  117.                 $autoincrement = false;
  118.                 if (!empty($column['extra']) && $column['extra'] == 'auto_increment') {
  119.                     $autoincrement = true;
  120.                 }
  121.  
  122.                 $definition[0] = array(
  123.                     'notnull' => $notnull,
  124.                     'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type'])
  125.                 );
  126.                 if (!is_null($length)) {
  127.                     $definition[0]['length'] = $length;
  128.                 }
  129.                 if (!is_null($unsigned)) {
  130.                     $definition[0]['unsigned'] = $unsigned;
  131.                 }
  132.                 if (!is_null($fixed)) {
  133.                     $definition[0]['fixed'] = $fixed;
  134.                 }
  135.                 if ($default !== false) {
  136.                     $definition[0]['default'] = $default;
  137.                 }
  138.                 if ($autoincrement !== false) {
  139.                     $definition[0]['autoincrement'] = $autoincrement;
  140.                 }
  141.                 foreach ($types as $key => $type) {
  142.                     $definition[$key] = $definition[0];
  143.                     if ($type == 'clob' || $type == 'blob') {
  144.                         unset($definition[$key]['default']);
  145.                     }
  146.                     $definition[$key]['type'] = $type;
  147.                     $definition[$key]['mdb2type'] = $type;
  148.                 }
  149.                 return $definition;
  150.             }
  151.         }
  152.  
  153.         return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
  154.             'it was not specified an existing table column', __FUNCTION__);
  155.     }
  156.  
  157.     // }}}
  158.     // {{{ getTableIndexDefinition()
  159.  
  160.     /**
  161.      * Get the structure of an index into an array
  162.      *
  163.      * @param string    $table      name of table that should be used in method
  164.      * @param string    $constraint_name name of constraint that should be used in method
  165.      * @return mixed data array on success, a MDB2 error on failure
  166.      * @access public
  167.      */
  168.     function getTableIndexDefinition($table, $constraint_name)
  169.     {
  170.         $db =& $this->getDBInstance();
  171.         if (PEAR::isError($db)) {
  172.             return $db;
  173.         }
  174.  
  175.         $table = $db->quoteIdentifier($table, true);
  176.         $query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = %s */";
  177.         $constraint_name_mdb2 = $db->getIndexName($constraint_name);
  178.         $result = $db->queryRow(sprintf($query, $db->quote($constraint_name_mdb2)));
  179.         if (!PEAR::isError($result) && !is_null($result)) {
  180.             // apply 'idxname_format' only if the query succeeded, otherwise
  181.             // fallback to the given $index_name, without transformation
  182.             $constraint_name = $constraint_name_mdb2;
  183.         }
  184.         $result = $db->query(sprintf($query, $db->quote($constraint_name)));
  185.         if (PEAR::isError($result)) {
  186.             return $result;
  187.         }
  188.         $colpos = 1;
  189.         $definition = array();
  190.         while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
  191.             $row = array_change_key_case($row, CASE_LOWER);
  192.             $key_name = $row['key_name'];
  193.             if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
  194.                 if ($db->options['field_case'] == CASE_LOWER) {
  195.                     $key_name = strtolower($key_name);
  196.                 } else {
  197.                     $key_name = strtoupper($key_name);
  198.                 }
  199.             }
  200.             if ($constraint_name == $key_name) {
  201.                 if (!$row['non_unique']) {
  202.                     return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
  203.                         $constraint_name . ' is not an existing table constraint', __FUNCTION__);
  204.                 }
  205.                 $column_name = $row['column_name'];
  206.                 if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
  207.                     if ($db->options['field_case'] == CASE_LOWER) {
  208.                         $column_name = strtolower($column_name);
  209.                     } else {
  210.                         $column_name = strtoupper($column_name);
  211.                     }
  212.                 }
  213.                 $definition['fields'][$column_name] = array(
  214.                     'position' => $colpos++
  215.                 );
  216.                 if (!empty($row['collation'])) {
  217.                     $definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
  218.                         ? 'ascending' : 'descending');
  219.                 }
  220.             }
  221.         }
  222.         $result->free();
  223.         if (empty($definition['fields'])) {
  224.             return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
  225.                 $constraint_name . ' is not an existing table constraint', __FUNCTION__);
  226.         }
  227.         return $definition;
  228.     }
  229.  
  230.     // }}}
  231.     // {{{ getTableConstraintDefinition()
  232.  
  233.     /**
  234.      * Get the structure of a constraint into an array
  235.      *
  236.      * @param string    $table      name of table that should be used in method
  237.      * @param string    $index_name name of index that should be used in method
  238.      * @return mixed data array on success, a MDB2 error on failure
  239.      * @access public
  240.      */
  241.     function getTableConstraintDefinition($table, $index_name)
  242.     {
  243.         $db =& $this->getDBInstance();
  244.         if (PEAR::isError($db)) {
  245.             return $db;
  246.         }
  247.  
  248.         $table = $db->quoteIdentifier($table, true);
  249.         $query = "SHOW INDEX FROM $table /*!50002 WHERE Key_name = %s */";
  250.         if (strtolower($index_name) != 'primary') {
  251.             $index_name_mdb2 = $db->getIndexName($index_name);
  252.             $result = $db->queryRow(sprintf($query, $db->quote($index_name_mdb2)));
  253.             if (!PEAR::isError($result) && !is_null($result)) {
  254.                 // apply 'idxname_format' only if the query succeeded, otherwise
  255.                 // fallback to the given $index_name, without transformation
  256.                 $index_name = $index_name_mdb2;
  257.             }
  258.         }
  259.         $result = $db->query(sprintf($query, $db->quote($index_name)));
  260.         if (PEAR::isError($result)) {
  261.             return $result;
  262.         }
  263.         $colpos = 1;
  264.         $definition = array();
  265.         while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
  266.             $row = array_change_key_case($row, CASE_LOWER);
  267.             $key_name = $row['key_name'];
  268.             if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
  269.                 if ($db->options['field_case'] == CASE_LOWER) {
  270.                     $key_name = strtolower($key_name);
  271.                 } else {
  272.                     $key_name = strtoupper($key_name);
  273.                 }
  274.             }
  275.             if ($index_name == $key_name) {
  276.                 if ($row['non_unique']) {
  277.                     return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
  278.                         'it was not specified an existing table constraint', __FUNCTION__);
  279.                 }
  280.                 if ($row['key_name'] == 'PRIMARY') {
  281.                     $definition['primary'] = true;
  282.                 } else {
  283.                     $definition['unique'] = true;
  284.                 }
  285.                 $column_name = $row['column_name'];
  286.                 if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
  287.                     if ($db->options['field_case'] == CASE_LOWER) {
  288.                         $column_name = strtolower($column_name);
  289.                     } else {
  290.                         $column_name = strtoupper($column_name);
  291.                     }
  292.                 }
  293.                 $definition['fields'][$column_name] = array(
  294.                     'position' => $colpos++
  295.                 );
  296.                 if (!empty($row['collation'])) {
  297.                     $definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A'
  298.                         ? 'ascending' : 'descending');
  299.                 }
  300.             }
  301.         }
  302.         $result->free();
  303.         if (empty($definition['fields'])) {
  304.             return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null,
  305.                 'it was not specified an existing table constraint', __FUNCTION__);
  306.         }
  307.         return $definition;
  308.     }
  309.  
  310.     // }}}
  311.     // {{{ getTriggerDefinition()
  312.  
  313.     /**
  314.      * Get the structure of a trigger into an array
  315.      *
  316.      * EXPERIMENTAL
  317.      *
  318.      * WARNING: this function is experimental and may change the returned value
  319.      * at any time until labelled as non-experimental
  320.      *
  321.      * @param string    $trigger    name of trigger that should be used in method
  322.      * @return mixed data array on success, a MDB2 error on failure
  323.      * @access public
  324.      */
  325.     function getTriggerDefinition($trigger)
  326.     {
  327.         $db =& $this->getDBInstance();
  328.         if (PEAR::isError($db)) {
  329.             return $db;
  330.         }
  331.  
  332.         $query = 'SELECT trigger_name,
  333.                          event_object_table AS table_name,
  334.                          action_statement AS trigger_body,
  335.                          action_timing AS trigger_type,
  336.                          event_manipulation AS trigger_event
  337.                     FROM information_schema.triggers
  338.                    WHERE trigger_name = '. $db->quote($trigger, 'text');
  339.         $types = array(
  340.             'trigger_name'    => 'text',
  341.             'table_name'      => 'text',
  342.             'trigger_body'    => 'text',
  343.             'trigger_type'    => 'text',
  344.             'trigger_event'   => 'text',
  345.         );
  346.         $def = $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC);
  347.         if (PEAR::isError($def)) {
  348.             return $def;
  349.         }
  350.         $def['trigger_comment'] = '';
  351.         $def['trigger_enabled'] = true;
  352.         return $def;
  353.     }
  354.  
  355.     // }}}
  356.     // {{{ tableInfo()
  357.  
  358.     /**
  359.      * Returns information about a table or a result set
  360.      *
  361.      * @param object|string  $result  MDB2_result object from a query or a
  362.      *                                 string containing the name of a table.
  363.      *                                 While this also accepts a query result
  364.      *                                 resource identifier, this behavior is
  365.      *                                 deprecated.
  366.      * @param int            $mode    a valid tableInfo mode
  367.      *
  368.      * @return array  an associative array with the information requested.
  369.      *                 A MDB2_Error object on failure.
  370.      *
  371.      * @see MDB2_Driver_Common::setOption()
  372.      */
  373.     function tableInfo($result, $mode = null)
  374.     {
  375.         if (is_string($result)) {
  376.            return parent::tableInfo($result, $mode);
  377.         }
  378.  
  379.         $db =& $this->getDBInstance();
  380.         if (PEAR::isError($db)) {
  381.             return $db;
  382.         }
  383.  
  384.         $resource = MDB2::isResultCommon($result) ? $result->getResource() : $result;
  385.         if (!is_resource($resource)) {
  386.             return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA, null, null,
  387.                 'Could not generate result resource', __FUNCTION__);
  388.         }
  389.  
  390.         if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) {
  391.             if ($db->options['field_case'] == CASE_LOWER) {
  392.                 $case_func = 'strtolower';
  393.             } else {
  394.                 $case_func = 'strtoupper';
  395.             }
  396.         } else {
  397.             $case_func = 'strval';
  398.         }
  399.  
  400.         $count = @mysql_num_fields($resource);
  401.         $res   = array();
  402.  
  403.         if ($mode) {
  404.             $res['num_fields'] = $count;
  405.         }
  406.  
  407.         $db->loadModule('Datatype', null, true);
  408.         for ($i = 0; $i < $count; $i++) {
  409.             $res[$i] = array(
  410.                 'table' => $case_func(@mysql_field_table($resource, $i)),
  411.                 'name'  => $case_func(@mysql_field_name($resource, $i)),
  412.                 'type'  => @mysql_field_type($resource, $i),
  413.                 'length'   => @mysql_field_len($resource, $i),
  414.                 'flags' => @mysql_field_flags($resource, $i),
  415.             );
  416.             if ($res[$i]['type'] == 'string') {
  417.                 $res[$i]['type'] = 'char';
  418.             } elseif ($res[$i]['type'] == 'unknown') {
  419.                 $res[$i]['type'] = 'decimal';
  420.             }
  421.             $mdb2type_info = $db->datatype->mapNativeDatatype($res[$i]);
  422.             if (PEAR::isError($mdb2type_info)) {
  423.                return $mdb2type_info;
  424.             }
  425.             $res[$i]['mdb2type'] = $mdb2type_info[0][0];
  426.             if ($mode & MDB2_TABLEINFO_ORDER) {
  427.                 $res['order'][$res[$i]['name']] = $i;
  428.             }
  429.             if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
  430.                 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
  431.             }
  432.         }
  433.  
  434.         return $res;
  435.     }
  436. }
  437. ?>