inc/dal.inc.php
changeset 8 47dd15d8bb8c
parent 7 ac0ca51809b1
child 9 d55459cd1712
equal deleted inserted replaced
7:ac0ca51809b1 8:47dd15d8bb8c
     1 <?php
       
     2 
       
     3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
       
     4 
       
     5 /**
       
     6  * Database independent query interface
       
     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: DB.php,v 1.80 2005/02/16 02:16:00 danielc 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 // {{{ constants
       
    34 // {{{ error codes
       
    35 
       
    36 /**#@+
       
    37  * One of PEAR DB's portable error codes.
       
    38  * @see DB_common::errorCode(), DB::errorMessage()
       
    39  *
       
    40  * {@internal If you add an error code here, make sure you also add a textual
       
    41  * version of it in DB::errorMessage().}}
       
    42  */
       
    43 
       
    44 /**
       
    45  * The code returned by many methods upon success
       
    46  */
       
    47 define('DB_OK', 1);
       
    48 
       
    49 /**
       
    50  * Unkown error
       
    51  */
       
    52 define('DB_ERROR', -1);
       
    53 
       
    54 /**
       
    55  * Syntax error
       
    56  */
       
    57 define('DB_ERROR_SYNTAX', -2);
       
    58 
       
    59 /**
       
    60  * Tried to insert a duplicate value into a primary or unique index
       
    61  */
       
    62 define('DB_ERROR_CONSTRAINT', -3);
       
    63 
       
    64 /**
       
    65  * An identifier in the query refers to a non-existant object
       
    66  */
       
    67 define('DB_ERROR_NOT_FOUND', -4);
       
    68 
       
    69 /**
       
    70  * Tried to create a duplicate object
       
    71  */
       
    72 define('DB_ERROR_ALREADY_EXISTS', -5);
       
    73 
       
    74 /**
       
    75  * The current driver does not support the action you attempted
       
    76  */
       
    77 define('DB_ERROR_UNSUPPORTED', -6);
       
    78 
       
    79 /**
       
    80  * The number of parameters does not match the number of placeholders
       
    81  */
       
    82 define('DB_ERROR_MISMATCH', -7);
       
    83 
       
    84 /**
       
    85  * A literal submitted did not match the data type expected
       
    86  */
       
    87 define('DB_ERROR_INVALID', -8);
       
    88 
       
    89 /**
       
    90  * The current DBMS does not support the action you attempted
       
    91  */
       
    92 define('DB_ERROR_NOT_CAPABLE', -9);
       
    93 
       
    94 /**
       
    95  * A literal submitted was too long so the end of it was removed
       
    96  */
       
    97 define('DB_ERROR_TRUNCATED', -10);
       
    98 
       
    99 /**
       
   100  * A literal number submitted did not match the data type expected
       
   101  */
       
   102 define('DB_ERROR_INVALID_NUMBER', -11);
       
   103 
       
   104 /**
       
   105  * A literal date submitted did not match the data type expected
       
   106  */
       
   107 define('DB_ERROR_INVALID_DATE', -12);
       
   108 
       
   109 /**
       
   110  * Attempt to divide something by zero
       
   111  */
       
   112 define('DB_ERROR_DIVZERO', -13);
       
   113 
       
   114 /**
       
   115  * A database needs to be selected
       
   116  */
       
   117 define('DB_ERROR_NODBSELECTED', -14);
       
   118 
       
   119 /**
       
   120  * Could not create the object requested
       
   121  */
       
   122 define('DB_ERROR_CANNOT_CREATE', -15);
       
   123 
       
   124 /**
       
   125  * Could not drop the database requested because it does not exist
       
   126  */
       
   127 define('DB_ERROR_CANNOT_DROP', -17);
       
   128 
       
   129 /**
       
   130  * An identifier in the query refers to a non-existant table
       
   131  */
       
   132 define('DB_ERROR_NOSUCHTABLE', -18);
       
   133 
       
   134 /**
       
   135  * An identifier in the query refers to a non-existant column
       
   136  */
       
   137 define('DB_ERROR_NOSUCHFIELD', -19);
       
   138 
       
   139 /**
       
   140  * The data submitted to the method was inappropriate
       
   141  */
       
   142 define('DB_ERROR_NEED_MORE_DATA', -20);
       
   143 
       
   144 /**
       
   145  * The attempt to lock the table failed
       
   146  */
       
   147 define('DB_ERROR_NOT_LOCKED', -21);
       
   148 
       
   149 /**
       
   150  * The number of columns doesn't match the number of values
       
   151  */
       
   152 define('DB_ERROR_VALUE_COUNT_ON_ROW', -22);
       
   153 
       
   154 /**
       
   155  * The DSN submitted has problems
       
   156  */
       
   157 define('DB_ERROR_INVALID_DSN', -23);
       
   158 
       
   159 /**
       
   160  * Could not connect to the database
       
   161  */
       
   162 define('DB_ERROR_CONNECT_FAILED', -24);
       
   163 
       
   164 /**
       
   165  * The PHP extension needed for this DBMS could not be found
       
   166  */
       
   167 define('DB_ERROR_EXTENSION_NOT_FOUND',-25);
       
   168 
       
   169 /**
       
   170  * The present user has inadequate permissions to perform the task requestd
       
   171  */
       
   172 define('DB_ERROR_ACCESS_VIOLATION', -26);
       
   173 
       
   174 /**
       
   175  * The database requested does not exist
       
   176  */
       
   177 define('DB_ERROR_NOSUCHDB', -27);
       
   178 
       
   179 /**
       
   180  * Tried to insert a null value into a column that doesn't allow nulls
       
   181  */
       
   182 define('DB_ERROR_CONSTRAINT_NOT_NULL',-29);
       
   183 /**#@-*/
       
   184 
       
   185 
       
   186 // }}}
       
   187 // {{{ prepared statement-related
       
   188 
       
   189 
       
   190 /**#@+
       
   191  * Identifiers for the placeholders used in prepared statements.
       
   192  * @see DB_common::prepare()
       
   193  */
       
   194 
       
   195 /**
       
   196  * Indicates a scalar (<kbd>?</kbd>) placeholder was used
       
   197  *
       
   198  * Quote and escape the value as necessary.
       
   199  */
       
   200 define('DB_PARAM_SCALAR', 1);
       
   201 
       
   202 /**
       
   203  * Indicates an opaque (<kbd>&</kbd>) placeholder was used
       
   204  *
       
   205  * The value presented is a file name.  Extract the contents of that file
       
   206  * and place them in this column.
       
   207  */
       
   208 define('DB_PARAM_OPAQUE', 2);
       
   209 
       
   210 /**
       
   211  * Indicates a misc (<kbd>!</kbd>) placeholder was used
       
   212  *
       
   213  * The value should not be quoted or escaped.
       
   214  */
       
   215 define('DB_PARAM_MISC',   3);
       
   216 /**#@-*/
       
   217 
       
   218 
       
   219 // }}}
       
   220 // {{{ binary data-related
       
   221 
       
   222 
       
   223 /**#@+
       
   224  * The different ways of returning binary data from queries.
       
   225  */
       
   226 
       
   227 /**
       
   228  * Sends the fetched data straight through to output
       
   229  */
       
   230 define('DB_BINMODE_PASSTHRU', 1);
       
   231 
       
   232 /**
       
   233  * Lets you return data as usual
       
   234  */
       
   235 define('DB_BINMODE_RETURN', 2);
       
   236 
       
   237 /**
       
   238  * Converts the data to hex format before returning it
       
   239  *
       
   240  * For example the string "123" would become "313233".
       
   241  */
       
   242 define('DB_BINMODE_CONVERT', 3);
       
   243 /**#@-*/
       
   244 
       
   245 
       
   246 // }}}
       
   247 // {{{ fetch modes
       
   248 
       
   249 
       
   250 /**#@+
       
   251  * Fetch Modes.
       
   252  * @see DB_common::setFetchMode()
       
   253  */
       
   254 
       
   255 /**
       
   256  * Indicates the current default fetch mode should be used
       
   257  * @see DB_common::$fetchmode
       
   258  */
       
   259 define('DB_FETCHMODE_DEFAULT', 0);
       
   260 
       
   261 /**
       
   262  * Column data indexed by numbers, ordered from 0 and up
       
   263  */
       
   264 define('DB_FETCHMODE_ORDERED', 1);
       
   265 
       
   266 /**
       
   267  * Column data indexed by column names
       
   268  */
       
   269 define('DB_FETCHMODE_ASSOC', 2);
       
   270 
       
   271 /**
       
   272  * Column data as object properties
       
   273  */
       
   274 define('DB_FETCHMODE_OBJECT', 3);
       
   275 
       
   276 /**
       
   277  * For multi-dimensional results, make the column name the first level
       
   278  * of the array and put the row number in the second level of the array
       
   279  *
       
   280  * This is flipped from the normal behavior, which puts the row numbers
       
   281  * in the first level of the array and the column names in the second level.
       
   282  */
       
   283 define('DB_FETCHMODE_FLIPPED', 4);
       
   284 /**#@-*/
       
   285 
       
   286 /**#@+
       
   287  * Old fetch modes.  Left here for compatibility.
       
   288  */
       
   289 define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
       
   290 define('DB_GETMODE_ASSOC',   DB_FETCHMODE_ASSOC);
       
   291 define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED);
       
   292 /**#@-*/
       
   293 
       
   294 
       
   295 // }}}
       
   296 // {{{ tableInfo() && autoPrepare()-related
       
   297 
       
   298 
       
   299 /**#@+
       
   300  * The type of information to return from the tableInfo() method.
       
   301  *
       
   302  * Bitwised constants, so they can be combined using <kbd>|</kbd>
       
   303  * and removed using <kbd>^</kbd>.
       
   304  *
       
   305  * @see DB_common::tableInfo()
       
   306  *
       
   307  * {@internal Since the TABLEINFO constants are bitwised, if more of them are
       
   308  * added in the future, make sure to adjust DB_TABLEINFO_FULL accordingly.}}
       
   309  */
       
   310 define('DB_TABLEINFO_ORDER', 1);
       
   311 define('DB_TABLEINFO_ORDERTABLE', 2);
       
   312 define('DB_TABLEINFO_FULL', 3);
       
   313 /**#@-*/
       
   314 
       
   315 
       
   316 /**#@+
       
   317  * The type of query to create with the automatic query building methods.
       
   318  * @see DB_common::autoPrepare(), DB_common::autoExecute()
       
   319  */
       
   320 define('DB_AUTOQUERY_INSERT', 1);
       
   321 define('DB_AUTOQUERY_UPDATE', 2);
       
   322 /**#@-*/
       
   323 
       
   324 
       
   325 // }}}
       
   326 // {{{ portability modes
       
   327 
       
   328 
       
   329 /**#@+
       
   330  * Portability Modes.
       
   331  *
       
   332  * Bitwised constants, so they can be combined using <kbd>|</kbd>
       
   333  * and removed using <kbd>^</kbd>.
       
   334  *
       
   335  * @see DB_common::setOption()
       
   336  *
       
   337  * {@internal Since the PORTABILITY constants are bitwised, if more of them are
       
   338  * added in the future, make sure to adjust DB_PORTABILITY_ALL accordingly.}}
       
   339  */
       
   340 
       
   341 /**
       
   342  * Turn off all portability features
       
   343  */
       
   344 define('DB_PORTABILITY_NONE', 0);
       
   345 
       
   346 /**
       
   347  * Convert names of tables and fields to lower case
       
   348  * when using the get*(), fetch*() and tableInfo() methods
       
   349  */
       
   350 define('DB_PORTABILITY_LOWERCASE', 1);
       
   351 
       
   352 /**
       
   353  * Right trim the data output by get*() and fetch*()
       
   354  */
       
   355 define('DB_PORTABILITY_RTRIM', 2);
       
   356 
       
   357 /**
       
   358  * Force reporting the number of rows deleted
       
   359  */
       
   360 define('DB_PORTABILITY_DELETE_COUNT', 4);
       
   361 
       
   362 /**
       
   363  * Enable hack that makes numRows() work in Oracle
       
   364  */
       
   365 define('DB_PORTABILITY_NUMROWS', 8);
       
   366 
       
   367 /**
       
   368  * Makes certain error messages in certain drivers compatible
       
   369  * with those from other DBMS's
       
   370  *
       
   371  * + mysql, mysqli:  change unique/primary key constraints
       
   372  *   DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT
       
   373  *
       
   374  * + odbc(access):  MS's ODBC driver reports 'no such field' as code
       
   375  *   07001, which means 'too few parameters.'  When this option is on
       
   376  *   that code gets mapped to DB_ERROR_NOSUCHFIELD.
       
   377  */
       
   378 define('DB_PORTABILITY_ERRORS', 16);
       
   379 
       
   380 /**
       
   381  * Convert null values to empty strings in data output by
       
   382  * get*() and fetch*()
       
   383  */
       
   384 define('DB_PORTABILITY_NULL_TO_EMPTY', 32);
       
   385 
       
   386 /**
       
   387  * Turn on all portability features
       
   388  */
       
   389 define('DB_PORTABILITY_ALL', 63);
       
   390 /**#@-*/
       
   391 
       
   392 // }}}
       
   393 
       
   394 
       
   395 // }}}
       
   396 // {{{ class DB
       
   397 
       
   398 /**
       
   399  * Database independent query interface
       
   400  *
       
   401  * The main "DB" class is simply a container class with some static
       
   402  * methods for creating DB objects as well as some utility functions
       
   403  * common to all parts of DB.
       
   404  *
       
   405  * The object model of DB is as follows (indentation means inheritance):
       
   406  * <pre>
       
   407  * DB           The main DB class.  This is simply a utility class
       
   408  *              with some "static" methods for creating DB objects as
       
   409  *              well as common utility functions for other DB classes.
       
   410  *
       
   411  * DB_common    The base for each DB implementation.  Provides default
       
   412  * |            implementations (in OO lingo virtual methods) for
       
   413  * |            the actual DB implementations as well as a bunch of
       
   414  * |            query utility functions.
       
   415  * |
       
   416  * +-DB_mysql   The DB implementation for MySQL.  Inherits DB_common.
       
   417  *              When calling DB::factory or DB::connect for MySQL
       
   418  *              connections, the object returned is an instance of this
       
   419  *              class.
       
   420  * </pre>
       
   421  *
       
   422  * @category   Database
       
   423  * @package    DB
       
   424  * @author     Stig Bakken <ssb@php.net>
       
   425  * @author     Tomas V.V.Cox <cox@idecnet.com>
       
   426  * @author     Daniel Convissor <danielc@php.net>
       
   427  * @copyright  1997-2005 The PHP Group
       
   428  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
       
   429  * @version    Release: @package_version@
       
   430  * @link       http://pear.php.net/package/DB
       
   431  */
       
   432 class DB
       
   433 {
       
   434     // {{{ &factory()
       
   435 
       
   436     /**
       
   437      * Create a new DB object for the specified database type but don't
       
   438      * connect to the database
       
   439      *
       
   440      * @param string $type     the database type (eg "mysql")
       
   441      * @param array  $options  an associative array of option names and values
       
   442      *
       
   443      * @return object  a new DB object.  A DB_Error object on failure.
       
   444      *
       
   445      * @see DB_common::setOption()
       
   446      */
       
   447     function &factory($type, $options = false)
       
   448     {
       
   449         if (!is_array($options)) {
       
   450             $options = array('persistent' => $options);
       
   451         }
       
   452 
       
   453         if (isset($options['debug']) && $options['debug'] >= 2) {
       
   454             // expose php errors with sufficient debug level
       
   455             include_once "DB/{$type}.php";
       
   456         } else {
       
   457             @include_once "DB/{$type}.php";
       
   458         }
       
   459 
       
   460         $classname = "DB_${type}";
       
   461 
       
   462         if (!class_exists($classname)) {
       
   463             $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null,
       
   464                                     "Unable to include the DB/{$type}.php"
       
   465                                     . " file for '$dsn'",
       
   466                                     'DB_Error', true);
       
   467             return $tmp;
       
   468         }
       
   469 
       
   470         @$obj =& new $classname;
       
   471 
       
   472         foreach ($options as $option => $value) {
       
   473             $test = $obj->setOption($option, $value);
       
   474             if (DB::isError($test)) {
       
   475                 return $test;
       
   476             }
       
   477         }
       
   478 
       
   479         return $obj;
       
   480     }
       
   481 
       
   482     // }}}
       
   483     // {{{ &connect()
       
   484 
       
   485     /**
       
   486      * Create a new DB object including a connection to the specified database
       
   487      *
       
   488      * Example 1.
       
   489      * <code>
       
   490      * require_once 'DB.php';
       
   491      *
       
   492      * $dsn = 'pgsql://user:password@host/database';
       
   493      * $options = array(
       
   494      *     'debug'       => 2,
       
   495      *     'portability' => DB_PORTABILITY_ALL,
       
   496      * );
       
   497      *
       
   498      * $db =& DB::connect($dsn, $options);
       
   499      * if (PEAR::isError($db)) {
       
   500      *     die($db->getMessage());
       
   501      * }
       
   502      * </code>
       
   503      *
       
   504      * @param mixed $dsn      the string "data source name" or array in the
       
   505      *                         format returned by DB::parseDSN()
       
   506      * @param array $options  an associative array of option names and values
       
   507      *
       
   508      * @return object  a new DB object.  A DB_Error object on failure.
       
   509      *
       
   510      * @uses DB_dbase::connect(), DB_fbsql::connect(), DB_ibase::connect(),
       
   511      *       DB_ifx::connect(), DB_msql::connect(), DB_mssql::connect(),
       
   512      *       DB_mysql::connect(), DB_mysqli::connect(), DB_oci8::connect(),
       
   513      *       DB_odbc::connect(), DB_pgsql::connect(), DB_sqlite::connect(),
       
   514      *       DB_sybase::connect()
       
   515      *
       
   516      * @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError()
       
   517      */
       
   518     function &connect($dsn, $options = array())
       
   519     {
       
   520         $dsninfo = DB::parseDSN($dsn);
       
   521         $type = $dsninfo['phptype'];
       
   522 
       
   523         if (!is_array($options)) {
       
   524             /*
       
   525              * For backwards compatibility.  $options used to be boolean,
       
   526              * indicating whether the connection should be persistent.
       
   527              */
       
   528             $options = array('persistent' => $options);
       
   529         }
       
   530 
       
   531         if (isset($options['debug']) && $options['debug'] >= 2) {
       
   532             // expose php errors with sufficient debug level
       
   533             include_once "DB/${type}.php";
       
   534         } else {
       
   535             @include_once "DB/${type}.php";
       
   536         }
       
   537 
       
   538         $classname = "DB_${type}";
       
   539         if (!class_exists($classname)) {
       
   540             $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null,
       
   541                                     "Unable to include the DB/{$type}.php"
       
   542                                     . " file for '$dsn'",
       
   543                                     'DB_Error', true);
       
   544             return $tmp;
       
   545         }
       
   546 
       
   547         @$obj =& new $classname;
       
   548 
       
   549         foreach ($options as $option => $value) {
       
   550             $test = $obj->setOption($option, $value);
       
   551             if (DB::isError($test)) {
       
   552                 return $test;
       
   553             }
       
   554         }
       
   555 
       
   556         $err = $obj->connect($dsninfo, $obj->getOption('persistent'));
       
   557         if (DB::isError($err)) {
       
   558             $err->addUserInfo($dsn);
       
   559             return $err;
       
   560         }
       
   561 
       
   562         return $obj;
       
   563     }
       
   564 
       
   565     // }}}
       
   566     // {{{ apiVersion()
       
   567 
       
   568     /**
       
   569      * Return the DB API version
       
   570      *
       
   571      * @return string  the DB API version number
       
   572      */
       
   573     function apiVersion()
       
   574     {
       
   575         return '@package_version@';
       
   576     }
       
   577 
       
   578     // }}}
       
   579     // {{{ isError()
       
   580 
       
   581     /**
       
   582      * Determines if a variable is a DB_Error object
       
   583      *
       
   584      * @param mixed $value  the variable to check
       
   585      *
       
   586      * @return bool  whether $value is DB_Error object
       
   587      */
       
   588     function isError($value)
       
   589     {
       
   590         return is_a($value, 'DB_Error');
       
   591     }
       
   592 
       
   593     // }}}
       
   594     // {{{ isConnection()
       
   595 
       
   596     /**
       
   597      * Determines if a value is a DB_<driver> object
       
   598      *
       
   599      * @param mixed $value  the value to test
       
   600      *
       
   601      * @return bool  whether $value is a DB_<driver> object
       
   602      */
       
   603     function isConnection($value)
       
   604     {
       
   605         return (is_object($value) &&
       
   606                 is_subclass_of($value, 'db_common') &&
       
   607                 method_exists($value, 'simpleQuery'));
       
   608     }
       
   609 
       
   610     // }}}
       
   611     // {{{ isManip()
       
   612 
       
   613     /**
       
   614      * Tell whether a query is a data manipulation or data definition query
       
   615      *
       
   616      * Examples of data manipulation queries are INSERT, UPDATE and DELETE.
       
   617      * Examples of data definition queries are CREATE, DROP, ALTER, GRANT,
       
   618      * REVOKE.
       
   619      *
       
   620      * @param string $query  the query
       
   621      *
       
   622      * @return boolean  whether $query is a data manipulation query
       
   623      */
       
   624     function isManip($query)
       
   625     {
       
   626         $manips = 'INSERT|UPDATE|DELETE|REPLACE|'
       
   627                 . 'CREATE|DROP|'
       
   628                 . 'LOAD DATA|SELECT .* INTO|COPY|'
       
   629                 . 'ALTER|GRANT|REVOKE|'
       
   630                 . 'LOCK|UNLOCK';
       
   631         if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) {
       
   632             return true;
       
   633         }
       
   634         return false;
       
   635     }
       
   636 
       
   637     // }}}
       
   638     // {{{ errorMessage()
       
   639 
       
   640     /**
       
   641      * Return a textual error message for a DB error code
       
   642      *
       
   643      * @param integer $value  the DB error code
       
   644      *
       
   645      * @return string  the error message or false if the error code was
       
   646      *                  not recognized
       
   647      */
       
   648     function errorMessage($value)
       
   649     {
       
   650         static $errorMessages;
       
   651         if (!isset($errorMessages)) {
       
   652             $errorMessages = array(
       
   653                 DB_ERROR                    => 'unknown error',
       
   654                 DB_ERROR_ACCESS_VIOLATION   => 'insufficient permissions',
       
   655                 DB_ERROR_ALREADY_EXISTS     => 'already exists',
       
   656                 DB_ERROR_CANNOT_CREATE      => 'can not create',
       
   657                 DB_ERROR_CANNOT_DROP        => 'can not drop',
       
   658                 DB_ERROR_CONNECT_FAILED     => 'connect failed',
       
   659                 DB_ERROR_CONSTRAINT         => 'constraint violation',
       
   660                 DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint',
       
   661                 DB_ERROR_DIVZERO            => 'division by zero',
       
   662                 DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
       
   663                 DB_ERROR_INVALID            => 'invalid',
       
   664                 DB_ERROR_INVALID_DATE       => 'invalid date or time',
       
   665                 DB_ERROR_INVALID_DSN        => 'invalid DSN',
       
   666                 DB_ERROR_INVALID_NUMBER     => 'invalid number',
       
   667                 DB_ERROR_MISMATCH           => 'mismatch',
       
   668                 DB_ERROR_NEED_MORE_DATA     => 'insufficient data supplied',
       
   669                 DB_ERROR_NODBSELECTED       => 'no database selected',
       
   670                 DB_ERROR_NOSUCHDB           => 'no such database',
       
   671                 DB_ERROR_NOSUCHFIELD        => 'no such field',
       
   672                 DB_ERROR_NOSUCHTABLE        => 'no such table',
       
   673                 DB_ERROR_NOT_CAPABLE        => 'DB backend not capable',
       
   674                 DB_ERROR_NOT_FOUND          => 'not found',
       
   675                 DB_ERROR_NOT_LOCKED         => 'not locked',
       
   676                 DB_ERROR_SYNTAX             => 'syntax error',
       
   677                 DB_ERROR_UNSUPPORTED        => 'not supported',
       
   678                 DB_ERROR_TRUNCATED          => 'truncated',
       
   679                 DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
       
   680                 DB_OK                       => 'no error',
       
   681             );
       
   682         }
       
   683 
       
   684         if (DB::isError($value)) {
       
   685             $value = $value->getCode();
       
   686         }
       
   687 
       
   688         return isset($errorMessages[$value]) ? $errorMessages[$value]
       
   689                      : $errorMessages[DB_ERROR];
       
   690     }
       
   691 
       
   692     // }}}
       
   693     // {{{ parseDSN()
       
   694 
       
   695     /**
       
   696      * Parse a data source name
       
   697      *
       
   698      * Additional keys can be added by appending a URI query string to the
       
   699      * end of the DSN.
       
   700      *
       
   701      * The format of the supplied DSN is in its fullest form:
       
   702      * <code>
       
   703      *  phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true
       
   704      * </code>
       
   705      *
       
   706      * Most variations are allowed:
       
   707      * <code>
       
   708      *  phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644
       
   709      *  phptype://username:password@hostspec/database_name
       
   710      *  phptype://username:password@hostspec
       
   711      *  phptype://username@hostspec
       
   712      *  phptype://hostspec/database
       
   713      *  phptype://hostspec
       
   714      *  phptype(dbsyntax)
       
   715      *  phptype
       
   716      * </code>
       
   717      *
       
   718      * @param string $dsn Data Source Name to be parsed
       
   719      *
       
   720      * @return array an associative array with the following keys:
       
   721      *  + phptype:  Database backend used in PHP (mysql, odbc etc.)
       
   722      *  + dbsyntax: Database used with regards to SQL syntax etc.
       
   723      *  + protocol: Communication protocol to use (tcp, unix etc.)
       
   724      *  + hostspec: Host specification (hostname[:port])
       
   725      *  + database: Database to use on the DBMS server
       
   726      *  + username: User name for login
       
   727      *  + password: Password for login
       
   728      */
       
   729     function parseDSN($dsn)
       
   730     {
       
   731         $parsed = array(
       
   732             'phptype'  => false,
       
   733             'dbsyntax' => false,
       
   734             'username' => false,
       
   735             'password' => false,
       
   736             'protocol' => false,
       
   737             'hostspec' => false,
       
   738             'port'     => false,
       
   739             'socket'   => false,
       
   740             'database' => false,
       
   741         );
       
   742 
       
   743         if (is_array($dsn)) {
       
   744             $dsn = array_merge($parsed, $dsn);
       
   745             if (!$dsn['dbsyntax']) {
       
   746                 $dsn['dbsyntax'] = $dsn['phptype'];
       
   747             }
       
   748             return $dsn;
       
   749         }
       
   750 
       
   751         // Find phptype and dbsyntax
       
   752         if (($pos = strpos($dsn, '://')) !== false) {
       
   753             $str = substr($dsn, 0, $pos);
       
   754             $dsn = substr($dsn, $pos + 3);
       
   755         } else {
       
   756             $str = $dsn;
       
   757             $dsn = null;
       
   758         }
       
   759 
       
   760         // Get phptype and dbsyntax
       
   761         // $str => phptype(dbsyntax)
       
   762         if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
       
   763             $parsed['phptype']  = $arr[1];
       
   764             $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2];
       
   765         } else {
       
   766             $parsed['phptype']  = $str;
       
   767             $parsed['dbsyntax'] = $str;
       
   768         }
       
   769 
       
   770         if (!count($dsn)) {
       
   771             return $parsed;
       
   772         }
       
   773 
       
   774         // Get (if found): username and password
       
   775         // $dsn => username:password@protocol+hostspec/database
       
   776         if (($at = strrpos($dsn,'@')) !== false) {
       
   777             $str = substr($dsn, 0, $at);
       
   778             $dsn = substr($dsn, $at + 1);
       
   779             if (($pos = strpos($str, ':')) !== false) {
       
   780                 $parsed['username'] = rawurldecode(substr($str, 0, $pos));
       
   781                 $parsed['password'] = rawurldecode(substr($str, $pos + 1));
       
   782             } else {
       
   783                 $parsed['username'] = rawurldecode($str);
       
   784             }
       
   785         }
       
   786 
       
   787         // Find protocol and hostspec
       
   788 
       
   789         if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) {
       
   790             // $dsn => proto(proto_opts)/database
       
   791             $proto       = $match[1];
       
   792             $proto_opts  = $match[2] ? $match[2] : false;
       
   793             $dsn         = $match[3];
       
   794 
       
   795         } else {
       
   796             // $dsn => protocol+hostspec/database (old format)
       
   797             if (strpos($dsn, '+') !== false) {
       
   798                 list($proto, $dsn) = explode('+', $dsn, 2);
       
   799             }
       
   800             if (strpos($dsn, '/') !== false) {
       
   801                 list($proto_opts, $dsn) = explode('/', $dsn, 2);
       
   802             } else {
       
   803                 $proto_opts = $dsn;
       
   804                 $dsn = null;
       
   805             }
       
   806         }
       
   807 
       
   808         // process the different protocol options
       
   809         $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
       
   810         $proto_opts = rawurldecode($proto_opts);
       
   811         if ($parsed['protocol'] == 'tcp') {
       
   812             if (strpos($proto_opts, ':') !== false) {
       
   813                 list($parsed['hostspec'],
       
   814                      $parsed['port']) = explode(':', $proto_opts);
       
   815             } else {
       
   816                 $parsed['hostspec'] = $proto_opts;
       
   817             }
       
   818         } elseif ($parsed['protocol'] == 'unix') {
       
   819             $parsed['socket'] = $proto_opts;
       
   820         }
       
   821 
       
   822         // Get dabase if any
       
   823         // $dsn => database
       
   824         if ($dsn) {
       
   825             if (($pos = strpos($dsn, '?')) === false) {
       
   826                 // /database
       
   827                 $parsed['database'] = rawurldecode($dsn);
       
   828             } else {
       
   829                 // /database?param1=value1&param2=value2
       
   830                 $parsed['database'] = rawurldecode(substr($dsn, 0, $pos));
       
   831                 $dsn = substr($dsn, $pos + 1);
       
   832                 if (strpos($dsn, '&') !== false) {
       
   833                     $opts = explode('&', $dsn);
       
   834                 } else { // database?param1=value1
       
   835                     $opts = array($dsn);
       
   836                 }
       
   837                 foreach ($opts as $opt) {
       
   838                     list($key, $value) = explode('=', $opt);
       
   839                     if (!isset($parsed[$key])) {
       
   840                         // don't allow params overwrite
       
   841                         $parsed[$key] = rawurldecode($value);
       
   842                     }
       
   843                 }
       
   844             }
       
   845         }
       
   846 
       
   847         return $parsed;
       
   848     }
       
   849 
       
   850     // }}}
       
   851 }
       
   852 
       
   853 // }}}
       
   854 // {{{ class DB_Error
       
   855 
       
   856 /**
       
   857  * DB_Error implements a class for reporting portable database error
       
   858  * messages
       
   859  *
       
   860  * @category   Database
       
   861  * @package    DB
       
   862  * @author     Stig Bakken <ssb@php.net>
       
   863  * @copyright  1997-2005 The PHP Group
       
   864  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
       
   865  * @version    Release: @package_version@
       
   866  * @link       http://pear.php.net/package/DB
       
   867  */
       
   868 class DB_Error extends PEAR_Error
       
   869 {
       
   870     // {{{ constructor
       
   871 
       
   872     /**
       
   873      * DB_Error constructor
       
   874      *
       
   875      * @param mixed $code       DB error code, or string with error message
       
   876      * @param int   $mode       what "error mode" to operate in
       
   877      * @param int   $level      what error level to use for $mode &
       
   878      *                           PEAR_ERROR_TRIGGER
       
   879      * @param mixed $debuginfo  additional debug info, such as the last query
       
   880      *
       
   881      * @see PEAR_Error
       
   882      */
       
   883     function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
       
   884                       $level = E_USER_NOTICE, $debuginfo = null)
       
   885     {
       
   886         if (is_int($code)) {
       
   887             $this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code,
       
   888                               $mode, $level, $debuginfo);
       
   889         } else {
       
   890             $this->PEAR_Error("DB Error: $code", DB_ERROR,
       
   891                               $mode, $level, $debuginfo);
       
   892         }
       
   893     }
       
   894 
       
   895     // }}}
       
   896 }
       
   897 
       
   898 // }}}
       
   899 // {{{ class DB_result
       
   900 
       
   901 /**
       
   902  * This class implements a wrapper for a DB result set
       
   903  *
       
   904  * A new instance of this class will be returned by the DB implementation
       
   905  * after processing a query that returns data.
       
   906  *
       
   907  * @category   Database
       
   908  * @package    DB
       
   909  * @author     Stig Bakken <ssb@php.net>
       
   910  * @copyright  1997-2005 The PHP Group
       
   911  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
       
   912  * @version    Release: @package_version@
       
   913  * @link       http://pear.php.net/package/DB
       
   914  */
       
   915 class DB_result
       
   916 {
       
   917     // {{{ properties
       
   918 
       
   919     /**
       
   920      * Should results be freed automatically when there are no more rows?
       
   921      * @var boolean
       
   922      * @see DB_common::$options
       
   923      */
       
   924     var $autofree;
       
   925 
       
   926     /**
       
   927      * A reference to the DB_<driver> object
       
   928      * @var object
       
   929      */
       
   930     var $dbh;
       
   931 
       
   932     /**
       
   933      * The current default fetch mode
       
   934      * @var integer
       
   935      * @see DB_common::$fetchmode
       
   936      */
       
   937     var $fetchmode;
       
   938 
       
   939     /**
       
   940      * The name of the class into which results should be fetched when
       
   941      * DB_FETCHMODE_OBJECT is in effect
       
   942      *
       
   943      * @var string
       
   944      * @see DB_common::$fetchmode_object_class
       
   945      */
       
   946     var $fetchmode_object_class;
       
   947 
       
   948     /**
       
   949      * The number of rows to fetch from a limit query
       
   950      * @var integer
       
   951      */
       
   952     var $limit_count = null;
       
   953 
       
   954     /**
       
   955      * The row to start fetching from in limit queries
       
   956      * @var integer
       
   957      */
       
   958     var $limit_from = null;
       
   959 
       
   960     /**
       
   961      * The execute parameters that created this result
       
   962      * @var array
       
   963      * @since Property available since Release 1.7.0
       
   964      */
       
   965     var $parameters;
       
   966 
       
   967     /**
       
   968      * The query string that created this result
       
   969      *
       
   970      * Copied here incase it changes in $dbh, which is referenced
       
   971      *
       
   972      * @var string
       
   973      * @since Property available since Release 1.7.0
       
   974      */
       
   975     var $query;
       
   976 
       
   977     /**
       
   978      * The query result resource id created by PHP
       
   979      * @var resource
       
   980      */
       
   981     var $result;
       
   982 
       
   983     /**
       
   984      * The present row being dealt with
       
   985      * @var integer
       
   986      */
       
   987     var $row_counter = null;
       
   988 
       
   989     /**
       
   990      * The prepared statement resource id created by PHP in $dbh
       
   991      *
       
   992      * This resource is only available when the result set was created using
       
   993      * a driver's native execute() method, not PEAR DB's emulated one.
       
   994      *
       
   995      * Copied here incase it changes in $dbh, which is referenced
       
   996      *
       
   997      * {@internal  Mainly here because the InterBase/Firebird API is only
       
   998      * able to retrieve data from result sets if the statemnt handle is
       
   999      * still in scope.}}
       
  1000      *
       
  1001      * @var resource
       
  1002      * @since Property available since Release 1.7.0
       
  1003      */
       
  1004     var $statement;
       
  1005 
       
  1006 
       
  1007     // }}}
       
  1008     // {{{ constructor
       
  1009 
       
  1010     /**
       
  1011      * This constructor sets the object's properties
       
  1012      *
       
  1013      * @param object   &$dbh     the DB object reference
       
  1014      * @param resource $result   the result resource id
       
  1015      * @param array    $options  an associative array with result options
       
  1016      *
       
  1017      * @return void
       
  1018      */
       
  1019     function DB_result(&$dbh, $result, $options = array())
       
  1020     {
       
  1021         $this->autofree    = $dbh->options['autofree'];
       
  1022         $this->dbh         = &$dbh;
       
  1023         $this->fetchmode   = $dbh->fetchmode;
       
  1024         $this->fetchmode_object_class = $dbh->fetchmode_object_class;
       
  1025         $this->parameters  = $dbh->last_parameters;
       
  1026         $this->query       = $dbh->last_query;
       
  1027         $this->result      = $result;
       
  1028         $this->statement   = empty($dbh->last_stmt) ? null : $dbh->last_stmt;
       
  1029         foreach ($options as $key => $value) {
       
  1030             $this->setOption($key, $value);
       
  1031         }
       
  1032     }
       
  1033 
       
  1034     /**
       
  1035      * Set options for the DB_result object
       
  1036      *
       
  1037      * @param string $key    the option to set
       
  1038      * @param mixed  $value  the value to set the option to
       
  1039      *
       
  1040      * @return void
       
  1041      */
       
  1042     function setOption($key, $value = null)
       
  1043     {
       
  1044         switch ($key) {
       
  1045             case 'limit_from':
       
  1046                 $this->limit_from = $value;
       
  1047                 break;
       
  1048             case 'limit_count':
       
  1049                 $this->limit_count = $value;
       
  1050         }
       
  1051     }
       
  1052 
       
  1053     // }}}
       
  1054     // {{{ fetchRow()
       
  1055 
       
  1056     /**
       
  1057      * Fetch a row of data and return it by reference into an array
       
  1058      *
       
  1059      * The type of array returned can be controlled either by setting this
       
  1060      * method's <var>$fetchmode</var> parameter or by changing the default
       
  1061      * fetch mode setFetchMode() before calling this method.
       
  1062      *
       
  1063      * There are two options for standardizing the information returned
       
  1064      * from databases, ensuring their values are consistent when changing
       
  1065      * DBMS's.  These portability options can be turned on when creating a
       
  1066      * new DB object or by using setOption().
       
  1067      *
       
  1068      *   + <var>DB_PORTABILITY_LOWERCASE</var>
       
  1069      *     convert names of fields to lower case
       
  1070      *
       
  1071      *   + <var>DB_PORTABILITY_RTRIM</var>
       
  1072      *     right trim the data
       
  1073      *
       
  1074      * @param int $fetchmode  the constant indicating how to format the data
       
  1075      * @param int $rownum     the row number to fetch (index starts at 0)
       
  1076      *
       
  1077      * @return mixed  an array or object containing the row's data,
       
  1078      *                 NULL when the end of the result set is reached
       
  1079      *                 or a DB_Error object on failure.
       
  1080      *
       
  1081      * @see DB_common::setOption(), DB_common::setFetchMode()
       
  1082      */
       
  1083     function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
       
  1084     {
       
  1085         if ($fetchmode === DB_FETCHMODE_DEFAULT) {
       
  1086             $fetchmode = $this->fetchmode;
       
  1087         }
       
  1088         if ($fetchmode === DB_FETCHMODE_OBJECT) {
       
  1089             $fetchmode = DB_FETCHMODE_ASSOC;
       
  1090             $object_class = $this->fetchmode_object_class;
       
  1091         }
       
  1092         if ($this->limit_from !== null) {
       
  1093             if ($this->row_counter === null) {
       
  1094                 $this->row_counter = $this->limit_from;
       
  1095                 // Skip rows
       
  1096                 if ($this->dbh->features['limit'] === false) {
       
  1097                     $i = 0;
       
  1098                     while ($i++ < $this->limit_from) {
       
  1099                         $this->dbh->fetchInto($this->result, $arr, $fetchmode);
       
  1100                     }
       
  1101                 }
       
  1102             }
       
  1103             if ($this->row_counter >= ($this->limit_from + $this->limit_count))
       
  1104             {
       
  1105                 if ($this->autofree) {
       
  1106                     $this->free();
       
  1107                 }
       
  1108                 $tmp = null;
       
  1109                 return $tmp;
       
  1110             }
       
  1111             if ($this->dbh->features['limit'] === 'emulate') {
       
  1112                 $rownum = $this->row_counter;
       
  1113             }
       
  1114             $this->row_counter++;
       
  1115         }
       
  1116         $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
       
  1117         if ($res === DB_OK) {
       
  1118             if (isset($object_class)) {
       
  1119                 // The default mode is specified in the
       
  1120                 // DB_common::fetchmode_object_class property
       
  1121                 if ($object_class == 'stdClass') {
       
  1122                     $arr = (object) $arr;
       
  1123                 } else {
       
  1124                     $arr = &new $object_class($arr);
       
  1125                 }
       
  1126             }
       
  1127             return $arr;
       
  1128         }
       
  1129         if ($res == null && $this->autofree) {
       
  1130             $this->free();
       
  1131         }
       
  1132         return $res;
       
  1133     }
       
  1134 
       
  1135     // }}}
       
  1136     // {{{ fetchInto()
       
  1137 
       
  1138     /**
       
  1139      * Fetch a row of data into an array which is passed by reference
       
  1140      *
       
  1141      * The type of array returned can be controlled either by setting this
       
  1142      * method's <var>$fetchmode</var> parameter or by changing the default
       
  1143      * fetch mode setFetchMode() before calling this method.
       
  1144      *
       
  1145      * There are two options for standardizing the information returned
       
  1146      * from databases, ensuring their values are consistent when changing
       
  1147      * DBMS's.  These portability options can be turned on when creating a
       
  1148      * new DB object or by using setOption().
       
  1149      *
       
  1150      *   + <var>DB_PORTABILITY_LOWERCASE</var>
       
  1151      *     convert names of fields to lower case
       
  1152      *
       
  1153      *   + <var>DB_PORTABILITY_RTRIM</var>
       
  1154      *     right trim the data
       
  1155      *
       
  1156      * @param array &$arr       the variable where the data should be placed
       
  1157      * @param int   $fetchmode  the constant indicating how to format the data
       
  1158      * @param int   $rownum     the row number to fetch (index starts at 0)
       
  1159      *
       
  1160      * @return mixed  DB_OK if a row is processed, NULL when the end of the
       
  1161      *                 result set is reached or a DB_Error object on failure
       
  1162      *
       
  1163      * @see DB_common::setOption(), DB_common::setFetchMode()
       
  1164      */
       
  1165     function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null)
       
  1166     {
       
  1167         if ($fetchmode === DB_FETCHMODE_DEFAULT) {
       
  1168             $fetchmode = $this->fetchmode;
       
  1169         }
       
  1170         if ($fetchmode === DB_FETCHMODE_OBJECT) {
       
  1171             $fetchmode = DB_FETCHMODE_ASSOC;
       
  1172             $object_class = $this->fetchmode_object_class;
       
  1173         }
       
  1174         if ($this->limit_from !== null) {
       
  1175             if ($this->row_counter === null) {
       
  1176                 $this->row_counter = $this->limit_from;
       
  1177                 // Skip rows
       
  1178                 if ($this->dbh->features['limit'] === false) {
       
  1179                     $i = 0;
       
  1180                     while ($i++ < $this->limit_from) {
       
  1181                         $this->dbh->fetchInto($this->result, $arr, $fetchmode);
       
  1182                     }
       
  1183                 }
       
  1184             }
       
  1185             if ($this->row_counter >= (
       
  1186                     $this->limit_from + $this->limit_count))
       
  1187             {
       
  1188                 if ($this->autofree) {
       
  1189                     $this->free();
       
  1190                 }
       
  1191                 return null;
       
  1192             }
       
  1193             if ($this->dbh->features['limit'] === 'emulate') {
       
  1194                 $rownum = $this->row_counter;
       
  1195             }
       
  1196 
       
  1197             $this->row_counter++;
       
  1198         }
       
  1199         $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
       
  1200         if ($res === DB_OK) {
       
  1201             if (isset($object_class)) {
       
  1202                 // default mode specified in the
       
  1203                 // DB_common::fetchmode_object_class property
       
  1204                 if ($object_class == 'stdClass') {
       
  1205                     $arr = (object) $arr;
       
  1206                 } else {
       
  1207                     $arr = new $object_class($arr);
       
  1208                 }
       
  1209             }
       
  1210             return DB_OK;
       
  1211         }
       
  1212         if ($res == null && $this->autofree) {
       
  1213             $this->free();
       
  1214         }
       
  1215         return $res;
       
  1216     }
       
  1217 
       
  1218     // }}}
       
  1219     // {{{ numCols()
       
  1220 
       
  1221     /**
       
  1222      * Get the the number of columns in a result set
       
  1223      *
       
  1224      * @return int  the number of columns.  A DB_Error object on failure.
       
  1225      */
       
  1226     function numCols()
       
  1227     {
       
  1228         return $this->dbh->numCols($this->result);
       
  1229     }
       
  1230 
       
  1231     // }}}
       
  1232     // {{{ numRows()
       
  1233 
       
  1234     /**
       
  1235      * Get the number of rows in a result set
       
  1236      *
       
  1237      * @return int  the number of rows.  A DB_Error object on failure.
       
  1238      */
       
  1239     function numRows()
       
  1240     {
       
  1241         if ($this->dbh->features['numrows'] === 'emulate'
       
  1242             && $this->dbh->options['portability'] & DB_PORTABILITY_NUMROWS)
       
  1243         {
       
  1244             if ($this->dbh->features['prepare']) {
       
  1245                 $res = $this->dbh->query($this->query, $this->parameters);
       
  1246             } else {
       
  1247                 $res = $this->dbh->query($this->query);
       
  1248             }
       
  1249             if (DB::isError($res)) {
       
  1250                 return $res;
       
  1251             }
       
  1252             $i = 0;
       
  1253             while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) {
       
  1254                 $i++;
       
  1255             }
       
  1256             return $i;
       
  1257         } else {
       
  1258             return $this->dbh->numRows($this->result);
       
  1259         }
       
  1260     }
       
  1261 
       
  1262     // }}}
       
  1263     // {{{ nextResult()
       
  1264 
       
  1265     /**
       
  1266      * Get the next result if a batch of queries was executed
       
  1267      *
       
  1268      * @return bool  true if a new result is available or false if not
       
  1269      */
       
  1270     function nextResult()
       
  1271     {
       
  1272         return $this->dbh->nextResult($this->result);
       
  1273     }
       
  1274 
       
  1275     // }}}
       
  1276     // {{{ free()
       
  1277 
       
  1278     /**
       
  1279      * Frees the resources allocated for this result set
       
  1280      *
       
  1281      * @return bool  true on success.  A DB_Error object on failure.
       
  1282      */
       
  1283     function free()
       
  1284     {
       
  1285         $err = $this->dbh->freeResult($this->result);
       
  1286         if (DB::isError($err)) {
       
  1287             return $err;
       
  1288         }
       
  1289         $this->result = false;
       
  1290         $this->statement = false;
       
  1291         return true;
       
  1292     }
       
  1293 
       
  1294     // }}}
       
  1295     // {{{ tableInfo()
       
  1296 
       
  1297     /**
       
  1298      * @see DB_common::tableInfo()
       
  1299      * @deprecated Method deprecated some time before Release 1.2
       
  1300      */
       
  1301     function tableInfo($mode = null)
       
  1302     {
       
  1303         if (is_string($mode)) {
       
  1304             return $this->dbh->raiseError(DB_ERROR_NEED_MORE_DATA);
       
  1305         }
       
  1306         return $this->dbh->tableInfo($this, $mode);
       
  1307     }
       
  1308 
       
  1309     // }}}
       
  1310     // {{{ getQuery()
       
  1311 
       
  1312     /**
       
  1313      * Determine the query string that created this result
       
  1314      *
       
  1315      * @return string  the query string
       
  1316      *
       
  1317      * @since Method available since Release 1.7.0
       
  1318      */
       
  1319     function getQuery()
       
  1320     {
       
  1321         return $this->query;
       
  1322     }
       
  1323 
       
  1324     // }}}
       
  1325     // {{{ getRowCounter()
       
  1326 
       
  1327     /**
       
  1328      * Tells which row number is currently being processed
       
  1329      *
       
  1330      * @return integer  the current row being looked at.  Starts at 1.
       
  1331      */
       
  1332     function getRowCounter()
       
  1333     {
       
  1334         return $this->row_counter;
       
  1335     }
       
  1336 
       
  1337     // }}}
       
  1338 }
       
  1339 
       
  1340 // }}}
       
  1341 // {{{ class DB_row
       
  1342 
       
  1343 /**
       
  1344  * PEAR DB Row Object
       
  1345  *
       
  1346  * The object contains a row of data from a result set.  Each column's data
       
  1347  * is placed in a property named for the column.
       
  1348  *
       
  1349  * @category   Database
       
  1350  * @package    DB
       
  1351  * @author     Stig Bakken <ssb@php.net>
       
  1352  * @copyright  1997-2005 The PHP Group
       
  1353  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
       
  1354  * @version    Release: @package_version@
       
  1355  * @link       http://pear.php.net/package/DB
       
  1356  * @see        DB_common::setFetchMode()
       
  1357  */
       
  1358 class DB_row
       
  1359 {
       
  1360     // {{{ constructor
       
  1361 
       
  1362     /**
       
  1363      * The constructor places a row's data into properties of this object
       
  1364      *
       
  1365      * @param array  the array containing the row's data
       
  1366      *
       
  1367      * @return void
       
  1368      */
       
  1369     function DB_row(&$arr)
       
  1370     {
       
  1371         foreach ($arr as $key => $value) {
       
  1372             $this->$key = &$arr[$key];
       
  1373         }
       
  1374     }
       
  1375 
       
  1376     // }}}
       
  1377 }
       
  1378 
       
  1379 // }}}
       
  1380 
       
  1381 /*
       
  1382  * Local variables:
       
  1383  * tab-width: 4
       
  1384  * c-basic-offset: 4
       
  1385  * End:
       
  1386  */
       
  1387 
       
  1388 ?>