Source for file common.php

Documentation is available at common.php

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * Contains the DB_common base class
  7.  *
  8.  * PHP versions 4 and 5
  9.  *
  10.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  11.  * that is available through the world-wide-web at the following URI:
  12.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  13.  * the PHP License and are unable to obtain it through the web, please
  14.  * send a note to license@php.net so we can mail you a copy immediately.
  15.  *
  16.  * @category   Database
  17.  * @package    DB
  18.  * @author     Stig Bakken <ssb@php.net>
  19.  * @author     Tomas V.V. Cox <cox@idecnet.com>
  20.  * @author     Daniel Convissor <danielc@php.net>
  21.  * @copyright  1997-2007 The PHP Group
  22.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  23.  * @version    CVS: $Id: common.php,v 1.143 2007/09/21 13:40:41 aharvey Exp $
  24.  * @link       http://pear.php.net/package/DB
  25.  */
  26.  
  27. /**
  28.  * Obtain the PEAR class so it can be extended from
  29.  */
  30. require_once DB_PEAR_PATH.'PEAR.php';
  31.  
  32. /**
  33.  * DB_common is the base class from which each database driver class extends
  34.  *
  35.  * All common methods are declared here.  If a given DBMS driver contains
  36.  * a particular method, that method will overload the one here.
  37.  *
  38.  * @category   Database
  39.  * @package    DB
  40.  * @author     Stig Bakken <ssb@php.net>
  41.  * @author     Tomas V.V. Cox <cox@idecnet.com>
  42.  * @author     Daniel Convissor <danielc@php.net>
  43.  * @copyright  1997-2007 The PHP Group
  44.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  45.  * @version    Release: 1.7.13
  46.  * @link       http://pear.php.net/package/DB
  47.  */
  48. class DB_common extends PEAR
  49. {
  50.     // {{{ properties
  51.  
  52.     /**
  53.      * The current default fetch mode
  54.      * @var integer 
  55.      */
  56.     var $fetchmode = DB_FETCHMODE_ORDERED;
  57.  
  58.     /**
  59.      * The name of the class into which results should be fetched when
  60.      * DB_FETCHMODE_OBJECT is in effect
  61.      *
  62.      * @var string 
  63.      */
  64.     var $fetchmode_object_class = 'stdClass';
  65.  
  66.     /**
  67.      * Was a connection present when the object was serialized()?
  68.      * @var bool 
  69.      * @see DB_common::__sleep(), DB_common::__wake()
  70.      */
  71.     var $was_connected = null;
  72.  
  73.     /**
  74.      * The most recently executed query
  75.      * @var string 
  76.      */
  77.     var $last_query = '';
  78.  
  79.     /**
  80.      * Run-time configuration options
  81.      *
  82.      * The 'optimize' option has been deprecated.  Use the 'portability'
  83.      * option instead.
  84.      *
  85.      * @var array 
  86.      * @see DB_common::setOption()
  87.      */
  88.     var $options = array(
  89.         'result_buffering' => 500,
  90.         'persistent' => false,
  91.         'ssl' => false,
  92.         'debug' => 0,
  93.         'seqname_format' => '%s_seq',
  94.         'autofree' => false,
  95.         'portability' => DB_PORTABILITY_NONE,
  96.         'optimize' => 'performance',  // Deprecated.  Use 'portability'.
  97.     );
  98.  
  99.     /**
  100.      * The parameters from the most recently executed query
  101.      * @var array 
  102.      * @since Property available since Release 1.7.0
  103.      */
  104.     var $last_parameters = array();
  105.  
  106.     /**
  107.      * The elements from each prepared statement
  108.      * @var array 
  109.      */
  110.     var $prepare_tokens = array();
  111.  
  112.     /**
  113.      * The data types of the various elements in each prepared statement
  114.      * @var array 
  115.      */
  116.     var $prepare_types = array();
  117.  
  118.     /**
  119.      * The prepared queries
  120.      * @var array 
  121.      */
  122.     var $prepared_queries = array();
  123.  
  124.     /**
  125.      * Flag indicating that the last query was a manipulation query.
  126.      * @access protected
  127.      * @var boolean 
  128.      */
  129.     var $_last_query_manip = false;
  130.  
  131.     /**
  132.      * Flag indicating that the next query <em>must</em> be a manipulation
  133.      * query.
  134.      * @access protected
  135.      * @var boolean 
  136.      */
  137.     var $_next_query_manip = false;
  138.  
  139.  
  140.     // }}}
  141.     // {{{ DB_common
  142.  
  143.     /**
  144.      * This constructor calls <kbd>$this->PEAR('DB_Error')</kbd>
  145.      *
  146.      * @return void 
  147.      */
  148.     function DB_common()
  149.     {
  150.         $this->PEAR('DB_Error');
  151.     }
  152.  
  153.     // }}}
  154.     // {{{ __sleep()
  155.  
  156.     /**
  157.      * Automatically indicates which properties should be saved
  158.      * when PHP's serialize() function is called
  159.      *
  160.      * @return array  the array of properties names that should be saved
  161.      */
  162.     function __sleep()
  163.     {
  164.         if ($this->connection{
  165.             // Don't disconnect(), people use serialize() for many reasons
  166.             $this->was_connected = true;
  167.         else {
  168.             $this->was_connected = false;
  169.         }
  170.         if (isset($this->autocommit)) {
  171.             return array('autocommit',
  172.                          'dbsyntax',
  173.                          'dsn',
  174.                          'features',
  175.                          'fetchmode',
  176.                          'fetchmode_object_class',
  177.                          'options',
  178.                          'was_connected',
  179.                    );
  180.         else {
  181.             return array('dbsyntax',
  182.                          'dsn',
  183.                          'features',
  184.                          'fetchmode',
  185.                          'fetchmode_object_class',
  186.                          'options',
  187.                          'was_connected',
  188.                    );
  189.         }
  190.     }
  191.  
  192.     // }}}
  193.     // {{{ __wakeup()
  194.  
  195.     /**
  196.      * Automatically reconnects to the database when PHP's unserialize()
  197.      * function is called
  198.      *
  199.      * The reconnection attempt is only performed if the object was connected
  200.      * at the time PHP's serialize() function was run.
  201.      *
  202.      * @return void 
  203.      */
  204.     function __wakeup()
  205.     {
  206.         if ($this->was_connected{
  207.             $this->connect($this->dsn$this->options);
  208.         }
  209.     }
  210.  
  211.     // }}}
  212.     // {{{ __toString()
  213.  
  214.     /**
  215.      * Automatic string conversion for PHP 5
  216.      *
  217.      * @return string  a string describing the current PEAR DB object
  218.      *
  219.      * @since Method available since Release 1.7.0
  220.      */
  221.     function __toString()
  222.     {
  223.         $info strtolower(get_class($this));
  224.         $info .=  ': (phptype=' $this->phptype .
  225.                   ', dbsyntax=' $this->dbsyntax .
  226.                   ')';
  227.         if ($this->connection{
  228.             $info .= ' [connected]';
  229.         }
  230.         return $info;
  231.     }
  232.  
  233.     // }}}
  234.     // {{{ toString()
  235.  
  236.     /**
  237.      * DEPRECATED:  String conversion method
  238.      *
  239.      * @return string  a string describing the current PEAR DB object
  240.      *
  241.      * @deprecated Method deprecated in Release 1.7.0
  242.      */
  243.     function toString()
  244.     {
  245.         return $this->__toString();
  246.     }
  247.  
  248.     // }}}
  249.     // {{{ quoteString()
  250.  
  251.     /**
  252.      * DEPRECATED: Quotes a string so it can be safely used within string
  253.      * delimiters in a query
  254.      *
  255.      * @param string $string  the string to be quoted
  256.      *
  257.      * @return string  the quoted string
  258.      *
  259.      * @see DB_common::quoteSmart(), DB_common::escapeSimple()
  260.      * @deprecated Method deprecated some time before Release 1.2
  261.      */
  262.     function quoteString($string)
  263.     {
  264.         $string $this->quote($string);
  265.         if ($string{0== "'"{
  266.             return substr($string1-1);
  267.         }
  268.         return $string;
  269.     }
  270.  
  271.     // }}}
  272.     // {{{ quote()
  273.  
  274.     /**
  275.      * DEPRECATED: Quotes a string so it can be safely used in a query
  276.      *
  277.      * @param string $string  the string to quote
  278.      *
  279.      * @return string  the quoted string or the string <samp>NULL</samp>
  280.      *                   if the value submitted is <kbd>null</kbd>.
  281.      *
  282.      * @see DB_common::quoteSmart(), DB_common::escapeSimple()
  283.      * @deprecated Deprecated in release 1.6.0
  284.      */
  285.     function quote($string null)
  286.     {
  287.         return ($string === null'NULL'
  288.                                   : "'" str_replace("'""''"$string"'";
  289.     }
  290.  
  291.     // }}}
  292.     // {{{ quoteIdentifier()
  293.  
  294.     /**
  295.      * Quotes a string so it can be safely used as a table or column name
  296.      *
  297.      * Delimiting style depends on which database driver is being used.
  298.      *
  299.      * NOTE: just because you CAN use delimited identifiers doesn't mean
  300.      * you SHOULD use them.  In general, they end up causing way more
  301.      * problems than they solve.
  302.      *
  303.      * Portability is broken by using the following characters inside
  304.      * delimited identifiers:
  305.      *   + backtick (<kbd>`</kbd>) -- due to MySQL
  306.      *   + double quote (<kbd>"</kbd>) -- due to Oracle
  307.      *   + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
  308.      *
  309.      * Delimited identifiers are known to generally work correctly under
  310.      * the following drivers:
  311.      *   + mssql
  312.      *   + mysql
  313.      *   + mysqli
  314.      *   + oci8
  315.      *   + odbc(access)
  316.      *   + odbc(db2)
  317.      *   + pgsql
  318.      *   + sqlite
  319.      *   + sybase (must execute <kbd>set quoted_identifier on</kbd> sometime
  320.      *     prior to use)
  321.      *
  322.      * InterBase doesn't seem to be able to use delimited identifiers
  323.      * via PHP 4.  They work fine under PHP 5.
  324.      *
  325.      * @param string $str  the identifier name to be quoted
  326.      *
  327.      * @return string  the quoted identifier
  328.      *
  329.      * @since Method available since Release 1.6.0
  330.      */
  331.     function quoteIdentifier($str)
  332.     {
  333.         return '"' str_replace('"''""'$str'"';
  334.     }
  335.  
  336.     // }}}
  337.     // {{{ quoteSmart()
  338.  
  339.     /**
  340.      * Formats input so it can be safely used in a query
  341.      *
  342.      * The output depends on the PHP data type of input and the database
  343.      * type being used.
  344.      *
  345.      * @param mixed $in  the data to be formatted
  346.      *
  347.      * @return mixed  the formatted data.  The format depends on the input's
  348.      *                  PHP type:
  349.      *  <ul>
  350.      *   <li>
  351.      *     <kbd>input</kbd> -> <samp>returns</samp>
  352.      *   </li>
  353.      *   <li>
  354.      *     <kbd>null</kbd> -> the string <samp>NULL</samp>
  355.      *   </li>
  356.      *   <li>
  357.      *     <kbd>integer</kbd> or <kbd>double</kbd> -> the unquoted number
  358.      *   </li>
  359.      *   <li>
  360.      *     <kbd>bool</kbd> -> output depends on the driver in use
  361.      *     Most drivers return integers: <samp>1</samp> if
  362.      *     <kbd>true</kbd> or <samp>0</samp> if
  363.      *     <kbd>false</kbd>.
  364.      *     Some return strings: <samp>TRUE</samp> if
  365.      *     <kbd>true</kbd> or <samp>FALSE</samp> if
  366.      *     <kbd>false</kbd>.
  367.      *     Finally one returns strings: <samp>T</samp> if
  368.      *     <kbd>true</kbd> or <samp>F</samp> if
  369.      *     <kbd>false</kbd>. Here is a list of each DBMS,
  370.      *     the values returned and the suggested column type:
  371.      *     <ul>
  372.      *       <li>
  373.      *         <kbd>dbase</kbd> -> <samp>T/F</samp>
  374.      *         (<kbd>Logical</kbd>)
  375.      *       </li>
  376.      *       <li>
  377.      *         <kbd>fbase</kbd> -> <samp>TRUE/FALSE</samp>
  378.      *         (<kbd>BOOLEAN</kbd>)
  379.      *       </li>
  380.      *       <li>
  381.      *         <kbd>ibase</kbd> -> <samp>1/0</samp>
  382.      *         (<kbd>SMALLINT</kbd>) [1]
  383.      *       </li>
  384.      *       <li>
  385.      *         <kbd>ifx</kbd> -> <samp>1/0</samp>
  386.      *         (<kbd>SMALLINT</kbd>) [1]
  387.      *       </li>
  388.      *       <li>
  389.      *         <kbd>msql</kbd> -> <samp>1/0</samp>
  390.      *         (<kbd>INTEGER</kbd>)
  391.      *       </li>
  392.      *       <li>
  393.      *         <kbd>mssql</kbd> -> <samp>1/0</samp>
  394.      *         (<kbd>BIT</kbd>)
  395.      *       </li>
  396.      *       <li>
  397.      *         <kbd>mysql</kbd> -> <samp>1/0</samp>
  398.      *         (<kbd>TINYINT(1)</kbd>)
  399.      *       </li>
  400.      *       <li>
  401.      *         <kbd>mysqli</kbd> -> <samp>1/0</samp>
  402.      *         (<kbd>TINYINT(1)</kbd>)
  403.      *       </li>
  404.      *       <li>
  405.      *         <kbd>oci8</kbd> -> <samp>1/0</samp>
  406.      *         (<kbd>NUMBER(1)</kbd>)
  407.      *       </li>
  408.      *       <li>
  409.      *         <kbd>odbc</kbd> -> <samp>1/0</samp>
  410.      *         (<kbd>SMALLINT</kbd>) [1]
  411.      *       </li>
  412.      *       <li>
  413.      *         <kbd>pgsql</kbd> -> <samp>TRUE/FALSE</samp>
  414.      *         (<kbd>BOOLEAN</kbd>)
  415.      *       </li>
  416.      *       <li>
  417.      *         <kbd>sqlite</kbd> -> <samp>1/0</samp>
  418.      *         (<kbd>INTEGER</kbd>)
  419.      *       </li>
  420.      *       <li>
  421.      *         <kbd>sybase</kbd> -> <samp>1/0</samp>
  422.      *         (<kbd>TINYINT(1)</kbd>)
  423.      *       </li>
  424.      *     </ul>
  425.      *     [1] Accommodate the lowest common denominator because not all
  426.      *     versions of have <kbd>BOOLEAN</kbd>.
  427.      *   </li>
  428.      *   <li>
  429.      *     other (including strings and numeric strings) ->
  430.      *     the data with single quotes escaped by preceeding
  431.      *     single quotes, backslashes are escaped by preceeding
  432.      *     backslashes, then the whole string is encapsulated
  433.      *     between single quotes
  434.      *   </li>
  435.      *  </ul>
  436.      *
  437.      * @see DB_common::escapeSimple()
  438.      * @since Method available since Release 1.6.0
  439.      */
  440.     function quoteSmart($in)
  441.     {
  442.         if (is_int($in)) {
  443.             return $in;
  444.         elseif (is_float($in)) {
  445.             return $this->quoteFloat($in);
  446.         elseif (is_bool($in)) {
  447.             return $this->quoteBoolean($in);
  448.         elseif (is_null($in)) {
  449.             return 'NULL';
  450.         else {
  451.             if ($this->dbsyntax == 'access'
  452.                 && preg_match('/^#.+#$/'$in))
  453.             {
  454.                 return $this->escapeSimple($in);
  455.             }
  456.             return "'" $this->escapeSimple($in"'";
  457.         }
  458.     }
  459.  
  460.     // }}}
  461.     // {{{ quoteBoolean()
  462.  
  463.     /**
  464.      * Formats a boolean value for use within a query in a locale-independent
  465.      * manner.
  466.      *
  467.      * @param boolean the boolean value to be quoted.
  468.      * @return string the quoted string.
  469.      * @see DB_common::quoteSmart()
  470.      * @since Method available since release 1.7.8.
  471.      */
  472.     function quoteBoolean($boolean{
  473.         return $boolean '1' '0';
  474.     }
  475.      
  476.     // }}}
  477.     // {{{ quoteFloat()
  478.  
  479.     /**
  480.      * Formats a float value for use within a query in a locale-independent
  481.      * manner.
  482.      *
  483.      * @param float the float value to be quoted.
  484.      * @return string the quoted string.
  485.      * @see DB_common::quoteSmart()
  486.      * @since Method available since release 1.7.8.
  487.      */
  488.     function quoteFloat($float{
  489.         return "'".$this->escapeSimple(str_replace(',''.'strval(floatval($float))))."'";
  490.     }
  491.      
  492.     // }}}
  493.     // {{{ escapeSimple()
  494.  
  495.     /**
  496.      * Escapes a string according to the current DBMS's standards
  497.      *
  498.      * In SQLite, this makes things safe for inserts/updates, but may
  499.      * cause problems when performing text comparisons against columns
  500.      * containing binary data. See the
  501.      * {@link http://php.net/sqlite_escape_string PHP manual} for more info.
  502.      *
  503.      * @param string $str  the string to be escaped
  504.      *
  505.      * @return string  the escaped string
  506.      *
  507.      * @see DB_common::quoteSmart()
  508.      * @since Method available since Release 1.6.0
  509.      */
  510.     function escapeSimple($str)
  511.     {
  512.         return str_replace("'""''"$str);
  513.     }
  514.  
  515.     // }}}
  516.     // {{{ provides()
  517.  
  518.     /**
  519.      * Tells whether the present driver supports a given feature
  520.      *
  521.      * @param string $feature  the feature you're curious about
  522.      *
  523.      * @return bool  whether this driver supports $feature
  524.      */
  525.     function provides($feature)
  526.     {
  527.         return $this->features[$feature];
  528.     }
  529.  
  530.     // }}}
  531.     // {{{ setFetchMode()
  532.  
  533.     /**
  534.      * Sets the fetch mode that should be used by default for query results
  535.      *
  536.      * @param integer $fetchmode    DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC
  537.      *                                or DB_FETCHMODE_OBJECT
  538.      * @param string $object_class  the class name of the object to be returned
  539.      *                                by the fetch methods when the
  540.      *                                DB_FETCHMODE_OBJECT mode is selected.
  541.      *                                If no class is specified by default a cast
  542.      *                                to object from the assoc array row will be
  543.      *                                done.  There is also the posibility to use
  544.      *                                and extend the 'DB_row' class.
  545.      *
  546.      * @see DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC, DB_FETCHMODE_OBJECT
  547.      */
  548.     function setFetchMode($fetchmode$object_class 'stdClass')
  549.     {
  550.         switch ($fetchmode{
  551.             case DB_FETCHMODE_OBJECT:
  552.                 $this->fetchmode_object_class = $object_class;
  553.             case DB_FETCHMODE_ORDERED:
  554.             case DB_FETCHMODE_ASSOC:
  555.                 $this->fetchmode = $fetchmode;
  556.                 break;
  557.             default:
  558.                 return $this->raiseError('invalid fetchmode mode');
  559.         }
  560.     }
  561.  
  562.     // }}}
  563.     // {{{ setOption()
  564.  
  565.     /**
  566.      * Sets run-time configuration options for PEAR DB
  567.      *
  568.      * Options, their data types, default values and description:
  569.      * <ul>
  570.      * <li>
  571.      * <var>autofree</var> <kbd>boolean</kbd> = <samp>false</samp>
  572.      *      <br />should results be freed automatically when there are no
  573.      *            more rows?
  574.      * </li><li>
  575.      * <var>result_buffering</var> <kbd>integer</kbd> = <samp>500</samp>
  576.      *      <br />how many rows of the result set should be buffered?
  577.      *      <br />In mysql: mysql_unbuffered_query() is used instead of
  578.      *            mysql_query() if this value is 0.  (Release 1.7.0)
  579.      *      <br />In oci8: this value is passed to ocisetprefetch().
  580.      *            (Release 1.7.0)
  581.      * </li><li>
  582.      * <var>debug</var> <kbd>integer</kbd> = <samp>0</samp>
  583.      *      <br />debug level
  584.      * </li><li>
  585.      * <var>persistent</var> <kbd>boolean</kbd> = <samp>false</samp>
  586.      *      <br />should the connection be persistent?
  587.      * </li><li>
  588.      * <var>portability</var> <kbd>integer</kbd> = <samp>DB_PORTABILITY_NONE</samp>
  589.      *      <br />portability mode constant (see below)
  590.      * </li><li>
  591.      * <var>seqname_format</var> <kbd>string</kbd> = <samp>%s_seq</samp>
  592.      *      <br />the sprintf() format string used on sequence names.  This
  593.      *            format is applied to sequence names passed to
  594.      *            createSequence(), nextID() and dropSequence().
  595.      * </li><li>
  596.      * <var>ssl</var> <kbd>boolean</kbd> = <samp>false</samp>
  597.      *      <br />use ssl to connect?
  598.      * </li>
  599.      * </ul>
  600.      *
  601.      * -----------------------------------------
  602.      *
  603.      * PORTABILITY MODES
  604.      *
  605.      * These modes are bitwised, so they can be combined using <kbd>|</kbd>
  606.      * and removed using <kbd>^</kbd>.  See the examples section below on how
  607.      * to do this.
  608.      *
  609.      * <samp>DB_PORTABILITY_NONE</samp>
  610.      * turn off all portability features
  611.      *
  612.      * This mode gets automatically turned on if the deprecated
  613.      * <var>optimize</var> option gets set to <samp>performance</samp>.
  614.      *
  615.      *
  616.      * <samp>DB_PORTABILITY_LOWERCASE</samp>
  617.      * convert names of tables and fields to lower case when using
  618.      * <kbd>get*()</kbd>, <kbd>fetch*()</kbd> and <kbd>tableInfo()</kbd>
  619.      *
  620.      * This mode gets automatically turned on in the following databases
  621.      * if the deprecated option <var>optimize</var> gets set to
  622.      * <samp>portability</samp>:
  623.      * + oci8
  624.      *
  625.      *
  626.      * <samp>DB_PORTABILITY_RTRIM</samp>
  627.      * right trim the data output by <kbd>get*()</kbd> <kbd>fetch*()</kbd>
  628.      *
  629.      *
  630.      * <samp>DB_PORTABILITY_DELETE_COUNT</samp>
  631.      * force reporting the number of rows deleted
  632.      *
  633.      * Some DBMS's don't count the number of rows deleted when performing
  634.      * simple <kbd>DELETE FROM tablename</kbd> queries.  This portability
  635.      * mode tricks such DBMS's into telling the count by adding
  636.      * <samp>WHERE 1=1</samp> to the end of <kbd>DELETE</kbd> queries.
  637.      *
  638.      * This mode gets automatically turned on in the following databases
  639.      * if the deprecated option <var>optimize</var> gets set to
  640.      * <samp>portability</samp>:
  641.      * + fbsql
  642.      * + mysql
  643.      * + mysqli
  644.      * + sqlite
  645.      *
  646.      *
  647.      * <samp>DB_PORTABILITY_NUMROWS</samp>
  648.      * enable hack that makes <kbd>numRows()</kbd> work in Oracle
  649.      *
  650.      * This mode gets automatically turned on in the following databases
  651.      * if the deprecated option <var>optimize</var> gets set to
  652.      * <samp>portability</samp>:
  653.      * + oci8
  654.      *
  655.      *
  656.      * <samp>DB_PORTABILITY_ERRORS</samp>
  657.      * makes certain error messages in certain drivers compatible
  658.      * with those from other DBMS's
  659.      *
  660.      * + mysql, mysqli:  change unique/primary key constraints
  661.      *   DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
  662.      *
  663.      * + odbc(access):  MS's ODBC driver reports 'no such field' as code
  664.      *   07001, which means 'too few parameters.'  When this option is on
  665.      *   that code gets mapped to DB_ERROR_NOSUCHFIELD.
  666.      *   DB_ERROR_MISMATCH -> DB_ERROR_NOSUCHFIELD
  667.      *
  668.      * <samp>DB_PORTABILITY_NULL_TO_EMPTY</samp>
  669.      * convert null values to empty strings in data output by get*() and
  670.      * fetch*().  Needed because Oracle considers empty strings to be null,
  671.      * while most other DBMS's know the difference between empty and null.
  672.      *
  673.      *
  674.      * <samp>DB_PORTABILITY_ALL</samp>
  675.      * turn on all portability features
  676.      *
  677.      * -----------------------------------------
  678.      *
  679.      * Example 1. Simple setOption() example
  680.      * <code>
  681.      * $db->setOption('autofree', true);
  682.      * </code>
  683.      *
  684.      * Example 2. Portability for lowercasing and trimming
  685.      * <code>
  686.      * $db->setOption('portability',
  687.      *                 DB_PORTABILITY_LOWERCASE | DB_PORTABILITY_RTRIM);
  688.      * </code>
  689.      *
  690.      * Example 3. All portability options except trimming
  691.      * <code>
  692.      * $db->setOption('portability',
  693.      *                 DB_PORTABILITY_ALL ^ DB_PORTABILITY_RTRIM);
  694.      * </code>
  695.      *
  696.      * @param string $option option name
  697.      * @param mixed  $value value for the option
  698.      *
  699.      * @return int  DB_OK on success.  A DB_Error object on failure.
  700.      *
  701.      * @see DB_common::$options
  702.      */
  703.     function setOption($option$value)
  704.     {
  705.         if (isset($this->options[$option])) {
  706.             $this->options[$option$value;
  707.  
  708.             /*
  709.              * Backwards compatibility check for the deprecated 'optimize'
  710.              * option.  Done here in case settings change after connecting.
  711.              */
  712.             if ($option == 'optimize'{
  713.                 if ($value == 'portability'{
  714.                     switch ($this->phptype{
  715.                         case 'oci8':
  716.                             $this->options['portability'=
  717.                                     DB_PORTABILITY_LOWERCASE |
  718.                                     DB_PORTABILITY_NUMROWS;
  719.                             break;
  720.                         case 'fbsql':
  721.                         case 'mysql':
  722.                         case 'mysqli':
  723.                         case 'sqlite':
  724.                             $this->options['portability'=
  725.                                     DB_PORTABILITY_DELETE_COUNT;
  726.                             break;
  727.                     }
  728.                 else {
  729.                     $this->options['portability'DB_PORTABILITY_NONE;
  730.                 }
  731.             }
  732.  
  733.             return DB_OK;
  734.         }
  735.         return $this->raiseError("unknown option $option");
  736.     }
  737.  
  738.     // }}}
  739.     // {{{ getOption()
  740.  
  741.     /**
  742.      * Returns the value of an option
  743.      *
  744.      * @param string $option  the option name you're curious about
  745.      *
  746.      * @return mixed  the option's value
  747.      */
  748.     function getOption($option)
  749.     {
  750.         if (isset($this->options[$option])) {
  751.             return $this->options[$option];
  752.         }
  753.         return $this->raiseError("unknown option $option");
  754.     }
  755.  
  756.     // }}}
  757.     // {{{ prepare()
  758.  
  759.     /**
  760.      * Prepares a query for multiple execution with execute()
  761.      *
  762.      * Creates a query that can be run multiple times.  Each time it is run,
  763.      * the placeholders, if any, will be replaced by the contents of
  764.      * execute()'s $data argument.
  765.      *
  766.      * Three types of placeholders can be used:
  767.      *   + <kbd>?</kbd>  scalar value (i.e. strings, integers).  The system
  768.      *                   will automatically quote and escape the data.
  769.      *   + <kbd>!</kbd>  value is inserted 'as is'
  770.      *   + <kbd>&</kbd>  requires a file name.  The file's contents get
  771.      *                   inserted into the query (i.e. saving binary
  772.      *                   data in a db)
  773.      *
  774.      * Example 1.
  775.      * <code>
  776.      * $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
  777.      * $data = array(
  778.      *     "John's text",
  779.      *     "'it''s good'",
  780.      *     'filename.txt'
  781.      * );
  782.      * $res = $db->execute($sth, $data);
  783.      * </code>
  784.      *
  785.      * Use backslashes to escape placeholder characters if you don't want
  786.      * them to be interpreted as placeholders:
  787.      * <pre>
  788.      *    "UPDATE foo SET col=? WHERE col='over \& under'"
  789.      * </pre>
  790.      *
  791.      * With some database backends, this is emulated.
  792.      *
  793.      * {@internal ibase and oci8 have their own prepare() methods.}}
  794.      *
  795.      * @param string $query  the query to be prepared
  796.      *
  797.      * @return mixed  DB statement resource on success. A DB_Error object
  798.      *                  on failure.
  799.      *
  800.      * @see DB_common::execute()
  801.      */
  802.     function prepare($query)
  803.     {
  804.         $tokens   preg_split('/((?<!\\\)[&?!])/'$query-1,
  805.                                PREG_SPLIT_DELIM_CAPTURE);
  806.         $token     0;
  807.         $types     array();
  808.         $newtokens array();
  809.  
  810.         foreach ($tokens as $val{
  811.             switch ($val{
  812.                 case '?':
  813.                     $types[$token++DB_PARAM_SCALAR;
  814.                     break;
  815.                 case '&':
  816.                     $types[$token++DB_PARAM_OPAQUE;
  817.                     break;
  818.                 case '!':
  819.                     $types[$token++DB_PARAM_MISC;
  820.                     break;
  821.                 default:
  822.                     $newtokens[preg_replace('/\\\([&?!])/'"\\1"$val);
  823.             }
  824.         }
  825.  
  826.         $this->prepare_tokens[&$newtokens;
  827.         end($this->prepare_tokens);
  828.  
  829.         $k key($this->prepare_tokens);
  830.         $this->prepare_types[$k$types;
  831.         $this->prepared_queries[$kimplode(' '$newtokens);
  832.  
  833.         return $k;
  834.     }
  835.  
  836.     // }}}
  837.     // {{{ autoPrepare()
  838.  
  839.     /**
  840.      * Automaticaly generates an insert or update query and pass it to prepare()
  841.      *
  842.      * @param string $table         the table name
  843.      * @param array  $table_fields  the array of field names
  844.      * @param int    $mode          a type of query to make:
  845.      *                                DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
  846.      * @param string $where         for update queries: the WHERE clause to
  847.      *                                append to the SQL statement.  Don't
  848.      *                                include the "WHERE" keyword.
  849.      *
  850.      * @return resource  the query handle
  851.      *
  852.      * @uses DB_common::prepare(), DB_common::buildManipSQL()
  853.      */
  854.     function autoPrepare($table$table_fields$mode DB_AUTOQUERY_INSERT,
  855.                          $where false)
  856.     {
  857.         $query $this->buildManipSQL($table$table_fields$mode$where);
  858.         if (DB::isError($query)) {
  859.             return $query;
  860.         }
  861.         return $this->prepare($query);
  862.     }
  863.  
  864.     // }}}
  865.     // {{{ autoExecute()
  866.  
  867.     /**
  868.      * Automaticaly generates an insert or update query and call prepare()
  869.      * and execute() with it
  870.      *
  871.      * @param string $table         the table name
  872.      * @param array  $fields_values the associative array where $key is a
  873.      *                                field name and $value its value
  874.      * @param int    $mode          a type of query to make:
  875.      *                                DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
  876.      * @param string $where         for update queries: the WHERE clause to
  877.      *                                append to the SQL statement.  Don't
  878.      *                                include the "WHERE" keyword.
  879.      *
  880.      * @return mixed  a new DB_result object for successful SELECT queries
  881.      *                  or DB_OK for successul data manipulation queries.
  882.      *                  A DB_Error object on failure.
  883.      *
  884.      * @uses DB_common::autoPrepare(), DB_common::execute()
  885.      */
  886.     function autoExecute($table$fields_values$mode DB_AUTOQUERY_INSERT,
  887.                          $where false)
  888.     {
  889.         $sth $this->autoPrepare($tablearray_keys($fields_values)$mode,
  890.                                   $where);
  891.         if (DB::isError($sth)) {
  892.             return $sth;
  893.         }
  894.         $ret $this->execute($stharray_values($fields_values));
  895.         $this->freePrepared($sth);
  896.         return $ret;
  897.  
  898.     }
  899.  
  900.     // }}}
  901.     // {{{ buildManipSQL()
  902.  
  903.     /**
  904.      * Produces an SQL query string for autoPrepare()
  905.      *
  906.      * Example:
  907.      * <pre>
  908.      * buildManipSQL('table_sql', array('field1', 'field2', 'field3'),
  909.      *               DB_AUTOQUERY_INSERT);
  910.      * </pre>
  911.      *
  912.      * That returns
  913.      * <samp>
  914.      * INSERT INTO table_sql (field1,field2,field3) VALUES (?,?,?)
  915.      * </samp>
  916.      *
  917.      * NOTES:
  918.      *   - This belongs more to a SQL Builder class, but this is a simple
  919.      *     facility.
  920.      *   - Be carefull! If you don't give a $where param with an UPDATE
  921.      *     query, all the records of the table will be updated!
  922.      *
  923.      * @param string $table         the table name
  924.      * @param array  $table_fields  the array of field names
  925.      * @param int    $mode          a type of query to make:
  926.      *                                DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE
  927.      * @param string $where         for update queries: the WHERE clause to
  928.      *                                append to the SQL statement.  Don't
  929.      *                                include the "WHERE" keyword.
  930.      *
  931.      * @return string  the sql query for autoPrepare()
  932.      */
  933.     function buildManipSQL($table$table_fields$mode$where false)
  934.     {
  935.         if (count($table_fields== 0{
  936.             return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
  937.         }
  938.         $first true;
  939.         switch ($mode{
  940.             case DB_AUTOQUERY_INSERT:
  941.                 $values '';
  942.                 $names '';
  943.                 foreach ($table_fields as $value{
  944.                     if ($first{
  945.                         $first false;
  946.                     else {
  947.                         $names .= ',';
  948.                         $values .= ',';
  949.                     }
  950.                     $names .= $value;
  951.                     $values .= '?';
  952.                 }
  953.                 return "INSERT INTO $table ($names) VALUES ($values)";
  954.             case DB_AUTOQUERY_UPDATE:
  955.                 $set '';
  956.                 foreach ($table_fields as $value{
  957.                     if ($first{
  958.                         $first false;
  959.                     else {
  960.                         $set .= ',';
  961.                     }
  962.                     $set .= "$value = ?";
  963.                 }
  964.                 $sql "UPDATE $table SET $set";
  965.                 if ($where{
  966.                     $sql .= " WHERE $where";
  967.                 }
  968.                 return $sql;
  969.             default:
  970.                 return $this->raiseError(DB_ERROR_SYNTAX);
  971.         }
  972.     }
  973.  
  974.     // }}}
  975.     // {{{ execute()
  976.  
  977.     /**
  978.      * Executes a DB statement prepared with prepare()
  979.      *
  980.      * Example 1.
  981.      * <code>
  982.      * $sth = $db->prepare('INSERT INTO tbl (a, b, c) VALUES (?, !, &)');
  983.      * $data = array(
  984.      *     "John's text",
  985.      *     "'it''s good'",
  986.      *     'filename.txt'
  987.      * );
  988.      * $res = $db->execute($sth, $data);
  989.      * </code>
  990.      *
  991.      * @param resource $stmt  a DB statement resource returned from prepare()
  992.      * @param mixed    $data  array, string or numeric data to be used in
  993.      *                          execution of the statement.  Quantity of items
  994.      *                          passed must match quantity of placeholders in
  995.      *                          query:  meaning 1 placeholder for non-array
  996.      *                          parameters or 1 placeholder per array element.
  997.      *
  998.      * @return mixed  a new DB_result object for successful SELECT queries
  999.      *                  or DB_OK for successul data manipulation queries.
  1000.      *                  A DB_Error object on failure.
  1001.      *
  1002.      *  {@internal ibase and oci8 have their own execute() methods.}}
  1003.      *
  1004.      * @see DB_common::prepare()
  1005.      */
  1006.     function &execute($stmt$data array())
  1007.     {
  1008.         $realquery $this->executeEmulateQuery($stmt$data);
  1009.         if (DB::isError($realquery)) {
  1010.             return $realquery;
  1011.         }
  1012.         $result $this->simpleQuery($realquery);
  1013.  
  1014.         if ($result === DB_OK || DB::isError($result)) {
  1015.             return $result;
  1016.         else {
  1017.             $tmp new DB_result($this$result);
  1018.             return $tmp;
  1019.         }
  1020.     }
  1021.  
  1022.     // }}}
  1023.     // {{{ executeEmulateQuery()
  1024.  
  1025.     /**
  1026.      * Emulates executing prepared statements if the DBMS not support them
  1027.      *
  1028.      * @param resource $stmt  a DB statement resource returned from execute()
  1029.      * @param mixed    $data  array, string or numeric data to be used in
  1030.      *                          execution of the statement.  Quantity of items
  1031.      *                          passed must match quantity of placeholders in
  1032.      *                          query:  meaning 1 placeholder for non-array
  1033.      *                          parameters or 1 placeholder per array element.
  1034.      *
  1035.      * @return mixed  a string containing the real query run when emulating
  1036.      *                  prepare/execute.  A DB_Error object on failure.
  1037.      *
  1038.      * @access protected
  1039.      * @see DB_common::execute()
  1040.      */
  1041.     function executeEmulateQuery($stmt$data array())
  1042.     {
  1043.         $stmt = (int)$stmt;
  1044.         $data = (array)$data;
  1045.         $this->last_parameters = $data;
  1046.  
  1047.         if (count($this->prepare_types[$stmt]!= count($data)) {
  1048.             $this->last_query = $this->prepared_queries[$stmt];
  1049.             return $this->raiseError(DB_ERROR_MISMATCH);
  1050.         }
  1051.  
  1052.         $realquery $this->prepare_tokens[$stmt][0];
  1053.  
  1054.         $i 0;
  1055.         foreach ($data as $value{
  1056.             if ($this->prepare_types[$stmt][$i== DB_PARAM_SCALAR{
  1057.                 $realquery .= $this->quoteSmart($value);
  1058.             elseif ($this->prepare_types[$stmt][$i== DB_PARAM_OPAQUE{
  1059.                 $fp @fopen($value'rb');
  1060.                 if (!$fp{
  1061.                     return $this->raiseError(DB_ERROR_ACCESS_VIOLATION);
  1062.                 }
  1063.                 $realquery .= $this->quoteSmart(fread($fpfilesize($value)));
  1064.                 fclose($fp);
  1065.             else {
  1066.                 $realquery .= $value;
  1067.             }
  1068.  
  1069.             $realquery .= $this->prepare_tokens[$stmt][++$i];
  1070.         }
  1071.  
  1072.         return $realquery;
  1073.     }
  1074.  
  1075.     // }}}
  1076.     // {{{ executeMultiple()
  1077.  
  1078.     /**
  1079.      * Performs several execute() calls on the same statement handle
  1080.      *
  1081.      * $data must be an array indexed numerically
  1082.      * from 0, one execute call is done for every "row" in the array.
  1083.      *
  1084.      * If an error occurs during execute(), executeMultiple() does not
  1085.      * execute the unfinished rows, but rather returns that error.
  1086.      *
  1087.      * @param resource $stmt  query handle from prepare()
  1088.      * @param array    $data  numeric array containing the
  1089.      *                          data to insert into the query
  1090.      *
  1091.      * @return int  DB_OK on success.  A DB_Error object on failure.
  1092.      *
  1093.      * @see DB_common::prepare(), DB_common::execute()
  1094.      */
  1095.     function executeMultiple($stmt$data)
  1096.     {
  1097.         foreach ($data as $value{
  1098.             $res $this->execute($stmt$value);
  1099.             if (DB::isError($res)) {
  1100.                 return $res;
  1101.             }
  1102.         }
  1103.         return DB_OK;
  1104.     }
  1105.  
  1106.     // }}}
  1107.     // {{{ freePrepared()
  1108.  
  1109.     /**
  1110.      * Frees the internal resources associated with a prepared query
  1111.      *
  1112.      * @param resource $stmt           the prepared statement's PHP resource
  1113.      * @param bool     $free_resource  should the PHP resource be freed too?
  1114.      *                                   Use false if you need to get data
  1115.      *                                   from the result set later.
  1116.      *
  1117.      * @return bool  TRUE on success, FALSE if $result is invalid
  1118.      *
  1119.      * @see DB_common::prepare()
  1120.      */
  1121.     function freePrepared($stmt$free_resource true)
  1122.     {
  1123.         $stmt = (int)$stmt;
  1124.         if (isset($this->prepare_tokens[$stmt])) {
  1125.             unset($this->prepare_tokens[$stmt]);
  1126.             unset($this->prepare_types[$stmt]);
  1127.             unset($this->prepared_queries[$stmt]);
  1128.             return true;
  1129.         }
  1130.         return false;
  1131.     }
  1132.  
  1133.     // }}}
  1134.     // {{{ modifyQuery()
  1135.  
  1136.     /**
  1137.      * Changes a query string for various DBMS specific reasons
  1138.      *
  1139.      * It is defined here to ensure all drivers have this method available.
  1140.      *
  1141.      * @param string $query  the query string to modify
  1142.      *
  1143.      * @return string  the modified query string
  1144.      *
  1145.      * @access protected
  1146.      * @see DB_mysql::modifyQuery(), DB_oci8::modifyQuery(),
  1147.      *       DB_sqlite::modifyQuery()
  1148.      */
  1149.     function modifyQuery($query)
  1150.     {
  1151.         return $query;
  1152.     }
  1153.  
  1154.     // }}}
  1155.     // {{{ modifyLimitQuery()
  1156.  
  1157.     /**
  1158.      * Adds LIMIT clauses to a query string according to current DBMS standards
  1159.      *
  1160.      * It is defined here to assure that all implementations
  1161.      * have this method defined.
  1162.      *
  1163.      * @param string $query   the query to modify
  1164.      * @param int    $from    the row to start to fetching (0 = the first row)
  1165.      * @param int    $count   the numbers of rows to fetch
  1166.      * @param mixed  $params  array, string or numeric data to be used in
  1167.      *                          execution of the statement.  Quantity of items
  1168.      *                          passed must match quantity of placeholders in
  1169.      *                          query:  meaning 1 placeholder for non-array
  1170.      *                          parameters or 1 placeholder per array element.
  1171.      *
  1172.      * @return string  the query string with LIMIT clauses added
  1173.      *
  1174.      * @access protected
  1175.      */
  1176.     function modifyLimitQuery($query$from$count$params array())
  1177.     {
  1178.         return $query;
  1179.     }
  1180.  
  1181.     // }}}
  1182.     // {{{ query()
  1183.  
  1184.     /**
  1185.      * Sends a query to the database server
  1186.      *
  1187.      * The query string can be either a normal statement to be sent directly
  1188.      * to the server OR if <var>$params</var> are passed the query can have
  1189.      * placeholders and it will be passed through prepare() and execute().
  1190.      *
  1191.      * @param string $query   the SQL query or the statement to prepare
  1192.      * @param mixed  $params  array, string or numeric data to be used in
  1193.      *                          execution of the statement.  Quantity of items
  1194.      *                          passed must match quantity of placeholders in
  1195.      *                          query:  meaning 1 placeholder for non-array
  1196.      *                          parameters or 1 placeholder per array element.
  1197.      *
  1198.      * @return mixed  a new DB_result object for successful SELECT queries
  1199.      *                  or DB_OK for successul data manipulation queries.
  1200.      *                  A DB_Error object on failure.
  1201.      *
  1202.      * @see DB_result, DB_common::prepare(), DB_common::execute()
  1203.      */
  1204.     function &query($query$params array())
  1205.     {
  1206.         if (sizeof($params0{
  1207.             $sth $this->prepare($query);
  1208.             if (DB::isError($sth)) {
  1209.                 return $sth;
  1210.             }
  1211.             $ret $this->execute($sth$params);
  1212.             $this->freePrepared($sthfalse);
  1213.             return $ret;
  1214.         else {
  1215.             $this->last_parameters = array();
  1216.             $result $this->simpleQuery($query);
  1217.             if ($result === DB_OK || DB::isError($result)) {
  1218.                 return $result;
  1219.             else {
  1220.                 $tmp new DB_result($this$result);
  1221.                 return $tmp;
  1222.             }
  1223.         }
  1224.     }
  1225.  
  1226.     // }}}
  1227.     // {{{ limitQuery()
  1228.  
  1229.     /**
  1230.      * Generates and executes a LIMIT query
  1231.      *
  1232.      * @param string $query   the query
  1233.      * @param intr   $from    the row to start to fetching (0 = the first row)
  1234.      * @param int    $count   the numbers of rows to fetch
  1235.      * @param mixed  $params  array, string or numeric data to be used in
  1236.      *                          execution of the statement.  Quantity of items
  1237.      *                          passed must match quantity of placeholders in
  1238.      *                          query:  meaning 1 placeholder for non-array
  1239.      *                          parameters or 1 placeholder per array element.
  1240.      *
  1241.      * @return mixed  a new DB_result object for successful SELECT queries
  1242.      *                  or DB_OK for successul data manipulation queries.
  1243.      *                  A DB_Error object on failure.
  1244.      */
  1245.     function &limitQuery($query$from$count$params array())
  1246.     {
  1247.         $query $this->modifyLimitQuery($query$from$count$params);
  1248.         if (DB::isError($query)){
  1249.             return $query;
  1250.         }
  1251.         $result $this->query($query$params);
  1252.         if (is_a($result'DB_result')) {
  1253.             $result->setOption('limit_from'$from);
  1254.             $result->setOption('limit_count'$count);
  1255.         }
  1256.         return $result;
  1257.     }
  1258.  
  1259.     // }}}
  1260.     // {{{ getOne()
  1261.  
  1262.     /**
  1263.      * Fetches the first column of the first row from a query result
  1264.      *
  1265.      * Takes care of doing the query and freeing the results when finished.
  1266.      *
  1267.      * @param string $query   the SQL query
  1268.      * @param mixed  $params  array, string or numeric data to be used in
  1269.      *                          execution of the statement.  Quantity of items
  1270.      *                          passed must match quantity of placeholders in
  1271.      *                          query:  meaning 1 placeholder for non-array
  1272.      *                          parameters or 1 placeholder per array element.
  1273.      *
  1274.      * @return mixed  the returned value of the query.
  1275.      *                  A DB_Error object on failure.
  1276.      */
  1277.     function &getOne($query$params array())
  1278.     {
  1279.         $params = (array)$params;
  1280.         // modifyLimitQuery() would be nice here, but it causes BC issues
  1281.         if (sizeof($params0{
  1282.             $sth $this->prepare($query);
  1283.             if (DB::isError($sth)) {
  1284.                 return $sth;
  1285.             }
  1286.             $res $this->execute($sth$params);
  1287.             $this->freePrepared($sth);
  1288.         else {
  1289.             $res $this->query($query);
  1290.         }
  1291.  
  1292.         if (DB::isError($res)) {
  1293.             return $res;
  1294.         }
  1295.  
  1296.         $err $res->fetchInto($rowDB_FETCHMODE_ORDERED);
  1297.         $res->free();
  1298.  
  1299.         if ($err !== DB_OK{
  1300.             return $err;
  1301.         }
  1302.  
  1303.         return $row[0];
  1304.     }
  1305.  
  1306.     // }}}
  1307.     // {{{ getRow()
  1308.  
  1309.     /**
  1310.      * Fetches the first row of data returned from a query result
  1311.      *
  1312.      * Takes care of doing the query and freeing the results when finished.
  1313.      *
  1314.      * @param string $query   the SQL query
  1315.      * @param mixed  $params  array, string or numeric data to be used in
  1316.      *                          execution of the statement.  Quantity of items
  1317.      *                          passed must match quantity of placeholders in
  1318.      *                          query:  meaning 1 placeholder for non-array
  1319.      *                          parameters or 1 placeholder per array element.
  1320.      * @param int $fetchmode  the fetch mode to use
  1321.      *
  1322.      * @return array  the first row of results as an array.
  1323.      *                  A DB_Error object on failure.
  1324.      */
  1325.     function &getRow($query$params array(),
  1326.                      $fetchmode DB_FETCHMODE_DEFAULT)
  1327.     {
  1328.         // compat check, the params and fetchmode parameters used to
  1329.         // have the opposite order
  1330.         if (!is_array($params)) {
  1331.             if (is_array($fetchmode)) {
  1332.                 if ($params === null{
  1333.                     $tmp DB_FETCHMODE_DEFAULT;
  1334.                 else {
  1335.                     $tmp $params;
  1336.                 }
  1337.                 $params $fetchmode;
  1338.                 $fetchmode $tmp;
  1339.             elseif ($params !== null{
  1340.                 $fetchmode $params;
  1341.                 $params array();
  1342.             }
  1343.         }
  1344.         // modifyLimitQuery() would be nice here, but it causes BC issues
  1345.         if (sizeof($params0{
  1346.             $sth $this->prepare($query);
  1347.             if (DB::isError($sth)) {
  1348.                 return $sth;
  1349.             }
  1350.             $res $this->execute($sth$params);
  1351.             $this->freePrepared($sth);
  1352.         else {
  1353.             $res $this->query($query);
  1354.         }
  1355.  
  1356.         if (DB::isError($res)) {
  1357.             return $res;
  1358.         }
  1359.  
  1360.         $err $res->fetchInto($row$fetchmode);
  1361.  
  1362.         $res->free();
  1363.  
  1364.         if ($err !== DB_OK{
  1365.             return $err;
  1366.         }
  1367.  
  1368.         return $row;
  1369.     }
  1370.  
  1371.     // }}}
  1372.     // {{{ getCol()
  1373.  
  1374.     /**
  1375.      * Fetches a single column from a query result and returns it as an
  1376.      * indexed array
  1377.      *
  1378.      * @param string $query   the SQL query
  1379.      * @param mixed  $col     which column to return (integer [column number,
  1380.      *                          starting at 0] or string [column name])
  1381.      * @param mixed  $params  array, string or numeric data to be used in
  1382.      *                          execution of the statement.  Quantity of items
  1383.      *                          passed must match quantity of placeholders in
  1384.      *                          query:  meaning 1 placeholder for non-array
  1385.      *                          parameters or 1 placeholder per array element.
  1386.      *
  1387.      * @return array  the results as an array.  A DB_Error object on failure.
  1388.      *
  1389.      * @see DB_common::query()
  1390.      */
  1391.     function &getCol($query$col 0$params array())
  1392.     {
  1393.         $params = (array)$params;
  1394.         if (sizeof($params0{
  1395.             $sth $this->prepare($query);
  1396.  
  1397.             if (DB::isError($sth)) {
  1398.                 return $sth;
  1399.             }
  1400.  
  1401.             $res $this->execute($sth$params);
  1402.             $this->freePrepared($sth);
  1403.         else {
  1404.             $res $this->query($query);
  1405.         }
  1406.  
  1407.         if (DB::isError($res)) {
  1408.             return $res;
  1409.         }
  1410.  
  1411.         $fetchmode is_int($colDB_FETCHMODE_ORDERED DB_FETCHMODE_ASSOC;
  1412.  
  1413.         if (!is_array($row $res->fetchRow($fetchmode))) {
  1414.             $ret array();
  1415.         else {
  1416.             if (!array_key_exists($col$row)) {
  1417.                 $ret $this->raiseError(DB_ERROR_NOSUCHFIELD);
  1418.             else {
  1419.                 $ret array($row[$col]);
  1420.                 while (is_array($row $res->fetchRow($fetchmode))) {
  1421.                     $ret[$row[$col];
  1422.                 }
  1423.             }
  1424.         }
  1425.  
  1426.         $res->free();
  1427.  
  1428.         if (DB::isError($row)) {
  1429.             $ret $row;
  1430.         }
  1431.  
  1432.         return $ret;
  1433.     }
  1434.  
  1435.     // }}}
  1436.     // {{{ getAssoc()
  1437.  
  1438.     /**
  1439.      * Fetches an entire query result and returns it as an
  1440.      * associative array using the first column as the key
  1441.      *
  1442.      * If the result set contains more than two columns, the value
  1443.      * will be an array of the values from column 2-n.  If the result
  1444.      * set contains only two columns, the returned value will be a
  1445.      * scalar with the value of the second column (unless forced to an
  1446.      * array with the $force_array parameter).  A DB error code is
  1447.      * returned on errors.  If the result set contains fewer than two
  1448.      * columns, a DB_ERROR_TRUNCATED error is returned.
  1449.      *
  1450.      * For example, if the table "mytable" contains:
  1451.      *
  1452.      * <pre>
  1453.      *  ID      TEXT       DATE
  1454.      * --------------------------------
  1455.      *  1       'one'      944679408
  1456.      *  2       'two'      944679408
  1457.      *  3       'three'    944679408
  1458.      * </pre>
  1459.      *
  1460.      * Then the call getAssoc('SELECT id,text FROM mytable') returns:
  1461.      * <pre>
  1462.      *   array(
  1463.      *     '1' => 'one',
  1464.      *     '2' => 'two',
  1465.      *     '3' => 'three',
  1466.      *   )
  1467.      * </pre>
  1468.      *
  1469.      * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
  1470.      * <pre>
  1471.      *   array(
  1472.      *     '1' => array('one', '944679408'),
  1473.      *     '2' => array('two', '944679408'),
  1474.      *     '3' => array('three', '944679408')
  1475.      *   )
  1476.      * </pre>
  1477.      *
  1478.      * If the more than one row occurs with the same value in the
  1479.      * first column, the last row overwrites all previous ones by
  1480.      * default.  Use the $group parameter if you don't want to
  1481.      * overwrite like this.  Example:
  1482.      *
  1483.      * <pre>
  1484.      * getAssoc('SELECT category,id,name FROM mytable', false, null,
  1485.      *          DB_FETCHMODE_ASSOC, true) returns:
  1486.      *
  1487.      *   array(
  1488.      *     '1' => array(array('id' => '4', 'name' => 'number four'),
  1489.      *                  array('id' => '6', 'name' => 'number six')
  1490.      *            ),
  1491.      *     '9' => array(array('id' => '4', 'name' => 'number four'),
  1492.      *                  array('id' => '6', 'name' => 'number six')
  1493.      *            )
  1494.      *   )
  1495.      * </pre>
  1496.      *
  1497.      * Keep in mind that database functions in PHP usually return string
  1498.      * values for results regardless of the database's internal type.
  1499.      *
  1500.      * @param string $query        the SQL query
  1501.      * @param bool   $force_array  used only when the query returns
  1502.      *                               exactly two columns.  If true, the values
  1503.      *                               of the returned array will be one-element
  1504.      *                               arrays instead of scalars.
  1505.      * @param mixed  $params       array, string or numeric data to be used in
  1506.      *                               execution of the statement.  Quantity of
  1507.      *                               items passed must match quantity of
  1508.      *                               placeholders in query:  meaning 1
  1509.      *                               placeholder for non-array parameters or
  1510.      *                               1 placeholder per array element.
  1511.      * @param int   $fetchmode     the fetch mode to use
  1512.      * @param bool  $group         if true, the values of the returned array
  1513.      *                               is wrapped in another array.  If the same
  1514.      *                               key value (in the first column) repeats
  1515.      *                               itself, the values will be appended to
  1516.      *                               this array instead of overwriting the
  1517.      *                               existing values.
  1518.      *
  1519.      * @return array  the associative array containing the query results.
  1520.      *                 A DB_Error object on failure.
  1521.      */
  1522.     function &getAssoc($query$force_array false$params array(),
  1523.                        $fetchmode DB_FETCHMODE_DEFAULT$group false)
  1524.     {
  1525.         $params = (array)$params;
  1526.         if (sizeof($params0{
  1527.             $sth $this->prepare($query);
  1528.  
  1529.             if (DB::isError($sth)) {
  1530.                 return $sth;
  1531.             }
  1532.  
  1533.             $res $this->execute($sth$params);
  1534.             $this->freePrepared($sth);
  1535.         else {
  1536.             $res $this->query($query);
  1537.         }
  1538.  
  1539.         if (DB::isError($res)) {
  1540.             return $res;
  1541.         }
  1542.         if ($fetchmode == DB_FETCHMODE_DEFAULT{
  1543.             $fetchmode $this->fetchmode;
  1544.         }
  1545.         $cols $res->numCols();
  1546.  
  1547.         if ($cols 2{
  1548.             $tmp $this->raiseError(DB_ERROR_TRUNCATED);
  1549.             return $tmp;
  1550.         }
  1551.  
  1552.         $results array();
  1553.  
  1554.         if ($cols || $force_array{
  1555.             // return array values
  1556.             // XXX this part can be optimized
  1557.             if ($fetchmode == DB_FETCHMODE_ASSOC{
  1558.                 while (is_array($row $res->fetchRow(DB_FETCHMODE_ASSOC))) {
  1559.                     reset($row);
  1560.                     $key current($row);
  1561.                     unset($row[key($row)]);
  1562.                     if ($group{
  1563.                         $results[$key][$row;
  1564.                     else {
  1565.                         $results[$key$row;
  1566.                     }
  1567.                 }
  1568.             elseif ($fetchmode == DB_FETCHMODE_OBJECT{
  1569.                 while ($row $res->fetchRow(DB_FETCHMODE_OBJECT)) {
  1570.                     $arr get_object_vars($row);
  1571.                     $key current($arr);
  1572.                     if ($group{
  1573.                         $results[$key][$row;
  1574.                     else {
  1575.                         $results[$key$row;
  1576.                     }
  1577.                 }
  1578.             else {
  1579.                 while (is_array($row $res->fetchRow(DB_FETCHMODE_ORDERED))) {
  1580.                     // we shift away the first element to get
  1581.                     // indices running from 0 again
  1582.                     $key array_shift($row);
  1583.                     if ($group{
  1584.                         $results[$key][$row;
  1585.                     else {
  1586.                         $results[$key$row;
  1587.                     }
  1588.                 }
  1589.             }
  1590.             if (DB::isError($row)) {
  1591.                 $results $row;
  1592.             }
  1593.         else {
  1594.             // return scalar values
  1595.             while (is_array($row $res->fetchRow(DB_FETCHMODE_ORDERED))) {
  1596.                 if ($group{
  1597.                     $results[$row[0]][$row[1];
  1598.                 else {
  1599.                     $results[$row[0]] $row[1];
  1600.                 }
  1601.             }
  1602.             if (DB::isError($row)) {
  1603.                 $results $row;
  1604.             }
  1605.         }
  1606.  
  1607.         $res->free();
  1608.  
  1609.         return $results;
  1610.     }
  1611.  
  1612.     // }}}
  1613.     // {{{ getAll()
  1614.  
  1615.     /**
  1616.      * Fetches all of the rows from a query result
  1617.      *
  1618.      * @param string $query      the SQL query
  1619.      * @param mixed  $params     array, string or numeric data to be used in
  1620.      *                             execution of the statement.  Quantity of
  1621.      *                             items passed must match quantity of
  1622.      *                             placeholders in query:  meaning 1
  1623.      *                             placeholder for non-array parameters or
  1624.      *                             1 placeholder per array element.
  1625.      * @param int    $fetchmode  the fetch mode to use:
  1626.      *                             + DB_FETCHMODE_ORDERED
  1627.      *                             + DB_FETCHMODE_ASSOC
  1628.      *                             + DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED
  1629.      *                             + DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED
  1630.      *
  1631.      * @return array  the nested array.  A DB_Error object on failure.
  1632.      */
  1633.     function &getAll($query$params array(),
  1634.                      $fetchmode DB_FETCHMODE_DEFAULT)
  1635.     {
  1636.         // compat check, the params and fetchmode parameters used to
  1637.         // have the opposite order
  1638.         if (!is_array($params)) {
  1639.             if (is_array($fetchmode)) {
  1640.                 if ($params === null{
  1641.                     $tmp DB_FETCHMODE_DEFAULT;
  1642.                 else {
  1643.                     $tmp $params;
  1644.                 }
  1645.                 $params $fetchmode;
  1646.                 $fetchmode $tmp;
  1647.             elseif ($params !== null{
  1648.                 $fetchmode $params;
  1649.                 $params array();
  1650.             }
  1651.         }
  1652.  
  1653.         if (sizeof($params0{
  1654.             $sth $this->prepare($query);
  1655.  
  1656.             if (DB::isError($sth)) {
  1657.                 return $sth;
  1658.             }
  1659.  
  1660.             $res $this->execute($sth$params);
  1661.             $this->freePrepared($sth);
  1662.         else {
  1663.             $res $this->query($query);
  1664.         }
  1665.  
  1666.         if ($res === DB_OK || DB::isError($res)) {
  1667.             return $res;
  1668.         }
  1669.  
  1670.         $results array();
  1671.         while (DB_OK === $res->fetchInto($row$fetchmode)) {
  1672.             if ($fetchmode DB_FETCHMODE_FLIPPED{
  1673.                 foreach ($row as $key => $val{
  1674.                     $results[$key][$val;
  1675.                 }
  1676.             else {
  1677.                 $results[$row;
  1678.             }
  1679.         }
  1680.  
  1681.         $res->free();
  1682.  
  1683.         if (DB::isError($row)) {
  1684.             $tmp $this->raiseError($row);
  1685.             return $tmp;
  1686.         }
  1687.         return $results;
  1688.     }
  1689.  
  1690.     // }}}
  1691.     // {{{ autoCommit()
  1692.  
  1693.     /**
  1694.      * Enables or disables automatic commits
  1695.      *
  1696.      * @param bool $onoff  true turns it on, false turns it off
  1697.      *
  1698.      * @return int  DB_OK on success.  A DB_Error object if the driver
  1699.      *                doesn't support auto-committing transactions.
  1700.      */
  1701.     function autoCommit($onoff false)
  1702.     {
  1703.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1704.     }
  1705.  
  1706.     // }}}
  1707.     // {{{ commit()
  1708.  
  1709.     /**
  1710.      * Commits the current transaction
  1711.      *
  1712.      * @return int  DB_OK on success.  A DB_Error object on failure.
  1713.      */
  1714.     function commit()
  1715.     {
  1716.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1717.     }
  1718.  
  1719.     // }}}
  1720.     // {{{ rollback()
  1721.  
  1722.     /**
  1723.      * Reverts the current transaction
  1724.      *
  1725.      * @return int  DB_OK on success.  A DB_Error object on failure.
  1726.      */
  1727.     function rollback()
  1728.     {
  1729.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1730.     }
  1731.  
  1732.     // }}}
  1733.     // {{{ numRows()
  1734.  
  1735.     /**
  1736.      * Determines the number of rows in a query result
  1737.      *
  1738.      * @param resource $result  the query result idenifier produced by PHP
  1739.      *
  1740.      * @return int  the number of rows.  A DB_Error object on failure.
  1741.      */
  1742.     function numRows($result)
  1743.     {
  1744.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1745.     }
  1746.  
  1747.     // }}}
  1748.     // {{{ affectedRows()
  1749.  
  1750.     /**
  1751.      * Determines the number of rows affected by a data maniuplation query
  1752.      *
  1753.      * 0 is returned for queries that don't manipulate data.
  1754.      *
  1755.      * @return int  the number of rows.  A DB_Error object on failure.
  1756.      */
  1757.     function affectedRows()
  1758.     {
  1759.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1760.     }
  1761.  
  1762.     // }}}
  1763.     // {{{ getSequenceName()
  1764.  
  1765.     /**
  1766.      * Generates the name used inside the database for a sequence
  1767.      *
  1768.      * The createSequence() docblock contains notes about storing sequence
  1769.      * names.
  1770.      *
  1771.      * @param string $sqn  the sequence's public name
  1772.      *
  1773.      * @return string  the sequence's name in the backend
  1774.      *
  1775.      * @access protected
  1776.      * @see DB_common::createSequence(), DB_common::dropSequence(),
  1777.      *       DB_common::nextID(), DB_common::setOption()
  1778.      */
  1779.     function getSequenceName($sqn)
  1780.     {
  1781.         return sprintf($this->getOption('seqname_format'),
  1782.                        preg_replace('/[^a-z0-9_.]/i''_'$sqn));
  1783.     }
  1784.  
  1785.     // }}}
  1786.     // {{{ nextId()
  1787.  
  1788.     /**
  1789.      * Returns the next free id in a sequence
  1790.      *
  1791.      * @param string  $seq_name  name of the sequence
  1792.      * @param boolean $ondemand  when true, the seqence is automatically
  1793.      *                             created if it does not exist
  1794.      *
  1795.      * @return int  the next id number in the sequence.
  1796.      *                A DB_Error object on failure.
  1797.      *
  1798.      * @see DB_common::createSequence(), DB_common::dropSequence(),
  1799.      *       DB_common::getSequenceName()
  1800.      */
  1801.     function nextId($seq_name$ondemand true)
  1802.     {
  1803.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1804.     }
  1805.  
  1806.     // }}}
  1807.     // {{{ createSequence()
  1808.  
  1809.     /**
  1810.      * Creates a new sequence
  1811.      *
  1812.      * The name of a given sequence is determined by passing the string
  1813.      * provided in the <var>$seq_name</var> argument through PHP's sprintf()
  1814.      * function using the value from the <var>seqname_format</var> option as
  1815.      * the sprintf()'s format argument.
  1816.      *
  1817.      * <var>seqname_format</var> is set via setOption().
  1818.      *
  1819.      * @param string $seq_name  name of the new sequence
  1820.      *
  1821.      * @return int  DB_OK on success.  A DB_Error object on failure.
  1822.      *
  1823.      * @see DB_common::dropSequence(), DB_common::getSequenceName(),
  1824.      *       DB_common::nextID()
  1825.      */
  1826.     function createSequence($seq_name)
  1827.     {
  1828.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1829.     }
  1830.  
  1831.     // }}}
  1832.     // {{{ dropSequence()
  1833.  
  1834.     /**
  1835.      * Deletes a sequence
  1836.      *
  1837.      * @param string $seq_name  name of the sequence to be deleted
  1838.      *
  1839.      * @return int  DB_OK on success.  A DB_Error object on failure.
  1840.      *
  1841.      * @see DB_common::createSequence(), DB_common::getSequenceName(),
  1842.      *       DB_common::nextID()
  1843.      */
  1844.     function dropSequence($seq_name)
  1845.     {
  1846.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1847.     }
  1848.  
  1849.     // }}}
  1850.     // {{{ raiseError()
  1851.  
  1852.     /**
  1853.      * Communicates an error and invoke error callbacks, etc
  1854.      *
  1855.      * Basically a wrapper for PEAR::raiseError without the message string.
  1856.      *
  1857.      * @param mixed   integer error code, or a PEAR error object (all
  1858.      *                  other parameters are ignored if this parameter is
  1859.      *                  an object
  1860.      * @param int     error mode, see PEAR_Error docs
  1861.      * @param mixed   if error mode is PEAR_ERROR_TRIGGER, this is the
  1862.      *                  error level (E_USER_NOTICE etc).  If error mode is
  1863.      *                  PEAR_ERROR_CALLBACK, this is the callback function,
  1864.      *                  either as a function name, or as an array of an
  1865.      *                  object and method name.  For other error modes this
  1866.      *                  parameter is ignored.
  1867.      * @param string  extra debug information.  Defaults to the last
  1868.      *                  query and native error code.
  1869.      * @param mixed   native error code, integer or string depending the
  1870.      *                  backend
  1871.      *
  1872.      * @return object  the PEAR_Error object
  1873.      *
  1874.      * @see PEAR_Error
  1875.      */
  1876.     function &raiseError($code DB_ERROR$mode null$options null,
  1877.                          $userinfo null$nativecode null)
  1878.     {
  1879.         // The error is yet a DB error object
  1880.         if (is_object($code)) {
  1881.             // because we the static PEAR::raiseError, our global
  1882.             // handler should be used if it is set
  1883.             if ($mode === null && !empty($this->_default_error_mode)) {
  1884.                 $mode    $this->_default_error_mode;
  1885.                 $options $this->_default_error_options;
  1886.             }
  1887.             $tmp PEAR::raiseError($codenull$mode$options,
  1888.                                     nullnulltrue);
  1889.             return $tmp;
  1890.         }
  1891.  
  1892.         if ($userinfo === null{
  1893.             $userinfo $this->last_query;
  1894.         }
  1895.  
  1896.         if ($nativecode{
  1897.             $userinfo .= ' [nativecode=' trim($nativecode']';
  1898.         else {
  1899.             $userinfo .= ' [DB Error: ' DB::errorMessage($code']';
  1900.         }
  1901.  
  1902.         $tmp PEAR::raiseError(null$code$mode$options$userinfo,
  1903.                                 'DB_Error'true);
  1904.         return $tmp;
  1905.     }
  1906.  
  1907.     // }}}
  1908.     // {{{ errorNative()
  1909.  
  1910.     /**
  1911.      * Gets the DBMS' native error code produced by the last query
  1912.      *
  1913.      * @return mixed  the DBMS' error code.  A DB_Error object on failure.
  1914.      */
  1915.     function errorNative()
  1916.     {
  1917.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  1918.     }
  1919.  
  1920.     // }}}
  1921.     // {{{ errorCode()
  1922.  
  1923.     /**
  1924.      * Maps native error codes to DB's portable ones
  1925.      *
  1926.      * Uses the <var>$errorcode_map</var> property defined in each driver.
  1927.      *
  1928.      * @param string|int$nativecode  the error code returned by the DBMS
  1929.      *
  1930.      * @return int  the portable DB error code.  Return DB_ERROR if the
  1931.      *                current driver doesn't have a mapping for the
  1932.      *                $nativecode submitted.
  1933.      */
  1934.     function errorCode($nativecode)
  1935.     {
  1936.         if (isset($this->errorcode_map[$nativecode])) {
  1937.             return $this->errorcode_map[$nativecode];
  1938.         }
  1939.         // Fall back to DB_ERROR if there was no mapping.
  1940.         return DB_ERROR;
  1941.     }
  1942.  
  1943.     // }}}
  1944.     // {{{ errorMessage()
  1945.  
  1946.     /**
  1947.      * Maps a DB error code to a textual message
  1948.      *
  1949.      * @param integer $dbcode  the DB error code
  1950.      *
  1951.      * @return string  the error message corresponding to the error code
  1952.      *                   submitted.  FALSE if the error code is unknown.
  1953.      *
  1954.      * @see DB::errorMessage()
  1955.      */
  1956.     function errorMessage($dbcode)
  1957.     {
  1958.         return DB::errorMessage($this->errorcode_map[$dbcode]);
  1959.     }
  1960.  
  1961.     // }}}
  1962.     // {{{ tableInfo()
  1963.  
  1964.     /**
  1965.      * Returns information about a table or a result set
  1966.      *
  1967.      * The format of the resulting array depends on which <var>$mode</var>
  1968.      * you select.  The sample output below is based on this query:
  1969.      * <pre>
  1970.      *    SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId
  1971.      *    FROM tblFoo
  1972.      *    JOIN tblBar ON tblFoo.fldId = tblBar.fldId
  1973.      * </pre>
  1974.      *
  1975.      * <ul>
  1976.      * <li>
  1977.      *
  1978.      * <kbd>null</kbd> (default)
  1979.      *   <pre>
  1980.      *   [0] => Array (
  1981.      *       [table] => tblFoo
  1982.      *       [name] => fldId
  1983.      *       [type] => int
  1984.      *       [len] => 11
  1985.      *       [flags] => primary_key not_null
  1986.      *   )
  1987.      *   [1] => Array (
  1988.      *       [table] => tblFoo
  1989.      *       [name] => fldPhone
  1990.      *       [type] => string
  1991.      *       [len] => 20
  1992.      *       [flags] =>
  1993.      *   )
  1994.      *   [2] => Array (
  1995.      *       [table] => tblBar
  1996.      *       [name] => fldId
  1997.      *       [type] => int
  1998.      *       [len] => 11
  1999.      *       [flags] => primary_key not_null
  2000.      *   )
  2001.      *   </pre>
  2002.      *
  2003.      * </li><li>
  2004.      *
  2005.      * <kbd>DB_TABLEINFO_ORDER</kbd>
  2006.      *
  2007.      *   <p>In addition to the information found in the default output,
  2008.      *   a notation of the number of columns is provided by the
  2009.      *   <samp>num_fields</samp> element while the <samp>order</samp>
  2010.      *   element provides an array with the column names as the keys and
  2011.      *   their location index number (corresponding to the keys in the
  2012.      *   the default output) as the values.</p>
  2013.      *
  2014.      *   <p>If a result set has identical field names, the last one is
  2015.      *   used.</p>
  2016.      *
  2017.      *   <pre>
  2018.      *   [num_fields] => 3
  2019.      *   [order] => Array (
  2020.      *       [fldId] => 2
  2021.      *       [fldTrans] => 1
  2022.      *   )
  2023.      *   </pre>
  2024.      *
  2025.      * </li><li>
  2026.      *
  2027.      * <kbd>DB_TABLEINFO_ORDERTABLE</kbd>
  2028.      *
  2029.      *   <p>Similar to <kbd>DB_TABLEINFO_ORDER</kbd> but adds more
  2030.      *   dimensions to the array in which the table names are keys and
  2031.      *   the field names are sub-keys.  This is helpful for queries that
  2032.      *   join tables which have identical field names.</p>
  2033.      *
  2034.      *   <pre>
  2035.      *   [num_fields] => 3
  2036.      *   [ordertable] => Array (
  2037.      *       [tblFoo] => Array (
  2038.      *           [fldId] => 0
  2039.      *           [fldPhone] => 1
  2040.      *       )
  2041.      *       [tblBar] => Array (
  2042.      *           [fldId] => 2
  2043.      *       )
  2044.      *   )
  2045.      *   </pre>
  2046.      *
  2047.      * </li>
  2048.      * </ul>
  2049.      *
  2050.      * The <samp>flags</samp> element contains a space separated list
  2051.      * of extra information about the field.  This data is inconsistent
  2052.      * between DBMS's due to the way each DBMS works.
  2053.      *   + <samp>primary_key</samp>
  2054.      *   + <samp>unique_key</samp>
  2055.      *   + <samp>multiple_key</samp>
  2056.      *   + <samp>not_null</samp>
  2057.      *
  2058.      * Most DBMS's only provide the <samp>table</samp> and <samp>flags</samp>
  2059.      * elements if <var>$result</var> is a table name.  The following DBMS's
  2060.      * provide full information from queries:
  2061.      *   + fbsql
  2062.      *   + mysql
  2063.      *
  2064.      * If the 'portability' option has <samp>DB_PORTABILITY_LOWERCASE</samp>
  2065.      * turned on, the names of tables and fields will be lowercased.
  2066.      *
  2067.      * @param object|string $result  DB_result object from a query or a
  2068.      *                                 string containing the name of a table.
  2069.      *                                 While this also accepts a query result
  2070.      *                                 resource identifier, this behavior is
  2071.      *                                 deprecated.
  2072.      * @param int  $mode   either unused or one of the tableInfo modes:
  2073.      *                      <kbd>DB_TABLEINFO_ORDERTABLE</kbd>,
  2074.      *                      <kbd>DB_TABLEINFO_ORDER</kbd> or
  2075.      *                      <kbd>DB_TABLEINFO_FULL</kbd> (which does both).
  2076.      *                      These are bitwise, so the first two can be
  2077.      *                      combined using <kbd>|</kbd>.
  2078.      *
  2079.      * @return array  an associative array with the information requested.
  2080.      *                  A DB_Error object on failure.
  2081.      *
  2082.      * @see DB_common::setOption()
  2083.      */
  2084.     function tableInfo($result$mode null)
  2085.     {
  2086.         /*
  2087.          * If the DB_<driver> class has a tableInfo() method, that one
  2088.          * overrides this one.  But, if the driver doesn't have one,
  2089.          * this method runs and tells users about that fact.
  2090.          */
  2091.         return $this->raiseError(DB_ERROR_NOT_CAPABLE);
  2092.     }
  2093.  
  2094.     // }}}
  2095.     // {{{ getTables()
  2096.  
  2097.     /**
  2098.      * Lists the tables in the current database
  2099.      *
  2100.      * @return array  the list of tables.  A DB_Error object on failure.
  2101.      *
  2102.      * @deprecated Method deprecated some time before Release 1.2
  2103.      */
  2104.     function getTables()
  2105.     {
  2106.         return $this->getListOf('tables');
  2107.     }
  2108.  
  2109.     // }}}
  2110.     // {{{ getListOf()
  2111.  
  2112.     /**
  2113.      * Lists internal database information
  2114.      *
  2115.      * @param string $type  type of information being sought.
  2116.      *                        Common items being sought are:
  2117.      *                        tables, databases, users, views, functions
  2118.      *                        Each DBMS's has its own capabilities.
  2119.      *
  2120.      * @return array  an array listing the items sought.
  2121.      *                  A DB DB_Error object on failure.
  2122.      */
  2123.     function getListOf($type)
  2124.     {
  2125.         $sql $this->getSpecialQuery($type);
  2126.         if ($sql === null{
  2127.             $this->last_query = '';
  2128.             return $this->raiseError(DB_ERROR_UNSUPPORTED);
  2129.         elseif (is_int($sql|| DB::isError($sql)) {
  2130.             // Previous error
  2131.             return $this->raiseError($sql);
  2132.         elseif (is_array($sql)) {
  2133.             // Already the result
  2134.             return $sql;
  2135.         }
  2136.         // Launch this query
  2137.         return $this->getCol($sql);
  2138.     }
  2139.  
  2140.     // }}}
  2141.     // {{{ getSpecialQuery()
  2142.  
  2143.     /**
  2144.      * Obtains the query string needed for listing a given type of objects
  2145.      *
  2146.      * @param string $type  the kind of objects you want to retrieve
  2147.      *
  2148.      * @return string  the SQL query string or null if the driver doesn't
  2149.      *                   support the object type requested
  2150.      *
  2151.      * @access protected
  2152.      * @see DB_common::getListOf()
  2153.      */
  2154.     function getSpecialQuery($type)
  2155.     {
  2156.         return $this->raiseError(DB_ERROR_UNSUPPORTED);
  2157.     }
  2158.  
  2159.     // }}}
  2160.     // {{{ nextQueryIsManip()
  2161.  
  2162.     /**
  2163.      * Sets (or unsets) a flag indicating that the next query will be a
  2164.      * manipulation query, regardless of the usual DB::isManip() heuristics.
  2165.      *
  2166.      * @param boolean true to set the flag overriding the isManip() behaviour,
  2167.      *  false to clear it and fall back onto isManip()
  2168.      *
  2169.      * @return void 
  2170.      *
  2171.      * @access public
  2172.      */
  2173.     function nextQueryIsManip($manip)
  2174.     {
  2175.         $this->_next_query_manip = $manip;
  2176.     }
  2177.  
  2178.     // }}}
  2179.     // {{{ _checkManip()
  2180.  
  2181.     /**
  2182.      * Checks if the given query is a manipulation query. This also takes into
  2183.      * account the _next_query_manip flag and sets the _last_query_manip flag
  2184.      * (and resets _next_query_manip) according to the result.
  2185.      *
  2186.      * @param string The query to check.
  2187.      *
  2188.      * @return boolean true if the query is a manipulation query, false
  2189.      *  otherwise
  2190.      *
  2191.      * @access protected
  2192.      */
  2193.     function _checkManip($query)
  2194.     {
  2195.         if ($this->_next_query_manip || DB::isManip($query)) {
  2196.             $this->_last_query_manip = true;
  2197.         else {
  2198.             $this->_last_query_manip = false;
  2199.         }
  2200.         $this->_next_query_manip = false;
  2201.         return $this->_last_query_manip;
  2202.         $manip $this->_next_query_manip;
  2203.     }
  2204.  
  2205.     // }}}
  2206.     // {{{ _rtrimArrayValues()
  2207.  
  2208.     /**
  2209.      * Right-trims all strings in an array
  2210.      *
  2211.      * @param array $array  the array to be trimmed (passed by reference)
  2212.      *
  2213.      * @return void 
  2214.      *
  2215.      * @access protected
  2216.      */
  2217.     function _rtrimArrayValues(&$array)
  2218.     {
  2219.         foreach ($array as $key => $value{
  2220.             if (is_string($value)) {
  2221.                 $array[$keyrtrim($value);
  2222.             }
  2223.         }
  2224.     }
  2225.  
  2226.     // }}}
  2227.     // {{{ _convertNullArrayValuesToEmpty()
  2228.  
  2229.     /**
  2230.      * Converts all null values in an array to empty strings
  2231.      *
  2232.      * @param array  $array  the array to be de-nullified (passed by reference)
  2233.      *
  2234.      * @return void 
  2235.      *
  2236.      * @access protected
  2237.      */
  2238.     function _convertNullArrayValuesToEmpty(&$array)
  2239.     {
  2240.         foreach ($array as $key => $value{
  2241.             if (is_null($value)) {
  2242.                 $array[$key'';
  2243.             }
  2244.         }
  2245.     }
  2246.  
  2247.     // }}}
  2248. }
  2249.  
  2250. /*
  2251.  * Local variables:
  2252.  * tab-width: 4
  2253.  * c-basic-offset: 4
  2254.  * End:
  2255.  */
  2256.  
  2257. ?>

Documentation generated on Wed, 09 Feb 2011 08:59:06 +0700 by phpDocumentor 1.4.2