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

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