Source for file DB.php

Documentation is available at DB.php

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

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