[ Index ] |
|
Code source de Dolibarr 2.0.1 |
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ 3 // +----------------------------------------------------------------------+ 4 // | PHP Version 4 | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 1997-2003 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@php.net> | 17 // +----------------------------------------------------------------------+ 18 // 19 // $Id: mysql.php,v 1.2 2004/07/20 17:41:40 rodolphe 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 DOL_DOCUMENT_ROOT."/includes/pear/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 if ($dbhost && $user && $pw) { 121 $conn = @$connect_function($dbhost, $user, $pw); 122 } elseif ($dbhost && $user) { 123 $conn = @$connect_function($dbhost, $user); 124 } elseif ($dbhost) { 125 $conn = @$connect_function($dbhost); 126 } else { 127 $conn = false; 128 } 129 if (empty($conn)) { 130 if (($err = @mysql_error()) != '') { 131 return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, 132 null, $err); 133 } elseif (empty($php_errormsg)) { 134 return $this->raiseError(DB_ERROR_CONNECT_FAILED); 135 } else { 136 return $this->raiseError(DB_ERROR_CONNECT_FAILED, null, null, 137 null, $php_errormsg); 138 } 139 } 140 141 if ($dsninfo['database']) { 142 if (!@mysql_select_db($dsninfo['database'], $conn)) { 143 switch(mysql_errno($conn)) { 144 case 1049: 145 return $this->raiseError(DB_ERROR_NOSUCHDB, null, null, 146 null, mysql_error($conn)); 147 break; 148 case 1044: 149 return $this->raiseError(DB_ERROR_ACCESS_VIOLATION, null, null, 150 null, mysql_error($conn)); 151 break; 152 default: 153 return $this->raiseError(DB_ERROR, null, null, 154 null, mysql_error($conn)); 155 break; 156 157 } 158 } 159 // fix to allow calls to different databases in the same script 160 $this->_db = $dsninfo['database']; 161 } 162 163 $this->connection = $conn; 164 return DB_OK; 165 } 166 167 // }}} 168 // {{{ disconnect() 169 170 /** 171 * Log out and disconnect from the database. 172 * 173 * @access public 174 * 175 * @return bool TRUE on success, FALSE if not connected. 176 */ 177 function disconnect() 178 { 179 $ret = mysql_close($this->connection); 180 $this->connection = null; 181 return $ret; 182 } 183 184 // }}} 185 // {{{ simpleQuery() 186 187 /** 188 * Send a query to MySQL and return the results as a MySQL resource 189 * identifier. 190 * 191 * @param the SQL query 192 * 193 * @access public 194 * 195 * @return mixed returns a valid MySQL result for successful SELECT 196 * queries, DB_OK for other successful queries. A DB error is 197 * returned on failure. 198 */ 199 function simpleQuery($query) 200 { 201 $ismanip = DB::isManip($query); 202 $this->last_query = $query; 203 $query = $this->modifyQuery($query); 204 if ($this->_db) { 205 if (!@mysql_select_db($this->_db, $this->connection)) { 206 return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); 207 } 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 * This method has not been implemented yet. 241 * 242 * @param a valid sql result resource 243 * 244 * @access public 245 * 246 * @return false 247 */ 248 function nextResult($result) 249 { 250 return false; 251 } 252 253 // }}} 254 // {{{ fetchInto() 255 256 /** 257 * Fetch a row and insert the data into an existing array. 258 * 259 * @param $result MySQL result identifier 260 * @param $arr (reference) array where data from the row is stored 261 * @param $fetchmode how the array data should be indexed 262 * @param $rownum the row number to fetch 263 * @access public 264 * 265 * @return int DB_OK on success, a DB error on failure 266 */ 267 function fetchInto($result, &$arr, $fetchmode, $rownum=null) 268 { 269 if ($rownum !== null) { 270 if (!@mysql_data_seek($result, $rownum)) { 271 return null; 272 } 273 } 274 if ($fetchmode & DB_FETCHMODE_ASSOC) { 275 $arr = @mysql_fetch_array($result, MYSQL_ASSOC); 276 } else { 277 $arr = @mysql_fetch_row($result); 278 } 279 if (!$arr) { 280 // See: http://bugs.php.net/bug.php?id=22328 281 // for why we can't check errors on fetching 282 return null; 283 /* 284 $errno = @mysql_errno($this->connection); 285 if (!$errno) { 286 return NULL; 287 } 288 return $this->mysqlRaiseError($errno); 289 */ 290 } 291 return DB_OK; 292 } 293 294 // }}} 295 // {{{ freeResult() 296 297 /** 298 * Free the internal resources associated with $result. 299 * 300 * @param $result MySQL result identifier or DB statement identifier 301 * 302 * @access public 303 * 304 * @return bool TRUE on success, FALSE if $result is invalid 305 */ 306 function freeResult($result) 307 { 308 if (is_resource($result)) { 309 return mysql_free_result($result); 310 } 311 312 $result = (int)$result; // $result is a prepared query handle 313 if (!isset($this->prepare_tokens[$result])) { 314 return false; 315 } 316 317 318 // I fixed the unset thing. 319 320 $this->prepare_types = array(); 321 $this->prepare_tokens = array(); 322 323 return true; 324 } 325 326 // }}} 327 // {{{ numCols() 328 329 /** 330 * Get the number of columns in a result set. 331 * 332 * @param $result MySQL result identifier 333 * 334 * @access public 335 * 336 * @return int the number of columns per row in $result 337 */ 338 function numCols($result) 339 { 340 $cols = @mysql_num_fields($result); 341 342 if (!$cols) { 343 return $this->mysqlRaiseError(); 344 } 345 346 return $cols; 347 } 348 349 // }}} 350 // {{{ numRows() 351 352 /** 353 * Get the number of rows in a result set. 354 * 355 * @param $result MySQL result identifier 356 * 357 * @access public 358 * 359 * @return int the number of rows in $result 360 */ 361 function numRows($result) 362 { 363 $rows = @mysql_num_rows($result); 364 if ($rows === null) { 365 return $this->mysqlRaiseError(); 366 } 367 return $rows; 368 } 369 370 // }}} 371 // {{{ autoCommit() 372 373 /** 374 * Enable/disable automatic commits 375 */ 376 function autoCommit($onoff = false) 377 { 378 // XXX if $this->transaction_opcount > 0, we should probably 379 // issue a warning here. 380 $this->autocommit = $onoff ? true : false; 381 return DB_OK; 382 } 383 384 // }}} 385 // {{{ commit() 386 387 /** 388 * Commit the current transaction. 389 */ 390 function commit() 391 { 392 if ($this->transaction_opcount > 0) { 393 if ($this->_db) { 394 if (!@mysql_select_db($this->_db, $this->connection)) { 395 return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); 396 } 397 } 398 $result = @mysql_query('COMMIT', $this->connection); 399 $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); 400 $this->transaction_opcount = 0; 401 if (!$result) { 402 return $this->mysqlRaiseError(); 403 } 404 } 405 return DB_OK; 406 } 407 408 // }}} 409 // {{{ rollback() 410 411 /** 412 * Roll back (undo) the current transaction. 413 */ 414 function rollback() 415 { 416 if ($this->transaction_opcount > 0) { 417 if ($this->_db) { 418 if (!@mysql_select_db($this->_db, $this->connection)) { 419 return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); 420 } 421 } 422 $result = @mysql_query('ROLLBACK', $this->connection); 423 $result = @mysql_query('SET AUTOCOMMIT=1', $this->connection); 424 $this->transaction_opcount = 0; 425 if (!$result) { 426 return $this->mysqlRaiseError(); 427 } 428 } 429 return DB_OK; 430 } 431 432 // }}} 433 // {{{ affectedRows() 434 435 /** 436 * Gets the number of rows affected by the data manipulation 437 * query. For other queries, this function returns 0. 438 * 439 * @return number of rows affected by the last query 440 */ 441 442 function affectedRows() 443 { 444 if (DB::isManip($this->last_query)) { 445 $result = @mysql_affected_rows($this->connection); 446 } else { 447 $result = 0; 448 } 449 return $result; 450 } 451 452 // }}} 453 // {{{ errorNative() 454 455 /** 456 * Get the native error code of the last error (if any) that 457 * occured on the current connection. 458 * 459 * @access public 460 * 461 * @return int native MySQL error code 462 */ 463 464 function errorNative() 465 { 466 return mysql_errno($this->connection); 467 } 468 469 // }}} 470 // {{{ nextId() 471 472 /** 473 * Get the next value in a sequence. We emulate sequences 474 * for MySQL. Will create the sequence if it does not exist. 475 * 476 * @access public 477 * 478 * @param string $seq_name the name of the sequence 479 * 480 * @param bool $ondemand whether to create the sequence table on demand 481 * (default is true) 482 * 483 * @return mixed a sequence integer, or a DB error 484 */ 485 function nextId($seq_name, $ondemand = true) 486 { 487 $seqname = $this->getSequenceName($seq_name); 488 do { 489 $repeat = 0; 490 $this->pushErrorHandling(PEAR_ERROR_RETURN); 491 $result = $this->query("UPDATE $seqname} ". 492 'SET id=LAST_INSERT_ID(id+1)'); 493 $this->popErrorHandling(); 494 if ($result == DB_OK) { 495 /** COMMON CASE **/ 496 $id = mysql_insert_id($this->connection); 497 if ($id != 0) { 498 return $id; 499 } 500 /** EMPTY SEQ TABLE **/ 501 // Sequence table must be empty for some reason, so fill it and return 1 502 // Obtain a user-level lock 503 $result = $this->getOne("SELECT GET_LOCK('$seqname}_lock',10)"); 504 if (DB::isError($result)) { 505 return $this->raiseError($result); 506 } 507 if ($result == 0) { 508 // Failed to get the lock, bail with a DB_ERROR_NOT_LOCKED error 509 return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); 510 } 511 512 // add the default value 513 $result = $this->query("REPLACE INTO $seqname} VALUES (0)"); 514 if (DB::isError($result)) { 515 return $this->raiseError($result); 516 } 517 518 // Release the lock 519 $result = $this->getOne("SELECT RELEASE_LOCK('$seqname}_lock')"); 520 if (DB::isError($result)) { 521 return $this->raiseError($result); 522 } 523 // We know what the result will be, so no need to try again 524 return 1; 525 526 /** ONDEMAND TABLE CREATION **/ 527 } elseif ($ondemand && DB::isError($result) && 528 $result->getCode() == DB_ERROR_NOSUCHTABLE) 529 { 530 $result = $this->createSequence($seq_name); 531 if (DB::isError($result)) { 532 return $this->raiseError($result); 533 } else { 534 $repeat = 1; 535 } 536 537 /** BACKWARDS COMPAT **/ 538 } elseif (DB::isError($result) && 539 $result->getCode() == DB_ERROR_ALREADY_EXISTS) 540 { 541 // see _BCsequence() comment 542 $result = $this->_BCsequence($seqname); 543 if (DB::isError($result)) { 544 return $this->raiseError($result); 545 } 546 $repeat = 1; 547 } 548 } while ($repeat); 549 550 return $this->raiseError($result); 551 } 552 553 // }}} 554 // {{{ createSequence() 555 556 function createSequence($seq_name) 557 { 558 $seqname = $this->getSequenceName($seq_name); 559 $res = $this->query("CREATE TABLE $seqname} ". 560 '(id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL,'. 561 ' PRIMARY KEY(id))'); 562 if (DB::isError($res)) { 563 return $res; 564 } 565 // insert yields value 1, nextId call will generate ID 2 566 $res = $this->query("INSERT INTO $seqname} VALUES(0)"); 567 if (DB::isError($res)) { 568 return $res; 569 } 570 // so reset to zero 571 return $this->query("UPDATE $seqname} SET id = 0;"); 572 } 573 574 // }}} 575 // {{{ dropSequence() 576 577 function dropSequence($seq_name) 578 { 579 $seqname = $this->getSequenceName($seq_name); 580 return $this->query("DROP TABLE $seqname}"); 581 } 582 583 // }}} 584 // {{{ _BCsequence() 585 586 /** 587 * Backwards compatibility with old sequence emulation implementation 588 * (clean up the dupes) 589 * 590 * @param string $seqname The sequence name to clean up 591 * @return mixed DB_Error or true 592 */ 593 function _BCsequence($seqname) 594 { 595 // Obtain a user-level lock... this will release any previous 596 // application locks, but unlike LOCK TABLES, it does not abort 597 // the current transaction and is much less frequently used. 598 $result = $this->getOne("SELECT GET_LOCK('$seqname}_lock',10)"); 599 if (DB::isError($result)) { 600 return $result; 601 } 602 if ($result == 0) { 603 // Failed to get the lock, can't do the conversion, bail 604 // with a DB_ERROR_NOT_LOCKED error 605 return $this->mysqlRaiseError(DB_ERROR_NOT_LOCKED); 606 } 607 608 $highest_id = $this->getOne("SELECT MAX(id) FROM $seqname}"); 609 if (DB::isError($highest_id)) { 610 return $highest_id; 611 } 612 // This should kill all rows except the highest 613 // We should probably do something if $highest_id isn't 614 // numeric, but I'm at a loss as how to handle that... 615 $result = $this->query("DELETE FROM $seqname} WHERE id <> $highest_id"); 616 if (DB::isError($result)) { 617 return $result; 618 } 619 620 // If another thread has been waiting for this lock, 621 // it will go thru the above procedure, but will have no 622 // real effect 623 $result = $this->getOne("SELECT RELEASE_LOCK('$seqname}_lock')"); 624 if (DB::isError($result)) { 625 return $result; 626 } 627 return true; 628 } 629 630 // }}} 631 // {{{ quote() 632 633 /** 634 * Quote the given string so it can be safely used within string delimiters 635 * in a query. 636 * @param $string mixed Data to be quoted 637 * @return mixed "NULL" string, quoted string or original data 638 */ 639 function quote($str = null) 640 { 641 switch (strtolower(gettype($str))) { 642 case 'null': 643 return 'NULL'; 644 case 'integer': 645 case 'double': 646 return $str; 647 case 'string': 648 default: 649 if(function_exists('mysql_real_escape_string')) { 650 return "'".mysql_real_escape_string($str, $this->connection)."'"; 651 } else { 652 return "'".mysql_escape_string($str)."'"; 653 } 654 } 655 } 656 657 // }}} 658 // {{{ modifyQuery() 659 660 function modifyQuery($query, $subject = null) 661 { 662 if ($this->options['optimize'] == 'portability') { 663 // "DELETE FROM table" gives 0 affected rows in MySQL. 664 // This little hack lets you know how many rows were deleted. 665 if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { 666 $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', 667 'DELETE FROM \1 WHERE 1=1', $query); 668 } 669 } 670 return $query; 671 } 672 673 // }}} 674 // {{{ modifyLimitQuery() 675 676 function modifyLimitQuery($query, $from, $count) 677 { 678 if (DB::isManip($query)) { 679 return $query . " LIMIT $count"; 680 } else { 681 return $query . " LIMIT $from, $count"; 682 } 683 } 684 685 // }}} 686 // {{{ mysqlRaiseError() 687 688 function mysqlRaiseError($errno = null) 689 { 690 if ($errno === null) { 691 $errno = $this->errorCode(mysql_errno($this->connection)); 692 } 693 return $this->raiseError($errno, null, null, null, 694 @mysql_errno($this->connection) . " ** " . 695 @mysql_error($this->connection)); 696 } 697 698 // }}} 699 // {{{ tableInfo() 700 701 function tableInfo($result, $mode = null) { 702 $count = 0; 703 $id = 0; 704 $res = array(); 705 706 /* 707 * depending on $mode, metadata returns the following values: 708 * 709 * - mode is null (default): 710 * $result[]: 711 * [0]["table"] table name 712 * [0]["name"] field name 713 * [0]["type"] field type 714 * [0]["len"] field length 715 * [0]["flags"] field flags 716 * 717 * - mode is DB_TABLEINFO_ORDER 718 * $result[]: 719 * ["num_fields"] number of metadata records 720 * [0]["table"] table name 721 * [0]["name"] field name 722 * [0]["type"] field type 723 * [0]["len"] field length 724 * [0]["flags"] field flags 725 * ["order"][field name] index of field named "field name" 726 * The last one is used, if you have a field name, but no index. 727 * Test: if (isset($result['meta']['myfield'])) { ... 728 * 729 * - mode is DB_TABLEINFO_ORDERTABLE 730 * the same as above. but additionally 731 * ["ordertable"][table name][field name] index of field 732 * named "field name" 733 * 734 * this is, because if you have fields from different 735 * tables with the same field name * they override each 736 * other with DB_TABLEINFO_ORDER 737 * 738 * you can combine DB_TABLEINFO_ORDER and 739 * DB_TABLEINFO_ORDERTABLE with DB_TABLEINFO_ORDER | 740 * DB_TABLEINFO_ORDERTABLE * or with DB_TABLEINFO_FULL 741 */ 742 743 // if $result is a string, then we want information about a 744 // table without a resultset 745 if (is_string($result)) { 746 $id = @mysql_list_fields($this->dsn['database'], 747 $result, $this->connection); 748 if (empty($id)) { 749 return $this->mysqlRaiseError(); 750 } 751 } else { // else we want information about a resultset 752 $id = $result; 753 if (empty($id)) { 754 return $this->mysqlRaiseError(); 755 } 756 } 757 758 $count = @mysql_num_fields($id); 759 760 // made this IF due to performance (one if is faster than $count if's) 761 if (empty($mode)) { 762 for ($i=0; $i<$count; $i++) { 763 $res[$i]['table'] = @mysql_field_table ($id, $i); 764 $res[$i]['name'] = @mysql_field_name ($id, $i); 765 $res[$i]['type'] = @mysql_field_type ($id, $i); 766 $res[$i]['len'] = @mysql_field_len ($id, $i); 767 $res[$i]['flags'] = @mysql_field_flags ($id, $i); 768 } 769 } else { // full 770 $res['num_fields']= $count; 771 772 for ($i=0; $i<$count; $i++) { 773 $res[$i]['table'] = @mysql_field_table ($id, $i); 774 $res[$i]['name'] = @mysql_field_name ($id, $i); 775 $res[$i]['type'] = @mysql_field_type ($id, $i); 776 $res[$i]['len'] = @mysql_field_len ($id, $i); 777 $res[$i]['flags'] = @mysql_field_flags ($id, $i); 778 if ($mode & DB_TABLEINFO_ORDER) { 779 $res['order'][$res[$i]['name']] = $i; 780 } 781 if ($mode & DB_TABLEINFO_ORDERTABLE) { 782 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; 783 } 784 } 785 } 786 787 // free the result only if we were called on a table 788 if (is_string($result)) { 789 @mysql_free_result($id); 790 } 791 return $res; 792 } 793 794 // }}} 795 // {{{ getSpecialQuery() 796 797 /** 798 * Returns the query needed to get some backend info 799 * @param string $type What kind of info you want to retrieve 800 * @return string The SQL query string 801 */ 802 function getSpecialQuery($type) 803 { 804 switch ($type) { 805 case 'tables': 806 $sql = "SHOW TABLES"; 807 break; 808 case 'views': 809 return DB_ERROR_NOT_CAPABLE; 810 case 'users': 811 $sql = "select distinct User from user"; 812 if($this->dsn['database'] != 'mysql') { 813 $dsn = $this->dsn; 814 $dsn['database'] = 'mysql'; 815 if (DB::isError($db = DB::connect($dsn))) { 816 return $db; 817 } 818 $sql = $db->getCol($sql); 819 $db->disconnect(); 820 // XXX Fixme the mysql driver should take care of this 821 if (!@mysql_select_db($this->dsn['database'], $this->connection)) { 822 return $this->mysqlRaiseError(DB_ERROR_NODBSELECTED); 823 } 824 } 825 return $sql; 826 break; 827 case 'databases': 828 $sql = "SHOW DATABASES"; 829 break; 830 default: 831 return null; 832 } 833 return $sql; 834 } 835 836 // }}} 837 838 // TODO/wishlist: 839 // longReadlen 840 // binmode 841 } 842 843 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Mon Nov 26 12:29:37 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |