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

Source for file mysql.php

Documentation is available at mysql.php

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PHP Version 4                                                        |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1998-2004 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@backendmedia.com>                         |
  43. // +----------------------------------------------------------------------+
  44. //
  45. // $Id: mysql.php,v 1.10 2004/04/10 10:46:53 lsmith 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@backendmedia.com>
  56.  */
  57. {
  58.     // }}}
  59.     // {{{ constructor
  60.  
  61.     /**
  62.      * Constructor
  63.      */
  64.     function MDB2_Driver_Reverse_mysql($db_index)
  65.     {
  66.         $this->MDB2_Driver_Reverse_Common($db_index);
  67.     }
  68.  
  69.     // }}}
  70.     // {{{ getTableFieldDefinition()
  71.  
  72.     /**
  73.      * get the stucture of a field into an array
  74.      *
  75.      * @param string    $table         name of table that should be used in method
  76.      * @param string    $field_name     name of field that should be used in method
  77.      * @return mixed data array on success, a MDB2 error on failure
  78.      * @access public
  79.      */
  80.     function getTableFieldDefinition($table, $field_name)
  81.     {
  82.         $db =& $GLOBALS['_MDB2_databases'][$this->db_index];
  83.         if ($field_name == $db->dummy_primary_key) {
  84.             return $db->raiseError(MDB2_ERROR, null, null,
  85.                 'getTableFieldDefinition: '.$db->dummy_primary_key.' is an hidden column');
  86.         }
  87.         $result = $db->query("SHOW COLUMNS FROM $table");
  88.         if (MDB2::isError($result)) {
  89.             return $result;
  90.         }
  91.         $columns = $result->getColumnNames();
  92.         if (MDB2::isError($columns)) {
  93.             return $columns;
  94.         }
  95.         if (!$db->options['portability'] & MDB2_PORTABILITY_LOWERCASE) {
  96.             $columns = array_change_key_case($columns, CASE_LOWER);
  97.         }
  98.         if (!isset($columns[$column = 'field'])
  99.             || !isset($columns[$column = 'type']))
  100.         {
  101.             return $db->raiseError(MDB2_ERROR, null, null,
  102.                 'getTableFieldDefinition: show columns does not return the column '.$column);
  103.         }
  104.         $field_column = $columns['field'];
  105.         $type_column = $columns['type'];
  106.         while (is_array($row = $result->fetchRow())) {
  107.             if ($field_name == $row[$field_column]) {
  108.                 $db_type = strtolower($row[$type_column]);
  109.                 $db_type = strtok($db_type, '(), ');
  110.                 if ($db_type == 'national') {
  111.                     $db_type = strtok('(), ');
  112.                 }
  113.                 $length = strtok('(), ');
  114.                 $decimal = strtok('(), ');
  115.                 $type = array();
  116.                 switch ($db_type) {
  117.                     case 'tinyint':
  118.                     case 'smallint':
  119.                     case 'mediumint':
  120.                     case 'int':
  121.                     case 'integer':
  122.                     case 'bigint':
  123.                         $type[0] = 'integer';
  124.                         if ($length == '1') {
  125.                             $type[1] = 'boolean';
  126.                             if (preg_match('/^[is|has]/', $field_name)) {
  127.                                 $type = array_reverse($type);
  128.                             }
  129.                         }
  130.                         break;
  131.                     case 'tinytext':
  132.                     case 'mediumtext':
  133.                     case 'longtext':
  134.                     case 'text':
  135.                     case 'char':
  136.                     case 'varchar':
  137.                         $type[0] = 'text';
  138.                         if ($decimal == 'binary') {
  139.                             $type[1] = 'blob';
  140.                         } elseif ($length == '1') {
  141.                             $type[1] = 'boolean';
  142.                             if (preg_match('/[is|has]/', $field_name)) {
  143.                                 $type = array_reverse($type);
  144.                             }
  145.                         } elseif (strstr($db_type, 'text'))
  146.                             $type[1] = 'clob';
  147.                         break;
  148.                     case 'enum':
  149.                         preg_match_all('/\'.+\'/U',$row[$type_column], $matches);
  150.                         $length = 0;
  151.                         if (is_array($matches)) {
  152.                             foreach ($matches[0] as $value) {
  153.                                 $length = max($length, strlen($value)-2);
  154.                             }
  155.                         }
  156.                         unset($decimal);
  157.                     case 'set':
  158.                         $type[0] = 'text';
  159.                         $type[1] = 'integer';
  160.                         break;
  161.                     case 'date':
  162.                         $type[0] = 'date';
  163.                         break;
  164.                     case 'datetime':
  165.                     case 'timestamp':
  166.                         $type[0] = 'timestamp';
  167.                         break;
  168.                     case 'time':
  169.                         $type[0] = 'time';
  170.                         break;
  171.                     case 'float':
  172.                     case 'double':
  173.                     case 'real':
  174.                         $type[0] = 'float';
  175.                         break;
  176.                     case 'decimal':
  177.                     case 'numeric':
  178.                         $type[0] = 'decimal';
  179.                         break;
  180.                     case 'tinyblob':
  181.                     case 'mediumblob':
  182.                     case 'longblob':
  183.                     case 'blob':
  184.                         $type[0] = 'blob';
  185.                         $type[1] = 'text';
  186.                         break;
  187.                     case 'year':
  188.                         $type[0] = 'integer';
  189.                         $type[1] = 'date';
  190.                         break;
  191.                     default:
  192.                         return $db->raiseError(MDB2_ERROR, null, null,
  193.                             'getTableFieldDefinition: unknown database attribute type');
  194.                 }
  195.                 unset($notnull);
  196.                 if (isset($columns['null'])
  197.                     && $row[$columns['null']] != 'YES')
  198.                 {
  199.                     $notnull = true;
  200.                 }
  201.                 unset($default);
  202.                 if (isset($columns['default'])
  203.                     && isset($row[$columns['default']]))
  204.                 {
  205.                     $default = $row[$columns['default']];
  206.                 }
  207.                 $definition = array();
  208.                 for ($field_choices = array(), $datatype = 0; $datatype < count($type); $datatype++) {
  209.                     $field_choices[$datatype] = array('type' => $type[$datatype]);
  210.                     if (isset($notnull)) {
  211.                         $field_choices[$datatype]['notnull'] = true;
  212.                     }
  213.                     if (isset($default)) {
  214.                         $field_choices[$datatype]['default'] = $default;
  215.                     }
  216.                     if ($type[$datatype] != 'boolean'
  217.                         && $type[$datatype] != 'time'
  218.                         && $type[$datatype] != 'date'
  219.                         && $type[$datatype] != 'timestamp')
  220.                     {
  221.                         if (strlen($length)) {
  222.                             $field_choices[$datatype]['length'] = $length;
  223.                         }
  224.                     }
  225.                 }
  226.                 $definition[0] = $field_choices;
  227.                 if (isset($columns['extra'])
  228.                     && isset($row[$columns['extra']])
  229.                     && $row[$columns['extra']] == 'auto_increment')
  230.                 {
  231.                     $implicit_sequence = array();
  232.                     $implicit_sequence['on'] = array();
  233.                     $implicit_sequence['on']['table'] = $table;
  234.                     $implicit_sequence['on']['field'] = $field_name;
  235.                     $definition[1]['name'] = $table.'_'.$field_name;
  236.                     $definition[1]['definition'] = $implicit_sequence;
  237.                 }
  238.                 if (isset($columns['key'])
  239.                     && isset($row[$columns['key']])
  240.                     && $row[$columns['key']] == 'PRI')
  241.                 {
  242.                     // check that its not just a unique field
  243.                     $query = "SHOW INDEX FROM $table";
  244.                     $indexes = $db->queryAll($query, null, MDB2_FETCHMODE_ASSOC);
  245.                     if (MDB2::isError($indexes)) {
  246.                         return $result;
  247.                     }
  248.                     $is_primary = false;
  249.                     foreach ($indexes as $index) {
  250.                         if (!$db->options['portability'] & MDB2_PORTABILITY_LOWERCASE) {
  251.                             $index = array_change_key_case($index, CASE_LOWER);
  252.                         }
  253.                         if ($index['key_name'] == 'PRIMARY' && $index['column_name'] == $field_name) {
  254.                             $is_primary = true;
  255.                             break;
  256.                         }
  257.                     }
  258.                     if ($is_primary) {
  259.                         $implicit_index = array();
  260.                         $implicit_index['unique'] = true;
  261.                         $implicit_index['fields'][$field_name] = '';
  262.                         $definition[2]['name'] = $field_name;
  263.                         $definition[2]['definition'] = $implicit_index;
  264.                     }
  265.                 }
  266.                 return $definition;
  267.             }
  268.         }
  269.         $db->free($result);
  270.  
  271.         if (MDB2::isError($row)) {
  272.             return $row;
  273.         }
  274.         return $db->raiseError(MDB2_ERROR, null, null,
  275.             'getTableFieldDefinition: it was not specified an existing table column');
  276.     }
  277.  
  278.     // }}}
  279.     // {{{ getTableIndexDefinition()
  280.  
  281.     /**
  282.      * get the stucture of an index into an array
  283.      *
  284.      * @param string    $table      name of table that should be used in method
  285.      * @param string    $index_name name of index that should be used in method
  286.      * @return mixed data array on success, a MDB2 error on failure
  287.      * @access public
  288.      */
  289.     function getTableIndexDefinition($table, $index_name)
  290.     {
  291.         $db =& $GLOBALS['_MDB2_databases'][$this->db_index];
  292.         if ($index_name == 'PRIMARY') {
  293.             return $db->raiseError(MDB2_ERROR, null, null,
  294.                 'getTableIndexDefinition: PRIMARY is an hidden index');
  295.         }
  296.         if (MDB2::isError($result = $db->query("SHOW INDEX FROM $table"))) {
  297.             return $result;
  298.         }
  299.         $definition = array();
  300.         while (is_array($row = $result->fetchRow(MDB2_FETCHMODE_ASSOC))) {
  301.             if (!$db->options['portability'] & MDB2_PORTABILITY_LOWERCASE) {
  302.                 $row = array_change_key_case($row, CASE_LOWER);
  303.             }
  304.             $key_name = strtolower($row['key_name']);
  305.             if (!strcmp($index_name, $key_name)) {
  306.                 if (!$row['non_unique']) {
  307.                     $definition[$index_name]['unique'] = true;
  308.                 }
  309.                 $column_name = $row['column_name'];
  310.                 $definition['fields'][$column_name] = array();
  311.                 if (isset($row['collation'])) {
  312.                     $definition['fields'][$column_name]['sorting'] = ($row['collation'] == 'A' ? 'ascending' : 'descending');
  313.                 }
  314.             }
  315.         }
  316.         $result->free();
  317.         if (!isset($definition['fields'])) {
  318.             return $db->raiseError(MDB2_ERROR, null, null,
  319.                 'getTableIndexDefinition: it was not specified an existing table index');
  320.         }
  321.         return $definition;
  322.     }
  323.  
  324.  
  325.     // }}}
  326.     // {{{ tableInfo()
  327.  
  328.     /**
  329.      * Returns information about a table or a result set.
  330.      *
  331.      * @param object|string $result  MDB2_result object from a query or a
  332.      *                                 string containing the name of a table
  333.      * @param int            $mode    a valid tableInfo mode
  334.      * @return array  an associative array with the information requested
  335.      *                 or an error object if something is wrong
  336.      * @access public
  337.      * @internal
  338.      * @see MDB2_Driver_Common::tableInfo()
  339.      */
  340.     function tableInfo($result, $mode = null) {
  341.         $db =& $GLOBALS['_MDB2_databases'][$this->db_index];
  342.         if ($db->options['portability'] & MDB2_PORTABILITY_LOWERCASE) {
  343.             $case_func = 'strtolower';
  344.         } else {
  345.             $case_func = 'strval';
  346.         }
  347.  
  348.         if (is_string($result)) {
  349.             /*
  350.              * Probably received a table name.
  351.              * Create a result resource identifier.
  352.              */
  353.             if (MDB2::isError($connect = $db->connect())) {
  354.                 return $connect;
  355.             }
  356.             $id = @mysql_list_fields($db->database_name,
  357.                 $result, $db->connection);
  358.             $got_string = true;
  359.         } else {
  360.             /*
  361.              * Probably received a result object.
  362.              * Extract the result resource identifier.
  363.              */
  364.             $id = $result->getResource();
  365.             if (empty($id)) {
  366.                 return $db->raiseError();
  367.             }
  368.             $got_string = false;
  369.         }
  370.  
  371.         if (!is_resource($id)) {
  372.             return $db->raiseError(MDB2_ERROR_NEED_MORE_DATA);
  373.         }
  374.  
  375.         $count = @mysql_num_fields($id);
  376.  
  377.         // made this IF due to performance (one if is faster than $count if's)
  378.         if (!$mode) {
  379.             for ($i=0,$j=0; $i<$count; $i++) {
  380.                 $name = $case_func(@mysql_field_name($id, $i));
  381.                 if ($name != 'dummy_primary_key') {
  382.                     $res[$j]['table'] = $case_func(@mysql_field_table($id, $i));
  383.                     $res[$j]['name']  = $name;
  384.                     $res[$j]['type']  = @mysql_field_type($id, $i);
  385.                     $res[$j]['len']   = @mysql_field_len($id, $i);
  386.                     $res[$j]['flags'] = @mysql_field_flags($id, $i);
  387.                     ++$j;
  388.                 }
  389.             }
  390.         } else { // full
  391.             $res['num_fields']= $count;
  392.  
  393.             for ($i=0,$j=0; $i<$count; $i++) {
  394.                 $name = $case_func(@mysql_field_name($id, $i));
  395.                 if ($name != 'dummy_primary_key') {
  396.                     $res[$j]['table'] = $case_func(@mysql_field_table($id, $i));
  397.                     $res[$j]['name']  = $name;
  398.                     $res[$j]['type']  = @mysql_field_type($id, $i);
  399.                     $res[$j]['len']   = @mysql_field_len($id, $i);
  400.                     $res[$j]['flags'] = @mysql_field_flags($id, $i);
  401.  
  402.                     if ($mode & MDB2_TABLEINFO_ORDER) {
  403.                         $res['order'][$res[$j]['name']] = $j;
  404.                     }
  405.                     if ($mode & MDB2_TABLEINFO_ORDERTABLE) {
  406.                         $res['ordertable'][$res[$j]['table']][$res[$j]['name']] = $j;
  407.                     }
  408.                     ++$j;
  409.                 }
  410.             }
  411.         }
  412.  
  413.         // free the result only if we were called on a table
  414.         if ($got_string) {
  415.             @mysql_free_result($id);
  416.         }
  417.         return $res;
  418.     }
  419. }
  420. ?>

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