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

Source for file mysql.php

Documentation is available at mysql.php

  1. <?php
  2. // vim: set et ts=4 sw=4 fdm=marker:
  3. // +----------------------------------------------------------------------+
  4. // | PHP versions 4 and 5                                                 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1998-2008 Manuel Lemos, Tomas V.V.Cox,                 |
  7. // | Stig. S. Bakken, Lukas Smith                                         |
  8. // | All rights reserved.                                                 |
  9. // +----------------------------------------------------------------------+
  10. // | MDB2 is a merge of PEAR DB and Metabases that provides a unified DB  |
  11. // | API as well as database abstraction for PHP applications.            |
  12. // | This LICENSE is in the BSD license style.                            |
  13. // |                                                                      |
  14. // | Redistribution and use in source and binary forms, with or without   |
  15. // | modification, are permitted provided that the following conditions   |
  16. // | are met:                                                             |
  17. // |                                                                      |
  18. // | Redistributions of source code must retain the above copyright       |
  19. // | notice, this list of conditions and the following disclaimer.        |
  20. // |                                                                      |
  21. // | Redistributions in binary form must reproduce the above copyright    |
  22. // | notice, this list of conditions and the following disclaimer in the  |
  23. // | documentation and/or other materials provided with the distribution. |
  24. // |                                                                      |
  25. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  26. // | Lukas Smith nor the names of his contributors may be used to endorse |
  27. // | or promote products derived from this software without specific prior|
  28. // | written permission.                                                  |
  29. // |                                                                      |
  30. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  31. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  32. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  33. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  34. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  35. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  36. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  37. // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  38. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  39. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  40. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  41. // | POSSIBILITY OF SUCH DAMAGE.                                          |
  42. // +----------------------------------------------------------------------+
  43. // | Author: Lukas Smith <smith@pooteeweet.org>                           |
  44. // +----------------------------------------------------------------------+
  45. //
  46. // $Id: mysql.php 327310 2012-08-27 15:16:18Z danielc $
  47. //
  48.  
  49. require_once 'MDB2/Driver/Datatype/Common.php';
  50.  
  51. /**
  52.  * MDB2 MySQL driver
  53.  *
  54.  * @package MDB2
  55.  * @category Database
  56.  * @author  Lukas Smith <smith@pooteeweet.org>
  57.  */
  58. class MDB2_Driver_Datatype_mysql extends MDB2_Driver_Datatype_Common
  59. {
  60.     // {{{ _getCharsetFieldDeclaration()
  61.  
  62.     /**
  63.      * Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
  64.      * of a field declaration to be used in statements like CREATE TABLE.
  65.      *
  66.      * @param string $charset   name of the charset
  67.      * @return string  DBMS specific SQL code portion needed to set the CHARACTER SET
  68.      *                  of a field declaration.
  69.      */
  70.     function _getCharsetFieldDeclaration($charset)
  71.     {
  72.         return 'CHARACTER SET '.$charset;
  73.     }
  74.  
  75.     // }}}
  76.     // {{{ _getCollationFieldDeclaration()
  77.  
  78.     /**
  79.      * Obtain DBMS specific SQL code portion needed to set the COLLATION
  80.      * of a field declaration to be used in statements like CREATE TABLE.
  81.      *
  82.      * @param string $collation   name of the collation
  83.      * @return string  DBMS specific SQL code portion needed to set the COLLATION
  84.      *                  of a field declaration.
  85.      */
  86.     function _getCollationFieldDeclaration($collation)
  87.     {
  88.         return 'COLLATE '.$collation;
  89.     }
  90.  
  91.     // }}}
  92.     // {{{ getDeclaration()
  93.  
  94.     /**
  95.      * Obtain DBMS specific SQL code portion needed to declare
  96.      * of the given type
  97.      *
  98.      * @param string $type  type to which the value should be converted to
  99.      * @param string $name  name the field to be declared.
  100.      * @param string $field definition of the field
  101.      *
  102.      * @return string DBMS-specific SQL code portion that should be used to
  103.      *                 declare the specified field.
  104.      * @access public
  105.      */
  106.     function getDeclaration($type$name$field)
  107.     {
  108.         // MySQL DDL syntax forbids combining NOT NULL with DEFAULT NULL.
  109.         // To get a default of NULL for NOT NULL columns, omit it.
  110.         if (   isset($field['notnull'])
  111.             && !empty($field['notnull'])
  112.             && array_key_exists('default'$field// do not use isset() here!
  113.             && null === $field['default']
  114.         {
  115.             unset($field['default']);
  116.         }
  117.         return parent::getDeclaration($type$name$field);
  118.     }
  119.  
  120.     // }}}
  121.     // {{{ getTypeDeclaration()
  122.  
  123.     /**
  124.      * Obtain DBMS specific SQL code portion needed to declare an text type
  125.      * field to be used in statements like CREATE TABLE.
  126.      *
  127.      * @param array $field  associative array with the name of the properties
  128.      *       of the field being declared as array indexes. Currently, the types
  129.      *       of supported field properties are as follows:
  130.      *
  131.      *       length
  132.      *           Integer value that determines the maximum length of the text
  133.      *           field. If this argument is missing the field should be
  134.      *           declared to have the longest length allowed by the DBMS.
  135.      *
  136.      *       default
  137.      *           Text value to be used as default for this field.
  138.      *
  139.      *       notnull
  140.      *           Boolean flag that indicates whether this field is constrained
  141.      *           to not be set to null.
  142.      * @return string  DBMS specific SQL code portion that should be used to
  143.      *       declare the specified field.
  144.      * @access public
  145.      */
  146.     function getTypeDeclaration($field)
  147.     {
  148.         $db $this->getDBInstance();
  149.         if (MDB2::isError($db)) {
  150.             return $db;
  151.         }
  152.  
  153.         switch ($field['type']{
  154.         case 'text':
  155.             if (empty($field['length']&& array_key_exists('default'$field)) {
  156.                 $field['length'$db->varchar_max_length;
  157.             }
  158.             $length !empty($field['length']$field['length': false;
  159.             $fixed !empty($field['fixed']$field['fixed': false;
  160.             return $fixed ($length 'CHAR('.$length.')' 'CHAR(255)')
  161.                 : ($length 'VARCHAR('.$length.')' 'TEXT');
  162.         case 'clob':
  163.             if (!empty($field['length'])) {
  164.                 $length $field['length'];
  165.                 if ($length <= 255{
  166.                     return 'TINYTEXT';
  167.                 elseif ($length <= 65532{
  168.                     return 'TEXT';
  169.                 elseif ($length <= 16777215{
  170.                     return 'MEDIUMTEXT';
  171.                 }
  172.             }
  173.             return 'LONGTEXT';
  174.         case 'blob':
  175.             if (!empty($field['length'])) {
  176.                 $length $field['length'];
  177.                 if ($length <= 255{
  178.                     return 'TINYBLOB';
  179.                 elseif ($length <= 65532{
  180.                     return 'BLOB';
  181.                 elseif ($length <= 16777215{
  182.                     return 'MEDIUMBLOB';
  183.                 }
  184.             }
  185.             return 'LONGBLOB';
  186.         case 'integer':
  187.             if (!empty($field['length'])) {
  188.                 $length $field['length'];
  189.                 if ($length <= 1{
  190.                     return 'TINYINT';
  191.                 elseif ($length == 2{
  192.                     return 'SMALLINT';
  193.                 elseif ($length == 3{
  194.                     return 'MEDIUMINT';
  195.                 elseif ($length == 4{
  196.                     return 'INT';
  197.                 elseif ($length > 4{
  198.                     return 'BIGINT';
  199.                 }
  200.             }
  201.             return 'INT';
  202.         case 'boolean':
  203.             return 'TINYINT(1)';
  204.         case 'date':
  205.             return 'DATE';
  206.         case 'time':
  207.             return 'TIME';
  208.         case 'timestamp':
  209.             return 'DATETIME';
  210.         case 'float':
  211.             $l '';
  212.             if (!empty($field['length'])) {
  213.                 $l '(' $field['length'];
  214.                 if (!empty($field['scale'])) {
  215.                     $l .= ',' $field['scale'];
  216.                 }
  217.                 $l .= ')';
  218.             }
  219.             return 'DOUBLE' $l;
  220.         case 'decimal':
  221.             $length !empty($field['length']$field['length': 18;
  222.             $scale !empty($field['scale']$field['scale'$db->options['decimal_places'];
  223.             return 'DECIMAL('.$length.','.$scale.')';
  224.         }
  225.         return '';
  226.     }
  227.  
  228.     // }}}
  229.     // {{{ _getIntegerDeclaration()
  230.  
  231.     /**
  232.      * Obtain DBMS specific SQL code portion needed to declare an integer type
  233.      * field to be used in statements like CREATE TABLE.
  234.      *
  235.      * @param string  $name   name the field to be declared.
  236.      * @param string  $field  associative array with the name of the properties
  237.      *                         of the field being declared as array indexes.
  238.      *                         Currently, the types of supported field
  239.      *                         properties are as follows:
  240.      *
  241.      *                        unsigned
  242.      *                         Boolean flag that indicates whether the field
  243.      *                         should be declared as unsigned integer if
  244.      *                         possible.
  245.      *
  246.      *                        default
  247.      *                         Integer value to be used as default for this
  248.      *                         field.
  249.      *
  250.      *                        notnull
  251.      *                         Boolean flag that indicates whether this field is
  252.      *                         constrained to not be set to null.
  253.      * @return string  DBMS specific SQL code portion that should be used to
  254.      *                  declare the specified field.
  255.      * @access protected
  256.      */
  257.     function _getIntegerDeclaration($name$field)
  258.     {
  259.         $db $this->getDBInstance();
  260.         if (MDB2::isError($db)) {
  261.             return $db;
  262.         }
  263.  
  264.         $default $autoinc '';
  265.         if (!empty($field['autoincrement'])) {
  266.             $autoinc ' AUTO_INCREMENT PRIMARY KEY';
  267.         elseif (array_key_exists('default'$field)) {
  268.             if ($field['default'=== ''{
  269.                 $field['default'= empty($field['notnull']? null : 0;
  270.             }
  271.             $default ' DEFAULT '.$this->quote($field['default']'integer');
  272.         }
  273.  
  274.         $notnull = empty($field['notnull']'' ' NOT NULL';
  275.         $unsigned = empty($field['unsigned']'' ' UNSIGNED';
  276.         if (empty($default&& empty($notnull)) {
  277.             $default ' DEFAULT NULL';
  278.         }
  279.         $name $db->quoteIdentifier($nametrue);
  280.         return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull.$autoinc;
  281.     }
  282.  
  283.     // }}}
  284.     // {{{ _getFloatDeclaration()
  285.  
  286.     /**
  287.      * Obtain DBMS specific SQL code portion needed to declare an float type
  288.      * field to be used in statements like CREATE TABLE.
  289.      *
  290.      * @param string  $name   name the field to be declared.
  291.      * @param string  $field  associative array with the name of the properties
  292.      *                         of the field being declared as array indexes.
  293.      *                         Currently, the types of supported field
  294.      *                         properties are as follows:
  295.      *
  296.      *                        unsigned
  297.      *                         Boolean flag that indicates whether the field
  298.      *                         should be declared as unsigned float if
  299.      *                         possible.
  300.      *
  301.      *                        default
  302.      *                         float value to be used as default for this
  303.      *                         field.
  304.      *
  305.      *                        notnull
  306.      *                         Boolean flag that indicates whether this field is
  307.      *                         constrained to not be set to null.
  308.      * @return string  DBMS specific SQL code portion that should be used to
  309.      *                  declare the specified field.
  310.      * @access protected
  311.      */
  312.     function _getFloatDeclaration($name$field)
  313.     {
  314.         // Since AUTO_INCREMENT can be used for integer or floating-point types,
  315.         // reuse the INTEGER declaration
  316.         // @see http://bugs.mysql.com/bug.php?id=31032
  317.         return $this->_getIntegerDeclaration($name$field);
  318.     }
  319.  
  320.     // }}}
  321.     // {{{ _getDecimalDeclaration()
  322.  
  323.     /**
  324.      * Obtain DBMS specific SQL code portion needed to declare an decimal type
  325.      * field to be used in statements like CREATE TABLE.
  326.      *
  327.      * @param string  $name   name the field to be declared.
  328.      * @param string  $field  associative array with the name of the properties
  329.      *                         of the field being declared as array indexes.
  330.      *                         Currently, the types of supported field
  331.      *                         properties are as follows:
  332.      *
  333.      *                        unsigned
  334.      *                         Boolean flag that indicates whether the field
  335.      *                         should be declared as unsigned integer if
  336.      *                         possible.
  337.      *
  338.      *                        default
  339.      *                         Decimal value to be used as default for this
  340.      *                         field.
  341.      *
  342.      *                        notnull
  343.      *                         Boolean flag that indicates whether this field is
  344.      *                         constrained to not be set to null.
  345.      * @return string  DBMS specific SQL code portion that should be used to
  346.      *                  declare the specified field.
  347.      * @access protected
  348.      */
  349.     function _getDecimalDeclaration($name$field)
  350.     {
  351.         $db $this->getDBInstance();
  352.         if (MDB2::isError($db)) {
  353.             return $db;
  354.         }
  355.  
  356.         $default '';
  357.         if (array_key_exists('default'$field)) {
  358.             if ($field['default'=== ''{
  359.                 $field['default'= empty($field['notnull']? null : 0;
  360.             }
  361.             $default ' DEFAULT '.$this->quote($field['default']'integer');
  362.         elseif (empty($field['notnull'])) {
  363.             $default ' DEFAULT NULL';
  364.         }
  365.  
  366.         $notnull = empty($field['notnull']'' ' NOT NULL';
  367.         $unsigned = empty($field['unsigned']'' ' UNSIGNED';
  368.         $name $db->quoteIdentifier($nametrue);
  369.         return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull;
  370.     }
  371.  
  372.     // }}}
  373.     // {{{ matchPattern()
  374.  
  375.     /**
  376.      * build a pattern matching string
  377.      *
  378.      * @access public
  379.      *
  380.      * @param array $pattern even keys are strings, odd are patterns (% and _)
  381.      * @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
  382.      * @param string $field optional field name that is being matched against
  383.      *                   (might be required when emulating ILIKE)
  384.      *
  385.      * @return string SQL pattern
  386.      */
  387.     function matchPattern($pattern$operator = null$field = null)
  388.     {
  389.         $db $this->getDBInstance();
  390.         if (MDB2::isError($db)) {
  391.             return $db;
  392.         }
  393.  
  394.         $match '';
  395.         if (null !== $operator{
  396.             $field (null === $field'' $field.' ';
  397.             $operator strtoupper($operator);
  398.             switch ($operator{
  399.             // case insensitive
  400.             case 'ILIKE':
  401.                 $match $field.'LIKE ';
  402.                 break;
  403.             case 'NOT ILIKE':
  404.                 $match $field.'NOT LIKE ';
  405.                 break;
  406.             // case sensitive
  407.             case 'LIKE':
  408.                 $match $field.'LIKE BINARY ';
  409.                 break;
  410.             case 'NOT LIKE':
  411.                 $match $field.'NOT LIKE BINARY ';
  412.                 break;
  413.             default:
  414.                 return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  415.                     'not a supported operator type:'$operator__FUNCTION__);
  416.             }
  417.         }
  418.         $match.= "'";
  419.         foreach ($pattern as $key => $value{
  420.             if ($key % 2{
  421.                 $match.= $value;
  422.             else {
  423.                 $match.= $db->escapePattern($db->escape($value));
  424.             }
  425.         }
  426.         $match.= "'";
  427.         $match.= $this->patternEscapeString();
  428.         return $match;
  429.     }
  430.  
  431.     // }}}
  432.     // {{{ _mapNativeDatatype()
  433.  
  434.     /**
  435.      * Maps a native array description of a field to a MDB2 datatype and length
  436.      *
  437.      * @param array  $field native field description
  438.      * @return array containing the various possible types, length, sign, fixed
  439.      * @access public
  440.      */
  441.     function _mapNativeDatatype($field)
  442.     {
  443.         $db_type strtolower($field['type']);
  444.         $db_type strtok($db_type'(), ');
  445.         if ($db_type == 'national'{
  446.             $db_type strtok('(), ');
  447.         }
  448.         if (!empty($field['length'])) {
  449.             $length strtok($field['length']', ');
  450.             $decimal strtok(', ');
  451.         else {
  452.             $length strtok('(), ');
  453.             $decimal strtok('(), ');
  454.         }
  455.         $type = array();
  456.         $unsigned $fixed = null;
  457.         switch ($db_type{
  458.         case 'tinyint':
  459.             $type['integer';
  460.             $type['boolean';
  461.             if (preg_match('/^(is|has)/'$field['name'])) {
  462.                 $type array_reverse($type);
  463.             }
  464.             $unsigned preg_match('/ unsigned/i'$field['type']);
  465.             $length = 1;
  466.             break;
  467.         case 'smallint':
  468.             $type['integer';
  469.             $unsigned preg_match('/ unsigned/i'$field['type']);
  470.             $length = 2;
  471.             break;
  472.         case 'mediumint':
  473.             $type['integer';
  474.             $unsigned preg_match('/ unsigned/i'$field['type']);
  475.             $length = 3;
  476.             break;
  477.         case 'int':
  478.         case 'integer':
  479.             $type['integer';
  480.             $unsigned preg_match('/ unsigned/i'$field['type']);
  481.             $length = 4;
  482.             break;
  483.         case 'bigint':
  484.             $type['integer';
  485.             $unsigned preg_match('/ unsigned/i'$field['type']);
  486.             $length = 8;
  487.             break;
  488.         case 'tinytext':
  489.         case 'mediumtext':
  490.         case 'longtext':
  491.         case 'text':
  492.         case 'varchar':
  493.             $fixed = false;
  494.         case 'string':
  495.         case 'char':
  496.             $type['text';
  497.             if ($length == '1'{
  498.                 $type['boolean';
  499.                 if (preg_match('/^(is|has)/'$field['name'])) {
  500.                     $type array_reverse($type);
  501.                 }
  502.             elseif (strstr($db_type'text')) {
  503.                 $type['clob';
  504.                 if ($decimal == 'binary'{
  505.                     $type['blob';
  506.                 }
  507.                 $type array_reverse($type);
  508.             }
  509.             if ($fixed !== false{
  510.                 $fixed = true;
  511.             }
  512.             break;
  513.         case 'enum':
  514.             $type['text';
  515.             preg_match_all('/\'.+\'/U'$field['type']$matches);
  516.             $length = 0;
  517.             $fixed = false;
  518.             if (is_array($matches)) {
  519.                 foreach ($matches[0as $value{
  520.                     $length max($lengthstrlen($value)-2);
  521.                 }
  522.                 if ($length == '1' && count($matches[0]== 2{
  523.                     $type['boolean';
  524.                     if (preg_match('/^(is|has)/'$field['name'])) {
  525.                         $type array_reverse($type);
  526.                     }
  527.                 }
  528.             }
  529.             $type['integer';
  530.         case 'set':
  531.             $fixed = false;
  532.             $type['text';
  533.             $type['integer';
  534.             break;
  535.         case 'date':
  536.             $type['date';
  537.             $length = null;
  538.             break;
  539.         case 'datetime':
  540.         case 'timestamp':
  541.             $type['timestamp';
  542.             $length = null;
  543.             break;
  544.         case 'time':
  545.             $type['time';
  546.             $length = null;
  547.             break;
  548.         case 'float':
  549.         case 'double':
  550.         case 'real':
  551.             $type['float';
  552.             $unsigned preg_match('/ unsigned/i'$field['type']);
  553.             if ($decimal !== false{
  554.                 $length $length.','.$decimal;
  555.             }
  556.             break;
  557.         case 'unknown':
  558.         case 'decimal':
  559.         case 'numeric':
  560.             $type['decimal';
  561.             $unsigned preg_match('/ unsigned/i'$field['type']);
  562.             if ($decimal !== false{
  563.                 $length $length.','.$decimal;
  564.             }
  565.             break;
  566.         case 'tinyblob':
  567.         case 'mediumblob':
  568.         case 'longblob':
  569.         case 'blob':
  570.             $type['blob';
  571.             $length = null;
  572.             break;
  573.         case 'binary':
  574.         case 'varbinary':
  575.             $type['blob';
  576.             break;
  577.         case 'year':
  578.             $type['integer';
  579.             $type['date';
  580.             $length = null;
  581.             break;
  582.         default:
  583.             $db $this->getDBInstance();
  584.             if (MDB2::isError($db)) {
  585.                 return $db;
  586.             }
  587.  
  588.             return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  589.                 'unknown database attribute type: '.$db_type__FUNCTION__);
  590.         }
  591.  
  592.         if ((int)$length <= 0{
  593.             $length = null;
  594.         }
  595.  
  596.         return array($type$length$unsigned$fixed);
  597.     }
  598.  
  599.     // }}}
  600. }
  601.  
  602. ?>

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