/[cvs]/nfo/php/libs/net.php.pear/DB.php
ViewVC logotype

Annotation of /nfo/php/libs/net.php.pear/DB.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Oct 29 19:11:40 2002 UTC (21 years, 8 months ago) by cvsjoko
Branch: MAIN
CVS Tags: HEAD
+ new pear-libraries

1 cvsjoko 1.1 <?php
2     /* vim: set expandtab tabstop=4 shiftwidth=4: */
3     // +----------------------------------------------------------------------+
4     // | PHP Version 4 |
5     // +----------------------------------------------------------------------+
6     // | Copyright (c) 1997-2002 The PHP Group |
7     // +----------------------------------------------------------------------+
8     // | This source file is subject to version 2.02 of the PHP license, |
9     // | that is bundled with this package in the file LICENSE, and is |
10     // | available at through the world-wide-web at |
11     // | http://www.php.net/license/2_02.txt. |
12     // | If you did not receive a copy of the PHP license and are unable to |
13     // | obtain it through the world-wide-web, please send a note to |
14     // | license@php.net so we can mail you a copy immediately. |
15     // +----------------------------------------------------------------------+
16     // | Authors: Stig Bakken <ssb@fast.no> |
17     // | Tomas V.V.Cox <cox@idecnet.com> |
18     // +----------------------------------------------------------------------+
19     //
20     // $Id: DB.php,v 1.86.2.2 2002/04/09 19:04:02 ssb Exp $
21     //
22     // Database independent query interface.
23     //
24    
25     require_once "PEAR.php";
26    
27     /*
28     * The method mapErrorCode in each DB_dbtype implementation maps
29     * native error codes to one of these.
30     *
31     * If you add an error code here, make sure you also add a textual
32     * version of it in DB::errorMessage().
33     */
34    
35     define("DB_OK", 1);
36     define("DB_ERROR", -1);
37     define("DB_ERROR_SYNTAX", -2);
38     define("DB_ERROR_CONSTRAINT", -3);
39     define("DB_ERROR_NOT_FOUND", -4);
40     define("DB_ERROR_ALREADY_EXISTS", -5);
41     define("DB_ERROR_UNSUPPORTED", -6);
42     define("DB_ERROR_MISMATCH", -7);
43     define("DB_ERROR_INVALID", -8);
44     define("DB_ERROR_NOT_CAPABLE", -9);
45     define("DB_ERROR_TRUNCATED", -10);
46     define("DB_ERROR_INVALID_NUMBER", -11);
47     define("DB_ERROR_INVALID_DATE", -12);
48     define("DB_ERROR_DIVZERO", -13);
49     define("DB_ERROR_NODBSELECTED", -14);
50     define("DB_ERROR_CANNOT_CREATE", -15);
51     define("DB_ERROR_CANNOT_DELETE", -16);
52     define("DB_ERROR_CANNOT_DROP", -17);
53     define("DB_ERROR_NOSUCHTABLE", -18);
54     define("DB_ERROR_NOSUCHFIELD", -19);
55     define("DB_ERROR_NEED_MORE_DATA", -20);
56     define("DB_ERROR_NOT_LOCKED", -21);
57     define("DB_ERROR_VALUE_COUNT_ON_ROW", -22);
58     define("DB_ERROR_INVALID_DSN", -23);
59     define("DB_ERROR_CONNECT_FAILED", -24);
60     define("DB_ERROR_EXTENSION_NOT_FOUND",-25);
61     define("DB_ERROR_NOSUCHDB", -25);
62     define("DB_ERROR_ACCESS_VIOLATION", -26);
63    
64     /*
65     * Warnings are not detected as errors by DB::isError(), and are not
66     * fatal. You can detect whether an error is in fact a warning with
67     * DB::isWarning().
68     */
69    
70     define('DB_WARNING', -1000);
71     define('DB_WARNING_READ_ONLY', -1001);
72    
73     /*
74     * These constants are used when storing information about prepared
75     * statements (using the "prepare" method in DB_dbtype).
76     *
77     * The prepare/execute model in DB is mostly borrowed from the ODBC
78     * extension, in a query the "?" character means a scalar parameter.
79     * There are two extensions though, a "&" character means an opaque
80     * parameter. An opaque parameter is simply a file name, the real
81     * data are in that file (useful for putting uploaded files into your
82     * database and such). The "!" char means a parameter that must be
83     * left as it is.
84     * They modify the quote behavoir:
85     * DB_PARAM_SCALAR (?) => 'original string quoted'
86     * DB_PARAM_OPAQUE (&) => 'string from file quoted'
87     * DB_PARAM_MISC (!) => original string
88     */
89    
90     define('DB_PARAM_SCALAR', 1);
91     define('DB_PARAM_OPAQUE', 2);
92     define('DB_PARAM_MISC', 3);
93    
94     /*
95     * These constants define different ways of returning binary data
96     * from queries. Again, this model has been borrowed from the ODBC
97     * extension.
98     *
99     * DB_BINMODE_PASSTHRU sends the data directly through to the browser
100     * when data is fetched from the database.
101     * DB_BINMODE_RETURN lets you return data as usual.
102     * DB_BINMODE_CONVERT returns data as well, only it is converted to
103     * hex format, for example the string "123" would become "313233".
104     */
105    
106     define('DB_BINMODE_PASSTHRU', 1);
107     define('DB_BINMODE_RETURN', 2);
108     define('DB_BINMODE_CONVERT', 3);
109    
110     /**
111     * This is a special constant that tells DB the user hasn't specified
112     * any particular get mode, so the default should be used.
113     */
114    
115     define('DB_FETCHMODE_DEFAULT', 0);
116    
117     /**
118     * Column data indexed by numbers, ordered from 0 and up
119     */
120    
121     define('DB_FETCHMODE_ORDERED', 1);
122    
123     /**
124     * Column data indexed by column names
125     */
126    
127     define('DB_FETCHMODE_ASSOC', 2);
128    
129     /**
130     * Column data as object properties
131     */
132    
133     define('DB_FETCHMODE_OBJECT', 3);
134    
135     /**
136     * For multi-dimensional results: normally the first level of arrays
137     * is the row number, and the second level indexed by column number or name.
138     * DB_FETCHMODE_FLIPPED switches this order, so the first level of arrays
139     * is the column name, and the second level the row number.
140     */
141    
142     define('DB_FETCHMODE_FLIPPED', 4);
143    
144     /* for compatibility */
145    
146     define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED);
147     define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC);
148     define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED);
149    
150     /**
151     * these are constants for the tableInfo-function
152     * they are bitwised or'ed. so if there are more constants to be defined
153     * in the future, adjust DB_TABLEINFO_FULL accordingly
154     */
155    
156     define('DB_TABLEINFO_ORDER', 1);
157     define('DB_TABLEINFO_ORDERTABLE', 2);
158     define('DB_TABLEINFO_FULL', 3);
159    
160    
161     /**
162     * The main "DB" class is simply a container class with some static
163     * methods for creating DB objects as well as some utility functions
164     * common to all parts of DB.
165     *
166     * The object model of DB is as follows (indentation means inheritance):
167     *
168     * DB The main DB class. This is simply a utility class
169     * with some "static" methods for creating DB objects as
170     * well as common utility functions for other DB classes.
171     *
172     * DB_common The base for each DB implementation. Provides default
173     * | implementations (in OO lingo virtual methods) for
174     * | the actual DB implementations as well as a bunch of
175     * | query utility functions.
176     * |
177     * +-DB_mysql The DB implementation for MySQL. Inherits DB_common.
178     * When calling DB::factory or DB::connect for MySQL
179     * connections, the object returned is an instance of this
180     * class.
181     *
182     * @package DB
183     * @author Stig Bakken <ssb@fast.no>
184     * @since PHP 4.0
185     */
186    
187     class DB
188     {
189     /**
190     * Create a new DB connection object for the specified database
191     * type
192     *
193     * @param string $type database type, for example "mysql"
194     *
195     * @return mixed a newly created DB object, or a DB error code on
196     * error
197     *
198     * access public
199     */
200    
201     function &factory($type)
202     {
203     @include_once("DB/${type}.php");
204    
205     $classname = "DB_${type}";
206    
207     if (!class_exists($classname)) {
208     return PEAR::raiseError(null, DB_ERROR_NOT_FOUND,
209     null, null, null, 'DB_Error', true);
210     }
211    
212     @$obj =& new $classname;
213    
214     return $obj;
215     }
216    
217     /**
218     * Create a new DB connection object and connect to the specified
219     * database
220     *
221     * @param mixed $dsn "data source name", see the DB::parseDSN
222     * method for a description of the dsn format. Can also be
223     * specified as an array of the format returned by DB::parseDSN.
224     *
225     * @param mixed $options An associative array of option names and
226     * their values. For backwards compatibility, this parameter may
227     * also be a boolean that tells whether the connection should be
228     * persistent. See DB_common::setOption for more information on
229     * connection options.
230     *
231     * @return mixed a newly created DB connection object, or a DB
232     * error object on error
233     *
234     * @see DB::parseDSN
235     * @see DB::isError
236     * @see DB_common::setOption
237     */
238     function &connect($dsn, $options = false)
239     {
240     if (is_array($dsn)) {
241     $dsninfo = $dsn;
242     } else {
243     $dsninfo = DB::parseDSN($dsn);
244     }
245     $type = $dsninfo["phptype"];
246    
247     if (is_array($options) && isset($options["debug"]) &&
248     $options["debug"] >= 2) {
249     // expose php errors with sufficient debug level
250     include_once "DB/${type}.php";
251     } else {
252     @include_once "DB/${type}.php";
253     }
254    
255     $classname = "DB_${type}";
256     if (!class_exists($classname)) {
257     return PEAR::raiseError(null, DB_ERROR_NOT_FOUND,
258     null, null, null, 'DB_Error', true);
259     }
260    
261     @$obj =& new $classname;
262    
263     if (is_array($options)) {
264     foreach ($options as $option => $value) {
265     $test = $obj->setOption($option, $value);
266     if (DB::isError($test)) {
267     return $test;
268     }
269     }
270     } else {
271     $obj->setOption('persistent', $options);
272     }
273     $err = $obj->connect($dsninfo, $obj->getOption('persistent'));
274     if (DB::isError($err)) {
275     $err->addUserInfo($dsn);
276     return $err;
277     }
278    
279     return $obj;
280     }
281    
282     /**
283     * Return the DB API version
284     *
285     * @return int the DB API version number
286     *
287     * @access public
288     */
289     function apiVersion()
290     {
291     return 2;
292     }
293    
294     /**
295     * Tell whether a result code from a DB method is an error
296     *
297     * @param $value int result code
298     *
299     * @return bool whether $value is an error
300     *
301     * @access public
302     */
303     function isError($value)
304     {
305     return (is_object($value) &&
306     (get_class($value) == 'db_error' ||
307     is_subclass_of($value, 'db_error')));
308     }
309    
310     /**
311     * Tell whether a query is a data manipulation query (insert,
312     * update or delete) or a data definition query (create, drop,
313     * alter, grant, revoke).
314     *
315     * @access public
316     *
317     * @param string $query the query
318     *
319     * @return boolean whether $query is a data manipulation query
320     */
321     function isManip($query)
322     {
323     $manips = 'INSERT|UPDATE|DELETE|'.'REPLACE|CREATE|DROP|'.
324     'ALTER|GRANT|REVOKE|'.'LOCK|UNLOCK';
325     if (preg_match('/^\s*"?('.$manips.')\s+/i', $query)) {
326     return true;
327     }
328     return false;
329     }
330    
331     /**
332     * Tell whether a result code from a DB method is a warning.
333     * Warnings differ from errors in that they are generated by DB,
334     * and are not fatal.
335     *
336     * @param mixed $value result value
337     *
338     * @return boolean whether $value is a warning
339     *
340     * @access public
341     */
342     function isWarning($value)
343     {
344     return (is_object($value) &&
345     (get_class($value) == "db_warning" ||
346     is_subclass_of($value, "db_warning")));
347     }
348    
349     /**
350     * Return a textual error message for a DB error code
351     *
352     * @param integer $value error code
353     *
354     * @return string error message, or false if the error code was
355     * not recognized
356     */
357     function errorMessage($value)
358     {
359     static $errorMessages;
360     if (!isset($errorMessages)) {
361     $errorMessages = array(
362     DB_ERROR => 'unknown error',
363     DB_ERROR_ALREADY_EXISTS => 'already exists',
364     DB_ERROR_CANNOT_CREATE => 'can not create',
365     DB_ERROR_CANNOT_DELETE => 'can not delete',
366     DB_ERROR_CANNOT_DROP => 'can not drop',
367     DB_ERROR_CONSTRAINT => 'constraint violation',
368     DB_ERROR_DIVZERO => 'division by zero',
369     DB_ERROR_INVALID => 'invalid',
370     DB_ERROR_INVALID_DATE => 'invalid date or time',
371     DB_ERROR_INVALID_NUMBER => 'invalid number',
372     DB_ERROR_MISMATCH => 'mismatch',
373     DB_ERROR_NODBSELECTED => 'no database selected',
374     DB_ERROR_NOSUCHFIELD => 'no such field',
375     DB_ERROR_NOSUCHTABLE => 'no such table',
376     DB_ERROR_NOT_CAPABLE => 'DB backend not capable',
377     DB_ERROR_NOT_FOUND => 'not found',
378     DB_ERROR_NOT_LOCKED => 'not locked',
379     DB_ERROR_SYNTAX => 'syntax error',
380     DB_ERROR_UNSUPPORTED => 'not supported',
381     DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row',
382     DB_ERROR_INVALID_DSN => 'invalid DSN',
383     DB_ERROR_CONNECT_FAILED => 'connect failed',
384     DB_OK => 'no error',
385     DB_WARNING => 'unknown warning',
386     DB_WARNING_READ_ONLY => 'read only',
387     DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied',
388     DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found',
389     DB_ERROR_NOSUCHDB => 'no such database',
390     DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions'
391     );
392     }
393    
394     if (DB::isError($value)) {
395     $value = $value->getCode();
396     }
397    
398     return isset($errorMessages[$value]) ? $errorMessages[$value] : $errorMessages[DB_ERROR];
399     }
400    
401     /**
402     * Parse a data source name
403     *
404     * A array with the following keys will be returned:
405     * phptype: Database backend used in PHP (mysql, odbc etc.)
406     * dbsyntax: Database used with regards to SQL syntax etc.
407     * protocol: Communication protocol to use (tcp, unix etc.)
408     * hostspec: Host specification (hostname[:port])
409     * database: Database to use on the DBMS server
410     * username: User name for login
411     * password: Password for login
412     *
413     * The format of the supplied DSN is in its fullest form:
414     *
415     * phptype(dbsyntax)://username:password@protocol+hostspec/database
416     *
417     * Most variations are allowed:
418     *
419     * phptype://username:password@protocol+hostspec:110//usr/db_file.db
420     * phptype://username:password@hostspec/database_name
421     * phptype://username:password@hostspec
422     * phptype://username@hostspec
423     * phptype://hostspec/database
424     * phptype://hostspec
425     * phptype(dbsyntax)
426     * phptype
427     *
428     * @param string $dsn Data Source Name to be parsed
429     *
430     * @return array an associative array
431     *
432     * @author Tomas V.V.Cox <cox@idecnet.com>
433     */
434     function parseDSN($dsn)
435     {
436     if (is_array($dsn)) {
437     return $dsn;
438     }
439    
440     $parsed = array(
441     'phptype' => false,
442     'dbsyntax' => false,
443     'username' => false,
444     'password' => false,
445     'protocol' => false,
446     'hostspec' => false,
447     'port' => false,
448     'socket' => false,
449     'database' => false
450     );
451    
452     // Find phptype and dbsyntax
453     if (($pos = strpos($dsn, '://')) !== false) {
454     $str = substr($dsn, 0, $pos);
455     $dsn = substr($dsn, $pos + 3);
456     } else {
457     $str = $dsn;
458     $dsn = NULL;
459     }
460    
461     // Get phptype and dbsyntax
462     // $str => phptype(dbsyntax)
463     if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) {
464     $parsed['phptype'] = $arr[1];
465     $parsed['dbsyntax'] = (empty($arr[2])) ? $arr[1] : $arr[2];
466     } else {
467     $parsed['phptype'] = $str;
468     $parsed['dbsyntax'] = $str;
469     }
470    
471     if (empty($dsn)) {
472     return $parsed;
473     }
474    
475     // Get (if found): username and password
476     // $dsn => username:password@protocol+hostspec/database
477     if (($at = strrpos($dsn,'@')) !== false) {
478     $str = substr($dsn, 0, $at);
479     $dsn = substr($dsn, $at + 1);
480     if (($pos = strpos($str, ':')) !== false) {
481     $parsed['username'] = urldecode(substr($str, 0, $pos));
482     $parsed['password'] = urldecode(substr($str, $pos + 1));
483     } else {
484     $parsed['username'] = urldecode($str);
485     }
486     }
487    
488     // Find protocol and hostspec
489    
490     // $dsn => proto(proto_opts)/database
491     if (preg_match('|^(.+?)\((.*?)\)/?(.*?)$|', $dsn, $match)) {
492     $proto = $match[1];
493     $proto_opts = (!empty($match[2])) ? $match[2] : false;
494     $dsn = $match[3];
495    
496     // $dsn => protocol+hostspec/database (old format)
497     } else {
498     if (strpos($dsn, '+') !== false) {
499     list($proto, $dsn) = explode('+', $dsn, 2);
500     }
501     if (strpos($dsn, '/') !== false) {
502     list($proto_opts, $dsn) = explode('/', $dsn, 2);
503     } else {
504     $proto_opts = $dsn;
505     $dsn = null;
506     }
507     }
508    
509     // process the different protocol options
510     $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp';
511     $proto_opts = urldecode($proto_opts);
512     if ($parsed['protocol'] == 'tcp') {
513     if (strpos($proto_opts, ':') !== false) {
514     list($parsed['hostspec'], $parsed['port']) = explode(':', $proto_opts);
515     } else {
516     $parsed['hostspec'] = $proto_opts;
517     }
518     } elseif ($parsed['protocol'] == 'unix') {
519     $parsed['socket'] = $proto_opts;
520     }
521    
522     // Get dabase if any
523     // $dsn => database
524     if (!empty($dsn)) {
525     // /database
526     if (($pos = strpos($dsn, '?')) === false) {
527     $parsed['database'] = $dsn;
528     // /database?param1=value1&param2=value2
529     } else {
530     $parsed['database'] = substr($dsn, 0, $pos);
531     $dsn = substr($dsn, $pos + 1);
532     if (strpos($dsn, '&') !== false) {
533     $opts = explode('&', $dsn);
534     } else { // database?param1=value1
535     $opts = array($dsn);
536     }
537     foreach ($opts as $opt) {
538     list($key, $value) = explode('=', $opt);
539     if (!isset($parsed[$key])) { // don't allow params overwrite
540     $parsed[$key] = urldecode($value);
541     }
542     }
543     }
544     }
545    
546     return $parsed;
547     }
548    
549     /**
550     * Load a PHP database extension if it is not loaded already.
551     *
552     * @access public
553     *
554     * @param string $name the base name of the extension (without the .so or
555     * .dll suffix)
556     *
557     * @return boolean true if the extension was already or successfully
558     * loaded, false if it could not be loaded
559     */
560     function assertExtension($name)
561     {
562     if (!extension_loaded($name)) {
563     $dlext = OS_WINDOWS ? '.dll' : '.so';
564     @dl($name . $dlext);
565     }
566     return extension_loaded($name);
567     }
568     }
569    
570     /**
571     * DB_Error implements a class for reporting portable database error
572     * messages.
573     *
574     * @package DB
575     * @author Stig Bakken <ssb@fast.no>
576     */
577     class DB_Error extends PEAR_Error
578     {
579     /**
580     * DB_Error constructor.
581     *
582     * @param mixed $code DB error code, or string with error message.
583     * @param integer $mode what "error mode" to operate in
584     * @param integer $level what error level to use for $mode & PEAR_ERROR_TRIGGER
585     * @param smixed $debuginfo additional debug info, such as the last query
586     *
587     * @access public
588     *
589     * @see PEAR_Error
590     */
591    
592     function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN,
593     $level = E_USER_NOTICE, $debuginfo = null)
594     {
595     if (is_int($code)) {
596     $this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo);
597     } else {
598     $this->PEAR_Error("DB Error: $code", DB_ERROR, $mode, $level, $debuginfo);
599     }
600     }
601     }
602    
603     /**
604     * DB_Warning implements a class for reporting portable database
605     * warning messages.
606     *
607     * @package DB
608     * @author Stig Bakken <ssb@fast.no>
609     */
610     class DB_Warning extends PEAR_Error
611     {
612     /**
613     * DB_Warning constructor.
614     *
615     * @param mixed $code DB error code, or string with error message.
616     * @param integer $mode what "error mode" to operate in
617     * @param integer $level what error level to use for $mode == PEAR_ERROR_TRIGGER
618     * @param mmixed $debuginfo additional debug info, such as the last query
619     *
620     * @access public
621     *
622     * @see PEAR_Error
623     */
624    
625     function DB_Warning($code = DB_WARNING, $mode = PEAR_ERROR_RETURN,
626     $level = E_USER_NOTICE, $debuginfo = null)
627     {
628     if (is_int($code)) {
629     $this->PEAR_Error('DB Warning: ' . DB::errorMessage($code), $code, $mode, $level, $debuginfo);
630     } else {
631     $this->PEAR_Error("DB Warning: $code", 0, $mode, $level, $debuginfo);
632     }
633     }
634     }
635    
636     /**
637     * This class implements a wrapper for a DB result set.
638     * A new instance of this class will be returned by the DB implementation
639     * after processing a query that returns data.
640     *
641     * @package DB
642     * @author Stig Bakken <ssb@fast.no>
643     */
644    
645     class DB_result
646     {
647     var $dbh;
648     var $result;
649     var $row_counter = null;
650     /**
651     * for limit queries, the row to start fetching
652     * @var integer
653     */
654     var $limit_from = null;
655    
656     /**
657     * for limit queries, the number of rows to fetch
658     * @var integer
659     */
660     var $limit_count = null;
661    
662     /**
663     * DB_result constructor.
664     * @param resource $dbh DB object reference
665     * @param resource $result result resource id
666     */
667    
668     function DB_result(&$dbh, $result)
669     {
670     $this->dbh = &$dbh;
671     $this->result = $result;
672     }
673    
674     /**
675     * Fetch and return a row of data (it uses driver->fetchInto for that)
676     * @param int $fetchmode format of fetched row
677     * @param int $rownum the row number to fetch
678     *
679     * @return array a row of data, NULL on no more rows or PEAR_Error on error
680     *
681     * @access public
682     */
683     function fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
684     {
685     if ($fetchmode === DB_FETCHMODE_DEFAULT) {
686     $fetchmode = $this->dbh->fetchmode;
687     }
688     if ($fetchmode === DB_FETCHMODE_OBJECT) {
689     $fetchmode = DB_FETCHMODE_ASSOC;
690     $object_class = $this->dbh->fetchmode_object_class;
691     }
692     if ($this->limit_from !== null) {
693     if ($this->row_counter === null) {
694     $this->row_counter = $this->limit_from;
695     // For Interbase
696     if ($this->dbh->features['limit'] == false) {
697     $i = 0;
698     while ($i++ < $this->limit_from) {
699     $this->dbh->fetchInto($this->result, $arr, $fetchmode);
700     }
701     }
702     }
703     if ($this->row_counter >= (
704     $this->limit_from + $this->limit_count))
705     {
706     return null;
707     }
708     if ($this->dbh->features['limit'] == 'emulate') {
709     $rownum = $this->row_counter;
710     }
711    
712     $this->row_counter++;
713     }
714     $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
715     if ($res !== DB_OK) {
716     return $res;
717     }
718     if (isset($object_class)) {
719     // default mode specified in DB_common::fetchmode_object_class property
720     if ($object_class == 'stdClass') {
721     $ret = (object) $arr;
722     } else {
723     $ret =& new $object_class($arr);
724     }
725     return $ret;
726     }
727     return $arr;
728     }
729    
730     /**
731     * Fetch a row of data into an existing variable.
732     *
733     * @param mixed $arr reference to data containing the row
734     * @param integer $fetchmode format of fetched row
735     * @param integer $rownum the row number to fetch
736     *
737     * @return mixed DB_OK on success, NULL on no more rows or
738     * a DB_Error object on error
739     *
740     * @access public
741     */
742     function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
743     {
744     if ($fetchmode === DB_FETCHMODE_DEFAULT) {
745     $fetchmode = $this->dbh->fetchmode;
746     }
747     if ($fetchmode === DB_FETCHMODE_OBJECT) {
748     $fetchmode = DB_FETCHMODE_ASSOC;
749     $object_class = $this->dbh->fetchmode_object_class;
750     }
751     if ($this->limit_from !== null) {
752     if ($this->row_counter === null) {
753     $this->row_counter = $this->limit_from;
754     // For Interbase
755     if ($this->dbh->features['limit'] == false) {
756     $i = 0;
757     while ($i++ < $this->limit_from) {
758     $this->dbh->fetchInto($this->result, $arr, $fetchmode);
759     }
760     }
761     }
762     if ($this->row_counter >= (
763     $this->limit_from + $this->limit_count))
764     {
765     return null;
766     }
767     if ($this->dbh->features['limit'] == 'emulate') {
768     $rownum = $this->row_counter;
769     }
770    
771     $this->row_counter++;
772     }
773     $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum);
774     if (($res === DB_OK) && isset($object_class)) {
775     // default mode specified in DB_common::fetchmode_object_class property
776     if ($object_class == 'stdClass') {
777     $arr = (object) $arr;
778     } else {
779     $arr = new $object_class($arr);
780     }
781     }
782     return $res;
783     }
784    
785     /**
786     * Get the the number of columns in a result set.
787     *
788     * @return int the number of columns, or a DB error
789     *
790     * @access public
791     */
792     function numCols()
793     {
794     return $this->dbh->numCols($this->result);
795     }
796    
797     /**
798     * Get the number of rows in a result set.
799     *
800     * @return int the number of rows, or a DB error
801     *
802     * @access public
803     */
804     function numRows()
805     {
806     return $this->dbh->numRows($this->result);
807     }
808    
809     /**
810     * Get the next result if a batch of queries was executed.
811     *
812     * @return bool true if a new result is available or false if not.
813     *
814     * @access public
815     */
816     function nextResult()
817     {
818     return $this->dbh->nextResult($this->result);
819     }
820    
821     /**
822     * Frees the resources allocated for this result set.
823     * @return int error code
824     *
825     * @access public
826     */
827     function free()
828     {
829     $err = $this->dbh->freeResult($this->result);
830     if(DB::isError($err)) {
831     return $err;
832     }
833     $this->result = false;
834     return true;
835     }
836    
837     /**
838     * @deprecated
839     */
840     function tableInfo($mode = null)
841     {
842     return $this->dbh->tableInfo($this->result, $mode);
843     }
844    
845     /**
846     * returns the actual rows number
847     * @return integer
848     */
849     function getRowCounter()
850     {
851     return $this->row_counter;
852     }
853     }
854    
855     /**
856     * Pear DB Row Object
857     * @see DB_common::setFetchMode()
858     */
859     class DB_row
860     {
861     /**
862     * constructor
863     *
864     * @param resource row data as array
865     */
866     function DB_row(&$arr)
867     {
868     for (reset($arr); $key = key($arr); next($arr)) {
869     $this->$key = &$arr[$key];
870     }
871     }
872     }
873    
874     ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed