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

Contents of /nfo/php/libs/net.php.pear/DB/mysql.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show 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 <?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: mysql.php,v 1.89.2.1 2002/04/09 19:04:14 ssb Exp $
20 //
21 // Database independent query interface definition for PHP's MySQL
22 // extension.
23 //
24
25 //
26 // XXX legend:
27 //
28 // XXX ERRORMSG: The error message from the mysql function should
29 // be registered here.
30 //
31
32 require_once "DB/common.php";
33
34 class DB_mysql extends DB_common
35 {
36 // {{{ properties
37
38 var $connection;
39 var $phptype, $dbsyntax;
40 var $prepare_tokens = array();
41 var $prepare_types = array();
42 var $num_rows = array();
43 var $transaction_opcount = 0;
44 var $autocommit = true;
45 var $fetchmode = DB_FETCHMODE_ORDERED; /* Default fetch mode */
46 var $_db = false;
47
48 // }}}
49 // {{{ constructor
50
51 /**
52 * DB_mysql constructor.
53 *
54 * @access public
55 */
56
57 function DB_mysql()
58 {
59 $this->DB_common();
60 $this->phptype = 'mysql';
61 $this->dbsyntax = 'mysql';
62 $this->features = array(
63 'prepare' => false,
64 'pconnect' => true,
65 'transactions' => true,
66 'limit' => 'alter'
67 );
68 $this->errorcode_map = array(
69 1004 => DB_ERROR_CANNOT_CREATE,
70 1005 => DB_ERROR_CANNOT_CREATE,
71 1006 => DB_ERROR_CANNOT_CREATE,
72 1007 => DB_ERROR_ALREADY_EXISTS,
73 1008 => DB_ERROR_CANNOT_DROP,
74 1046 => DB_ERROR_NODBSELECTED,
75 1050 => DB_ERROR_ALREADY_EXISTS,
76 1051 => DB_ERROR_NOSUCHTABLE,
77 1054 => DB_ERROR_NOSUCHFIELD,
78 1062 => DB_ERROR_ALREADY_EXISTS,
79 1064 => DB_ERROR_SYNTAX,
80 1100 => DB_ERROR_NOT_LOCKED,
81 1136 => DB_ERROR_VALUE_COUNT_ON_ROW,
82 1146 => DB_ERROR_NOSUCHTABLE,
83 1048 => DB_ERROR_CONSTRAINT,
84 );
85 }
86
87 // }}}
88
89 // {{{ connect()
90
91 /**
92 * Connect to a database and log in as the specified user.
93 *
94 * @param $dsn the data source name (see DB::parseDSN for syntax)
95 * @param $persistent (optional) whether the connection should
96 * be persistent
97 * @access public
98 * @return int DB_OK on success, a DB error on failure
99 */
100
101 function connect($dsninfo, $persistent = false)
102 {
103 if (!DB::assertExtension('mysql'))
104 return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND);
105
106 $this->dsn = $dsninfo;
107 if (isset($dsninfo['protocol']) && $dsninfo['protocol'] == 'unix') {
108 $dbhost = ':' . $dsninfo['socket'];
109 } else {
110 $dbhost = $dsninfo['hostspec'] ? $dsninfo['hostspec'] : 'localhost';
111 if (!empty($dsninfo['port'])) {
112 $dbhost .= ':' . $dsninfo['port'];
113 }
114 }
115 $user = $dsninfo['username'];
116 $pw = $dsninfo['password'];
117
118 $connect_function = $persistent ? 'mysql_pconnect' : 'mysql_connect';
119
120 @ini_set('track_errors', true);
121 if ($dbhost && $user && $pw) {
122 $conn = @$connect_function($dbhost, $user, $pw);
123 } elseif ($dbhost && $user) {
124 $conn = @$connect_function($dbhost, $user);
125 } elseif ($dbhost) {
126 $conn = @$connect_function($dbhost);
127 } else {
128 $conn = false;
129 }
130 @ini_restore('track_errors');
131 if (empty($conn)) {
132 if (($err = @mysql_error()) != '') {
133 return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
134 null, $err);
135 } elseif (empty($php_errormsg)) {
136 return $this->raiseError(DB_ERROR_CONNECT_FAILED);
137 } else {
138 return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null,
139 null, $php_errormsg);
140 }
141 }
142
143 if ($dsninfo['database']) {
144 if (!@mysql_select_db($dsninfo['database'], $conn)) {
145 switch(mysql_errno($conn)) {
146 case 1049:
147 return $this->raiseError(DB_ERROR_NOSUCHDB, null, null,
148 null, mysql_error($conn));
149 break;
150 case 1044:
151 return $this->raiseError(DB_ERROR_ACCESS_VIOLATION, null, null,
152 null, mysql_error($conn));
153 break;
154 default:
155 return $this->raiseError(DB_ERROR, null, null,
156 null, mysql_error($conn));
157 break;
158
159 }
160 }
161 // fix to allow calls to different databases in the same script
162 $this->_db = $dsninfo['database'];
163 }
164
165 $this->connection = $conn;
166 return DB_OK;
167 }
168
169 // }}}
170 // {{{ disconnect()
171
172 /**
173 * Log out and disconnect from the database.
174 *
175 * @access public
176 *
177 * @return bool TRUE on success, FALSE if not connected.
178 */
179 function disconnect()
180 {
181 $ret = mysql_close($this->connection);
182 $this->connection = null;
183 return $ret;
184 }
185
186 // }}}
187 // {{{ simpleQuery()
188
189 /**
190 * Send a query to MySQL and return the results as a MySQL resource
191 * identifier.
192 *
193 * @param the SQL query
194 *
195 * @access public
196 *
197 * @return mixed returns a valid MySQL result for successful SELECT
198 * queries, DB_OK for other successful queries. A DB error is
199 * returned on failure.
200 */
201 function simpleQuery($query)
202 {
203 $ismanip = DB::isManip($query);
204 $this->last_query = $query;
205 $query = $this->modifyQuery($query);
206 if (!@mysql_select_db($this->_db, $this->connection)) {
207 return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
208 }
209 if (!$this->autocommit && $ismanip) {
210 if ($this->transaction_opcount == 0) {
211 $result = @mysql_query('SET AUTOCOMMIT=0', $this->connection);
212 $result = @mysql_query('BEGIN', $this->connection);
213 if (!$result) {
214 return $this->mysqlRaiseError();
215 }
216 }
217 $this->transaction_opcount++;
218 }
219 $result = @mysql_query($query, $this->connection);
220 if (!$result) {
221 return $this->mysqlRaiseError();
222 }
223 if (is_resource($result)) {
224 $numrows = $this->numrows($result);
225 if (is_object($numrows)) {
226 return $numrows;
227 }
228 $this->num_rows[$result] = $numrows;
229 return $result;
230 }
231 return DB_OK;
232 }
233
234 // }}}
235 // {{{ nextResult()
236
237 /**
238 * Move the internal mysql result pointer to the next available result
239 *
240 * @param a valid fbsql result resource
241 *
242 * @access public
243 *
244 * @return true if a result is available otherwise return false
245 */
246 function nextResult($result)
247 {
248 return false;
249 }
250
251 // }}}
252 // {{{ fetchRow()
253
254 /**
255 * Fetch and return a row of data (it uses fetchInto for that)
256 * @param $result MySQL result identifier
257 * @param $fetchmode format of fetched row array
258 * @param $rownum the absolute row number to fetch
259 *
260 * @return array a row of data, or false on error
261 */
262 function fetchRow($result, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum=null)
263 {
264 if ($fetchmode == DB_FETCHMODE_DEFAULT) {
265 $fetchmode = $this->fetchmode;
266 }
267 $res = $this->fetchInto ($result, $arr, $fetchmode, $rownum);
268 if ($res !== DB_OK) {
269 return $res;
270 }
271 return $arr;
272 }
273
274 // }}}
275 // {{{ fetchInto()
276
277 /**
278 * Fetch a row and insert the data into an existing array.
279 *
280 * @param $result MySQL result identifier
281 * @param $arr (reference) array where data from the row is stored
282 * @param $fetchmode how the array data should be indexed
283 * @param $rownum the row number to fetch
284 * @access public
285 *
286 * @return int DB_OK on success, a DB error on failure
287 */
288 function fetchInto($result, &$arr, $fetchmode, $rownum=null)
289 {
290 if ($rownum !== null) {
291 if (!@mysql_data_seek($result, $rownum)) {
292 return null;
293 }
294 }
295 if ($fetchmode & DB_FETCHMODE_ASSOC) {
296 $arr = @mysql_fetch_array($result, MYSQL_ASSOC);
297 } else {
298 $arr = @mysql_fetch_row($result);
299 }
300 if (!$arr) {
301 $errno = @mysql_errno($this->connection);
302 if (!$errno) {
303 return NULL;
304 }
305 return $this->mysqlRaiseError($errno);
306 }
307 return DB_OK;
308 }
309
310 // }}}
311 // {{{ freeResult()
312
313 /**
314 * Free the internal resources associated with $result.
315 *
316 * @param $result MySQL result identifier or DB statement identifier
317 *
318 * @access public
319 *
320 * @return bool TRUE on success, FALSE if $result is invalid
321 */
322 function freeResult($result)
323 {
324 if (is_resource($result)) {
325 return mysql_free_result($result);
326 }
327
328 $result = (int)$result; // $result is a prepared query handle
329 if (!isset($this->prepare_tokens[$result])) {
330 return false;
331 }
332
333 // [ssb]: WTF? unset($this->prepare_types[$result]) makes PHP
334 // crash on my laptop (4.1.2 as well as 4.3.0-dev)
335
336 $copy = $this->prepare_types;
337 unset($copy[$result]);
338 $this->prepare_types = $copy;
339 // unset($this->prepare_types[$result]);
340
341 $copy = $this->prepare_tokens;
342 unset($copy[$result]);
343 $this->prepare_tokens = $copy;
344 // unset($this->prepare_tokens[$result]);
345
346 return true;
347 }
348
349 // }}}
350 // {{{ numCols()
351
352 /**
353 * Get the number of columns in a result set.
354 *
355 * @param $result MySQL result identifier
356 *
357 * @access public
358 *
359 * @return int the number of columns per row in $result
360 */
361 function numCols($result)
362 {
363 $cols = @mysql_num_fields($result);
364
365 if (!$cols) {
366 return $this->mysqlRaiseError();
367 }
368
369 return $cols;
370 }
371
372 // }}}
373 // {{{ numRows()
374
375 /**
376 * Get the number of rows in a result set.
377 *
378 * @param $result MySQL result identifier
379 *
380 * @access public
381 *
382 * @return int the number of rows in $result
383 */
384 function numRows($result)
385 {
386 $rows = @mysql_num_rows($result);
387 if ($rows === null) {
388 return $this->mysqlRaiseError();
389 }
390 return $rows;
391 }
392
393 // }}}
394 // {{{ autoCommit()
395
396 /**
397 * Enable/disable automatic commits
398 */
399 function autoCommit($onoff = false)
400 {
401 // XXX if $this->transaction_opcount > 0, we should probably
402 // issue a warning here.
403 $this->autocommit = $onoff ? true : false;
404 return DB_OK;
405 }
406
407 // }}}
408 // {{{ commit()
409
410 /**
411 * Commit the current transaction.
412 */
413 function commit()
414 {
415 if ($this->transaction_opcount > 0) {
416 if (!@mysql_select_db($this->_db, $this->connection)) {
417 return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
418 }
419 $result = @mysql_query('COMMIT', $this->connection);
420 $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
421 $this->transaction_opcount = 0;
422 if (!$result) {
423 return $this->mysqlRaiseError();
424 }
425 }
426 return DB_OK;
427 }
428
429 // }}}
430 // {{{ rollback()
431
432 /**
433 * Roll back (undo) the current transaction.
434 */
435 function rollback()
436 {
437 if ($this->transaction_opcount > 0) {
438 if (!@mysql_select_db($this->_db, $this->connection)) {
439 return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
440 }
441 $result = @mysql_query('ROLLBACK', $this->connection);
442 $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection);
443 $this->transaction_opcount = 0;
444 if (!$result) {
445 return $this->mysqlRaiseError();
446 }
447 }
448 return DB_OK;
449 }
450
451 // }}}
452 // {{{ affectedRows()
453
454 /**
455 * Gets the number of rows affected by the data manipulation
456 * query. For other queries, this function returns 0.
457 *
458 * @return number of rows affected by the last query
459 */
460
461 function affectedRows()
462 {
463 if (DB::isManip($this->last_query)) {
464 $result = @mysql_affected_rows($this->connection);
465 } else {
466 $result = 0;
467 }
468 return $result;
469 }
470
471 // }}}
472 // {{{ errorNative()
473
474 /**
475 * Get the native error code of the last error (if any) that
476 * occured on the current connection.
477 *
478 * @access public
479 *
480 * @return int native MySQL error code
481 */
482
483 function errorNative()
484 {
485 return mysql_errno($this->connection);
486 }
487
488 // }}}
489 // {{{ nextId()
490
491 /**
492 * Get the next value in a sequence. We emulate sequences
493 * for MySQL. Will create the sequence if it does not exist.
494 *
495 * @access public
496 *
497 * @param string $seq_name the name of the sequence
498 *
499 * @param bool $ondemand whether to create the sequence table on demand
500 * (default is true)
501 *
502 * @return mixed a sequence integer, or a DB error
503 */
504 function nextId($seq_name, $ondemand = true)
505 {
506 $seqname = $this->getSequenceName($seq_name);
507 do {
508 $repeat = 0;
509 $this->pushErrorHandling(PEAR_ERROR_RETURN);
510 $result = $this->query("UPDATE ${seqname} ".
511 'SET id=LAST_INSERT_ID(id+1)');
512 $this->popErrorHandling();
513 if ($result == DB_OK) {
514 /** COMMON CASE **/
515 $id = mysql_insert_id($this->connection);
516 if ($id != 0) {
517 return $id;
518 }
519 /** EMPTY SEQ TABLE **/
520 // Sequence table must be empty for some reason, so fill it and return 1
521 // Obtain a user-level lock
522 $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
523 if (DB::isError($result)) {
524 return $this->raiseError($result);
525 }
526 if ($result == 0) {
527 // Failed to get the lock, bail with a DB_ERROR_NOT_LOCKED error
528 return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
529 }
530
531 // add the default value
532 $result = $this->query("REPLACE INTO ${seqname} VALUES (0)");
533 if (DB::isError($result)) {
534 return $this->raiseError($result);
535 }
536
537 // Release the lock
538 $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')");
539 if (DB::isError($result)) {
540 return $this->raiseError($result);
541 }
542 // We know what the result will be, so no need to try again
543 return 1;
544
545 /** ONDEMAND TABLE CREATION **/
546 } elseif ($ondemand && DB::isError($result) &&
547 $result->getCode() == DB_ERROR_NOSUCHTABLE)
548 {
549 $result = $this->createSequence($seq_name);
550 // Since createSequence initializes the ID to be 1,
551 // we do not need to retrieve the ID again (or we will get 2)
552 if (DB::isError($result)) {
553 return $this->raiseError($result);
554 } else {
555 // First ID of a newly created sequence is 1
556 return 1;
557 }
558
559 /** BACKWARDS COMPAT **/
560 } elseif (DB::isError($result) &&
561 $result->getCode() == DB_ERROR_ALREADY_EXISTS)
562 {
563 // see _BCsequence() comment
564 $result = $this->_BCsequence($seqname);
565 if (DB::isError($result)) {
566 return $this->raiseError($result);
567 }
568 $repeat = 1;
569 }
570 } while ($repeat);
571
572 return $this->raiseError($result);
573 }
574
575 // }}}
576 // {{{ createSequence()
577
578 function createSequence($seq_name)
579 {
580 $seqname = $this->getSequenceName($seq_name);
581 $res = $this->query("CREATE TABLE ${seqname} ".
582 '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'.
583 ' PRIMARY KEY(id))');
584 if (DB::isError($res)) {
585 return $res;
586 }
587 // insert yields value 1, nextId call will generate ID 2
588 return $this->query("INSERT INTO ${seqname} VALUES(0)");
589 }
590
591 // }}}
592 // {{{ dropSequence()
593
594 function dropSequence($seq_name)
595 {
596 $seqname = $this->getSequenceName($seq_name);
597 return $this->query("DROP TABLE ${seqname}");
598 }
599
600 // }}}
601
602 /**
603 * Bacwards Compatibility with old sequence emulation implementation
604 * (clean up the dupes)
605 * @param string $seqname The sequence name to clean up
606 * @return mixed DB_Error or true
607 */
608 function _BCsequence($seqname)
609 {
610 // Obtain a user-level lock... this will release any previous
611 // application locks, but unlike LOCK TABLES, it does not abort
612 // the current transaction and is much less frequently used.
613 $result = $this->getOne("SELECT GET_LOCK('${seqname}_lock',10)");
614 if (DB::isError($result)) {
615 return $result;
616 }
617 if ($result == 0) {
618 // Failed to get the lock, can't do the conversion, bail
619 // with a DB_ERROR_NOT_LOCKED error
620 return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED);
621 }
622
623 $highest_id = $this->getOne("SELECT MAX(id) FROM ${seqname}");
624 if (DB::isError($highest_id)) {
625 return $highest_id;
626 }
627 // This should kill all rows except the highest
628 // We should probably do something if $highest_id isn't
629 // numeric, but I'm at a loss as how to handle that...
630 $result = $this->query("DELETE FROM ${seqname} WHERE id <> $highest_id");
631 if (DB::isError($result)) {
632 return $result;
633 }
634
635 // If another thread has been waiting for this lock,
636 // it will go thru the above procedure, but will have no
637 // real effect
638 $result = $this->getOne("SELECT RELEASE_LOCK('${seqname}_lock')");
639 if (DB::isError($result)) {
640 return $result;
641 }
642 return true;
643 }
644
645 // {{{ quote()
646 /**
647 * Quote the given string so it can be safely used within string delimiters
648 * in a query.
649 * @param $string mixed Data to be quoted
650 * @return mixed "NULL" string, quoted string or original data
651 */
652 function quote($str = null)
653 {
654 switch (strtolower(gettype($str))) {
655 case 'null':
656 return 'NULL';
657 case 'integer':
658 return $str;
659 case 'string':
660 default:
661 return "'".mysql_escape_string($str)."'";
662 }
663 }
664 // }}}
665 // {{{ modifyQuery()
666
667 function modifyQuery($query, $subject = null)
668 {
669 if ($this->options['optimize'] == 'portability') {
670 // "DELETE FROM table" gives 0 affected rows in MySQL.
671 // This little hack lets you know how many rows were deleted.
672 if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) {
673 $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/',
674 'DELETE FROM \1 WHERE 1=1', $query);
675 }
676 }
677 return $query;
678 }
679
680 // }}}
681 // {{{ modifyLimitQuery()
682
683 function modifyLimitQuery($query, $from, $count)
684 {
685 $query = $query . " LIMIT $from, $count";
686 return $query;
687 }
688
689 // }}}
690 // {{{ mysqlRaiseError()
691
692 function mysqlRaiseError($errno = null)
693 {
694 if ($errno === null) {
695 $errno = $this->errorCode(mysql_errno($this->connection));
696 }
697 return $this->raiseError($errno, null, null, null,
698 @mysql_errno($this->connection) . " ** " .
699 @mysql_error($this->connection));
700 }
701
702 // }}}
703 // {{{ tableInfo()
704
705 function tableInfo($result, $mode = null) {
706 $count = 0;
707 $id = 0;
708 $res = array();
709
710 /*
711 * depending on $mode, metadata returns the following values:
712 *
713 * - mode is false (default):
714 * $result[]:
715 * [0]["table"] table name
716 * [0]["name"] field name
717 * [0]["type"] field type
718 * [0]["len"] field length
719 * [0]["flags"] field flags
720 *
721 * - mode is DB_TABLEINFO_ORDER
722 * $result[]:
723 * ["num_fields"] number of metadata records
724 * [0]["table"] table name
725 * [0]["name"] field name
726 * [0]["type"] field type
727 * [0]["len"] field length
728 * [0]["flags"] field flags
729 * ["order"][field name] index of field named "field name"
730 * The last one is used, if you have a field name, but no index.
731 * Test: if (isset($result['meta']['myfield'])) { ...
732 *
733 * - mode is DB_TABLEINFO_ORDERTABLE
734 * the same as above. but additionally
735 * ["ordertable"][table name][field name] index of field
736 * named "field name"
737 *
738 * this is, because if you have fields from different
739 * tables with the same field name * they override each
740 * other with DB_TABLEINFO_ORDER
741 *
742 * you can combine DB_TABLEINFO_ORDER and
743 * DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER |
744 * DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL
745 */
746
747 // if $result is a string, then we want information about a
748 // table without a resultset
749 if (is_string($result)) {
750 $id = @mysql_list_fields($this->dsn['database'],
751 $result, $this->connection);
752 if (empty($id)) {
753 return $this->mysqlRaiseError();
754 }
755 } else { // else we want information about a resultset
756 $id = $result;
757 if (empty($id)) {
758 return $this->mysqlRaiseError();
759 }
760 }
761
762 $count = @mysql_num_fields($id);
763
764 // made this IF due to performance (one if is faster than $count if's)
765 if (empty($mode)) {
766 for ($i=0; $i<$count; $i++) {
767 $res[$i]['table'] = @mysql_field_table ($id, $i);
768 $res[$i]['name'] = @mysql_field_name ($id, $i);
769 $res[$i]['type'] = @mysql_field_type ($id, $i);
770 $res[$i]['len'] = @mysql_field_len ($id, $i);
771 $res[$i]['flags'] = @mysql_field_flags ($id, $i);
772 }
773 } else { // full
774 $res['num_fields']= $count;
775
776 for ($i=0; $i<$count; $i++) {
777 $res[$i]['table'] = @mysql_field_table ($id, $i);
778 $res[$i]['name'] = @mysql_field_name ($id, $i);
779 $res[$i]['type'] = @mysql_field_type ($id, $i);
780 $res[$i]['len'] = @mysql_field_len ($id, $i);
781 $res[$i]['flags'] = @mysql_field_flags ($id, $i);
782 if ($mode & DB_TABLEINFO_ORDER) {
783 $res['order'][$res[$i]['name']] = $i;
784 }
785 if ($mode & DB_TABLEINFO_ORDERTABLE) {
786 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i;
787 }
788 }
789 }
790
791 // free the result only if we were called on a table
792 if (is_string($result)) {
793 @mysql_free_result($id);
794 }
795 return $res;
796 }
797
798 // }}}
799 // {{{ getTablesQuery()
800
801 /**
802 * Returns the query needed to get some backend info
803 * @param string $type What kind of info you want to retrieve
804 * @return string The SQL query string
805 */
806 function getSpecialQuery($type)
807 {
808 switch ($type) {
809 case 'tables':
810 $sql = "SHOW TABLES";
811 break;
812 case 'views':
813 return DB_ERROR_NOT_CAPABLE;
814 case 'users':
815 $sql = "select distinct User from user";
816 if($this->dsn['database'] != 'mysql') {
817 $dsn = $this->dsn;
818 $dsn['database'] = 'mysql';
819 if (DB::isError($db = DB::connect($dsn))) {
820 return $db;
821 }
822 $sql = $db->getCol($sql);
823 $db->disconnect();
824 // XXX Fixme the mysql driver should take care of this
825 if (!@mysql_select_db($this->dsn['database'], $this->connection)) {
826 return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED);
827 }
828 }
829 return $sql;
830 break;
831 case 'databases':
832 $sql = "SHOW DATABASES";
833 break;
834 default:
835 return null;
836 }
837 return $sql;
838 }
839
840 // }}}
841
842 // TODO/wishlist:
843 // longReadlen
844 // binmode
845 }
846
847 ?>

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