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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 cvsjoko 1.1 <?php
2     //
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     // | Author: Stig Bakken <ssb@fast.no> |
17     // +----------------------------------------------------------------------+
18     //
19     // $Id: common.php,v 1.81.2.2 2002/04/09 19:04:11 ssb Exp $
20     //
21     // Base class for DB implementations.
22     //
23    
24     /**
25     * DB_common is a base class for DB implementations, and must be
26     * inherited by all such.
27     */
28    
29     class DB_common extends PEAR
30     {
31     // {{{ properties
32     /**
33     * assoc of capabilities for this DB implementation
34     * $features['limit'] => 'emulate' => emulate with fetch row by number
35     * 'alter' => alter the query
36     * false => skip rows
37     * @var array
38     */
39     var $features;
40    
41     /**
42     * assoc mapping native error codes to DB ones
43     * @var array
44     */
45     var $errorcode_map;
46    
47     /**
48     * DB type (mysql, oci8, odbc etc.)
49     * @var string
50     */
51     var $type;
52    
53     /**
54     * @var string
55     */
56     var $prepare_tokens;
57    
58     /**
59     * @var string
60     */
61     var $prepare_types;
62    
63     /**
64     * @var string
65     */
66     var $prepared_queries;
67    
68     /**
69     * @var integer
70     */
71     var $prepare_maxstmt = 0;
72    
73     /**
74     * @var string
75     */
76     var $last_query = '';
77    
78     /**
79     * @var integer
80     */
81     var $fetchmode = DB_FETCHMODE_ORDERED;
82    
83     /**
84     * @var string
85     */
86     var $fetchmode_object_class = 'stdClass';
87    
88     /**
89     * $options["persistent"] -> boolean persistent connection true|false?
90     * $options["optimize"] -> string 'performance' or 'portability'
91     * $options["debug"] -> integer numeric debug level
92     * @var array
93     */
94     var $options = array(
95     'persistent' => false,
96     'optimize' => 'performance',
97     'debug' => 0,
98     'seqname_format' => '%s_seq',
99     );
100    
101     /**
102     * DB handle
103     * @var resource
104     */
105     var $dbh;
106    
107     // }}}
108     // {{{ toString()
109     /**
110     * String conversation
111     *
112     * @return string
113     * @access private
114     */
115     function toString()
116     {
117     $info = get_class($this);
118     $info .= ": (phptype=" . $this->phptype .
119     ", dbsyntax=" . $this->dbsyntax .
120     ")";
121    
122     if ($this->connection) {
123     $info .= " [connected]";
124     }
125    
126     return $info;
127     }
128    
129     // }}}
130     // {{{ constructor
131     /**
132     * Constructor
133     */
134     function DB_common()
135     {
136     $this->PEAR('DB_Error');
137     $this->features = array();
138     $this->errorcode_map = array();
139     $this->fetchmode = DB_FETCHMODE_ORDERED;
140     }
141    
142     // }}}
143     // {{{ quoteString()
144    
145     /**
146     * Quotes a string so it can be safely used within string delimiters
147     * in a query (preserved for compatibility issues, quote() is preffered).
148     *
149     * @return string quoted string
150     * @access public
151     * @see quote()
152     */
153     function quoteString($string)
154     {
155     $string = $this->quote($string);
156     if ($string{0} == "'") {
157     return substr($string, 1, -1);
158     }
159     return $string;
160     }
161    
162     /**
163     * Quotes a string so it can be safely used in a query. It will return
164     * the string with single quotes around. Other backend quote styles
165     * should override this method.
166     *
167     * @param string $string the input string to quote
168     *
169     * @return string The NULL string or the string quotes
170     * in magic_quote_sybase style
171     */
172     function quote($string)
173     {
174     return ($string === null) ? 'NULL' : "'".str_replace("'", "''", $string)."'";
175     }
176    
177     // }}}
178     // {{{ provides()
179    
180     /**
181     * Tell whether a DB implementation or its backend extension
182     * supports a given feature.
183     *
184     * @param array $feature name of the feature (see the DB class doc)
185     * @return bool whether this DB implementation supports $feature
186     * @access public
187     */
188    
189     function provides($feature)
190     {
191     return $this->features[$feature];
192     }
193    
194     // }}}
195     // {{{ errorCode()
196    
197     /**
198     * Map native error codes to DB's portable ones. Requires that
199     * the DB implementation's constructor fills in the $errorcode_map
200     * property.
201     *
202     * @param mixed $nativecode the native error code, as returned by the backend
203     * database extension (string or integer)
204     *
205     * @return int a portable DB error code, or FALSE if this DB
206     * implementation has no mapping for the given error code.
207     *
208     * @access public
209     */
210    
211     function errorCode($nativecode)
212     {
213     if (isset($this->errorcode_map[$nativecode])) {
214     return $this->errorcode_map[$nativecode];
215     }
216    
217     //php_error(E_WARNING, get_class($this)."::errorCode: no mapping for $nativecode");
218     // Fall back to DB_ERROR if there was no mapping.
219    
220     return DB_ERROR;
221     }
222    
223     // }}}
224     // {{{ errorMessage()
225    
226     /**
227     * Map a DB error code to a textual message. This is actually
228     * just a wrapper for DB::errorMessage().
229     *
230     * @param integer $dbcode the DB error code
231     *
232     * @return string the corresponding error message, of FALSE
233     * if the error code was unknown
234     *
235     * @access public
236     */
237    
238     function errorMessage($dbcode)
239     {
240     return DB::errorMessage($this->errorcode_map[$dbcode]);
241     }
242    
243     // }}}
244     // {{{ raiseError()
245    
246     /**
247     * This method is used to communicate an error and invoke error
248     * callbacks etc. Basically a wrapper for PEAR::raiseError
249     * without the message string.
250     *
251     * @param mixed integer error code, or a PEAR error object (all
252     * other parameters are ignored if this parameter is
253     * an object
254     *
255     * @param int error mode, see PEAR_Error docs
256     *
257     * @param mixed If error mode is PEAR_ERROR_TRIGGER, this is the
258     * error level (E_USER_NOTICE etc). If error mode is
259     * PEAR_ERROR_CALLBACK, this is the callback function,
260     * either as a function name, or as an array of an
261     * object and method name. For other error modes this
262     * parameter is ignored.
263     *
264     * @param string Extra debug information. Defaults to the last
265     * query and native error code.
266     *
267     * @param mixed Native error code, integer or string depending the
268     * backend.
269     *
270     * @return object a PEAR error object
271     *
272     * @access public
273     * @see PEAR_Error
274     */
275     function &raiseError($code = DB_ERROR, $mode = null, $options = null,
276     $userinfo = null, $nativecode = null)
277     {
278     // The error is yet a DB error object
279     if (is_object($code)) {
280     // because we the static PEAR::raiseError, our global
281     // handler should be used if it is set
282     if ($mode === null && !empty($this->_default_error_mode)) {
283     $mode = $this->_default_error_mode;
284     $options = $this->_default_error_options;
285     }
286     return PEAR::raiseError($code, null, $mode, $options, null, null, true);
287     }
288    
289     if ($userinfo === null) {
290     $userinfo = $this->last_query;
291     }
292    
293     if ($nativecode) {
294     $userinfo .= " [nativecode=$nativecode]";
295     }
296    
297     return PEAR::raiseError(null, $code, $mode, $options, $userinfo,
298     'DB_Error', true);
299     }
300    
301     // }}}
302     // {{{ setFetchMode()
303    
304     /**
305     * Sets which fetch mode should be used by default on queries
306     * on this connection.
307     *
308     * @param integer $fetchmode DB_FETCHMODE_ORDERED or
309     * DB_FETCHMODE_ASSOC, possibly bit-wise OR'ed with
310     * DB_FETCHMODE_FLIPPED.
311     *
312     * @param string $object_class The class of the object
313     * to be returned by the fetch methods when
314     * the DB_FETCHMODE_OBJECT mode is selected.
315     * If no class is specified by default a cast
316     * to object from the assoc array row will be done.
317     * There is also the posibility to use and extend the
318     * 'DB_Row' class.
319     *
320     * @see DB_FETCHMODE_ORDERED
321     * @see DB_FETCHMODE_ASSOC
322     * @see DB_FETCHMODE_FLIPPED
323     * @see DB_FETCHMODE_OBJECT
324     * @see DB_Row::DB_Row()
325     * @access public
326     */
327    
328     function setFetchMode($fetchmode, $object_class = null)
329     {
330     switch ($fetchmode) {
331     case DB_FETCHMODE_OBJECT:
332     if ($object_class) {
333     $this->fetchmode_object_class = $object_class;
334     }
335     case DB_FETCHMODE_ORDERED:
336     case DB_FETCHMODE_ASSOC:
337     $this->fetchmode = $fetchmode;
338     break;
339     default:
340     return $this->raiseError('invalid fetchmode mode');
341     }
342     }
343    
344     // }}}
345     // {{{ setOption()
346     /**
347     * set the option for the db class
348     *
349     * @param string $option option name
350     * @param mixed $value value for the option
351     *
352     * @return mixed DB_OK or DB_Error
353     */
354     function setOption($option, $value)
355     {
356     if (isset($this->options[$option])) {
357     $this->options[$option] = $value;
358     return DB_OK;
359     }
360     return $this->raiseError("unknown option $option");
361     }
362    
363     // }}}
364     // {{{ getOption()
365     /**
366     * returns the value of an option
367     *
368     * @param string $option option name
369     *
370     * @return mixed the option value
371     */
372     function getOption($option)
373     {
374     if (isset($this->options[$option])) {
375     return $this->options[$option];
376     }
377     return $this->raiseError("unknown option $option");
378     }
379    
380     // }}}
381     // {{{ prepare()
382    
383     /**
384     * Prepares a query for multiple execution with execute().
385     * With some database backends, this is emulated.
386     * prepare() requires a generic query as string like
387     * "INSERT INTO numbers VALUES(?,?,?)". The ? are wildcards.
388     * Types of wildcards:
389     * ? - a quoted scalar value, i.e. strings, integers
390     * & - requires a file name, the content of the file
391     * insert into the query (i.e. saving binary data
392     * in a db)
393     * ! - value is inserted 'as is'
394     *
395     * @param string the query to prepare
396     *
397     * @return resource handle for the query
398     *
399     * @access public
400     * @see execute
401     */
402    
403     function prepare($query)
404     {
405     $tokens = split("[\&\?\!]", $query);
406     $token = 0;
407     $types = array();
408    
409     for ($i = 0; $i < strlen($query); $i++) {
410     switch ($query[$i]) {
411     case '?':
412     $types[$token++] = DB_PARAM_SCALAR;
413     break;
414     case '&':
415     $types[$token++] = DB_PARAM_OPAQUE;
416     break;
417     case '!':
418     $types[$token++] = DB_PARAM_MISC;
419     break;
420     }
421     }
422    
423     $this->prepare_tokens[] = &$tokens;
424     end($this->prepare_tokens);
425    
426     $k = key($this->prepare_tokens);
427     $this->prepare_types[$k] = $types;
428     $this->prepared_queries[$k] = &$query;
429    
430     return $k;
431     }
432    
433     // }}}
434     // {{{ execute()
435     /**
436     * Executes a prepared SQL query
437     * With execute() the generic query of prepare is
438     * assigned with the given data array. The values
439     * of the array inserted into the query in the same
440     * order like the array order
441     *
442     * @param resource $stmt query handle from prepare()
443     * @param array $data numeric array containing the
444     * data to insert into the query
445     *
446     * @return mixed a new DB_Result or a DB_Error when fail
447     *
448     * @access public
449     * @see prepare()
450     */
451     function execute($stmt, $data = false)
452     {
453     $realquery = $this->executeEmulateQuery($stmt, $data);
454     if (DB::isError($realquery)) {
455     return $realquery;
456     }
457     $result = $this->simpleQuery($realquery);
458     if (DB::isError($result) || $result === DB_OK) {
459     return $result;
460     } else {
461     return new DB_result($this, $result);
462     }
463     }
464    
465     // }}}
466     // {{{ executeEmulateQuery()
467    
468     /**
469     * Emulates the execute statement, when not supported
470     *
471     * @param resource $stmt query handle from prepare()
472     * @param array $data numeric array containing the
473     * data to insert into the query
474     *
475     * @return mixed a string containing the real query run when emulating
476     * prepare/execute. A DB error code is returned on failure.
477     *
478     * @access private
479     * @see execute()
480     */
481    
482     function executeEmulateQuery($stmt, $data = false)
483     {
484     $p = &$this->prepare_tokens;
485    
486     if (!isset($this->prepare_tokens[$stmt]) ||
487     !is_array($this->prepare_tokens[$stmt]) ||
488     !sizeof($this->prepare_tokens[$stmt]))
489     {
490     return $this->raiseError(DB_ERROR_INVALID);
491     }
492    
493     $qq = &$this->prepare_tokens[$stmt];
494     $qp = sizeof($qq) - 1;
495    
496     if ((!$data && $qp > 0) ||
497     (!is_array($data) && $qp > 1) ||
498     (is_array($data) && $qp > sizeof($data)))
499     {
500     $this->last_query = $this->prepared_queries[$stmt];
501     return $this->raiseError(DB_ERROR_NEED_MORE_DATA);
502     }
503    
504     $realquery = $qq[0];
505     for ($i = 0; $i < $qp; $i++) {
506     $type = $this->prepare_types[$stmt][$i];
507     if ($type == DB_PARAM_OPAQUE) {
508     if (is_array($data)) {
509     $fp = fopen($data[$i], 'r');
510     } else {
511     $fp = fopen($data, 'r');
512     }
513    
514     $pdata = '';
515    
516     if ($fp) {
517     while (($buf = fread($fp, 4096)) != false) {
518     $pdata .= $buf;
519     }
520     }
521     } else {
522     if (is_array($data)) {
523     $pdata = &$data[$i];
524     } else {
525     $pdata = &$data;
526     }
527     }
528    
529     $realquery .= ($type != DB_PARAM_MISC) ? $this->quote($pdata) : $pdata;
530     $realquery .= $qq[$i + 1];
531     }
532    
533     return $realquery;
534     }
535    
536     // }}}
537     // {{{ executeMultiple()
538    
539     /**
540     * This function does several execute() calls on the same
541     * statement handle. $data must be an array indexed numerically
542     * from 0, one execute call is done for every "row" in the array.
543     *
544     * If an error occurs during execute(), executeMultiple() does not
545     * execute the unfinished rows, but rather returns that error.
546     *
547     * @param resource $stmt query handle from prepare()
548     * @param array $data numeric array containing the
549     * data to insert into the query
550     *
551     * @return mixed DB_OK or DB_Error
552     *
553     * @access public
554     * @see prepare(), execute()
555     */
556    
557     function executeMultiple( $stmt, &$data )
558     {
559     for($i = 0; $i < sizeof( $data ); $i++) {
560     $res = $this->execute($stmt, $data[$i]);
561     if (DB::isError($res)) {
562     return $res;
563     }
564     }
565     return DB_OK;
566     }
567    
568     // }}}
569     // {{{ modifyQuery()
570    
571     /**
572     * This method is used by backends to alter queries for various
573     * reasons. It is defined here to assure that all implementations
574     * have this method defined.
575     *
576     * @param string $query query to modify
577     *
578     * @return the new (modified) query
579     *
580     * @access private
581     */
582     function modifyQuery($query) {
583     return $query;
584     }
585    
586     // }}}
587     // {{{ modifyLimitQuery()
588     /**
589     * This method is used by backends to alter limited queries
590     *
591     * @param string $query query to modify
592     * @param integer $from the row to start to fetching
593     * @param integer $count the numbers of rows to fetch
594     *
595     * @return the new (modified) query
596     *
597     * @access private
598     */
599    
600     function modifyLimitQuery($query, $from, $count)
601     {
602     return $query;
603     }
604    
605     // }}}
606     // {{{ query()
607    
608     /**
609     * Send a query to the database and return any results with a
610     * DB_result object.
611     *
612     * @access public
613     *
614     * @param string $query the SQL query or the statement to prepare
615     * @param string $params the data to be added to the query
616     * @return mixed a DB_result object or DB_OK on success, a DB
617     * error on failure
618     *
619     * @see DB::isError
620     * @see DB_common::prepare
621     * @see DB_common::execute
622     */
623     function &query($query, $params = array()) {
624     if (sizeof($params) > 0) {
625     $sth = $this->prepare($query);
626     if (DB::isError($sth)) {
627     return $sth;
628     }
629     return $this->execute($sth, $params);
630     } else {
631     $result = $this->simpleQuery($query);
632     if (DB::isError($result) || $result === DB_OK) {
633     return $result;
634     } else {
635     return new DB_result($this, $result);
636     }
637     }
638     }
639    
640     // }}}
641     // {{{ limitQuery()
642     /**
643     * Generates a limited query
644     * *EXPERIMENTAL*
645     *
646     * @param string $query query
647     * @param integer $from the row to start to fetching
648     * @param integer $count the numbers of rows to fetch
649     *
650     * @return mixed a DB_Result object or a DB_Error
651     *
652     * @access public
653     */
654     function limitQuery($query, $from, $count)
655     {
656     $query = $this->modifyLimitQuery($query, $from, $count);
657     $result = $this->simpleQuery($query);
658     if (DB::isError($result) || $result === DB_OK) {
659     return $result;
660     } else {
661     $res_obj =& new DB_result($this, $result);
662     $res_obj->limit_from = $from;
663     $res_obj->limit_count = $count;
664     return $res_obj;
665     }
666     }
667    
668     // }}}
669     // {{{ getOne()
670    
671     /**
672     * Fetch the first column of the first row of data returned from
673     * a query. Takes care of doing the query and freeing the results
674     * when finished.
675     *
676     * @param string $query the SQL query
677     * @param array $params if supplied, prepare/execute will be used
678     * with this array as execute parameters
679     *
680     * @return mixed DB_Error or the returned value of the query
681     *
682     * @access public
683     */
684    
685     function &getOne($query, $params = array())
686     {
687     settype($params, "array");
688     if (sizeof($params) > 0) {
689     $sth = $this->prepare($query);
690     if (DB::isError($sth)) {
691     return $sth;
692     }
693     $res = $this->execute($sth, $params);
694     } else {
695     $res = $this->query($query);
696     }
697    
698     if (DB::isError($res)) {
699     return $res;
700     }
701    
702     $err = $res->fetchInto($row, DB_FETCHMODE_ORDERED);
703     if ($err !== DB_OK) {
704     return $err;
705     }
706    
707     $res->free();
708    
709     if (isset($sth)) {
710     $this->freeResult($sth);
711     }
712    
713     return $row[0];
714     }
715    
716     // }}}
717     // {{{ getRow()
718    
719     /**
720     * Fetch the first row of data returned from a query. Takes care
721     * of doing the query and freeing the results when finished.
722     *
723     * @param string $query the SQL query
724     * @param integer $fetchmode the fetch mode to use
725     * @param array $params array if supplied, prepare/execute will be used
726     * with this array as execute parameters
727     * @access public
728     * @return array the first row of results as an array indexed from
729     * 0, or a DB error code.
730     */
731    
732     function &getRow($query,
733     $params = null,
734     $fetchmode = DB_FETCHMODE_DEFAULT)
735     {
736     // compat check, the params and fetchmode parameters used to
737     // have the opposite order
738     if (!is_array($params)) {
739     if (is_array($fetchmode)) {
740     $tmp = $params;
741     $params = $fetchmode;
742     $fetchmode = $tmp;
743     } elseif ($params !== null) {
744     $fetchmode = $params;
745     $params = null;
746     }
747     }
748     $params = (empty($params)) ? array() : $params;
749     $fetchmode = (empty($fetchmode)) ? DB_FETCHMODE_DEFAULT : $fetchmode;
750     settype($params, 'array');
751     if (sizeof($params) > 0) {
752     $sth = $this->prepare($query);
753     if (DB::isError($sth)) {
754     return $sth;
755     }
756     $res = $this->execute($sth, $params);
757     } else {
758     $res = $this->query($query);
759     }
760    
761     if (DB::isError($res)) {
762     return $res;
763     }
764    
765     $err = $res->fetchInto($row, $fetchmode);
766    
767     if ($err !== DB_OK) {
768     return $err;
769     }
770     $res->free();
771    
772     if (isset($sth)) {
773     $this->freeResult($sth);
774     }
775    
776     return $row;
777     }
778    
779     // }}}
780     // {{{ getCol()
781    
782     /**
783     * Fetch a single column from a result set and return it as an
784     * indexed array.
785     *
786     * @param string $query the SQL query
787     *
788     * @param mixed $col which column to return (integer [column number,
789     * starting at 0] or string [column name])
790     *
791     * @param array $params array if supplied, prepare/execute will be used
792     * with this array as execute parameters
793     * @access public
794     *
795     * @return array an indexed array with the data from the first
796     * row at index 0, or a DB error code.
797     */
798    
799     function &getCol($query, $col = 0, $params = array())
800     {
801     settype($params, "array");
802     if (sizeof($params) > 0) {
803     $sth = $this->prepare($query);
804    
805     if (DB::isError($sth)) {
806     return $sth;
807     }
808    
809     $res = $this->execute($sth, $params);
810     } else {
811     $res = $this->query($query);
812     }
813    
814     if (DB::isError($res)) {
815     return $res;
816     }
817    
818     $fetchmode = is_int($col) ? DB_FETCHMODE_ORDERED : DB_FETCHMODE_ASSOC;
819     $ret = array();
820    
821     while (is_array($row = $res->fetchRow($fetchmode))) {
822     $ret[] = $row[$col];
823     }
824     if (DB::isError($row)) {
825     $ret = $row;
826     }
827     $res->free();
828    
829     if (isset($sth)) {
830     $this->freeResult($sth);
831     }
832    
833     return $ret;
834     }
835    
836     // }}}
837     // {{{ getAssoc()
838    
839     /**
840     * Fetch the entire result set of a query and return it as an
841     * associative array using the first column as the key.
842     *
843     * If the result set contains more than two columns, the value
844     * will be an array of the values from column 2-n. If the result
845     * set contains only two columns, the returned value will be a
846     * scalar with the value of the second column (unless forced to an
847     * array with the $force_array parameter). A DB error code is
848     * returned on errors. If the result set contains fewer than two
849     * columns, a DB_ERROR_TRUNCATED error is returned.
850     *
851     * For example, if the table "mytable" contains:
852     *
853     * ID TEXT DATE
854     * --------------------------------
855     * 1 'one' 944679408
856     * 2 'two' 944679408
857     * 3 'three' 944679408
858     *
859     * Then the call getAssoc('SELECT id,text FROM mytable') returns:
860     * array(
861     * '1' => 'one',
862     * '2' => 'two',
863     * '3' => 'three',
864     * )
865     *
866     * ...while the call getAssoc('SELECT id,text,date FROM mytable') returns:
867     * array(
868     * '1' => array('one', '944679408'),
869     * '2' => array('two', '944679408'),
870     * '3' => array('three', '944679408')
871     * )
872     *
873     * If the more than one row occurs with the same value in the
874     * first column, the last row overwrites all previous ones by
875     * default. Use the $group parameter if you don't want to
876     * overwrite like this. Example:
877     *
878     * getAssoc('SELECT category,id,name FROM mytable', false, null,
879     * DB_FETCHMODE_ASSOC, true) returns:
880     * array(
881     * '1' => array(array('id' => '4', 'name' => 'number four'),
882     * array('id' => '6', 'name' => 'number six')
883     * ),
884     * '9' => array(array('id' => '4', 'name' => 'number four'),
885     * array('id' => '6', 'name' => 'number six')
886     * )
887     * )
888     *
889     * Keep in mind that database functions in PHP usually return string
890     * values for results regardless of the database's internal type.
891     *
892     * @param string $query the SQL query
893     *
894     * @param boolean $force_array used only when the query returns
895     * exactly two columns. If true, the values of the returned array
896     * will be one-element arrays instead of scalars.
897     *
898     * @param array $params array if supplied, prepare/execute will be used
899     * with this array as execute parameters
900     *
901     * @param boolean $group if true, the values of the returned array
902     * is wrapped in another array. If the same
903     * key value (in the first column) repeats
904     * itself, the values will be appended to
905     * this array instead of overwriting the
906     * existing values.
907     *
908     * @access public
909     *
910     * @return array associative array with results from the query.
911     */
912    
913     function &getAssoc($query, $force_array = false, $params = array(),
914     $fetchmode = DB_FETCHMODE_ORDERED, $group = false)
915     {
916     settype($params, "array");
917     if (sizeof($params) > 0) {
918     $sth = $this->prepare($query);
919    
920     if (DB::isError($sth)) {
921     return $sth;
922     }
923    
924     $res = $this->execute($sth, $params);
925     } else {
926     $res = $this->query($query);
927     }
928    
929     if (DB::isError($res)) {
930     return $res;
931     }
932    
933     $cols = $res->numCols();
934    
935     if ($cols < 2) {
936     return $this->raiseError(DB_ERROR_TRUNCATED);
937     }
938    
939     $results = array();
940    
941     if ($cols > 2 || $force_array) {
942     // return array values
943     // XXX this part can be optimized
944     if ($fetchmode == DB_FETCHMODE_ASSOC) {
945     while (is_array($row = $res->fetchRow(DB_FETCHMODE_ASSOC))) {
946     reset($row);
947     $key = current($row);
948     unset($row[key($row)]);
949     if ($group) {
950     $results[$key][] = $row;
951     } else {
952     $results[$key] = $row;
953     }
954     }
955     } else {
956     while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
957     // we shift away the first element to get
958     // indices running from 0 again
959     $key = array_shift($row);
960     if ($group) {
961     $results[$key][] = $row;
962     } else {
963     $results[$key] = $row;
964     }
965     }
966     }
967     if (DB::isError($row)) {
968     $results = $row;
969     }
970     } else {
971     // return scalar values
972     while (is_array($row = $res->fetchRow(DB_FETCHMODE_ORDERED))) {
973     if ($group) {
974     $results[$row[0]][] = $row[1];
975     } else {
976     $results[$row[0]] = $row[1];
977     }
978     }
979     if (DB::isError($row)) {
980     $results = $row;
981     }
982     }
983    
984     $res->free();
985    
986     if (isset($sth)) {
987     $this->freeResult($sth);
988     }
989    
990     return $results;
991     }
992    
993     // }}}
994     // {{{ getAll()
995    
996     /**
997     * Fetch all the rows returned from a query.
998     *
999     * @param string $query the SQL query
1000     *
1001     * @param array $params array if supplied, prepare/execute will be used
1002     * with this array as execute parameters
1003     * @param integer $fetchmode the fetch mode to use
1004     *
1005     * @access public
1006     * @return array an nested array, or a DB error
1007     */
1008    
1009     function &getAll($query,
1010     $params = null,
1011     $fetchmode = DB_FETCHMODE_DEFAULT)
1012     {
1013     // compat check, the params and fetchmode parameters used to
1014     // have the opposite order
1015     if (!is_array($params)) {
1016     if (is_array($fetchmode)) {
1017     $tmp = $params;
1018     $params = $fetchmode;
1019     $fetchmode = $tmp;
1020     } elseif ($params !== null) {
1021     $fetchmode = $params;
1022     $params = null;
1023     }
1024     }
1025     $params = (empty($params)) ? array() : $params;
1026     $fetchmode = (empty($fetchmode)) ? DB_FETCHMODE_DEFAULT : $fetchmode;
1027     settype($params, "array");
1028     if (sizeof($params) > 0) {
1029     $sth = $this->prepare($query);
1030    
1031     if (DB::isError($sth)) {
1032     return $sth;
1033     }
1034    
1035     $res = $this->execute($sth, $params);
1036     } else {
1037     $res = $this->query($query);
1038     }
1039    
1040     if (DB::isError($res)) {
1041     return $res;
1042     }
1043    
1044     $results = array();
1045     $this->pushErrorHandling(PEAR_ERROR_RETURN);
1046     while (DB_OK === $res->fetchInto($row, $fetchmode)) {
1047     if ($fetchmode & DB_FETCHMODE_FLIPPED) {
1048     foreach ($row as $key => $val) {
1049     $results[$key][] = $val;
1050     }
1051     } else {
1052     $results[] = $row;
1053     }
1054     }
1055     $this->popErrorHandling();
1056    
1057     $res->free();
1058    
1059     if (isset($sth)) {
1060     $this->freeResult($sth);
1061     }
1062     if (DB::isError($row)) {
1063     return $this->raiseError($row);
1064     }
1065     return $results;
1066     }
1067    
1068     // }}}
1069     // {{{ autoCommit()
1070     /**
1071     * enable automatic Commit
1072     *
1073     * @param boolean $onoff
1074     * @return mixed DB_Error
1075     *
1076     * @access public
1077     */
1078     function autoCommit($onoff=false)
1079     {
1080     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1081     }
1082    
1083     // }}}
1084     // {{{ commit()
1085     /**
1086     * starts a Commit
1087     *
1088     * @return mixed DB_Error
1089     *
1090     * @access public
1091     */
1092     function commit()
1093     {
1094     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1095     }
1096    
1097     // }}}
1098     // {{{ rollback()
1099     /**
1100     * starts a rollback
1101     *
1102     * @return mixed DB_Error
1103     *
1104     * @access public
1105     */
1106     function rollback()
1107     {
1108     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1109     }
1110    
1111     // }}}
1112     // {{{ numRows()
1113     /**
1114     * returns the number of rows in a result object
1115     *
1116     * @param object DB_Result the result object to check
1117     *
1118     * @return mixed DB_Error or the number of rows
1119     *
1120     * @access public
1121     */
1122     function numRows($result)
1123     {
1124     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1125     }
1126    
1127     // }}}
1128     // {{{ affectedRows()
1129     /**
1130     * returns the affected rows of a query
1131     *
1132     * @return mixed DB_Error or number of rows
1133     *
1134     * @access public
1135     */
1136     function affectedRows()
1137     {
1138     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1139     }
1140    
1141     // }}}
1142     // {{{ errorNative()
1143     /**
1144     * returns an errormessage, provides by the database
1145     *
1146     * @return mixed DB_Error or message
1147     *
1148     * @access public
1149     */
1150     function errorNative()
1151     {
1152     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1153     }
1154    
1155     // }}}
1156     // {{{ nextId()
1157     /**
1158     * returns the next free id of a sequence
1159     *
1160     * @param string $seq_name name of the sequence
1161     * @param boolean $ondemand when true the seqence is
1162     * automatic created, if it
1163     * not exists
1164     *
1165     * @return mixed DB_Error or id
1166     */
1167     function nextId($seq_name, $ondemand = true)
1168     {
1169     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1170     }
1171    
1172     // }}}
1173     // {{{ createSequence()
1174     /**
1175     * creates a new sequence
1176     *
1177     * @param string $seq_name name of the new sequence
1178     *
1179     * @return mixed DB_Error
1180     *
1181     * @access public
1182     */
1183     function createSequence($seq_name)
1184     {
1185     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1186     }
1187    
1188     // }}}
1189     // {{{ dropSequence()
1190     /**
1191     * deletes a sequence
1192     *
1193     * @param string $seq_name name of the sequence
1194     *
1195     * @return mixed DB_Error
1196     *
1197     * @access public
1198     */
1199     function dropSequence($seq_name)
1200     {
1201     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1202     }
1203    
1204     // }}}
1205     // {{{ tableInfo()
1206     /**
1207     * returns meta data about the result set
1208     *
1209     * @param object DB_Result $result the result object to analyse
1210     * @param mixed $mode depends on implementation
1211     *
1212     * @return mixed DB_Error
1213     *
1214     * @access public
1215     */
1216     function tableInfo($result, $mode = null)
1217     {
1218     return $this->raiseError(DB_ERROR_NOT_CAPABLE);
1219     }
1220    
1221     // }}}
1222     // {{{ getTables()
1223     /**
1224     * @deprecated
1225     */
1226     function getTables()
1227     {
1228     return $this->getListOf('tables');
1229     }
1230    
1231     // }}}
1232     // {{{ getListOf()
1233     /**
1234     * list internal DB info
1235     * valid values for $type are db dependent,
1236     * often: databases, users, view, functions
1237     *
1238     * @param string $type type of requested info
1239     *
1240     * @return mixed DB_Error or the requested data
1241     *
1242     * @access public
1243     */
1244     function getListOf($type)
1245     {
1246     $sql = $this->getSpecialQuery($type);
1247     if ($sql === null) { // No support
1248     return $this->raiseError(DB_ERROR_UNSUPPORTED);
1249     } elseif (is_int($sql) || DB::isError($sql)) { // Previous error
1250     return $this->raiseError($sql);
1251     } elseif (is_array($sql)) { // Already the result
1252     return $sql;
1253     }
1254     return $this->getCol($sql); // Launch this query
1255     }
1256     // }}}
1257     // {{{ getSequenceName()
1258    
1259     function getSequenceName($sqn)
1260     {
1261     return sprintf($this->getOption("seqname_format"),
1262     preg_replace('/[^a-z0-9_]/i', '_', $sqn));
1263     }
1264    
1265     // }}}
1266     }
1267    
1268     // Used by many drivers
1269     if (!function_exists('array_change_key_case')) {
1270     define('CASE_UPPER', 1);
1271     define('CASE_LOWER', 0);
1272     function &array_change_key_case(&$array, $case) {
1273     $casefunc = ($case == CASE_LOWER) ? 'strtolower' : 'strtoupper';
1274     $ret = array();
1275     foreach ($array as $key => $value) {
1276     $ret[$casefunc($key)] = $value;
1277     }
1278     return $ret;
1279     }
1280     }
1281    
1282     ?>

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