Error Buddy

Do you have an error message from your application? Then find the answer with Error Buddy. You can search over 40000 source code files and troubleshooting documents using our beta lucene/nutch search interface or if you prefer, search as normal using google. With LXR technology you can drill right down into the line of source code where it came from with full cross-referencing.

If after searching you didn't get your ideal answer, or you are still unclear what the error means, you can choose to post that question to the community forums following the link included in the search results.

corestack/ DB-1.7.6/ DB.php [1.6]
001 <?php
002 
003 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
004 
005 /**
006  * Database independent query interface
007  *
008  * PHP versions 4 and 5
009  *
010  * LICENSE: This source file is subject to version 3.0 of the PHP license
011  * that is available through the world-wide-web at the following URI:
012  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
013  * the PHP License and are unable to obtain it through the web, please
014  * send a note to license@php.net so we can mail you a copy immediately.
015  *
016  * @category   Database
017  * @package    DB
018  * @author     Stig Bakken <ssb@php.net>
019  * @author     Tomas V.V.Cox <cox@idecnet.com>
020  * @author     Daniel Convissor <danielc@php.net>
021  * @copyright  1997-2005 The PHP Group
022  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
023  * @version    CVS: $Id: DB.php,v 1.80 2005/02/16 02:16:00 danielc Exp $
024  * @link       http://pear.php.net/package/DB
025  */
026 
027 /**
028  * Obtain the PEAR class so it can be extended from
029  */
030 require_once 'PEAR.php';
031 
032 
033 // {{{ constants
034 // {{{ error codes
035 
036 /**#@+
037  * One of PEAR DB's portable error codes.
038  * @see DB_common::errorCode(), DB::errorMessage()
039  *
040  * {@internal If you add an error code here, make sure you also add a textual
041  * version of it in DB::errorMessage().}}
042  */
043 
044 /**
045  * The code returned by many methods upon success
046  */
047 define('DB_OK', 1);
048 
049 /**
050  * Unkown error
051  */
052 define('DB_ERROR', -1);
053 
054 /**
055  * Syntax error
056  */
057 define('DB_ERROR_SYNTAX', -2);
058 
059 /**
060  * Tried to insert a duplicate value into a primary or unique index
061  */
062 define('DB_ERROR_CONSTRAINT', -3);
063 
064 /**
065  * An identifier in the query refers to a non-existant object
066  */
067 define('DB_ERROR_NOT_FOUND', -4);
068 
069 /**
070  * Tried to create a duplicate object
071  */
072 define('DB_ERROR_ALREADY_EXISTS', -5);
073 
074 /**
075  * The current driver does not support the action you attempted
076  */
077 define('DB_ERROR_UNSUPPORTED', -6);
078 
079 /**
080  * The number of parameters does not match the number of placeholders
081  */
082 define('DB_ERROR_MISMATCH', -7);
083 
084 /**
085  * A literal submitted did not match the data type expected
086  */
087 define('DB_ERROR_INVALID', -8);
088 
089 /**
090  * The current DBMS does not support the action you attempted
091  */
092 define('DB_ERROR_NOT_CAPABLE', -9);
093 
094 /**
095  * A literal submitted was too long so the end of it was removed
096  */
097 define('DB_ERROR_TRUNCATED', -10);
098 
099 /**
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 ?>

Powered by Lucene and the LXR engine.