[ Index ]
 

Code source de PHP PEAR 1.4.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/DB/ -> common.php (source)

   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-2005 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.140 2007/01/12 02:41:07 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  '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-2005 The PHP Group
  44   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  45   * @version    Release: 1.7.9
  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($string, 1, -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[$k] = implode(' ', $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($table, array_keys($fields_values), $mode,
 890                                    $where);
 891          if (DB::isError($sth)) {
 892              return $sth;
 893          }
 894          $ret =& $this->execute($sth, array_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($fp, filesize($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($params) > 0) {
1207              $sth = $this->prepare($query);
1208              if (DB::isError($sth)) {
1209                  return $sth;
1210              }
1211              $ret =& $this->execute($sth, $params);
1212              $this->freePrepared($sth, false);
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($params) > 0) {
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($row, DB_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($params) > 0) {
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($params) > 0) {
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($col) ? DB_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($params) > 0) {
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 > 2 || $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($params) > 0) {
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($code, null, $mode, $options,
1888                                      null, null, true);
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[$key] = rtrim($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  ?>


Généré le : Sun Feb 25 14:08:00 2007 par Balluche grâce à PHPXref 0.7