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

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