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-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.112 2006/10/14 13:42:00 lsmith Exp $
  46.  
  47. require_once 'MDB2/LOB.php';
  48.  
  49. /**
  50.  * @package  MDB2
  51.  * @category Database
  52.  * @author   Lukas Smith <smith@pooteeweet.org>
  53.  */
  54.  
  55. /**
  56.  * MDB2_Driver_Common: Base class that is extended by each MDB2 driver
  57.  *
  58.  * @package MDB2
  59.  * @category Database
  60.  * @author Lukas Smith <smith@pooteeweet.org>
  61.  */
  62. {
  63.     var $valid_default_values = array(
  64.         'text'      => '',
  65.         'boolean'   => true,
  66.         'integer'   => 0,
  67.         'decimal'   => 0.0,
  68.         'float'     => 0.0,
  69.         'timestamp' => '1970-01-01 00:00:00',
  70.         'time'      => '00:00:00',
  71.         'date'      => '1970-01-01',
  72.         'clob'      => '',
  73.         'blob'      => '',
  74.     );
  75.  
  76.     /**
  77.      * contains all LOB objects created with this MDB2 instance
  78.      * @var array 
  79.      * @access protected
  80.      */
  81.     var $lobs = array();
  82.  
  83.     // }}}
  84.     // {{{ getValidTypes()
  85.  
  86.     /**
  87.      * Get the list of valid types
  88.      *
  89.      * This function returns an array of valid types as keys with the values
  90.      * being possible default values for all native datatypes and mapped types
  91.      * for custom datatypes.
  92.      *
  93.      * @return mixed array on success, a MDB2 error on failure
  94.      * @access public
  95.      */
  96.     function getValidTypes()
  97.     {
  98.         $types $this->valid_default_values;
  99.         $db =$this->getDBInstance();
  100.         if (PEAR::isError($db)) {
  101.             return $db;
  102.         }
  103.         if (!empty($db->options['datatype_map'])) {
  104.             foreach ($db->options['datatype_map'as $type => $mapped_type{
  105.                 if (array_key_exists($mapped_type$types)) {
  106.                     $types[$type$types[$mapped_type];
  107.                 elseif (!empty($db->options['datatype_map_callback'][$type])) {
  108.                     $parameter = array('type' => $type'mapped_type' => $mapped_type);
  109.                     $default =  call_user_func_array($db->options['datatype_map_callback'][$type]array(&$db__FUNCTION__$parameter));
  110.                     $types[$type$default;
  111.                 }
  112.             }
  113.         }
  114.         return $types;
  115.     }
  116.  
  117.     // }}}
  118.     // {{{ checkResultTypes()
  119.  
  120.     /**
  121.      * Define the list of types to be associated with the columns of a given
  122.      * result set.
  123.      *
  124.      * This function may be called before invoking fetchRow(), fetchOne()
  125.      * fetchCole() and fetchAll() so that the necessary data type
  126.      * conversions are performed on the data to be retrieved by them. If this
  127.      * function is not called, the type of all result set columns is assumed
  128.      * to be text, thus leading to not perform any conversions.
  129.      *
  130.      * @param string $types array variable that lists the
  131.      *        data types to be expected in the result set columns. If this array
  132.      *        contains less types than the number of columns that are returned
  133.      *        in the result set, the remaining columns are assumed to be of the
  134.      *        type text. Currently, the types clob and blob are not fully
  135.      *        supported.
  136.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  137.      * @access public
  138.      */
  139.     function checkResultTypes($types)
  140.     {
  141.         $types is_array($types$types : array($types);
  142.         foreach ($types as $key => $type{
  143.             if (!isset($this->valid_default_values[$type])) {
  144.                 $db =$this->getDBInstance();
  145.                 if (PEAR::isError($db)) {
  146.                     return $db;
  147.                 }
  148.                 if (empty($db->options['datatype_map'][$type])) {
  149.                     return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  150.                         $type.' for '.$key.' is not a supported column type'__FUNCTION__);
  151.                 }
  152.             }
  153.         }
  154.         return $types;
  155.     }
  156.  
  157.     // }}}
  158.     // {{{ _baseConvertResult()
  159.  
  160.     /**
  161.      * general type conversion method
  162.      *
  163.      * @param mixed $value refernce to a value to be converted
  164.      * @param string $type specifies which type to convert to
  165.      * @return object MDB2 error on failure
  166.      * @access protected
  167.      */
  168.     function _baseConvertResult($value$type$rtrim = true)
  169.     {
  170.         switch ($type{
  171.         case 'text':
  172.             if ($rtrim{
  173.                 $value rtrim($value);
  174.             }
  175.             return $value;
  176.         case 'integer':
  177.             return intval($value);
  178.         case 'boolean':
  179.             return !empty($value);
  180.         case 'decimal':
  181.             return $value;
  182.         case 'float':
  183.             return doubleval($value);
  184.         case 'date':
  185.             return $value;
  186.         case 'time':
  187.             return $value;
  188.         case 'timestamp':
  189.             return $value;
  190.         case 'clob':
  191.         case 'blob':
  192.             $this->lobs[= array(
  193.                 'buffer' => null,
  194.                 'position' => 0,
  195.                 'lob_index' => null,
  196.                 'endOfLOB' => false,
  197.                 'resource' => $value,
  198.                 'value' => null,
  199.                 'loaded' => false,
  200.             );
  201.             end($this->lobs);
  202.             $lob_index key($this->lobs);
  203.             $this->lobs[$lob_index]['lob_index'$lob_index;
  204.             return fopen('MDB2LOB://'.$lob_index.'@'.$this->db_index'r+');
  205.         }
  206.  
  207.         $db =$this->getDBInstance();
  208.         if (PEAR::isError($db)) {
  209.             return $db;
  210.         }
  211.  
  212.         return $db->raiseError(MDB2_ERROR_INVALIDnullnull,
  213.             'attempt to convert result value to an unknown type :' $type__FUNCTION__);
  214.     }
  215.  
  216.     // }}}
  217.     // {{{ convertResult()
  218.  
  219.     /**
  220.      * convert a value to a RDBMS indepdenant MDB2 type
  221.      *
  222.      * @param mixed $value value to be converted
  223.      * @param string $type specifies which type to convert to
  224.      * @param bool   $rtrim   if to rtrim text values or not
  225.      * @return mixed converted value
  226.      * @access public
  227.      */
  228.     function convertResult($value$type$rtrim = true)
  229.     {
  230.         if (is_null($value)) {
  231.             return null;
  232.         }
  233.         $db =$this->getDBInstance();
  234.         if (PEAR::isError($db)) {
  235.             return $db;
  236.         }
  237.         if (!empty($db->options['datatype_map'][$type])) {
  238.             $type $db->options['datatype_map'][$type];
  239.             if (!empty($db->options['datatype_map_callback'][$type])) {
  240.                 $parameter = array('type' => $type'value' => $value'rtrim' => $rtrim);
  241.                 return call_user_func_array($db->options['datatype_map_callback'][$type]array(&$db__FUNCTION__$parameter));
  242.             }
  243.         }
  244.         return $this->_baseConvertResult($value$type$rtrim);
  245.     }
  246.  
  247.     // }}}
  248.     // {{{ convertResultRow()
  249.  
  250.     /**
  251.      * convert a result row
  252.      *
  253.      * @param array $types 
  254.      * @param array $row specifies the types to convert to
  255.      * @param bool   $rtrim   if to rtrim text values or not
  256.      * @return mixed MDB2_OK on success,  a MDB2 error on failure
  257.      * @access public
  258.      */
  259.     function convertResultRow($types$row$rtrim = true)
  260.     {
  261.         reset($types);
  262.         $current_column = -1;
  263.         foreach ($row as $key => $value{
  264.             ++$current_column;
  265.             if (!isset($value)) {
  266.                 continue;
  267.             }
  268.             if (isset($types[$current_column])) {
  269.                 $type $types[$current_column];
  270.             elseif (isset($types[$key])) {
  271.                 $type $types[$key];
  272.             elseif (current($types)) {
  273.                 $type current($types);
  274.                 next($types);
  275.             else {
  276.                 continue;
  277.             }
  278.             $value $this->convertResult($row[$key]$type$rtrim);
  279.             if (PEAR::isError($value)) {
  280.                 return $value;
  281.             }
  282.             $row[$key$value;
  283.         }
  284.         return $row;
  285.     }
  286.  
  287.     // }}}
  288.     // {{{ getDeclaration()
  289.  
  290.     /**
  291.      * Obtain DBMS specific SQL code portion needed to declare
  292.      * of the given type
  293.      *
  294.      * @param string $type type to which the value should be converted to
  295.      * @param string  $name   name the field to be declared.
  296.      * @param string  $field  definition of the field
  297.      * @return string  DBMS specific SQL code portion that should be used to
  298.      *                  declare the specified field.
  299.      * @access public
  300.      */
  301.     function getDeclaration($type$name$field)
  302.     {
  303.         $db =$this->getDBInstance();
  304.         if (PEAR::isError($db)) {
  305.             return $db;
  306.         }
  307.  
  308.         if (!empty($db->options['datatype_map'][$type])) {
  309.             $type $db->options['datatype_map'][$type];
  310.             if (!empty($db->options['datatype_map_callback'][$type])) {
  311.                 $parameter = array('type' => $type'name' => $name'field' => $field);
  312.                 return call_user_func_array($db->options['datatype_map_callback'][$type]array(&$db__FUNCTION__$parameter));
  313.             }
  314.         }
  315.  
  316.         if (!method_exists($this"_get{$type}Declaration")) {
  317.             return $db->raiseError(MDB2_ERROR_NOT_FOUNDnullnull,
  318.                 'type not defined: '.$type__FUNCTION__);
  319.         }
  320.         return $this->{"_get{$type}Declaration"}($name$field);
  321.     }
  322.  
  323.     // }}}
  324.     // {{{ getTypeDeclaration()
  325.  
  326.     /**
  327.      * Obtain DBMS specific SQL code portion needed to declare an text type
  328.      * field to be used in statements like CREATE TABLE.
  329.      *
  330.      * @param array $field  associative array with the name of the properties
  331.      *       of the field being declared as array indexes. Currently, the types
  332.      *       of supported field properties are as follows:
  333.      *
  334.      *       length
  335.      *           Integer value that determines the maximum length of the text
  336.      *           field. If this argument is missing the field should be
  337.      *           declared to have the longest length allowed by the DBMS.
  338.      *
  339.      *       default
  340.      *           Text value to be used as default for this field.
  341.      *
  342.      *       notnull
  343.      *           Boolean flag that indicates whether this field is constrained
  344.      *           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 public
  348.      */
  349.     function getTypeDeclaration($field)
  350.     {
  351.         $db =$this->getDBInstance();
  352.         if (PEAR::isError($db)) {
  353.             return $db;
  354.         }
  355.  
  356.         switch ($field['type']{
  357.         case 'text':
  358.             $length !empty($field['length']$field['length'$db->options['default_text_field_length'];
  359.             $fixed !empty($field['fixed']$field['fixed': false;
  360.             return $fixed ($length 'CHAR('.$length.')' 'CHAR('.$db->options['default_text_field_length'].')')
  361.                 : ($length 'VARCHAR('.$length.')' 'TEXT');
  362.         case 'clob':
  363.             return 'TEXT';
  364.         case 'blob':
  365.             return 'TEXT';
  366.         case 'integer':
  367.             return 'INT';
  368.         case 'boolean':
  369.             return 'INT';
  370.         case 'date':
  371.             return 'CHAR ('.strlen('YYYY-MM-DD').')';
  372.         case 'time':
  373.             return 'CHAR ('.strlen('HH:MM:SS').')';
  374.         case 'timestamp':
  375.             return 'CHAR ('.strlen('YYYY-MM-DD HH:MM:SS').')';
  376.         case 'float':
  377.             return 'TEXT';
  378.         case 'decimal':
  379.             return 'TEXT';
  380.         }
  381.         return '';
  382.     }
  383.  
  384.     // }}}
  385.     // {{{ _getDeclaration()
  386.  
  387.     /**
  388.      * Obtain DBMS specific SQL code portion needed to declare a generic type
  389.      * field to be used in statements like CREATE TABLE.
  390.      *
  391.      * @param string $name   name the field to be declared.
  392.      * @param array  $field  associative array with the name of the properties
  393.      *       of the field being declared as array indexes. Currently, the types
  394.      *       of supported field properties are as follows:
  395.      *
  396.      *       length
  397.      *           Integer value that determines the maximum length of the text
  398.      *           field. If this argument is missing the field should be
  399.      *           declared to have the longest length allowed by the DBMS.
  400.      *
  401.      *       default
  402.      *           Text value to be used as default for this field.
  403.      *
  404.      *       notnull
  405.      *           Boolean flag that indicates whether this field is constrained
  406.      *           to not be set to null.
  407.      *       charset
  408.      *           Text value with the default CHARACTER SET for this field.
  409.      *       collation
  410.      *           Text value with the default COLLATION for this field.
  411.      * @return string  DBMS specific SQL code portion that should be used to
  412.      *       declare the specified field.
  413.      * @access protected
  414.      */
  415.     function _getDeclaration($name$field)
  416.     {
  417.         $db =$this->getDBInstance();
  418.         if (PEAR::isError($db)) {
  419.             return $db;
  420.         }
  421.  
  422.         $default '';
  423.         if (array_key_exists('default'$field)) {
  424.             if ($field['default'=== ''{
  425.                 $field['default'= empty($field['notnull'])
  426.                     ? null : $this->valid_default_values[$field['type']];
  427.                 if ($field['default'=== ''
  428.                     && ($db->options['portability'MDB2_PORTABILITY_EMPTY_TO_NULL)
  429.                 {
  430.                     $field['default'' ';
  431.                 }
  432.             }
  433.             $default ' DEFAULT '.$this->quote($field['default']$field['type']);
  434.         elseif (empty($field['notnull'])) {
  435.             $default ' DEFAULT NULL';
  436.         }
  437.  
  438.         $charset = empty($field['charset']'' :
  439.             ' '.$this->_getCharsetFieldDeclaration($field['charset']);
  440.         
  441.         $collation = empty($field['collation']'' :
  442.             ' '.$this->_getCollationFieldDeclaration($field['collation']);
  443.         
  444.         $notnull = empty($field['notnull']'' ' NOT NULL';
  445.         $name $db->quoteIdentifier($nametrue);
  446.         return $name.' '.$this->getTypeDeclaration($field).$charset.$default.$notnull.$collation;
  447.     }
  448.  
  449.     // }}}
  450.     // {{{ _getCharsetFieldDeclaration()
  451.     
  452.     /**
  453.      * Obtain DBMS specific SQL code portion needed to set the CHARACTER SET
  454.      * of a field declaration to be used in statements like CREATE TABLE.
  455.      *
  456.      * @param string $charset   name of the charset
  457.      * @return string  DBMS specific SQL code portion needed to set the CHARACTER SET
  458.      *                  of a field declaration.
  459.      */
  460.     function _getCharsetFieldDeclaration($charset)
  461.     {
  462.         return '';
  463.     }
  464.  
  465.     // }}}
  466.     // {{{ _getCollationFieldDeclaration()
  467.  
  468.     /**
  469.      * Obtain DBMS specific SQL code portion needed to set the COLLATION
  470.      * of a field declaration to be used in statements like CREATE TABLE.
  471.      *
  472.      * @param string $collation   name of the collation
  473.      * @return string  DBMS specific SQL code portion needed to set the COLLATION
  474.      *                  of a field declaration.
  475.      */
  476.     function _getCollationFieldDeclaration($collation)
  477.     {
  478.         return '';
  479.     }
  480.  
  481.     // }}}
  482.     // {{{ _getIntegerDeclaration()
  483.  
  484.     /**
  485.      * Obtain DBMS specific SQL code portion needed to declare an integer type
  486.      * field to be used in statements like CREATE TABLE.
  487.      *
  488.      * @param string $name name the field to be declared.
  489.      * @param array $field associative array with the name of the properties
  490.      *        of the field being declared as array indexes. Currently, the types
  491.      *        of supported field properties are as follows:
  492.      *
  493.      *        unsigned
  494.      *            Boolean flag that indicates whether the field should be
  495.      *            declared as unsigned integer if possible.
  496.      *
  497.      *        default
  498.      *            Integer value to be used as default for this field.
  499.      *
  500.      *        notnull
  501.      *            Boolean flag that indicates whether this field is constrained
  502.      *            to not be set to null.
  503.      * @return string DBMS specific SQL code portion that should be used to
  504.      *        declare the specified field.
  505.      * @access protected
  506.      */
  507.     function _getIntegerDeclaration($name$field)
  508.     {
  509.         if (!empty($field['unsigned'])) {
  510.             $db =$this->getDBInstance();
  511.             if (PEAR::isError($db)) {
  512.                 return $db;
  513.             }
  514.  
  515.             $db->warnings[= "unsigned integer field \"$name\" is being declared as signed integer";
  516.         }
  517.         return $this->_getDeclaration($name$field);
  518.     }
  519.  
  520.     // }}}
  521.     // {{{ _getTextDeclaration()
  522.  
  523.     /**
  524.      * Obtain DBMS specific SQL code portion needed to declare an text type
  525.      * field to be used in statements like CREATE TABLE.
  526.      *
  527.      * @param string $name name the field to be declared.
  528.      * @param array $field associative array with the name of the properties
  529.      *        of the field being declared as array indexes. Currently, the types
  530.      *        of supported field properties are as follows:
  531.      *
  532.      *        length
  533.      *            Integer value that determines the maximum length of the text
  534.      *            field. If this argument is missing the field should be
  535.      *            declared to have the longest length allowed by the DBMS.
  536.      *
  537.      *        default
  538.      *            Text value to be used as default for this field.
  539.      *
  540.      *        notnull
  541.      *            Boolean flag that indicates whether this field is constrained
  542.      *            to not be set to null.
  543.      * @return string DBMS specific SQL code portion that should be used to
  544.      *        declare the specified field.
  545.      * @access protected
  546.      */
  547.     function _getTextDeclaration($name$field)
  548.     {
  549.         return $this->_getDeclaration($name$field);
  550.     }
  551.  
  552.     // }}}
  553.     // {{{ _getCLOBDeclaration()
  554.  
  555.     /**
  556.      * Obtain DBMS specific SQL code portion needed to declare an character
  557.      * large object type field to be used in statements like CREATE TABLE.
  558.      *
  559.      * @param string $name name the field to be declared.
  560.      * @param array $field associative array with the name of the properties
  561.      *         of the field being declared as array indexes. Currently, the types
  562.      *         of supported field properties are as follows:
  563.      *
  564.      *         length
  565.      *             Integer value that determines the maximum length of the large
  566.      *             object field. If this argument is missing the field should be
  567.      *             declared to have the longest length allowed by the DBMS.
  568.      *
  569.      *         notnull
  570.      *             Boolean flag that indicates whether this field is constrained
  571.      *             to not be set to null.
  572.      * @return string DBMS specific SQL code portion that should be used to
  573.      *         declare the specified field.
  574.      * @access public
  575.      */
  576.     function _getCLOBDeclaration($name$field)
  577.     {
  578.         $db =$this->getDBInstance();
  579.         if (PEAR::isError($db)) {
  580.             return $db;
  581.         }
  582.  
  583.         $notnull = empty($field['notnull']'' ' NOT NULL';
  584.         $name $db->quoteIdentifier($nametrue);
  585.         return $name.' '.$this->getTypeDeclaration($field).$notnull;
  586.     }
  587.  
  588.     // }}}
  589.     // {{{ _getBLOBDeclaration()
  590.  
  591.     /**
  592.      * Obtain DBMS specific SQL code portion needed to declare an binary large
  593.      * object type field to be used in statements like CREATE TABLE.
  594.      *
  595.      * @param string $name name the field to be declared.
  596.      * @param array $field associative array with the name of the properties
  597.      *         of the field being declared as array indexes. Currently, the types
  598.      *         of supported field properties are as follows:
  599.      *
  600.      *         length
  601.      *             Integer value that determines the maximum length of the large
  602.      *             object field. If this argument is missing the field should be
  603.      *             declared to have the longest length allowed by the DBMS.
  604.      *
  605.      *         notnull
  606.      *             Boolean flag that indicates whether this field is constrained
  607.      *             to not be set to null.
  608.      * @return string DBMS specific SQL code portion that should be used to
  609.      *         declare the specified field.
  610.      * @access protected
  611.      */
  612.     function _getBLOBDeclaration($name$field)
  613.     {
  614.         $db =$this->getDBInstance();
  615.         if (PEAR::isError($db)) {
  616.             return $db;
  617.         }
  618.  
  619.         $notnull = empty($field['notnull']'' ' NOT NULL';
  620.         $name $db->quoteIdentifier($nametrue);
  621.         return $name.' '.$this->getTypeDeclaration($field).$notnull;
  622.     }
  623.  
  624.     // }}}
  625.     // {{{ _getBooleanDeclaration()
  626.  
  627.     /**
  628.      * Obtain DBMS specific SQL code portion needed to declare a boolean type
  629.      * field to be used in statements like CREATE TABLE.
  630.      *
  631.      * @param string $name name the field to be declared.
  632.      * @param array $field associative array with the name of the properties
  633.      *        of the field being declared as array indexes. Currently, the types
  634.      *        of supported field properties are as follows:
  635.      *
  636.      *        default
  637.      *            Boolean value to be used as default for this field.
  638.      *
  639.      *        notnullL
  640.      *            Boolean flag that indicates whether this field is constrained
  641.      *            to not be set to null.
  642.      * @return string DBMS specific SQL code portion that should be used to
  643.      *        declare the specified field.
  644.      * @access protected
  645.      */
  646.     function _getBooleanDeclaration($name$field)
  647.     {
  648.         return $this->_getDeclaration($name$field);
  649.     }
  650.  
  651.     // }}}
  652.     // {{{ _getDateDeclaration()
  653.  
  654.     /**
  655.      * Obtain DBMS specific SQL code portion needed to declare a date type
  656.      * field to be used in statements like CREATE TABLE.
  657.      *
  658.      * @param string $name name the field to be declared.
  659.      * @param array $field associative array with the name of the properties
  660.      *        of the field being declared as array indexes. Currently, the types
  661.      *        of supported field properties are as follows:
  662.      *
  663.      *        default
  664.      *            Date value to be used as default for this field.
  665.      *
  666.      *        notnull
  667.      *            Boolean flag that indicates whether this field is constrained
  668.      *            to not be set to null.
  669.      * @return string DBMS specific SQL code portion that should be used to
  670.      *        declare the specified field.
  671.      * @access protected
  672.      */
  673.     function _getDateDeclaration($name$field)
  674.     {
  675.         return $this->_getDeclaration($name$field);
  676.     }
  677.  
  678.     // }}}
  679.     // {{{ _getTimestampDeclaration()
  680.  
  681.     /**
  682.      * Obtain DBMS specific SQL code portion needed to declare a timestamp
  683.      * field to be used in statements like CREATE TABLE.
  684.      *
  685.      * @param string $name name the field to be declared.
  686.      * @param array $field associative array with the name of the properties
  687.      *        of the field being declared as array indexes. Currently, the types
  688.      *        of supported field properties are as follows:
  689.      *
  690.      *        default
  691.      *            Timestamp value to be used as default for this field.
  692.      *
  693.      *        notnull
  694.      *            Boolean flag that indicates whether this field is constrained
  695.      *            to not be set to null.
  696.      * @return string DBMS specific SQL code portion that should be used to
  697.      *        declare the specified field.
  698.      * @access protected
  699.      */
  700.     function _getTimestampDeclaration($name$field)
  701.     {
  702.         return $this->_getDeclaration($name$field);
  703.     }
  704.  
  705.     // }}}
  706.     // {{{ _getTimeDeclaration()
  707.  
  708.     /**
  709.      * Obtain DBMS specific SQL code portion needed to declare a time
  710.      * field to be used in statements like CREATE TABLE.
  711.      *
  712.      * @param string $name name the field to be declared.
  713.      * @param array $field associative array with the name of the properties
  714.      *        of the field being declared as array indexes. Currently, the types
  715.      *        of supported field properties are as follows:
  716.      *
  717.      *        default
  718.      *            Time value to be used as default for this field.
  719.      *
  720.      *        notnull
  721.      *            Boolean flag that indicates whether this field is constrained
  722.      *            to not be set to null.
  723.      * @return string DBMS specific SQL code portion that should be used to
  724.      *        declare the specified field.
  725.      * @access protected
  726.      */
  727.     function _getTimeDeclaration($name$field)
  728.     {
  729.         return $this->_getDeclaration($name$field);
  730.     }
  731.  
  732.     // }}}
  733.     // {{{ _getFloatDeclaration()
  734.  
  735.     /**
  736.      * Obtain DBMS specific SQL code portion needed to declare a float type
  737.      * field to be used in statements like CREATE TABLE.
  738.      *
  739.      * @param string $name name the field to be declared.
  740.      * @param array $field associative array with the name of the properties
  741.      *        of the field being declared as array indexes. Currently, the types
  742.      *        of supported field properties are as follows:
  743.      *
  744.      *        default
  745.      *            Float value to be used as default for this field.
  746.      *
  747.      *        notnull
  748.      *            Boolean flag that indicates whether this field is constrained
  749.      *            to not be set to null.
  750.      * @return string DBMS specific SQL code portion that should be used to
  751.      *        declare the specified field.
  752.      * @access protected
  753.      */
  754.     function _getFloatDeclaration($name$field)
  755.     {
  756.         return $this->_getDeclaration($name$field);
  757.     }
  758.  
  759.     // }}}
  760.     // {{{ _getDecimalDeclaration()
  761.  
  762.     /**
  763.      * Obtain DBMS specific SQL code portion needed to declare a decimal type
  764.      * field to be used in statements like CREATE TABLE.
  765.      *
  766.      * @param string $name name the field to be declared.
  767.      * @param array $field associative array with the name of the properties
  768.      *        of the field being declared as array indexes. Currently, the types
  769.      *        of supported field properties are as follows:
  770.      *
  771.      *        default
  772.      *            Decimal value to be used as default for this field.
  773.      *
  774.      *        notnull
  775.      *            Boolean flag that indicates whether this field is constrained
  776.      *            to not be set to null.
  777.      * @return string DBMS specific SQL code portion that should be used to
  778.      *        declare the specified field.
  779.      * @access protected
  780.      */
  781.     function _getDecimalDeclaration($name$field)
  782.     {
  783.         return $this->_getDeclaration($name$field);
  784.     }
  785.  
  786.     // }}}
  787.     // {{{ compareDefinition()
  788.  
  789.     /**
  790.      * Obtain an array of changes that may need to applied
  791.      *
  792.      * @param array $current new definition
  793.      * @param array  $previous old definition
  794.      * @return array  containing all changes that will need to be applied
  795.      * @access public
  796.      */
  797.     function compareDefinition($current$previous)
  798.     {
  799.         $type !empty($current['type']$current['type': null;
  800.  
  801.         if (!method_exists($this"_compare{$type}Definition")) {
  802.             $db =$this->getDBInstance();
  803.             if (PEAR::isError($db)) {
  804.                 return $db;
  805.             }
  806.  
  807.             return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  808.                 'type "'.$current['type'].'" is not yet supported'__FUNCTION__);
  809.         }
  810.  
  811.         if (empty($previous['type']|| $previous['type'!= $type{
  812.             return $current;
  813.         }
  814.  
  815.         $change $this->{"_compare{$type}Definition"}($current$previous);
  816.  
  817.         if ($previous['type'!= $type{
  818.             $change['type'= true;
  819.         }
  820.  
  821.         $previous_notnull !empty($previous['notnull']$previous['notnull': false;
  822.         $notnull !empty($current['notnull']$current['notnull': false;
  823.         if ($previous_notnull != $notnull{
  824.             $change['notnull'= true;
  825.         }
  826.  
  827.         $previous_default array_key_exists('default'$previous$previous['default':
  828.             ($previous_notnull '' : null);
  829.         $default array_key_exists('default'$current$current['default':
  830.             ($notnull '' : null);
  831.         if ($previous_default !== $default{
  832.             $change['default'= true;
  833.         }
  834.  
  835.         return $change;
  836.     }
  837.  
  838.     // }}}
  839.     // {{{ _compareIntegerDefinition()
  840.  
  841.     /**
  842.      * Obtain an array of changes that may need to applied to an integer field
  843.      *
  844.      * @param array $current new definition
  845.      * @param array  $previous old definition
  846.      * @return array  containing all changes that will need to be applied
  847.      * @access protected
  848.      */
  849.     function _compareIntegerDefinition($current$previous)
  850.     {
  851.         $change = array();
  852.         $previous_unsigned !empty($previous['unsigned']$previous['unsigned': false;
  853.         $unsigned !empty($current['unsigned']$current['unsigned': false;
  854.         if ($previous_unsigned != $unsigned{
  855.             $change['unsigned'= true;
  856.         }
  857.         $previous_autoincrement !empty($previous['autoincrement']$previous['autoincrement': false;
  858.         $autoincrement !empty($current['autoincrement']$current['autoincrement': false;
  859.         if ($previous_autoincrement != $autoincrement{
  860.             $change['autoincrement'= true;
  861.         }
  862.         return $change;
  863.     }
  864.  
  865.     // }}}
  866.     // {{{ _compareTextDefinition()
  867.  
  868.     /**
  869.      * Obtain an array of changes that may need to applied to an text field
  870.      *
  871.      * @param array $current new definition
  872.      * @param array  $previous old definition
  873.      * @return array  containing all changes that will need to be applied
  874.      * @access protected
  875.      */
  876.     function _compareTextDefinition($current$previous)
  877.     {
  878.         $change = array();
  879.         $previous_length !empty($previous['length']$previous['length': 0;
  880.         $length !empty($current['length']$current['length': 0;
  881.         if ($previous_length != $length{
  882.             $change['length'= true;
  883.         }
  884.         $previous_fixed !empty($previous['fixed']$previous['fixed': 0;
  885.         $fixed !empty($current['fixed']$current['fixed': 0;
  886.         if ($previous_fixed != $fixed{
  887.             $change['fixed'= true;
  888.         }
  889.         return $change;
  890.     }
  891.  
  892.     // }}}
  893.     // {{{ _compareCLOBDefinition()
  894.  
  895.     /**
  896.      * Obtain an array of changes that may need to applied to an CLOB field
  897.      *
  898.      * @param array $current new definition
  899.      * @param array  $previous old definition
  900.      * @return array  containing all changes that will need to be applied
  901.      * @access protected
  902.      */
  903.     function _compareCLOBDefinition($current$previous)
  904.     {
  905.         return $this->_compareTextDefinition($current$previous);
  906.     }
  907.  
  908.     // }}}
  909.     // {{{ _compareBLOBDefinition()
  910.  
  911.     /**
  912.      * Obtain an array of changes that may need to applied to an BLOB field
  913.      *
  914.      * @param array $current new definition
  915.      * @param array  $previous old definition
  916.      * @return array  containing all changes that will need to be applied
  917.      * @access protected
  918.      */
  919.     function _compareBLOBDefinition($current$previous)
  920.     {
  921.         return $this->_compareTextDefinition($current$previous);
  922.     }
  923.  
  924.     // }}}
  925.     // {{{ _compareDateDefinition()
  926.  
  927.     /**
  928.      * Obtain an array of changes that may need to applied to an date field
  929.      *
  930.      * @param array $current new definition
  931.      * @param array  $previous old definition
  932.      * @return array  containing all changes that will need to be applied
  933.      * @access protected
  934.      */
  935.     function _compareDateDefinition($current$previous)
  936.     {
  937.         return array();
  938.     }
  939.  
  940.     // }}}
  941.     // {{{ _compareTimeDefinition()
  942.  
  943.     /**
  944.      * Obtain an array of changes that may need to applied to an time field
  945.      *
  946.      * @param array $current new definition
  947.      * @param array  $previous old definition
  948.      * @return array  containing all changes that will need to be applied
  949.      * @access protected
  950.      */
  951.     function _compareTimeDefinition($current$previous)
  952.     {
  953.         return array();
  954.     }
  955.  
  956.     // }}}
  957.     // {{{ _compareTimestampDefinition()
  958.  
  959.     /**
  960.      * Obtain an array of changes that may need to applied to an timestamp field
  961.      *
  962.      * @param array $current new definition
  963.      * @param array  $previous old definition
  964.      * @return array  containing all changes that will need to be applied
  965.      * @access protected
  966.      */
  967.     function _compareTimestampDefinition($current$previous)
  968.     {
  969.         return array();
  970.     }
  971.  
  972.     // }}}
  973.     // {{{ _compareBooleanDefinition()
  974.  
  975.     /**
  976.      * Obtain an array of changes that may need to applied to an boolean field
  977.      *
  978.      * @param array $current new definition
  979.      * @param array  $previous old definition
  980.      * @return array  containing all changes that will need to be applied
  981.      * @access protected
  982.      */
  983.     function _compareBooleanDefinition($current$previous)
  984.     {
  985.         return array();
  986.     }
  987.  
  988.     // }}}
  989.     // {{{ _compareFloatDefinition()
  990.  
  991.     /**
  992.      * Obtain an array of changes that may need to applied to an float field
  993.      *
  994.      * @param array $current new definition
  995.      * @param array  $previous old definition
  996.      * @return array  containing all changes that will need to be applied
  997.      * @access protected
  998.      */
  999.     function _compareFloatDefinition($current$previous)
  1000.     {
  1001.         return array();
  1002.     }
  1003.  
  1004.     // }}}
  1005.     // {{{ _compareDecimalDefinition()
  1006.  
  1007.     /**
  1008.      * Obtain an array of changes that may need to applied to an decimal field
  1009.      *
  1010.      * @param array $current new definition
  1011.      * @param array  $previous old definition
  1012.      * @return array  containing all changes that will need to be applied
  1013.      * @access protected
  1014.      */
  1015.     function _compareDecimalDefinition($current$previous)
  1016.     {
  1017.         return array();
  1018.     }
  1019.  
  1020.     // }}}
  1021.     // {{{ quote()
  1022.  
  1023.     /**
  1024.      * Convert a text value into a DBMS specific format that is suitable to
  1025.      * compose query statements.
  1026.      *
  1027.      * @param string $value text string value that is intended to be converted.
  1028.      * @param string $type type to which the value should be converted to
  1029.      * @param bool $quote determines if the value should be quoted and escaped
  1030.      * @param bool $escape_wildcards if to escape escape wildcards
  1031.      * @return string text string that represents the given argument value in
  1032.      *        a DBMS specific format.
  1033.      * @access public
  1034.      */
  1035.     function quote($value$type = null$quote = true$escape_wildcards = false)
  1036.     {
  1037.         $db =$this->getDBInstance();
  1038.         if (PEAR::isError($db)) {
  1039.             return $db;
  1040.         }
  1041.  
  1042.         if (is_null($value)
  1043.             || ($value === '' && $db->options['portability'MDB2_PORTABILITY_EMPTY_TO_NULL)
  1044.         {
  1045.             if (!$quote{
  1046.                 return null;
  1047.             }
  1048.             return 'NULL';
  1049.         }
  1050.  
  1051.         if (is_null($type)) {
  1052.             switch (gettype($value)) {
  1053.             case 'integer':
  1054.                 $type 'integer';
  1055.                 break;
  1056.             case 'double':
  1057.                 // todo: default to decimal as float is quite unusual
  1058.                 // $type = 'float';
  1059.                 $type 'decimal';
  1060.                 break;
  1061.             case 'boolean':
  1062.                 $type 'boolean';
  1063.                 break;
  1064.             case 'array':
  1065.                  $value serialize($value);
  1066.             case 'object':
  1067.                  $type 'text';
  1068.                 break;
  1069.             default:
  1070.                 if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/'$value)) {
  1071.                     $type 'timestamp';
  1072.                 elseif (preg_match('/^\d{2}:\d{2}$/'$value)) {
  1073.                     $type 'time';
  1074.                 elseif (preg_match('/^\d{4}-\d{2}-\d{2}$/'$value)) {
  1075.                     $type 'date';
  1076.                 else {
  1077.                     $type 'text';
  1078.                 }
  1079.                 break;
  1080.             }
  1081.         elseif (!empty($db->options['datatype_map'][$type])) {
  1082.             $type $db->options['datatype_map'][$type];
  1083.             if (!empty($db->options['datatype_map_callback'][$type])) {
  1084.                 $parameter = array('type' => $type'value' => $value'quote' => $quote'escape_wildcards' => $escape_wildcards);
  1085.                 return call_user_func_array($db->options['datatype_map_callback'][$type]array(&$db__FUNCTION__$parameter));
  1086.             }
  1087.         }
  1088.  
  1089.         if (!method_exists($this"_quote{$type}")) {
  1090.             return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  1091.                 'type not defined: '.$type__FUNCTION__);
  1092.         }
  1093.         $value $this->{"_quote{$type}"}($value$quote$escape_wildcards);
  1094.         if ($quote && $escape_wildcards && $db->string_quoting['escape_pattern']
  1095.             && $db->string_quoting['escape'!== $db->string_quoting['escape_pattern']
  1096.         {
  1097.             $value.= $this->patternEscapeString();
  1098.         }
  1099.         return $value;
  1100.     }
  1101.  
  1102.     // }}}
  1103.     // {{{ _quoteInteger()
  1104.  
  1105.     /**
  1106.      * Convert a text value into a DBMS specific format that is suitable to
  1107.      * compose query statements.
  1108.      *
  1109.      * @param string $value text string value that is intended to be converted.
  1110.      * @param bool $quote determines if the value should be quoted and escaped
  1111.      * @param bool $escape_wildcards if to escape escape wildcards
  1112.      * @return string text string that represents the given argument value in
  1113.      *        a DBMS specific format.
  1114.      * @access protected
  1115.      */
  1116.     function _quoteInteger($value$quote$escape_wildcards)
  1117.     {
  1118.         return (int)$value;
  1119.     }
  1120.  
  1121.     // }}}
  1122.     // {{{ _quoteText()
  1123.  
  1124.     /**
  1125.      * Convert a text value into a DBMS specific format that is suitable to
  1126.      * compose query statements.
  1127.      *
  1128.      * @param string $value text string value that is intended to be converted.
  1129.      * @param bool $quote determines if the value should be quoted and escaped
  1130.      * @param bool $escape_wildcards if to escape escape wildcards
  1131.      * @return string text string that already contains any DBMS specific
  1132.      *        escaped character sequences.
  1133.      * @access protected
  1134.      */
  1135.     function _quoteText($value$quote$escape_wildcards)
  1136.     {
  1137.         if (!$quote{
  1138.             return $value;
  1139.         }
  1140.  
  1141.         $db =$this->getDBInstance();
  1142.         if (PEAR::isError($db)) {
  1143.             return $db;
  1144.         }
  1145.  
  1146.         $value $db->escape($value$escape_wildcards);
  1147.         return "'".$value."'";
  1148.     }
  1149.  
  1150.     // }}}
  1151.     // {{{ _readFile()
  1152.  
  1153.     /**
  1154.      * Convert a text value into a DBMS specific format that is suitable to
  1155.      * compose query statements.
  1156.      *
  1157.      * @param string $value text string value that is intended to be converted.
  1158.      * @return string text string that represents the given argument value in
  1159.      *        a DBMS specific format.
  1160.      * @access protected
  1161.      */
  1162.     function _readFile($value)
  1163.     {
  1164.         $close = false;
  1165.         if (preg_match('/^(\w+:\/\/)(.*)$/'$value$match)) {
  1166.             $close = true;
  1167.             if ($match[1== 'file://'{
  1168.                 $value $match[2];
  1169.             }
  1170.             $value @fopen($value'r');
  1171.         }
  1172.  
  1173.         if (is_resource($value)) {
  1174.             $db =$this->getDBInstance();
  1175.             if (PEAR::isError($db)) {
  1176.                 return $db;
  1177.             }
  1178.  
  1179.             $fp $value;
  1180.             $value '';
  1181.             while (!@feof($fp)) {
  1182.                 $value.= @fread($fp$db->options['lob_buffer_length']);
  1183.             }
  1184.             if ($close{
  1185.                 @fclose($fp);
  1186.             }
  1187.         }
  1188.  
  1189.         return $value;
  1190.     }
  1191.  
  1192.     // }}}
  1193.     // {{{ _quoteLOB()
  1194.  
  1195.     /**
  1196.      * Convert a text value into a DBMS specific format that is suitable to
  1197.      * compose query statements.
  1198.      *
  1199.      * @param string $value text string value that is intended to be converted.
  1200.      * @param bool $quote determines if the value should be quoted and escaped
  1201.      * @param bool $escape_wildcards if to escape escape wildcards
  1202.      * @return string text string that represents the given argument value in
  1203.      *        a DBMS specific format.
  1204.      * @access protected
  1205.      */
  1206.     function _quoteLOB($value$quote$escape_wildcards)
  1207.     {
  1208.         $value $this->_readFile($value);
  1209.         return $this->_quoteText($value$quote$escape_wildcards);
  1210.     }
  1211.  
  1212.     // }}}
  1213.     // {{{ _quoteCLOB()
  1214.  
  1215.     /**
  1216.      * Convert a text value into a DBMS specific format that is suitable to
  1217.      * compose query statements.
  1218.      *
  1219.      * @param string $value text string value that is intended to be converted.
  1220.      * @param bool $quote determines if the value should be quoted and escaped
  1221.      * @param bool $escape_wildcards if to escape escape wildcards
  1222.      * @return string text string that represents the given argument value in
  1223.      *        a DBMS specific format.
  1224.      * @access protected
  1225.      */
  1226.     function _quoteCLOB($value$quote$escape_wildcards)
  1227.     {
  1228.         return $this->_quoteLOB($value$quote$escape_wildcards);
  1229.     }
  1230.  
  1231.     // }}}
  1232.     // {{{ _quoteBLOB()
  1233.  
  1234.     /**
  1235.      * Convert a text value into a DBMS specific format that is suitable to
  1236.      * compose query statements.
  1237.      *
  1238.      * @param string $value text string value that is intended to be converted.
  1239.      * @param bool $quote determines if the value should be quoted and escaped
  1240.      * @param bool $escape_wildcards if to escape escape wildcards
  1241.      * @return string text string that represents the given argument value in
  1242.      *        a DBMS specific format.
  1243.      * @access protected
  1244.      */
  1245.     function _quoteBLOB($value$quote$escape_wildcards)
  1246.     {
  1247.         return $this->_quoteLOB($value$quote$escape_wildcards);
  1248.     }
  1249.  
  1250.     // }}}
  1251.     // {{{ _quoteBoolean()
  1252.  
  1253.     /**
  1254.      * Convert a text value into a DBMS specific format that is suitable to
  1255.      * compose query statements.
  1256.      *
  1257.      * @param string $value text string value that is intended to be converted.
  1258.      * @param bool $quote determines if the value should be quoted and escaped
  1259.      * @param bool $escape_wildcards if to escape escape wildcards
  1260.      * @return string text string that represents the given argument value in
  1261.      *        a DBMS specific format.
  1262.      * @access protected
  1263.      */
  1264.     function _quoteBoolean($value$quote$escape_wildcards)
  1265.     {
  1266.         return ($value ? 1 : 0);
  1267.     }
  1268.  
  1269.     // }}}
  1270.     // {{{ _quoteDate()
  1271.  
  1272.     /**
  1273.      * Convert a text value into a DBMS specific format that is suitable to
  1274.      * compose query statements.
  1275.      *
  1276.      * @param string $value text string value that is intended to be converted.
  1277.      * @param bool $quote determines if the value should be quoted and escaped
  1278.      * @param bool $escape_wildcards if to escape escape wildcards
  1279.      * @return string text string that represents the given argument value in
  1280.      *        a DBMS specific format.
  1281.      * @access protected
  1282.      */
  1283.     function _quoteDate($value$quote$escape_wildcards)
  1284.     {
  1285.         if ($value === 'CURRENT_DATE'{
  1286.             $db =$this->getDBInstance();
  1287.             if (PEAR::isError($db)) {
  1288.                 return $db;
  1289.             }
  1290.             if (isset($db->function&& is_a($db->function'MDB2_Driver_Function_Common')) {
  1291.                 return $db->function->now('date');
  1292.             }
  1293.             return 'CURRENT_DATE';
  1294.         }
  1295.         return $this->_quoteText($value$quote$escape_wildcards);
  1296.     }
  1297.  
  1298.     // }}}
  1299.     // {{{ _quoteTimestamp()
  1300.  
  1301.     /**
  1302.      * Convert a text value into a DBMS specific format that is suitable to
  1303.      * compose query statements.
  1304.      *
  1305.      * @param string $value text string value that is intended to be converted.
  1306.      * @param bool $quote determines if the value should be quoted and escaped
  1307.      * @param bool $escape_wildcards if to escape escape wildcards
  1308.      * @return string text string that represents the given argument value in
  1309.      *        a DBMS specific format.
  1310.      * @access protected
  1311.      */
  1312.     function _quoteTimestamp($value$quote$escape_wildcards)
  1313.     {
  1314.         if ($value === 'CURRENT_TIMESTAMP'{
  1315.             $db =$this->getDBInstance();
  1316.             if (PEAR::isError($db)) {
  1317.                 return $db;
  1318.             }
  1319.             if (isset($db->function&& is_a($db->function'MDB2_Driver_Function_Common')) {
  1320.                 return $db->function->now('timestamp');
  1321.             }
  1322.             return 'CURRENT_TIMESTAMP';
  1323.         }
  1324.         return $this->_quoteText($value$quote$escape_wildcards);
  1325.     }
  1326.  
  1327.     // }}}
  1328.     // {{{ _quoteTime()
  1329.  
  1330.     /**
  1331.      * Convert a text value into a DBMS specific format that is suitable to
  1332.      *       compose query statements.
  1333.      *
  1334.      * @param string $value text string value that is intended to be converted.
  1335.      * @param bool $quote determines if the value should be quoted and escaped
  1336.      * @param bool $escape_wildcards if to escape escape wildcards
  1337.      * @return string text string that represents the given argument value in
  1338.      *        a DBMS specific format.
  1339.      * @access protected
  1340.      */
  1341.     function _quoteTime($value$quote$escape_wildcards)
  1342.     {
  1343.         if ($value === 'CURRENT_TIME'{
  1344.             $db =$this->getDBInstance();
  1345.             if (PEAR::isError($db)) {
  1346.                 return $db;
  1347.             }
  1348.             if (isset($db->function&& is_a($db->function'MDB2_Driver_Function_Common')) {
  1349.                 return $db->function->now('time');
  1350.             }
  1351.             return 'CURRENT_TIME';
  1352.         }
  1353.         return $this->_quoteText($value$quote$escape_wildcards);
  1354.     }
  1355.  
  1356.     // }}}
  1357.     // {{{ _quoteFloat()
  1358.  
  1359.     /**
  1360.      * Convert a text value into a DBMS specific format that is suitable to
  1361.      * compose query statements.
  1362.      *
  1363.      * @param string $value text string value that is intended to be converted.
  1364.      * @param bool $quote determines if the value should be quoted and escaped
  1365.      * @param bool $escape_wildcards if to escape escape wildcards
  1366.      * @return string text string that represents the given argument value in
  1367.      *        a DBMS specific format.
  1368.      * @access protected
  1369.      */
  1370.     function _quoteFloat($value$quote$escape_wildcards)
  1371.     {
  1372.         if (preg_match('/^(.*)e([-+])(\d+)$/i'$value$matches)) {
  1373.             $decimal $this->_quoteDecimal($matches[1]$quote$escape_wildcards);
  1374.             $sign $matches[2];
  1375.             $exponent str_pad($matches[3]2'0'STR_PAD_LEFT);
  1376.             $value $decimal.'E'.$sign.$exponent;
  1377.         else {
  1378.             $value $this->_quoteDecimal($value$quote$escape_wildcards);
  1379.         }
  1380.         return $value;
  1381.     }
  1382.  
  1383.     // }}}
  1384.     // {{{ _quoteDecimal()
  1385.  
  1386.     /**
  1387.      * Convert a text value into a DBMS specific format that is suitable to
  1388.      * compose query statements.
  1389.      *
  1390.      * @param string $value text string value that is intended to be converted.
  1391.      * @param bool $quote determines if the value should be quoted and escaped
  1392.      * @param bool $escape_wildcards if to escape escape wildcards
  1393.      * @return string text string that represents the given argument value in
  1394.      *        a DBMS specific format.
  1395.      * @access protected
  1396.      */
  1397.     function _quoteDecimal($value$quote$escape_wildcards)
  1398.     {
  1399.         $value = (string)$value;
  1400.         if (preg_match('/[^.0-9]/'$value)) {
  1401.             if (strpos($value',')) {
  1402.                 // 1000,00
  1403.                 if (!strpos($value'.')) {
  1404.                     // convert the last "," to a "."
  1405.                     $value strrev(str_replace(',''.'strrev($value)));
  1406.                 // 1.000,00
  1407.                 elseif (strpos($value'.'&& strpos($value'.'strpos($value',')) {
  1408.                     $value str_replace('.'''$value);
  1409.                     // convert the last "," to a "."
  1410.                     $value strrev(str_replace(',''.'strrev($value)));
  1411.                 // 1,000.00
  1412.                 else {
  1413.                     $value str_replace(','''$value);
  1414.                 }
  1415.             }
  1416.         }
  1417.         return $value;
  1418.     }
  1419.  
  1420.     // }}}
  1421.     // {{{ writeLOBToFile()
  1422.  
  1423.     /**
  1424.      * retrieve LOB from the database
  1425.      *
  1426.      * @param resource $lob stream handle
  1427.      * @param string $file name of the file into which the LOb should be fetched
  1428.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1429.      * @access protected
  1430.      */
  1431.     function writeLOBToFile($lob$file)
  1432.     {
  1433.         $db =$this->getDBInstance();
  1434.         if (PEAR::isError($db)) {
  1435.             return $db;
  1436.         }
  1437.  
  1438.         if (preg_match('/^(\w+:\/\/)(.*)$/'$file$match)) {
  1439.             if ($match[1== 'file://'{
  1440.                 $file $match[2];
  1441.             }
  1442.         }
  1443.  
  1444.         $fp @fopen($file'wb');
  1445.         while (!@feof($lob)) {
  1446.             $result @fread($lob$db->options['lob_buffer_length']);
  1447.             $read strlen($result);
  1448.             if (@fwrite($fp$result$read!= $read{
  1449.                 @fclose($fp);
  1450.                 return $db->raiseError(MDB2_ERRORnullnull,
  1451.                     'could not write to the output file'__FUNCTION__);
  1452.             }
  1453.         }
  1454.         @fclose($fp);
  1455.         return MDB2_OK;
  1456.     }
  1457.  
  1458.     // }}}
  1459.     // {{{ _retrieveLOB()
  1460.  
  1461.     /**
  1462.      * retrieve LOB from the database
  1463.      *
  1464.      * @param array $lob array
  1465.      * @return mixed MDB2_OK on success, a MDB2 error on failure
  1466.      * @access protected
  1467.      */
  1468.     function _retrieveLOB(&$lob)
  1469.     {
  1470.         if (is_null($lob['value'])) {
  1471.             $lob['value'$lob['resource'];
  1472.         }
  1473.         $lob['loaded'= true;
  1474.         return MDB2_OK;
  1475.     }
  1476.  
  1477.     // }}}
  1478.     // {{{ readLOB()
  1479.  
  1480.     /**
  1481.      * Read data from large object input stream.
  1482.      *
  1483.      * @param resource $lob stream handle
  1484.      * @param string $data reference to a variable that will hold data
  1485.      *                           to be read from the large object input stream
  1486.      * @param integer $length    value that indicates the largest ammount ofdata
  1487.      *                           to be read from the large object input stream.
  1488.      * @return mixed the effective number of bytes read from the large object
  1489.      *                       input stream on sucess or an MDB2 error object.
  1490.      * @access public
  1491.      * @see endOfLOB()
  1492.      */
  1493.     function _readLOB($lob$length)
  1494.     {
  1495.         return substr($lob['value']$lob['position']$length);
  1496.     }
  1497.  
  1498.     // }}}
  1499.     // {{{ _endOfLOB()
  1500.  
  1501.     /**
  1502.      * Determine whether it was reached the end of the large object and
  1503.      * therefore there is no more data to be read for the its input stream.
  1504.      *
  1505.      * @param array $lob array
  1506.      * @return mixed true or false on success, a MDB2 error on failure
  1507.      * @access protected
  1508.      */
  1509.     function _endOfLOB($lob)
  1510.     {
  1511.         return $lob['endOfLOB'];
  1512.     }
  1513.  
  1514.     // }}}
  1515.     // {{{ destroyLOB()
  1516.  
  1517.     /**
  1518.      * Free any resources allocated during the lifetime of the large object
  1519.      * handler object.
  1520.      *
  1521.      * @param resource $lob stream handle
  1522.      * @access public
  1523.      */
  1524.     function destroyLOB($lob)
  1525.     {
  1526.         $lob_data stream_get_meta_data($lob);
  1527.         $lob_index $lob_data['wrapper_data']->lob_index;
  1528.         fclose($lob);
  1529.         if (isset($this->lobs[$lob_index])) {
  1530.             $this->_destroyLOB($this->lobs[$lob_index]);
  1531.             unset($this->lobs[$lob_index]);
  1532.         }
  1533.         return MDB2_OK;
  1534.     }
  1535.  
  1536.     // }}}
  1537.     // {{{ _destroyLOB()
  1538.  
  1539.     /**
  1540.      * Free any resources allocated during the lifetime of the large object
  1541.      * handler object.
  1542.      *
  1543.      * @param array $lob array
  1544.      * @access private
  1545.      */
  1546.     function _destroyLOB(&$lob)
  1547.     {
  1548.         return MDB2_OK;
  1549.     }
  1550.  
  1551.     // }}}
  1552.     // {{{ implodeArray()
  1553.  
  1554.     /**
  1555.      * apply a type to all values of an array and return as a comma seperated string
  1556.      * useful for generating IN statements
  1557.      *
  1558.      * @access public
  1559.      *
  1560.      * @param array $array data array
  1561.      * @param string $type determines type of the field
  1562.      *
  1563.      * @return string comma seperated values
  1564.      */
  1565.     function implodeArray($array$type = false)
  1566.     {
  1567.         if (!is_array($array|| empty($array)) {
  1568.             return 'NULL';
  1569.         }
  1570.         if ($type{
  1571.             foreach ($array as $value{
  1572.                 $return[$this->quote($value$type);
  1573.             }
  1574.         else {
  1575.             $return $array;
  1576.         }
  1577.         return implode(', '$return);
  1578.     }
  1579.  
  1580.     // }}}
  1581.     // {{{ matchPattern()
  1582.  
  1583.     /**
  1584.      * build a pattern matching string
  1585.      *
  1586.      * EXPERIMENTAL
  1587.      *
  1588.      * WARNING: this function is experimental and may change signature at
  1589.      * any time until labelled as non-experimental
  1590.      *
  1591.      * @access public
  1592.      *
  1593.      * @param array $pattern even keys are strings, odd are patterns (% and _)
  1594.      * @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future)
  1595.      * @param string $field optional field name that is being matched against
  1596.      *                   (might be required when emulating ILIKE)
  1597.      *
  1598.      * @return string SQL pattern
  1599.      */
  1600.     function matchPattern($pattern$operator = null$field = null)
  1601.     {
  1602.         $db =$this->getDBInstance();
  1603.         if (PEAR::isError($db)) {
  1604.             return $db;
  1605.         }
  1606.  
  1607.         $match '';
  1608.         if (!is_null($operator)) {
  1609.             $operator strtoupper($operator);
  1610.             switch ($operator{
  1611.             // case insensitive
  1612.             case 'ILIKE':
  1613.                 if (is_null($field)) {
  1614.                     return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  1615.                         'case insensitive LIKE matching requires passing the field name'__FUNCTION__);
  1616.                 }
  1617.                 $db->loadModule('Function'nulltrue);
  1618.                 $match $db->function->lower($field).' '.'LIKE ';
  1619.                 break;
  1620.             // case sensitive
  1621.             case 'LIKE':
  1622.                 $match is_null($field'LIKE ' $field.' LIKE ';
  1623.                 break;
  1624.             default:
  1625.                 return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  1626.                     'not a supported operator type:'$operator__FUNCTION__);
  1627.             }
  1628.         }
  1629.         $match.= "'";
  1630.         foreach ($pattern as $key => $value{
  1631.             if ($key % 2{
  1632.                 $match.= $value;
  1633.             else {
  1634.                 if ($operator === 'ILIKE'{
  1635.                     $value strtolower($value);
  1636.                 }
  1637.                 $match.= $db->escapePattern($db->escape($value));
  1638.             }
  1639.         }
  1640.         $match.= "'";
  1641.         $match.= $this->patternEscapeString();
  1642.         return $match;
  1643.     }
  1644.  
  1645.     // }}}
  1646.     // {{{ patternEscapeString()
  1647.  
  1648.     /**
  1649.      * build string to define pattern escape character
  1650.      *
  1651.      * EXPERIMENTAL
  1652.      *
  1653.      * WARNING: this function is experimental and may change signature at
  1654.      * any time until labelled as non-experimental
  1655.      *
  1656.      * @access public
  1657.      *
  1658.      * @return string define pattern escape character
  1659.      */
  1660.     function patternEscapeString()
  1661.     {
  1662.         return '';
  1663.     }
  1664.  
  1665.     // }}}
  1666.     // {{{ mapNativeDatatype()
  1667.  
  1668.     /**
  1669.      * Maps a native array description of a field to a MDB2 datatype and length
  1670.      *
  1671.      * @param array  $field native field description
  1672.      * @return array containing the various possible types, length, sign, fixed
  1673.      * @access public
  1674.      */
  1675.     function mapNativeDatatype($field)
  1676.     {
  1677.         $db =$this->getDBInstance();
  1678.         if (PEAR::isError($db)) {
  1679.             return $db;
  1680.         }
  1681.  
  1682.         return $db->raiseError(MDB2_ERROR_UNSUPPORTEDnullnull,
  1683.             'method not implemented'__FUNCTION__);
  1684.     }
  1685.  
  1686.     // }}}
  1687.     // {{{ mapPrepareDatatype()
  1688.  
  1689.     /**
  1690.      * Maps an mdb2 datatype to mysqli prepare type
  1691.      *
  1692.      * @param string $type 
  1693.      * @return string 
  1694.      * @access public
  1695.      */
  1696.     function mapPrepareDatatype($type)
  1697.     {
  1698.         $db =$this->getDBInstance();
  1699.         if (PEAR::isError($db)) {
  1700.             return $db;
  1701.         }
  1702.  
  1703.         if (!empty($db->options['datatype_map'][$type])) {
  1704.             $type $db->options['datatype_map'][$type];
  1705.             if (!empty($db->options['datatype_map_callback'][$type])) {
  1706.                 $parameter = array('type' => $type);
  1707.                 return call_user_func_array($db->options['datatype_map_callback'][$type]array(&$db__FUNCTION__$parameter));
  1708.             }
  1709.         }
  1710.  
  1711.         return $type;
  1712.     }
  1713. }
  1714.  
  1715. ?>

Documentation generated on Mon, 11 Mar 2019 14:48:05 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.