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

Source for file mysql.php

Documentation is available at mysql.php

  1. <?php
  2. // vim: set et ts=4 sw=4 fdm=marker:
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1998-2004 Manuel Lemos, Tomas V.V.Cox,                 |
  7. // | Stig. S. Bakken, Lukas Smith                                         |
  8. // | All rights reserved.                                                 |
  9. // +----------------------------------------------------------------------+
  10. // | MDB is a merge of PEAR DB and Metabases that provides a unified DB   |
  11. // | API as well as database abstraction for PHP applications.            |
  12. // | This LICENSE is in the BSD license style.                            |
  13. // |                                                                      |
  14. // | Redistribution and use in source and binary forms, with or without   |
  15. // | modification, are permitted provided that the following conditions   |
  16. // | are met:                                                             |
  17. // |                                                                      |
  18. // | Redistributions of source code must retain the above copyright       |
  19. // | notice, this list of conditions and the following disclaimer.        |
  20. // |                                                                      |
  21. // | Redistributions in binary form must reproduce the above copyright    |
  22. // | notice, this list of conditions and the following disclaimer in the  |
  23. // | documentation and/or other materials provided with the distribution. |
  24. // |                                                                      |
  25. // | Neither the name of Manuel Lemos, Tomas V.V.Cox, Stig. S. Bakken,    |
  26. // | Lukas Smith nor the names of his contributors may be used to endorse |
  27. // | or promote products derived from this software without specific prior|
  28. // | written permission.                                                  |
  29. // |                                                                      |
  30. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  |
  31. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT    |
  32. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS    |
  33. // | FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE      |
  34. // | REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,          |
  35. // | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
  36. // | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS|
  37. // |  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  |
  38. // | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          |
  39. // | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY|
  40. // | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE          |
  41. // | POSSIBILITY OF SUCH DAMAGE.                                          |
  42. // +----------------------------------------------------------------------+
  43. // | Author: Lukas Smith <smith@backendmedia.com>                         |
  44. // +----------------------------------------------------------------------+
  45. //
  46. // $Id: mysql.php,v 1.80.4.18 2004/04/22 11:31:56 lsmith Exp $
  47. //
  48.  
  49. require_once('MDB/Common.php');
  50.  
  51. /**
  52.  * MDB MySQL driver
  53.  *
  54.  * Notes:
  55.  * - The decimal type fields are emulated with integer fields.
  56.  *
  57.  * @package MDB
  58.  * @category Database
  59.  * @author  Lukas Smith <smith@backendmedia.com>
  60.  */
  61. class MDB_mysql extends MDB_Common
  62. {
  63.     // {{{ properties
  64.  
  65.     var $connection = 0;
  66.     var $connected_host;
  67.     var $connected_user;
  68.     var $connected_password;
  69.     var $connected_port;
  70.     var $opened_persistent = '';
  71.  
  72.     var $escape_quotes = "\\";
  73.     var $decimal_factor = 1.0;
  74.  
  75.     var $highest_fetched_row = array();
  76.     var $columns = array();
  77.  
  78.     // MySQL specific class variable
  79.     var $default_table_type = '';
  80.     var $fixed_float = 0;
  81.     var $dummy_primary_key = 'dummy_primary_key';
  82.  
  83.     // }}}
  84.     // {{{ constructor
  85.  
  86.     /**
  87.     * Constructor
  88.     */
  89.     function MDB_mysql()
  90.     {
  91.         $this->MDB_Common();
  92.         $this->phptype 'mysql';
  93.         $this->dbsyntax 'mysql';
  94.  
  95.         $this->supported['Sequences'= 1;
  96.         $this->supported['Indexes'= 1;
  97.         $this->supported['AffectedRows'= 1;
  98.         $this->supported['Summaryfunctions'= 1;
  99.         $this->supported['OrderByText'= 1;
  100.         $this->supported['CurrId'= 1;
  101.         $this->supported['SelectRowRanges'= 1;
  102.         $this->supported['LOBs'= 1;
  103.         $this->supported['Replace'= 1;
  104.         $this->supported['SubSelects'= 0;
  105.         $this->supported['Transactions'= 0;
  106.  
  107.         $this->decimal_factor = pow(10.0$this->decimal_places);
  108.  
  109.         $this->options['DefaultTableType'= FALSE;
  110.         $this->options['fixed_float'= FALSE;
  111.  
  112.         $this->errorcode_map = array(
  113.             1004 => MDB_ERROR_CANNOT_CREATE,
  114.             1005 => MDB_ERROR_CANNOT_CREATE,
  115.             1006 => MDB_ERROR_CANNOT_CREATE,
  116.             1007 => MDB_ERROR_ALREADY_EXISTS,
  117.             1008 => MDB_ERROR_CANNOT_DROP,
  118.             1022 => MDB_ERROR_ALREADY_EXISTS,
  119.             1046 => MDB_ERROR_NODBSELECTED,
  120.             1050 => MDB_ERROR_ALREADY_EXISTS,
  121.             1051 => MDB_ERROR_NOSUCHTABLE,
  122.             1054 => MDB_ERROR_NOSUCHFIELD,
  123.             1062 => MDB_ERROR_ALREADY_EXISTS,
  124.             1064 => MDB_ERROR_SYNTAX,
  125.             1100 => MDB_ERROR_NOT_LOCKED,
  126.             1136 => MDB_ERROR_VALUE_COUNT_ON_ROW,
  127.             1146 => MDB_ERROR_NOSUCHTABLE,
  128.             1048 => MDB_ERROR_CONSTRAINT,
  129.             1213 => MDB_ERROR_DEADLOCK,
  130.             1216 => MDB_ERROR_CONSTRAINT,
  131.         );
  132.     }
  133.  
  134.     // }}}
  135.     // {{{ errorNative()
  136.  
  137.     /**
  138.      * Get the native error code of the last error (if any) that
  139.      * occured on the current connection.
  140.      *
  141.      * @access public
  142.      *
  143.      * @return int native MySQL error code
  144.      */
  145.     function errorNative()
  146.     {
  147.         return(@mysql_errno($this->connection));
  148.     }
  149.  
  150.     // }}}
  151.     // {{{ mysqlRaiseError()
  152.  
  153.     /**
  154.      * This method is used to communicate an error and invoke error
  155.      * callbacks etc.  Basically a wrapper for MDB::raiseError
  156.      * that checks for native error msgs.
  157.      *
  158.      * @param integer $errno error code
  159.      * @param string  $message userinfo message
  160.      * @return object PEAR error object
  161.      * @access public
  162.      * @see PEAR_Error
  163.      */
  164.     function mysqlRaiseError($errno = NULL$message = NULL)
  165.     {
  166.         if ($errno == NULL{
  167.             if ($this->connection{
  168.                 $errno @mysql_errno($this->connection);
  169.             else {
  170.                 $errno @mysql_errno();
  171.             }
  172.         }
  173.         if ($this->connection{
  174.             $error @mysql_errno($this->connection);
  175.         else {
  176.             $error @mysql_error();
  177.         }
  178.         return($this->raiseError($this->errorCode($errno)NULLNULL,
  179.             $message$error));
  180.     }
  181.  
  182.     // }}}
  183.     // {{{ quoteIdentifier()
  184.  
  185.     /**
  186.      * Quote a string so it can be safely used as a table or column name
  187.      *
  188.      * Quoting style depends on which database driver is being used.
  189.      *
  190.      * MySQL can't handle the backtick character (<kbd>`</kbd>) in
  191.      * table or column names.
  192.      *
  193.      * @param string $str  identifier name to be quoted
  194.      *
  195.      * @return string  quoted identifier string
  196.      *
  197.      * @access public
  198.      * @internal
  199.      */
  200.     function quoteIdentifier($str)
  201.     {
  202.         return '`' $str '`';
  203.     }
  204.  
  205.     // }}}
  206.     // {{{ autoCommit()
  207.  
  208.     /**
  209.      * Define whether database changes done on the database be automatically
  210.      * committed. This function may also implicitly start or end a transaction.
  211.      *
  212.      * @param boolean $auto_commit    flag that indicates whether the database
  213.      *                                 changes should be committed right after
  214.      *                                 executing every query statement. If this
  215.      *                                 argument is 0 a transaction implicitly
  216.      *                                 started. Otherwise, if a transaction is
  217.      *                                 in progress it is ended by committing any
  218.      *                                 database changes that were pending.
  219.      *
  220.      * @access public
  221.      *
  222.      * @return mixed MDB_OK on success, a MDB error on failure
  223.      */
  224.     function autoCommit($auto_commit)
  225.     {
  226.         $this->debug("AutoCommit: ".($auto_commit "On" "Off"));
  227.         if (!isset($this->supported['Transactions'])) {
  228.             return($this->raiseError(MDB_ERROR_UNSUPPORTEDNULLNULL,
  229.                 'Auto-commit transactions: transactions are not in use'));
  230.         }
  231.         if ($this->auto_commit == $auto_commit{
  232.             return(MDB_OK);
  233.         }
  234.         if ($this->connection{
  235.             if ($auto_commit{
  236.                 $result $this->query('COMMIT');
  237.                 if (MDB::isError($result)) {
  238.                     return($result);
  239.                 }
  240.                 $result $this->query('SET AUTOCOMMIT = 1');
  241.                 if (MDB::isError($result)) {
  242.                     return($result);
  243.                 }
  244.             else {
  245.                 $result $this->query('SET AUTOCOMMIT = 0');
  246.                 if (MDB::isError($result)) {
  247.                     return($result);
  248.                 }
  249.             }
  250.         }
  251.         $this->auto_commit $auto_commit;
  252.         $this->in_transaction !$auto_commit;
  253.         return(MDB_OK);
  254.     }
  255.  
  256.     // }}}
  257.     // {{{ commit()
  258.  
  259.     /**
  260.      * Commit the database changes done during a transaction that is in
  261.      * progress. This function may only be called when auto-committing is
  262.      * disabled, otherwise it will fail. Therefore, a new transaction is
  263.      * implicitly started after committing the pending changes.
  264.      *
  265.      * @access public
  266.      *
  267.      * @return mixed MDB_OK on success, a MDB error on failure
  268.      */
  269.     function commit()
  270.     {
  271.         $this->debug("Commit Transaction");
  272.         if (!isset($this->supported['Transactions'])) {
  273.             return($this->raiseError(MDB_ERROR_UNSUPPORTEDNULLNULL,
  274.                 'Commit transactions: transactions are not in use'));
  275.         }
  276.         if ($this->auto_commit{
  277.             return($this->raiseError(MDB_ERRORNULLNULL,
  278.             'Commit transactions: transaction changes are being auto commited'));
  279.         }
  280.         return($this->query('COMMIT'));
  281.     }
  282.  
  283.     // }}}
  284.     // {{{ rollback()
  285.  
  286.     /**
  287.      * Cancel any database changes done during a transaction that is in
  288.      * progress. This function may only be called when auto-committing is
  289.      * disabled, otherwise it will fail. Therefore, a new transaction is
  290.      * implicitly started after canceling the pending changes.
  291.      *
  292.      * @access public
  293.      *
  294.      * @return mixed MDB_OK on success, a MDB error on failure
  295.      */
  296.     function rollback()
  297.     {
  298.         $this->debug("Rollback Transaction");
  299.         if (!isset($this->supported['Transactions'])) {
  300.             return($this->raiseError(MDB_ERROR_UNSUPPORTEDNULLNULL,
  301.                 'Rollback transactions: transactions are not in use'));
  302.         }
  303.         if ($this->auto_commit{
  304.             return($this->raiseError(MDB_ERRORNULLNULL,
  305.                 'Rollback transactions: transactions can not be rolled back when changes are auto commited'));
  306.         }
  307.         return($this->query('ROLLBACK'));
  308.     }
  309.  
  310.     // }}}
  311.     // {{{ connect()
  312.  
  313.     /**
  314.      * Connect to the database
  315.      *
  316.      * @return TRUE on success, MDB_Error on failure
  317.      ***/
  318.     function connect()
  319.     {
  320.         $port (isset($this->port$this->port '');
  321.         if($this->connection != 0{
  322.             if (!strcmp($this->connected_host$this->host)
  323.                 && !strcmp($this->connected_user$this->user)
  324.                 && !strcmp($this->connected_password$this->password)
  325.                 && !strcmp($this->connected_port$port)
  326.                 && $this->opened_persistent == $this->options['persistent'])
  327.             {
  328.                 return(MDB_OK);
  329.             }
  330.             @mysql_close($this->connection);
  331.             $this->connection = 0;
  332.             $this->affected_rows = -1;
  333.         }
  334.  
  335.         if(!PEAR::loadExtension($this->phptype)) {
  336.             return(PEAR::raiseError(NULLMDB_ERROR_NOT_FOUND,
  337.                 NULLNULL'extension '.$this->phptype.' is not compiled into PHP',
  338.                 'MDB_Error'TRUE));
  339.         }
  340.         $UseTransactions $this->getOption('UseTransactions');
  341.         if(!MDB::isError($UseTransactions&& $UseTransactions{
  342.             $this->supported['Transactions'= 1;
  343.             $this->default_table_type = 'BDB';
  344.         else {
  345.             $this->supported['Transactions'= 0;
  346.             $this->default_table_type = '';
  347.         }
  348.         $DefaultTableType $this->getOption('DefaultTableType');
  349.         if(!MDB::isError($DefaultTableType&& $DefaultTableType{
  350.             switch($this->default_table_type = strtoupper($DefaultTableType)) {
  351.                 case 'BERKELEYDB':
  352.                     $this->default_table_type = 'BDB';
  353.                 case 'BDB':
  354.                 case 'INNODB':
  355.                 case 'GEMINI':
  356.                     break;
  357.                 case 'HEAP':
  358.                 case 'ISAM':
  359.                 case 'MERGE':
  360.                 case 'MRG_MYISAM':
  361.                 case 'MYISAM':
  362.                     if(isset($this->supported['Transactions'])) {
  363.                         $this->warnings[$DefaultTableType
  364.                             .' is not a transaction-safe default table type';
  365.                     }
  366.                     break;
  367.                 default:
  368.                     $this->warnings[$DefaultTableType
  369.                         .' is not a supported default table type';
  370.             }
  371.         }
  372.  
  373.         $this->fixed_float = 30;
  374.         $function ($this->options['persistent''mysql_pconnect' 'mysql_connect');
  375.         if (!function_exists($function)) {
  376.             return($this->raiseError(MDB_ERROR_UNSUPPORTED));
  377.         }
  378.  
  379.         @ini_set('track_errors'TRUE);
  380.         $this->connection = @$function(
  381.             $this->host.(!strcmp($port,'''' ':'.$port),
  382.             $this->user$this->password);
  383.         @ini_restore('track_errors');
  384.         if ($this->connection <= 0{
  385.             return($this->raiseError(MDB_ERROR_CONNECT_FAILEDNULLNULL,
  386.                 $php_errormsg));
  387.         }
  388.  
  389.         if (isset($this->options['fixedfloat'])) {
  390.             $this->fixed_float = $this->options['fixedfloat'];
  391.         else {
  392.             if (($result @mysql_query('SELECT VERSION()'$this->connection))) {
  393.                 $version explode('.'@mysql_result($result,0,0));
  394.                 $major intval($version[0]);
  395.                 $minor intval($version[1]);
  396.                 $revision intval($version[2]);
  397.                 if ($major > 3 || ($major == 3 && $minor >= 23
  398.                     && ($minor > 23 || $revision >= 6)))
  399.                 {
  400.                     $this->fixed_float = 0;
  401.                 }
  402.                 @mysql_free_result($result);
  403.             }
  404.         }
  405.         if (isset($this->supported['Transactions']&& !$this->auto_commit{
  406.             if (!@mysql_query('SET AUTOCOMMIT = 0'$this->connection)) {
  407.                 @mysql_close($this->connection);
  408.                 $this->connection = 0;
  409.                 $this->affected_rows = -1;
  410.                 return($this->raiseError());
  411.             }
  412.             $this->in_transaction = TRUE;
  413.         }
  414.         $this->connected_host = $this->host;
  415.         $this->connected_user = $this->user;
  416.         $this->connected_password = $this->password;
  417.         $this->connected_port = $port;
  418.         $this->opened_persistent = $this->getoption('persistent');
  419.         return(MDB_OK);
  420.     }
  421.  
  422.     // }}}
  423.     // {{{ _close()
  424.     /**
  425.      * all the RDBMS specific things needed close a DB connection
  426.      *
  427.      * @return boolean 
  428.      * @access private
  429.      ***/
  430.     function _close()
  431.     {
  432.         if ($this->connection != 0{
  433.             if (isset($this->supported['Transactions']&& !$this->auto_commit{
  434.                 $result $this->autoCommit(TRUE);
  435.             }
  436.             @mysql_close($this->connection);
  437.             $this->connection = 0;
  438.             $this->affected_rows = -1;
  439.  
  440.             if (isset($result&& MDB::isError($result)) {
  441.                 return($result);
  442.             }
  443.             unset($GLOBALS['_MDB_databases'][$this->database]);
  444.             return(TRUE);
  445.         }
  446.         return(FALSE);
  447.     }
  448.  
  449.     // }}}
  450.     // {{{ query()
  451.  
  452.     /**
  453.      * Send a query to the database and return any results
  454.      *
  455.      * @access public
  456.      *
  457.      * @param string  $query  the SQL query
  458.      * @param mixed   $types  array that contains the types of the columns in
  459.      *                         the result set
  460.      *
  461.      * @return mixed a result handle or MDB_OK on success, a MDB error on failure
  462.      */
  463.     function query($query$types = NULL)
  464.     {
  465.         $this->debug("Query: $query");
  466.         $ismanip MDB::isManip($query);
  467.         $this->last_query $query;
  468.         $first $this->first_selected_row;
  469.         $limit $this->selected_row_limit;
  470.         $this->first_selected_row $this->selected_row_limit = 0;
  471.  
  472.         $result $this->connect();
  473.         if (MDB::isError($result)) {
  474.             return($result);
  475.         }
  476.         if($limit > 0{
  477.             if ($ismanip{
  478.                 $query .= " LIMIT $limit";
  479.             else {
  480.                 $query .= " LIMIT $first,$limit";
  481.             }
  482.         }
  483.         if ($this->database_name{
  484.             if(!@mysql_select_db($this->database_name$this->connection)) {
  485.                 return($this->mysqlRaiseError());
  486.             }
  487.         }
  488.         if ($result @mysql_query($query$this->connection)) {
  489.             if ($ismanip{
  490.                 $this->affected_rows @mysql_affected_rows($this->connection);
  491.                 return(MDB_OK);
  492.             else {
  493.                 $result_value intval($result);
  494.                 $this->highest_fetched_row[$result_value= -1;
  495.                 if ($types != NULL{
  496.                     if (!is_array($types)) {
  497.                         $types = array($types);
  498.                     }
  499.                     if (MDB::isError($err $this->setResultTypes($result$types))) {
  500.                         $this->freeResult($result);
  501.                         return($err);
  502.                     }
  503.                 }
  504.                 return($result);
  505.             }
  506.         }
  507.         return($this->mysqlRaiseError());
  508.     }
  509.  
  510.     // }}}
  511.     // {{{ subSelect()
  512.  
  513.     /**
  514.      * simple subselect emulation for Mysql
  515.      *
  516.      * @access public
  517.      *
  518.      * @param string $query the SQL query for the subselect that may only
  519.      *                       return a column
  520.      * @param string $quote determines if the data needs to be quoted before
  521.      *                       being returned
  522.      *
  523.      * @return string the query
  524.      */
  525.     function subSelect($query$quote = FALSE)
  526.     {
  527.         if($this->supported['SubSelects'== 1{
  528.             return($query);
  529.         }
  530.         $col $this->queryCol($query);
  531.         if (MDB::isError($col)) {
  532.             return($col);
  533.         }
  534.         if(!is_array($col|| count($col== 0{
  535.             return 'NULL';
  536.         }
  537.         if($quote{
  538.             for($i = 0$j count($col)$i $j; ++$i{
  539.                 $col[$i$this->getTextValue($col[$i]);
  540.             }
  541.         }
  542.         return(implode(', '$col));
  543.     }
  544.  
  545.     // }}}
  546.     // {{{ replace()
  547.  
  548.     /**
  549.      * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
  550.      * query, except that if there is already a row in the table with the same
  551.      * key field values, the REPLACE query just updates its values instead of
  552.      * inserting a new row.
  553.      *
  554.      * The REPLACE type of query does not make part of the SQL standards. Since
  555.      * practically only MySQL implements it natively, this type of query is
  556.      * emulated through this method for other DBMS using standard types of
  557.      * queries inside a transaction to assure the atomicity of the operation.
  558.      *
  559.      * @access public
  560.      *
  561.      * @param string $table name of the table on which the REPLACE query will
  562.      *   be executed.
  563.      * @param array $fields associative array that describes the fields and the
  564.      *   values that will be inserted or updated in the specified table. The
  565.      *   indexes of the array are the names of all the fields of the table. The
  566.      *   values of the array are also associative arrays that describe the
  567.      *   values and other properties of the table fields.
  568.      *
  569.      *   Here follows a list of field properties that need to be specified:
  570.      *
  571.      *     Value:
  572.      *           Value to be assigned to the specified field. This value may be
  573.      *           of specified in database independent type format as this
  574.      *           function can perform the necessary datatype conversions.
  575.      *
  576.      *     Default:
  577.      *           this property is required unless the Null property
  578.      *           is set to 1.
  579.      *
  580.      *     Type
  581.      *           Name of the type of the field. Currently, all types Metabase
  582.      *           are supported except for clob and blob.
  583.      *
  584.      *     Default: no type conversion
  585.      *
  586.      *     Null
  587.      *           Boolean property that indicates that the value for this field
  588.      *           should be set to NULL.
  589.      *
  590.      *           The default value for fields missing in INSERT queries may be
  591.      *           specified the definition of a table. Often, the default value
  592.      *           is already NULL, but since the REPLACE may be emulated using
  593.      *           an UPDATE query, make sure that all fields of the table are
  594.      *           listed in this function argument array.
  595.      *
  596.      *     Default: 0
  597.      *
  598.      *     Key
  599.      *           Boolean property that indicates that this field should be
  600.      *           handled as a primary key or at least as part of the compound
  601.      *           unique index of the table that will determine the row that will
  602.      *           updated if it exists or inserted a new row otherwise.
  603.      *
  604.      *           This function will fail if no key field is specified or if the
  605.      *           value of a key field is set to NULL because fields that are
  606.      *           part of unique index they may not be NULL.
  607.      *
  608.      *     Default: 0
  609.      *
  610.      * @return mixed MDB_OK on success, a MDB error on failure
  611.      */
  612.     function replace($table$fields)
  613.     {
  614.         $count count($fields);
  615.         for($keys = 0$query $values '',reset($fields)$field = 0;
  616.             $field<$count;
  617.             next($fields)$field++)
  618.         {
  619.             $name key($fields);
  620.             if ($field > 0{
  621.                 $query .= ',';
  622.                 $values .= ',';
  623.             }
  624.             $query .= $name;
  625.             if (isset($fields[$name]['Null']&& $fields[$name]['Null']{
  626.                 $value 'NULL';
  627.             else {
  628.                 if(isset($fields[$name]['Type'])) {
  629.                     switch ($fields[$name]['Type']{
  630.                         case 'text':
  631.                             $value $this->getTextValue($fields[$name]['Value']);
  632.                             break;
  633.                         case 'boolean':
  634.                             $value $this->getBooleanValue($fields[$name]['Value']);
  635.                             break;
  636.                         case 'integer':
  637.                             $value $this->getIntegerValue($fields[$name]['Value']);
  638.                             break;
  639.                         case 'decimal':
  640.                             $value $this->getDecimalValue($fields[$name]['Value']);
  641.                             break;
  642.                         case 'float':
  643.                             $value $this->getFloatValue($fields[$name]['Value']);
  644.                             break;
  645.                         case 'date':
  646.                             $value $this->getDateValue($fields[$name]['Value']);
  647.                             break;
  648.                         case 'time':
  649.                             $value $this->getTimeValue($fields[$name]['Value']);
  650.                             break;
  651.                         case 'timestamp':
  652.                             $value $this->getTimestampValue($fields[$name]['Value']);
  653.                             break;
  654.                         default:
  655.                             return($this->raiseError(MDB_ERROR_CANNOT_REPLACENULLNULL,
  656.                                 'no supported type for field "' $name '" specified'));
  657.                     }
  658.                 else {
  659.                     $value $fields[$name]['Value'];
  660.                 }
  661.             }
  662.             $values .= $value;
  663.             if (isset($fields[$name]['Key']&& $fields[$name]['Key']{
  664.                 if ($value === 'NULL'{
  665.                     return($this->raiseError(MDB_ERROR_CANNOT_REPLACENULLNULL,
  666.                         $name.': key values may not be NULL'));
  667.                 }
  668.                 $keys++;
  669.             }
  670.         }
  671.         if ($keys == 0{
  672.             return($this->raiseError(MDB_ERROR_CANNOT_REPLACENULLNULL,
  673.                 'not specified which fields are keys'));
  674.         }
  675.         return($this->query("REPLACE INTO $table ($query) VALUES ($values)"));
  676.     }
  677.  
  678.     // }}}
  679.     // {{{ getColumnNames()
  680.  
  681.     /**
  682.      * Retrieve the names of columns returned by the DBMS in a query result.
  683.      *
  684.      * @param resource   $result    result identifier
  685.      * @return mixed                an associative array variable
  686.      *                               that will hold the names of columns. The
  687.      *                               indexes of the array are the column names
  688.      *                               mapped to lower case and the values are the
  689.      *                               respective numbers of the columns starting
  690.      *                               from 0. Some DBMS may not return any
  691.      *                               columns when the result set does not
  692.      *                               contain any rows.
  693.      *
  694.      *                               a MDB error on failure
  695.      * @access public
  696.      */
  697.     function getColumnNames($result)
  698.     {
  699.         $result_value intval($result);
  700.         if (!isset($this->highest_fetched_row[$result_value])) {
  701.             return($this->raiseError(MDB_ERROR_INVALIDNULLNULL,
  702.                 'Get column names: it was specified an inexisting result set'));
  703.         }
  704.         if (!isset($this->columns[$result_value])) {
  705.             $this->columns[$result_value= array();
  706.             $columns @mysql_num_fields($result);
  707.             for($column = 0; $column $columns$column++{
  708.                 $field_name @mysql_field_name($result$column);
  709.                 if ($this->options['optimize'== 'portability'{
  710.                     $field_name strtolower($field_name);
  711.                 }
  712.                 $this->columns[$result_value][$field_name$column;
  713.             }
  714.         }
  715.         return($this->columns[$result_value]);
  716.     }
  717.  
  718.     // }}}
  719.     // {{{ numCols()
  720.  
  721.     /**
  722.      * Count the number of columns returned by the DBMS in a query result.
  723.      *
  724.      * @param resource    $result        result identifier
  725.      * @access public
  726.      * @return mixed integer value with the number of columns, a MDB error
  727.      *                        on failure
  728.      */
  729.     function numCols($result)
  730.     {
  731.         $result_value intval($result);
  732.         if (!isset($this->highest_fetched_row[$result_value])) {
  733.             return($this->raiseError(MDB_ERROR_INVALIDNULLNULL,
  734.                 'numCols: it was specified an inexisting result set'));
  735.         }
  736.         return(@mysql_num_fields($result));
  737.     }
  738.  
  739.     // }}}
  740.     // {{{ endOfResult()
  741.  
  742.     /**
  743.     * check if the end of the result set has been reached
  744.     *
  745.     * @param resource    $result result identifier
  746.     * @return mixed TRUE or FALSE on sucess, a MDB error on failure
  747.     * @access public
  748.     */
  749.     function endOfResult($result)
  750.     {
  751.         $result_value intval($result);
  752.         if (!isset($this->highest_fetched_row[$result_value])) {
  753.             return($this->raiseError(MDB_ERRORNULLNULL,
  754.                 'End of result: attempted to check the end of an unknown result'));
  755.         }
  756.         return($this->highest_fetched_row[$result_value>= $this->numRows($result)-1);
  757.     }
  758.  
  759.     // }}}
  760.     // {{{ fetch()
  761.  
  762.     /**
  763.     * fetch value from a result set
  764.     *
  765.     * @param resource    $result result identifier
  766.     * @param int    $row    number of the row where the data can be found
  767.     * @param int    $field    field number where the data can be found
  768.     * @return mixed string on success, a MDB error on failure
  769.     * @access public
  770.     */
  771.     function fetch($result$row$field)
  772.     {
  773.         $result_value intval($result);
  774.         $this->highest_fetched_row[$result_value=
  775.             max($this->highest_fetched_row[$result_value]$row);
  776.         $res @mysql_result($result$row$field);
  777.         if ($res === FALSE && $res != NULL{
  778.             return($this->mysqlRaiseError());
  779.         }
  780.         return($res);
  781.     }
  782.  
  783.     // }}}
  784.     // {{{ fetchClob()
  785.  
  786.     /**
  787.     * fetch a clob value from a result set
  788.     *
  789.     * @param resource    $result result identifier
  790.     * @param int    $row    number of the row where the data can be found
  791.     * @param int    $field    field number where the data can be found
  792.     * @return mixed content of the specified data cell, a MDB error on failure,
  793.     *                a MDB error on failure
  794.     * @access public
  795.     */
  796.     function fetchClob($result$row$field)
  797.     {
  798.         return($this->fetchLob($result$row$field));
  799.     }
  800.  
  801.     // }}}
  802.     // {{{ fetchBlob()
  803.  
  804.     /**
  805.     * fetch a blob value from a result set
  806.     *
  807.     * @param resource    $result result identifier
  808.     * @param int    $row    number of the row where the data can be found
  809.     * @param int    $field    field number where the data can be found
  810.     * @return mixed content of the specified data cell, a MDB error on failure
  811.     * @access public
  812.     */
  813.     function fetchBlob($result$row$field)
  814.     {
  815.         return($this->fetchLob($result$row$field));
  816.     }
  817.  
  818.     // }}}
  819.     // {{{ convertResult()
  820.  
  821.     /**
  822.     * convert a value to a RDBMS indepdenant MDB type
  823.     *
  824.     * @param mixed  $value   value to be converted
  825.     * @param int    $type    constant that specifies which type to convert to
  826.     * @return mixed converted value
  827.     * @access public
  828.     */
  829.     function convertResult($value$type)
  830.     {
  831.         switch($type{
  832.             case MDB_TYPE_DECIMAL:
  833.                 return(sprintf('%.'.$this->decimal_places.'f'doubleval($value)/$this->decimal_factor));
  834.             default:
  835.                 return($this->_baseConvertResult($value$type));
  836.         }
  837.     }
  838.  
  839.     // }}}
  840.     // {{{ numRows()
  841.  
  842.     /**
  843.     * returns the number of rows in a result object
  844.     *
  845.      * @param ressource $result a valid result ressouce pointer
  846.     * @return mixed MDB_Error or the number of rows
  847.     * @access public
  848.     */
  849.     function numRows($result)
  850.     {
  851.         return(@mysql_num_rows($result));
  852.     }
  853.  
  854.     // }}}
  855.     // {{{ freeResult()
  856.  
  857.     /**
  858.      * Free the internal resources associated with $result.
  859.      *
  860.      * @param $result result identifier
  861.      * @return boolean TRUE on success, FALSE if $result is invalid
  862.      * @access public
  863.      */
  864.     function freeResult($result)
  865.     {
  866.         $result_value intval($result);
  867.         if(isset($this->highest_fetched_row[$result_value])) {
  868.             unset($this->highest_fetched_row[$result_value]);
  869.         }
  870.         if(isset($this->columns[$result_value])) {
  871.             unset($this->columns[$result_value]);
  872.         }
  873.         if(isset($this->result_types[$result_value])) {
  874.             unset($this->result_types[$result_value]);
  875.         }
  876.         return(@mysql_free_result($result));
  877.     }
  878.  
  879.     // }}}
  880.     // {{{ getIntegerDeclaration()
  881.  
  882.     /**
  883.      * Obtain DBMS specific SQL code portion needed to declare an integer type
  884.      * field to be used in statements like CREATE TABLE.
  885.      *
  886.      * @param string  $name   name the field to be declared.
  887.      * @param string  $field  associative array with the name of the properties
  888.      *                         of the field being declared as array indexes.
  889.      *                         Currently, the types of supported field
  890.      *                         properties are as follows:
  891.      *
  892.      *                        unsigned
  893.      *                         Boolean flag that indicates whether the field
  894.      *                         should be declared as unsigned integer if
  895.      *                         possible.
  896.      *
  897.      *                        default
  898.      *                         Integer value to be used as default for this
  899.      *                         field.
  900.      *
  901.      *                        notnull
  902.      *                         Boolean flag that indicates whether this field is
  903.      *                         constrained to not be set to NULL.
  904.      * @return string  DBMS specific SQL code portion that should be used to
  905.      *                  declare the specified field.
  906.      * @access public
  907.      */
  908.     function getIntegerDeclaration($name$field)
  909.     {
  910.         return("$name INT".
  911.                 (isset($field['unsigned']' UNSIGNED' '').
  912.                 (isset($field['default']' DEFAULT '.$field['default''').
  913.                 (isset($field['notnull']' NOT NULL' '')
  914.                );
  915.     }
  916.  
  917.     // }}}
  918.     // {{{ getClobDeclaration()
  919.  
  920.     /**
  921.      * Obtain DBMS specific SQL code portion needed to declare an character
  922.      * large object type field to be used in statements like CREATE TABLE.
  923.      *
  924.      * @param string  $name   name the field to be declared.
  925.      * @param string  $field  associative array with the name of the
  926.      *                         properties of the field being declared as array
  927.      *                         indexes. Currently, the types of supported field
  928.      *                         properties are as follows:
  929.      *
  930.      *                        length
  931.      *                         Integer value that determines the maximum length
  932.      *                         of the large object field. If this argument is
  933.      *                         missing the field should be declared to have the
  934.      *                         longest length allowed by the DBMS.
  935.      *
  936.      *                        notnull
  937.      *                         Boolean flag that indicates whether this field
  938.      *                         is constrained to not be set to NULL.
  939.      * @return string  DBMS specific SQL code portion that should be used to
  940.      *                  declare the specified field.
  941.      * @access public
  942.      */
  943.     function getClobDeclaration($name$field)
  944.     {
  945.         if (isset($field['length'])) {
  946.             $length $field['length'];
  947.             if ($length <= 255{
  948.                 $type 'TINYTEXT';
  949.             else {
  950.                 if ($length <= 65535{
  951.                     $type 'TEXT';
  952.                 else {
  953.                     if ($length <= 16777215{
  954.                         $type 'MEDIUMTEXT';
  955.                     else {
  956.                         $type 'LONGTEXT';
  957.                     }
  958.                 }
  959.             }
  960.         else {
  961.             $type 'LONGTEXT';
  962.         }
  963.         return("$name $type".
  964.                  (isset($field['notnull']' NOT NULL' ''));
  965.     }
  966.  
  967.     // }}}
  968.     // {{{ getBlobDeclaration()
  969.  
  970.     /**
  971.      * Obtain DBMS specific SQL code portion needed to declare an binary large
  972.      * object type field to be used in statements like CREATE TABLE.
  973.      *
  974.      * @param string  $name   name the field to be declared.
  975.      * @param string  $field  associative array with the name of the properties
  976.      *                         of the field being declared as array indexes.
  977.      *                         Currently, the types of supported field
  978.      *                         properties are as follows:
  979.      *
  980.      *                        length
  981.      *                         Integer value that determines the maximum length
  982.      *                         of the large object field. If this argument is
  983.      *                         missing the field should be declared to have the
  984.      *                         longest length allowed by the DBMS.
  985.      *
  986.      *                        notnull
  987.      *                         Boolean flag that indicates whether this field is
  988.      *                         constrained to not be set to NULL.
  989.      * @return string  DBMS specific SQL code portion that should be used to
  990.      *                  declare the specified field.
  991.      * @access public
  992.      */
  993.     function getBlobDeclaration($name$field)
  994.     {
  995.         if (isset($field['length'])) {
  996.             $length $field['length'];
  997.             if ($length <= 255{
  998.                 $type 'TINYBLOB';
  999.             else {
  1000.                 if ($length <= 65535{
  1001.                     $type 'BLOB';
  1002.                 else {
  1003.                     if ($length <= 16777215{
  1004.                         $type 'MEDIUMBLOB';
  1005.                     else {
  1006.                         $type 'LONGBLOB';
  1007.                     }
  1008.                 }
  1009.             }
  1010.         }
  1011.         else {
  1012.             $type 'LONGBLOB';
  1013.         }
  1014.         return("$name $type".
  1015.                 (isset($field['notnull']' NOT NULL' ''));
  1016.     }
  1017.  
  1018.     // }}}
  1019.     // {{{ getDateDeclaration()
  1020.  
  1021.     /**
  1022.      * Obtain DBMS specific SQL code portion needed to declare an date type
  1023.      * field to be used in statements like CREATE TABLE.
  1024.      *
  1025.      * @param string  $name   name the field to be declared.
  1026.      * @param string  $field  associative array with the name of the properties
  1027.      *                         of the field being declared as array indexes.
  1028.      *                         Currently, the types of supported field properties
  1029.      *                         are as follows:
  1030.      *
  1031.      *                        default
  1032.      *                         Date value to be used as default for this field.
  1033.      *
  1034.      *                        notnull
  1035.      *                         Boolean flag that indicates whether this field is
  1036.      *                         constrained to not be set to NULL.
  1037.      * @return string  DBMS specific SQL code portion that should be used to
  1038.      *                  declare the specified field.
  1039.      * @access public
  1040.      */
  1041.     function getDateDeclaration($name$field)
  1042.     {
  1043.         return("$name DATE".
  1044.                 (isset($field['default']" DEFAULT '".$field['default']."'" '').
  1045.                 (isset($field['notnull']' NOT NULL' '')
  1046.                );
  1047.     }
  1048.  
  1049.     // }}}
  1050.     // {{{ getTimestampDeclaration()
  1051.  
  1052.     /**
  1053.      * Obtain DBMS specific SQL code portion needed to declare an timestamp
  1054.      * type field to be used in statements like CREATE TABLE.
  1055.      *
  1056.      * @param string  $name   name the field to be declared.
  1057.      * @param string  $field  associative array with the name of the properties
  1058.      *                         of the field being declared as array indexes.
  1059.      *                         Currently, the types of supported field
  1060.      *                         properties are as follows:
  1061.      *
  1062.      *                        default
  1063.      *                         Time stamp value to be used as default for this
  1064.      *                         field.
  1065.      *
  1066.      *                        notnull
  1067.      *                         Boolean flag that indicates whether this field is
  1068.      *                         constrained to not be set to NULL.
  1069.      * @return string  DBMS specific SQL code portion that should be used to
  1070.      *                  declare the specified field.
  1071.      * @access public
  1072.      */
  1073.     function getTimestampDeclaration($name$field)
  1074.     {
  1075.         return("$name DATETIME".
  1076.                 (isset($field['default']" DEFAULT '".$field['default']."'" '').
  1077.                 (isset($field['notnull']' NOT NULL' '')
  1078.                );
  1079.     }
  1080.  
  1081.     // }}}
  1082.     // {{{ getTimeDeclaration()
  1083.  
  1084.     /**
  1085.      * Obtain DBMS specific SQL code portion needed to declare an time type
  1086.      * field to be used in statements like CREATE TABLE.
  1087.      *
  1088.      * @param string  $name   name the field to be declared.
  1089.      * @param string  $field  associative array with the name of the properties
  1090.      *                         of the field being declared as array indexes.
  1091.      *                         Currently, the types of supported field
  1092.      *                         properties are as follows:
  1093.      *
  1094.      *                        default
  1095.      *                         Time value to be used as default for this field.
  1096.      *
  1097.      *                        notnull
  1098.      *                         Boolean flag that indicates whether this field is
  1099.      *                         constrained to not be set to NULL.
  1100.      * @return string  DBMS specific SQL code portion that should be used to
  1101.      *                  declare the specified field.
  1102.      * @access public
  1103.      */
  1104.     function getTimeDeclaration($name$field)
  1105.     {
  1106.         return("$name TIME".
  1107.                 (isset($field['default']" DEFAULT '".$field['default']."'" '').
  1108.                 (isset($field['notnull']' NOT NULL' '')
  1109.                );
  1110.     }
  1111.  
  1112.     // }}}
  1113.     // {{{ getFloatDeclaration()
  1114.  
  1115.     /**
  1116.      * Obtain DBMS specific SQL code portion needed to declare an float type
  1117.      * field to be used in statements like CREATE TABLE.
  1118.      *
  1119.      * @param string  $name   name the field to be declared.
  1120.      * @param string  $field  associative array with the name of the properties
  1121.      *                         of the field being declared as array indexes.
  1122.      *                         Currently, the types of supported field
  1123.      *                         properties are as follows:
  1124.      *
  1125.      *                        default
  1126.      *                         Integer value to be used as default for this
  1127.      *                         field.
  1128.      *
  1129.      *                        notnull
  1130.      *                         Boolean flag that indicates whether this field is
  1131.      *                         constrained to not be set to NULL.
  1132.      * @return string  DBMS specific SQL code portion that should be used to
  1133.      *                  declare the specified field.
  1134.      * @access public
  1135.      */
  1136.     function getFloatDeclaration($name$field)
  1137.     {
  1138.         if (isset($this->options['fixedfloat'])) {
  1139.             $this->fixed_float = $this->options['fixedfloat'];
  1140.         else {
  1141.             if ($this->connection == 0{
  1142.                 // XXX needs more checking
  1143.                 $this->connect();
  1144.             }
  1145.         }
  1146.         return("$name DOUBLE".
  1147.                 ($this->fixed_float ?
  1148.                  '('.($this->fixed_float + 2).','.$this->fixed_float.')' '').
  1149.                 (isset($field['default']?
  1150.                  ' DEFAULT '.$this->getFloatValue($field['default']'').
  1151.                 (isset($field['notnull']' NOT NULL' '')
  1152.                );
  1153.     }
  1154.  
  1155.     // }}}
  1156.     // {{{ getDecimalDeclaration()
  1157.  
  1158.     /**
  1159.      * Obtain DBMS specific SQL code portion needed to declare an decimal type
  1160.      * field to be used in statements like CREATE TABLE.
  1161.      *
  1162.      * @param string  $name   name the field to be declared.
  1163.      * @param string  $field  associative array with the name of the properties
  1164.      *                         of the field being declared as array indexes.
  1165.      *                         Currently, the types of supported field
  1166.      *                         properties are as follows:
  1167.      *
  1168.      *                        default
  1169.      *                         Integer value to be used as default for this
  1170.      *                         field.
  1171.      *
  1172.      *                        notnull
  1173.      *                         Boolean flag that indicates whether this field is
  1174.      *                         constrained to not be set to NULL.
  1175.      * @return string  DBMS specific SQL code portion that should be used to
  1176.      *                  declare the specified field.
  1177.      * @access public
  1178.      */
  1179.     function getDecimalDeclaration($name$field)
  1180.     {
  1181.         return("$name BIGINT".
  1182.                 (isset($field['default']?
  1183.                  ' DEFAULT '.$this->getDecimalValue($field['default']'').
  1184.                  (isset($field['notnull']' NOT NULL' '')
  1185.                );
  1186.     }
  1187.  
  1188.     // }}}
  1189.     // {{{ getClobValue()
  1190.  
  1191.     /**
  1192.      * Convert a text value into a DBMS specific format that is suitable to
  1193.      * compose query statements.
  1194.      *
  1195.      * @param resource  $prepared_query query handle from prepare()
  1196.      * @param           $parameter 
  1197.      * @param           $clob 
  1198.      * @return string  text string that represents the given argument value in
  1199.      *                  a DBMS specific format.
  1200.      * @access public
  1201.      */
  1202.     function getClobValue($prepared_query$parameter$clob)
  1203.     {
  1204.         $value "'";
  1205.         while(!$this->endOfLob($clob)) {
  1206.             if (MDB::isError($result $this->readLob($clob$data$this->options['lob_buffer_length']))) {
  1207.                 return($result);
  1208.             }
  1209.             $value .= $this->_quote($data);
  1210.         }
  1211.         $value .= "'";
  1212.         return($value);
  1213.     }
  1214.  
  1215.     // }}}
  1216.     // {{{ freeClobValue()
  1217.  
  1218.     /**
  1219.      * free a character large object
  1220.      *
  1221.      * @param resource  $prepared_query query handle from prepare()
  1222.      * @param string    $clob 
  1223.      * @return MDB_OK 
  1224.      * @access public
  1225.      */
  1226.     function freeClobValue($prepared_query$clob)
  1227.     {
  1228.         unset($this->lobs[$clob]);
  1229.         return(MDB_OK);
  1230.     }
  1231.  
  1232.     // }}}
  1233.     // {{{ getBlobValue()
  1234.  
  1235.     /**
  1236.      * Convert a text value into a DBMS specific format that is suitable to
  1237.      * compose query statements.
  1238.      *
  1239.      * @param resource  $prepared_query query handle from prepare()
  1240.      * @param           $parameter 
  1241.      * @param           $blob 
  1242.      * @return string  text string that represents the given argument value in
  1243.      *                  a DBMS specific format.
  1244.      * @access public
  1245.      */
  1246.     function getBlobValue($prepared_query$parameter$blob)
  1247.     {
  1248.         $value "'";
  1249.         while(!$this->endOfLob($blob)) {
  1250.             if (MDB::isError($result $this->readLob($blob$data$this->options['lob_buffer_length']))) {
  1251.                 return($result);
  1252.             }
  1253.             $value .= addslashes($data);
  1254.         }
  1255.         $value .= "'";
  1256.         return($value);
  1257.     }
  1258.  
  1259.     // }}}
  1260.     // {{{ freeBlobValue()
  1261.  
  1262.     /**
  1263.      * free a binary large object
  1264.      *
  1265.      * @param resource  $prepared_query query handle from prepare()
  1266.      * @param string    $blob 
  1267.      * @return MDB_OK 
  1268.      * @access public
  1269.      */
  1270.     function freeBlobValue($prepared_query$blob)
  1271.     {
  1272.         unset($this->lobs[$blob]);
  1273.         return(MDB_OK);
  1274.     }
  1275.  
  1276.     // }}}
  1277.     // {{{ getFloatValue()
  1278.  
  1279.     /**
  1280.      * Convert a text value into a DBMS specific format that is suitable to
  1281.      * compose query statements.
  1282.      *
  1283.      * @param string  $value text string value that is intended to be converted.
  1284.      * @return string  text string that represents the given argument value in
  1285.      *                  a DBMS specific format.
  1286.      * @access public
  1287.      */
  1288.     function getFloatValue($value)
  1289.     {
  1290.         return(($value === NULL'NULL' : (float)$value);
  1291.     }
  1292.  
  1293.     // }}}
  1294.     // {{{ getDecimalValue()
  1295.  
  1296.     /**
  1297.      * Convert a text value into a DBMS specific format that is suitable to
  1298.      * compose query statements.
  1299.      *
  1300.      * @param string  $value text string value that is intended to be converted.
  1301.      * @return string  text string that represents the given argument value in
  1302.      *                  a DBMS specific format.
  1303.      * @access public
  1304.      */
  1305.     function getDecimalValue($value)
  1306.     {
  1307.         return(($value === NULL'NULL' strval(round(doubleval($value)*$this->decimal_factor)));
  1308.     }
  1309.  
  1310.     // }}}
  1311.     // {{{ nextId()
  1312.  
  1313.     /**
  1314.      * returns the next free id of a sequence
  1315.      *
  1316.      * @param string  $seq_name name of the sequence
  1317.      * @param boolean $ondemand when true the seqence is
  1318.      *                           automatic created, if it
  1319.      *                           not exists
  1320.      *
  1321.      * @return mixed MDB_Error or id
  1322.      * @access public
  1323.      */
  1324.     function nextId($seq_name$ondemand = TRUE)
  1325.     {
  1326.         $sequence_name $this->getSequenceName($seq_name);
  1327.         $this->expectError(MDB_ERROR_NOSUCHTABLE);
  1328.         $result $this->query("INSERT INTO $sequence_name ("
  1329.             .$this->options['sequence_col_name'].") VALUES (NULL)");
  1330.         $this->popExpect();
  1331.         if ($ondemand && MDB::isError($result&&
  1332.             $result->getCode(== MDB_ERROR_NOSUCHTABLE)
  1333.         {
  1334.             // Since we are create the sequence on demand
  1335.             // we know the first id = 1 so initialize the
  1336.             // sequence at 2
  1337.             $result $this->createSequence($seq_name2);
  1338.             if (MDB::isError($result)) {
  1339.                 return($this->raiseError(MDB_ERRORNULLNULL,
  1340.                     'Next ID: on demand sequence could not be created'));
  1341.             else {
  1342.                 // First ID of a newly created sequence is 1
  1343.                 return(1);
  1344.             }
  1345.         }
  1346.         $value intval(@mysql_insert_id($this->connection));
  1347.         $res $this->query("DELETE FROM $sequence_name WHERE "
  1348.             .$this->options['sequence_col_name']." < $value");
  1349.         if (MDB::isError($res)) {
  1350.             $this->warnings['Next ID: could not delete previous sequence table values';
  1351.         }
  1352.         return($value);
  1353.     }
  1354.  
  1355.  
  1356.     // }}}
  1357.     // {{{ currId()
  1358.  
  1359.     /**
  1360.      * returns the current id of a sequence
  1361.      *
  1362.      * @param string  $seq_name name of the sequence
  1363.      * @return mixed MDB_Error or id
  1364.      * @access public
  1365.      */
  1366.     function currId($seq_name)
  1367.     {
  1368.         $sequence_name $this->getSequenceName($seq_name);
  1369.         $result $this->query("SELECT MAX(".$this->options['sequence_col_name'].") FROM $sequence_name"'integer');
  1370.         if (MDB::isError($result)) {
  1371.             return($result);
  1372.         }
  1373.  
  1374.         return($this->fetchOne($result));
  1375.     }
  1376.  
  1377.     // }}}
  1378.     // {{{ fetchInto()
  1379.  
  1380.     /**
  1381.      * Fetch a row and insert the data into an existing array.
  1382.      *
  1383.      * @param resource  $result     result identifier
  1384.      * @param int       $fetchmode  how the array data should be indexed
  1385.      * @param int       $rownum     the row number to fetch
  1386.      * @return int data array on success, a MDB error on failure
  1387.      * @access public
  1388.      */
  1389.     function fetchInto($result$fetchmode = MDB_FETCHMODE_DEFAULT$rownum = NULL)
  1390.     {
  1391.         $result_value intval($result);
  1392.         if ($rownum == NULL{
  1393.             ++$this->highest_fetched_row[$result_value];
  1394.         else {
  1395.             if (!@mysql_data_seek($result$rownum)) {
  1396.                 return(NULL);
  1397.             }
  1398.             $this->highest_fetched_row[$result_value=
  1399.                 max($this->highest_fetched_row[$result_value]$rownum);
  1400.         }
  1401.         if ($fetchmode == MDB_FETCHMODE_DEFAULT{
  1402.             $fetchmode $this->fetchmode;
  1403.         }
  1404.         if ($fetchmode MDB_FETCHMODE_ASSOC{
  1405.             $row @mysql_fetch_assoc($result);
  1406.             if (is_array($row&& $this->options['optimize'== 'portability'{
  1407.                 $row array_change_key_case($rowCASE_LOWER);
  1408.             }
  1409.         else {
  1410.             $row @mysql_fetch_row($result);
  1411.         }
  1412.         if (!$row{
  1413.             if($this->options['autofree']{
  1414.                 $this->freeResult($result);
  1415.             }
  1416.             return(NULL);
  1417.         }
  1418.         if (isset($this->result_types[$result_value])) {
  1419.             $row $this->convertResultRow($result$row);
  1420.         }
  1421.         return($row);
  1422.     }
  1423.  
  1424.     // }}}
  1425.     // {{{ nextResult()
  1426.  
  1427.     /**
  1428.      * Move the internal mysql result pointer to the next available result
  1429.      * Currently not supported
  1430.      *
  1431.      * @param valid result resource
  1432.      * @return true if a result is available otherwise return false
  1433.      * @access public
  1434.      */
  1435.     function nextResult($result)
  1436.     {
  1437.         return(FALSE);
  1438.     }
  1439.  
  1440.     // }}}
  1441.     // {{{ tableInfo()
  1442.  
  1443.     /**
  1444.     * returns meta data about the result set
  1445.     *
  1446.     * @param resource    $result    result identifier
  1447.     * @param mixed $mode depends on implementation
  1448.     * @return array an nested array, or a MDB error
  1449.     * @access public
  1450.     */
  1451.     function tableInfo($result$mode = NULL{
  1452.         $count = 0;
  1453.         $id     = 0;
  1454.         $res  = array();
  1455.  
  1456.         /*
  1457.          * depending on $mode, metadata returns the following values:
  1458.          *
  1459.          * - mode is false (default):
  1460.          * $result[]:
  1461.          *   [0]['table']  table name
  1462.          *   [0]['name']   field name
  1463.          *   [0]['type']   field type
  1464.          *   [0]['len']    field length
  1465.          *   [0]['flags']  field flags
  1466.          *
  1467.          * - mode is MDB_TABLEINFO_ORDER
  1468.          * $result[]:
  1469.          *   ['num_fields'] number of metadata records
  1470.          *   [0]['table']  table name
  1471.          *   [0]['name']   field name
  1472.          *   [0]['type']   field type
  1473.          *   [0]['len']    field length
  1474.          *   [0]['flags']  field flags
  1475.          *   ['order'][field name]  index of field named "field name"
  1476.          *   The last one is used, if you have a field name, but no index.
  1477.          *   Test:  if (isset($result['meta']['myfield'])) { ...
  1478.          *
  1479.          * - mode is MDB_TABLEINFO_ORDERTABLE
  1480.          *    the same as above. but additionally
  1481.          *   ['ordertable'][table name][field name] index of field
  1482.          *      named 'field name'
  1483.          *
  1484.          *      this is, because if you have fields from different
  1485.          *      tables with the same field name * they override each
  1486.          *      other with MDB_TABLEINFO_ORDER
  1487.          *
  1488.          *      you can combine MDB_TABLEINFO_ORDER and
  1489.          *      MDB_TABLEINFO_ORDERTABLE with MDB_TABLEINFO_ORDER |
  1490.          *      MDB_TABLEINFO_ORDERTABLE * or with MDB_TABLEINFO_FULL
  1491.          */
  1492.  
  1493.         // if $result is a string, then we want information about a
  1494.         // table without a resultset
  1495.         if (is_string($result)) {
  1496.             if (MDB::isError($connect $this->connect())) {
  1497.                 return $connect;
  1498.             }
  1499.             $id @mysql_list_fields($this->database_name,
  1500.                 $result$this->connection);
  1501.             if (empty($id)) {
  1502.                 return($this->mysqlRaiseError());
  1503.             }
  1504.         else // else we want information about a resultset
  1505.             $id $result;
  1506.             if (empty($id)) {
  1507.                 return($this->mysqlRaiseError());
  1508.             }
  1509.         }
  1510.  
  1511.         $count @mysql_num_fields($id);
  1512.  
  1513.         // made this IF due to performance (one if is faster than $count if's)
  1514.         if (empty($mode)) {
  1515.             for ($i = 0$j = 0; $i<$count$i++{
  1516.                 $name @mysql_field_name($id$i);
  1517.                 if ($name != 'dummy_primary_key'{
  1518.                     $res[$j]['table'@mysql_field_table($id$i);
  1519.                     $res[$j]['name'$name;
  1520.                     $res[$j]['type'@mysql_field_type($id$i);
  1521.                     $res[$j]['len']  @mysql_field_len($id$i);
  1522.                     $res[$j]['flags'@mysql_field_flags($id$i);
  1523.                     $j++;
  1524.                 }
  1525.             }
  1526.         else // full
  1527.             $res['num_fields'$count;
  1528.  
  1529.             for ($i = 0; $i<$count$i++{
  1530.                 $name @mysql_field_name($id$i);
  1531.                 if ($name != 'dummy_primary_key'{
  1532.                     $res[$j]['table'@mysql_field_table($id$i);
  1533.                     $res[$j]['name'$name;
  1534.                     $res[$j]['type'@mysql_field_type($id$i);
  1535.                     $res[$j]['len']  @mysql_field_len($id$i);
  1536.                     $res[$j]['flags'@mysql_field_flags($id$i);
  1537.                     if ($mode MDB_TABLEINFO_ORDER{
  1538.                         // note sure if this should be $i or $j
  1539.                         $res['order'][$res[$j]['name']] $i;
  1540.                     }
  1541.                     if ($mode MDB_TABLEINFO_ORDERTABLE{
  1542.                         $res['ordertable'][$res[$j]['table']][$res[$j]['name']] $j;
  1543.                     }
  1544.                     $j++;
  1545.                 }
  1546.             }
  1547.         }
  1548.  
  1549.         // free the result only if we were called on a table
  1550.         if (is_string($result)) {
  1551.             @mysql_free_result($id);
  1552.         }
  1553.         return($res);
  1554.     }
  1555. }
  1556.  
  1557. ?>

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