Error Buddy
Do you have an error message from your application? Then find the answer with Error Buddy. You can search over 40000 source code files and troubleshooting documents using our beta lucene/nutch search interface or if you prefer, search as normal using google. With LXR technology you can drill right down into the line of source code where it came from with full cross-referencing.
If after searching you didn't get your ideal answer, or you are still unclear what the error means, you can choose to post that question to the community forums following the link included in the search results.
[1.6]001 <?php 002 003 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 004 005 /** 006 * Database independent query interface 007 * 008 * PHP versions 4 and 5 009 * 010 * LICENSE: This source file is subject to version 3.0 of the PHP license 011 * that is available through the world-wide-web at the following URI: 012 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 013 * the PHP License and are unable to obtain it through the web, please 014 * send a note to license@php.net so we can mail you a copy immediately. 015 * 016 * @category Database 017 * @package DB 018 * @author Stig Bakken <ssb@php.net> 019 * @author Tomas V.V.Cox <cox@idecnet.com> 020 * @author Daniel Convissor <danielc@php.net> 021 * @copyright 1997-2005 The PHP Group 022 * @license http://www.php.net/license/3_0.txt PHP License 3.0 023 * @version CVS: $Id: DB.php,v 1.80 2005/02/16 02:16:00 danielc Exp $ 024 * @link http://pear.php.net/package/DB 025 */ 026 027 /** 028 * Obtain the PEAR class so it can be extended from 029 */ 030 require_once 'PEAR.php'; 031 032 033 // {{{ constants 034 // {{{ error codes 035 036 /**#@+ 037 * One of PEAR DB's portable error codes. 038 * @see DB_common::errorCode(), DB::errorMessage() 039 * 040 * {@internal If you add an error code here, make sure you also add a textual 041 * version of it in DB::errorMessage().}} 042 */ 043 044 /** 045 * The code returned by many methods upon success 046 */ 047 define('DB_OK', 1); 048 049 /** 050 * Unkown error 051 */ 052 define('DB_ERROR', -1); 053 054 /** 055 * Syntax error 056 */ 057 define('DB_ERROR_SYNTAX', -2); 058 059 /** 060 * Tried to insert a duplicate value into a primary or unique index 061 */ 062 define('DB_ERROR_CONSTRAINT', -3); 063 064 /** 065 * An identifier in the query refers to a non-existant object 066 */ 067 define('DB_ERROR_NOT_FOUND', -4); 068 069 /** 070 * Tried to create a duplicate object 071 */ 072 define('DB_ERROR_ALREADY_EXISTS', -5); 073 074 /** 075 * The current driver does not support the action you attempted 076 */ 077 define('DB_ERROR_UNSUPPORTED', -6); 078 079 /** 080 * The number of parameters does not match the number of placeholders 081 */ 082 define('DB_ERROR_MISMATCH', -7); 083 084 /** 085 * A literal submitted did not match the data type expected 086 */ 087 define('DB_ERROR_INVALID', -8); 088 089 /** 090 * The current DBMS does not support the action you attempted 091 */ 092 define('DB_ERROR_NOT_CAPABLE', -9); 093 094 /** 095 * A literal submitted was too long so the end of it was removed 096 */ 097 define('DB_ERROR_TRUNCATED', -10); 098 099 /** 100 * A literal number submitted did not match the data type expected 101 */ 102 define('DB_ERROR_INVALID_NUMBER', -11); 103 104 /** 105 * A literal date submitted did not match the data type expected 106 */ 107 define('DB_ERROR_INVALID_DATE', -12); 108 109 /** 110 * Attempt to divide something by zero 111 */ 112 define('DB_ERROR_DIVZERO', -13); 113 114 /** 115 * A database needs to be selected 116 */ 117 define('DB_ERROR_NODBSELECTED', -14); 118 119 /** 120 * Could not create the object requested 121 */ 122 define('DB_ERROR_CANNOT_CREATE', -15); 123 124 /** 125 * Could not drop the database requested because it does not exist 126 */ 127 define('DB_ERROR_CANNOT_DROP', -17); 128 129 /** 130 * An identifier in the query refers to a non-existant table 131 */ 132 define('DB_ERROR_NOSUCHTABLE', -18); 133 134 /** 135 * An identifier in the query refers to a non-existant column 136 */ 137 define('DB_ERROR_NOSUCHFIELD', -19); 138 139 /** 140 * The data submitted to the method was inappropriate 141 */ 142 define('DB_ERROR_NEED_MORE_DATA', -20); 143 144 /** 145 * The attempt to lock the table failed 146 */ 147 define('DB_ERROR_NOT_LOCKED', -21); 148 149 /** 150 * The number of columns doesn't match the number of values 151 */ 152 define('DB_ERROR_VALUE_COUNT_ON_ROW', -22); 153 154 /** 155 * The DSN submitted has problems 156 */ 157 define('DB_ERROR_INVALID_DSN', -23); 158 159 /** 160 * Could not connect to the database 161 */ 162 define('DB_ERROR_CONNECT_FAILED', -24); 163 164 /** 165 * The PHP extension needed for this DBMS could not be found 166 */ 167 define('DB_ERROR_EXTENSION_NOT_FOUND',-25); 168 169 /** 170 * The present user has inadequate permissions to perform the task requestd 171 */ 172 define('DB_ERROR_ACCESS_VIOLATION', -26); 173 174 /** 175 * The database requested does not exist 176 */ 177 define('DB_ERROR_NOSUCHDB', -27); 178 179 /** 180 * Tried to insert a null value into a column that doesn't allow nulls 181 */ 182 define('DB_ERROR_CONSTRAINT_NOT_NULL',-29); 183 /**#@-*/ 184 185 186 // }}} 187 // {{{ prepared statement-related 188 189 190 /**#@+ 191 * Identifiers for the placeholders used in prepared statements. 192 * @see DB_common::prepare() 193 */ 194 195 /** 196 * Indicates a scalar (<kbd>?</kbd>) placeholder was used 197 * 198 * Quote and escape the value as necessary. 199 */ 200 define('DB_PARAM_SCALAR', 1); 201 202 /** 203 * Indicates an opaque (<kbd>&</kbd>) placeholder was used 204 * 205 * The value presented is a file name. Extract the contents of that file 206 * and place them in this column. 207 */ 208 define('DB_PARAM_OPAQUE', 2); 209 210 /** 211 * Indicates a misc (<kbd>!</kbd>) placeholder was used 212 * 213 * The value should not be quoted or escaped. 214 */ 215 define('DB_PARAM_MISC', 3); 216 /**#@-*/ 217 218 219 // }}} 220 // {{{ binary data-related 221 222 223 /**#@+ 224 * The different ways of returning binary data from queries. 225 */ 226 227 /** 228 * Sends the fetched data straight through to output 229 */ 230 define('DB_BINMODE_PASSTHRU', 1); 231 232 /** 233 * Lets you return data as usual 234 */ 235 define('DB_BINMODE_RETURN', 2); 236 237 /** 238 * Converts the data to hex format before returning it 239 * 240 * For example the string "123" would become "313233". 241 */ 242 define('DB_BINMODE_CONVERT', 3); 243 /**#@-*/ 244 245 246 // }}} 247 // {{{ fetch modes 248 249 250 /**#@+ 251 * Fetch Modes. 252 * @see DB_common::setFetchMode() 253 */ 254 255 /** 256 * Indicates the current default fetch mode should be used 257 * @see DB_common::$fetchmode 258 */ 259 define('DB_FETCHMODE_DEFAULT', 0); 260 261 /** 262 * Column data indexed by numbers, ordered from 0 and up 263 */ 264 define('DB_FETCHMODE_ORDERED', 1); 265 266 /** 267 * Column data indexed by column names 268 */ 269 define('DB_FETCHMODE_ASSOC', 2); 270 271 /** 272 * Column data as object properties 273 */ 274 define('DB_FETCHMODE_OBJECT', 3); 275 276 /** 277 * For multi-dimensional results, make the column name the first level 278 * of the array and put the row number in the second level of the array 279 * 280 * This is flipped from the normal behavior, which puts the row numbers 281 * in the first level of the array and the column names in the second level. 282 */ 283 define('DB_FETCHMODE_FLIPPED', 4); 284 /**#@-*/ 285 286 /**#@+ 287 * Old fetch modes. Left here for compatibility. 288 */ 289 define('DB_GETMODE_ORDERED', DB_FETCHMODE_ORDERED); 290 define('DB_GETMODE_ASSOC', DB_FETCHMODE_ASSOC); 291 define('DB_GETMODE_FLIPPED', DB_FETCHMODE_FLIPPED); 292 /**#@-*/ 293 294 295 // }}} 296 // {{{ tableInfo() && autoPrepare()-related 297 298 299 /**#@+ 300 * The type of information to return from the tableInfo() method. 301 * 302 * Bitwised constants, so they can be combined using <kbd>|</kbd> 303 * and removed using <kbd>^</kbd>. 304 * 305 * @see DB_common::tableInfo() 306 * 307 * {@internal Since the TABLEINFO constants are bitwised, if more of them are 308 * added in the future, make sure to adjust DB_TABLEINFO_FULL accordingly.}} 309 */ 310 define('DB_TABLEINFO_ORDER', 1); 311 define('DB_TABLEINFO_ORDERTABLE', 2); 312 define('DB_TABLEINFO_FULL', 3); 313 /**#@-*/ 314 315 316 /**#@+ 317 * The type of query to create with the automatic query building methods. 318 * @see DB_common::autoPrepare(), DB_common::autoExecute() 319 */ 320 define('DB_AUTOQUERY_INSERT', 1); 321 define('DB_AUTOQUERY_UPDATE', 2); 322 /**#@-*/ 323 324 325 // }}} 326 // {{{ portability modes 327 328 329 /**#@+ 330 * Portability Modes. 331 * 332 * Bitwised constants, so they can be combined using <kbd>|</kbd> 333 * and removed using <kbd>^</kbd>. 334 * 335 * @see DB_common::setOption() 336 * 337 * {@internal Since the PORTABILITY constants are bitwised, if more of them are 338 * added in the future, make sure to adjust DB_PORTABILITY_ALL accordingly.}} 339 */ 340 341 /** 342 * Turn off all portability features 343 */ 344 define('DB_PORTABILITY_NONE', 0); 345 346 /** 347 * Convert names of tables and fields to lower case 348 * when using the get*(), fetch*() and tableInfo() methods 349 */ 350 define('DB_PORTABILITY_LOWERCASE', 1); 351 352 /** 353 * Right trim the data output by get*() and fetch*() 354 */ 355 define('DB_PORTABILITY_RTRIM', 2); 356 357 /** 358 * Force reporting the number of rows deleted 359 */ 360 define('DB_PORTABILITY_DELETE_COUNT', 4); 361 362 /** 363 * Enable hack that makes numRows() work in Oracle 364 */ 365 define('DB_PORTABILITY_NUMROWS', 8); 366 367 /** 368 * Makes certain error messages in certain drivers compatible 369 * with those from other DBMS's 370 * 371 * + mysql, mysqli: change unique/primary key constraints 372 * DB_ERROR_ALREADY_EXISTS -> DB_ERROR_CONSTRAINT 373 * 374 * + odbc(access): MS's ODBC driver reports 'no such field' as code 375 * 07001, which means 'too few parameters.' When this option is on 376 * that code gets mapped to DB_ERROR_NOSUCHFIELD. 377 */ 378 define('DB_PORTABILITY_ERRORS', 16); 379 380 /** 381 * Convert null values to empty strings in data output by 382 * get*() and fetch*() 383 */ 384 define('DB_PORTABILITY_NULL_TO_EMPTY', 32); 385 386 /** 387 * Turn on all portability features 388 */ 389 define('DB_PORTABILITY_ALL', 63); 390 /**#@-*/ 391 392 // }}} 393 394 395 // }}} 396 // {{{ class DB 397 398 /** 399 * Database independent query interface 400 * 401 * The main "DB" class is simply a container class with some static 402 * methods for creating DB objects as well as some utility functions 403 * common to all parts of DB. 404 * 405 * The object model of DB is as follows (indentation means inheritance): 406 * <pre> 407 * DB The main DB class. This is simply a utility class 408 * with some "static" methods for creating DB objects as 409 * well as common utility functions for other DB classes. 410 * 411 * DB_common The base for each DB implementation. Provides default 412 * | implementations (in OO lingo virtual methods) for 413 * | the actual DB implementations as well as a bunch of 414 * | query utility functions. 415 * | 416 * +-DB_mysql The DB implementation for MySQL. Inherits DB_common. 417 * When calling DB::factory or DB::connect for MySQL 418 * connections, the object returned is an instance of this 419 * class. 420 * </pre> 421 * 422 * @category Database 423 * @package DB 424 * @author Stig Bakken <ssb@php.net> 425 * @author Tomas V.V.Cox <cox@idecnet.com> 426 * @author Daniel Convissor <danielc@php.net> 427 * @copyright 1997-2005 The PHP Group 428 * @license http://www.php.net/license/3_0.txt PHP License 3.0 429 * @version Release: @package_version@ 430 * @link http://pear.php.net/package/DB 431 */ 432 class DB 433 { 434 // {{{ &factory() 435 436 /** 437 * Create a new DB object for the specified database type but don't 438 * connect to the database 439 * 440 * @param string $type the database type (eg "mysql") 441 * @param array $options an associative array of option names and values 442 * 443 * @return object a new DB object. A DB_Error object on failure. 444 * 445 * @see DB_common::setOption() 446 */ 447 function &factory($type, $options = false) 448 { 449 if (!is_array($options)) { 450 $options = array('persistent' => $options); 451 } 452 453 if (isset($options['debug']) && $options['debug'] >= 2) { 454 // expose php errors with sufficient debug level 455 include_once "DB/{$type}.php"; 456 } else { 457 @include_once "DB/{$type}.php"; 458 } 459 460 $classname = "DB_${type}"; 461 462 if (!class_exists($classname)) { 463 $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, 464 "Unable to include the DB/{$type}.php" 465 . " file for '$dsn'", 466 'DB_Error', true); 467 return $tmp; 468 } 469 470 @$obj =& new $classname; 471 472 foreach ($options as $option => $value) { 473 $test = $obj->setOption($option, $value); 474 if (DB::isError($test)) { 475 return $test; 476 } 477 } 478 479 return $obj; 480 } 481 482 // }}} 483 // {{{ &connect() 484 485 /** 486 * Create a new DB object including a connection to the specified database 487 * 488 * Example 1. 489 * <code> 490 * require_once 'DB.php'; 491 * 492 * $dsn = 'pgsql://user:password@host/database'; 493 * $options = array( 494 * 'debug' => 2, 495 * 'portability' => DB_PORTABILITY_ALL, 496 * ); 497 * 498 * $db =& DB::connect($dsn, $options); 499 * if (PEAR::isError($db)) { 500 * die($db->getMessage()); 501 * } 502 * </code> 503 * 504 * @param mixed $dsn the string "data source name" or array in the 505 * format returned by DB::parseDSN() 506 * @param array $options an associative array of option names and values 507 * 508 * @return object a new DB object. A DB_Error object on failure. 509 * 510 * @uses DB_dbase::connect(), DB_fbsql::connect(), DB_ibase::connect(), 511 * DB_ifx::connect(), DB_msql::connect(), DB_mssql::connect(), 512 * DB_mysql::connect(), DB_mysqli::connect(), DB_oci8::connect(), 513 * DB_odbc::connect(), DB_pgsql::connect(), DB_sqlite::connect(), 514 * DB_sybase::connect() 515 * 516 * @uses DB::parseDSN(), DB_common::setOption(), PEAR::isError() 517 */ 518 function &connect($dsn, $options = array()) 519 { 520 $dsninfo = DB::parseDSN($dsn); 521 $type = $dsninfo['phptype']; 522 523 if (!is_array($options)) { 524 /* 525 * For backwards compatibility. $options used to be boolean, 526 * indicating whether the connection should be persistent. 527 */ 528 $options = array('persistent' => $options); 529 } 530 531 if (isset($options['debug']) && $options['debug'] >= 2) { 532 // expose php errors with sufficient debug level 533 include_once "DB/${type}.php"; 534 } else { 535 @include_once "DB/${type}.php"; 536 } 537 538 $classname = "DB_${type}"; 539 if (!class_exists($classname)) { 540 $tmp = PEAR::raiseError(null, DB_ERROR_NOT_FOUND, null, null, 541 "Unable to include the DB/{$type}.php" 542 . " file for '$dsn'", 543 'DB_Error', true); 544 return $tmp; 545 } 546 547 @$obj =& new $classname; 548 549 foreach ($options as $option => $value) { 550 $test = $obj->setOption($option, $value); 551 if (DB::isError($test)) { 552 return $test; 553 } 554 } 555 556 $err = $obj->connect($dsninfo, $obj->getOption('persistent')); 557 if (DB::isError($err)) { 558 $err->addUserInfo($dsn); 559 return $err; 560 } 561 562 return $obj; 563 } 564 565 // }}} 566 // {{{ apiVersion() 567 568 /** 569 * Return the DB API version 570 * 571 * @return string the DB API version number 572 */ 573 function apiVersion() 574 { 575 return '@package_version@'; 576 } 577 578 // }}} 579 // {{{ isError() 580 581 /** 582 * Determines if a variable is a DB_Error object 583 * 584 * @param mixed $value the variable to check 585 * 586 * @return bool whether $value is DB_Error object 587 */ 588 function isError($value) 589 { 590 return is_a($value, 'DB_Error'); 591 } 592 593 // }}} 594 // {{{ isConnection() 595 596 /** 597 * Determines if a value is a DB_<driver> object 598 * 599 * @param mixed $value the value to test 600 * 601 * @return bool whether $value is a DB_<driver> object 602 */ 603 function isConnection($value) 604 { 605 return (is_object($value) && 606 is_subclass_of($value, 'db_common') && 607 method_exists($value, 'simpleQuery')); 608 } 609 610 // }}} 611 // {{{ isManip() 612 613 /** 614 * Tell whether a query is a data manipulation or data definition query 615 * 616 * Examples of data manipulation queries are INSERT, UPDATE and DELETE. 617 * Examples of data definition queries are CREATE, DROP, ALTER, GRANT, 618 * REVOKE. 619 * 620 * @param string $query the query 621 * 622 * @return boolean whether $query is a data manipulation query 623 */ 624 function isManip($query) 625 { 626 $manips = 'INSERT|UPDATE|DELETE|REPLACE|' 627 . 'CREATE|DROP|' 628 . 'LOAD DATA|SELECT .* INTO|COPY|' 629 . 'ALTER|GRANT|REVOKE|' 630 . 'LOCK|UNLOCK'; 631 if (preg_match('/^\s*"?(' . $manips . ')\s+/i', $query)) { 632 return true; 633 } 634 return false; 635 } 636 637 // }}} 638 // {{{ errorMessage() 639 640 /** 641 * Return a textual error message for a DB error code 642 * 643 * @param integer $value the DB error code 644 * 645 * @return string the error message or false if the error code was 646 * not recognized 647 */ 648 function errorMessage($value) 649 { 650 static $errorMessages; 651 if (!isset($errorMessages)) { 652 $errorMessages = array( 653 DB_ERROR => 'unknown error', 654 DB_ERROR_ACCESS_VIOLATION => 'insufficient permissions', 655 DB_ERROR_ALREADY_EXISTS => 'already exists', 656 DB_ERROR_CANNOT_CREATE => 'can not create', 657 DB_ERROR_CANNOT_DROP => 'can not drop', 658 DB_ERROR_CONNECT_FAILED => 'connect failed', 659 DB_ERROR_CONSTRAINT => 'constraint violation', 660 DB_ERROR_CONSTRAINT_NOT_NULL=> 'null value violates not-null constraint', 661 DB_ERROR_DIVZERO => 'division by zero', 662 DB_ERROR_EXTENSION_NOT_FOUND=> 'extension not found', 663 DB_ERROR_INVALID => 'invalid', 664 DB_ERROR_INVALID_DATE => 'invalid date or time', 665 DB_ERROR_INVALID_DSN => 'invalid DSN', 666 DB_ERROR_INVALID_NUMBER => 'invalid number', 667 DB_ERROR_MISMATCH => 'mismatch', 668 DB_ERROR_NEED_MORE_DATA => 'insufficient data supplied', 669 DB_ERROR_NODBSELECTED => 'no database selected', 670 DB_ERROR_NOSUCHDB => 'no such database', 671 DB_ERROR_NOSUCHFIELD => 'no such field', 672 DB_ERROR_NOSUCHTABLE => 'no such table', 673 DB_ERROR_NOT_CAPABLE => 'DB backend not capable', 674 DB_ERROR_NOT_FOUND => 'not found', 675 DB_ERROR_NOT_LOCKED => 'not locked', 676 DB_ERROR_SYNTAX => 'syntax error', 677 DB_ERROR_UNSUPPORTED => 'not supported', 678 DB_ERROR_TRUNCATED => 'truncated', 679 DB_ERROR_VALUE_COUNT_ON_ROW => 'value count on row', 680 DB_OK => 'no error', 681 ); 682 } 683 684 if (DB::isError($value)) { 685 $value = $value->getCode(); 686 } 687 688 return isset($errorMessages[$value]) ? $errorMessages[$value] 689 : $errorMessages[DB_ERROR]; 690 } 691 692 // }}} 693 // {{{ parseDSN() 694 695 /** 696 * Parse a data source name 697 * 698 * Additional keys can be added by appending a URI query string to the 699 * end of the DSN. 700 * 701 * The format of the supplied DSN is in its fullest form: 702 * <code> 703 * phptype(dbsyntax)://username:password@protocol+hostspec/database?option=8&another=true 704 * </code> 705 * 706 * Most variations are allowed: 707 * <code> 708 * phptype://username:password@protocol+hostspec:110//usr/db_file.db?mode=0644 709 * phptype://username:password@hostspec/database_name 710 * phptype://username:password@hostspec 711 * phptype://username@hostspec 712 * phptype://hostspec/database 713 * phptype://hostspec 714 * phptype(dbsyntax) 715 * phptype 716 * </code> 717 * 718 * @param string $dsn Data Source Name to be parsed 719 * 720 * @return array an associative array with the following keys: 721 * + phptype: Database backend used in PHP (mysql, odbc etc.) 722 * + dbsyntax: Database used with regards to SQL syntax etc. 723 * + protocol: Communication protocol to use (tcp, unix etc.) 724 * + hostspec: Host specification (hostname[:port]) 725 * + database: Database to use on the DBMS server 726 * + username: User name for login 727 * + password: Password for login 728 */ 729 function parseDSN($dsn) 730 { 731 $parsed = array( 732 'phptype' => false, 733 'dbsyntax' => false, 734 'username' => false, 735 'password' => false, 736 'protocol' => false, 737 'hostspec' => false, 738 'port' => false, 739 'socket' => false, 740 'database' => false, 741 ); 742 743 if (is_array($dsn)) { 744 $dsn = array_merge($parsed, $dsn); 745 if (!$dsn['dbsyntax']) { 746 $dsn['dbsyntax'] = $dsn['phptype']; 747 } 748 return $dsn; 749 } 750 751 // Find phptype and dbsyntax 752 if (($pos = strpos($dsn, '://')) !== false) { 753 $str = substr($dsn, 0, $pos); 754 $dsn = substr($dsn, $pos + 3); 755 } else { 756 $str = $dsn; 757 $dsn = null; 758 } 759 760 // Get phptype and dbsyntax 761 // $str => phptype(dbsyntax) 762 if (preg_match('|^(.+?)\((.*?)\)$|', $str, $arr)) { 763 $parsed['phptype'] = $arr[1]; 764 $parsed['dbsyntax'] = !$arr[2] ? $arr[1] : $arr[2]; 765 } else { 766 $parsed['phptype'] = $str; 767 $parsed['dbsyntax'] = $str; 768 } 769 770 if (!count($dsn)) { 771 return $parsed; 772 } 773 774 // Get (if found): username and password 775 // $dsn => username:password@protocol+hostspec/database 776 if (($at = strrpos($dsn,'@')) !== false) { 777 $str = substr($dsn, 0, $at); 778 $dsn = substr($dsn, $at + 1); 779 if (($pos = strpos($str, ':')) !== false) { 780 $parsed['username'] = rawurldecode(substr($str, 0, $pos)); 781 $parsed['password'] = rawurldecode(substr($str, $pos + 1)); 782 } else { 783 $parsed['username'] = rawurldecode($str); 784 } 785 } 786 787 // Find protocol and hostspec 788 789 if (preg_match('|^([^(]+)\((.*?)\)/?(.*?)$|', $dsn, $match)) { 790 // $dsn => proto(proto_opts)/database 791 $proto = $match[1]; 792 $proto_opts = $match[2] ? $match[2] : false; 793 $dsn = $match[3]; 794 795 } else { 796 // $dsn => protocol+hostspec/database (old format) 797 if (strpos($dsn, '+') !== false) { 798 list($proto, $dsn) = explode('+', $dsn, 2); 799 } 800 if (strpos($dsn, '/') !== false) { 801 list($proto_opts, $dsn) = explode('/', $dsn, 2); 802 } else { 803 $proto_opts = $dsn; 804 $dsn = null; 805 } 806 } 807 808 // process the different protocol options 809 $parsed['protocol'] = (!empty($proto)) ? $proto : 'tcp'; 810 $proto_opts = rawurldecode($proto_opts); 811 if ($parsed['protocol'] == 'tcp') { 812 if (strpos($proto_opts, ':') !== false) { 813 list($parsed['hostspec'], 814 $parsed['port']) = explode(':', $proto_opts); 815 } else { 816 $parsed['hostspec'] = $proto_opts; 817 } 818 } elseif ($parsed['protocol'] == 'unix') { 819 $parsed['socket'] = $proto_opts; 820 } 821 822 // Get dabase if any 823 // $dsn => database 824 if ($dsn) { 825 if (($pos = strpos($dsn, '?')) === false) { 826 // /database 827 $parsed['database'] = rawurldecode($dsn); 828 } else { 829 // /database?param1=value1¶m2=value2 830 $parsed['database'] = rawurldecode(substr($dsn, 0, $pos)); 831 $dsn = substr($dsn, $pos + 1); 832 if (strpos($dsn, '&') !== false) { 833 $opts = explode('&', $dsn); 834 } else { // database?param1=value1 835 $opts = array($dsn); 836 } 837 foreach ($opts as $opt) { 838 list($key, $value) = explode('=', $opt); 839 if (!isset($parsed[$key])) { 840 // don't allow params overwrite 841 $parsed[$key] = rawurldecode($value); 842 } 843 } 844 } 845 } 846 847 return $parsed; 848 } 849 850 // }}} 851 } 852 853 // }}} 854 // {{{ class DB_Error 855 856 /** 857 * DB_Error implements a class for reporting portable database error 858 * messages 859 * 860 * @category Database 861 * @package DB 862 * @author Stig Bakken <ssb@php.net> 863 * @copyright 1997-2005 The PHP Group 864 * @license http://www.php.net/license/3_0.txt PHP License 3.0 865 * @version Release: @package_version@ 866 * @link http://pear.php.net/package/DB 867 */ 868 class DB_Error extends PEAR_Error 869 { 870 // {{{ constructor 871 872 /** 873 * DB_Error constructor 874 * 875 * @param mixed $code DB error code, or string with error message 876 * @param int $mode what "error mode" to operate in 877 * @param int $level what error level to use for $mode & 878 * PEAR_ERROR_TRIGGER 879 * @param mixed $debuginfo additional debug info, such as the last query 880 * 881 * @see PEAR_Error 882 */ 883 function DB_Error($code = DB_ERROR, $mode = PEAR_ERROR_RETURN, 884 $level = E_USER_NOTICE, $debuginfo = null) 885 { 886 if (is_int($code)) { 887 $this->PEAR_Error('DB Error: ' . DB::errorMessage($code), $code, 888 $mode, $level, $debuginfo); 889 } else { 890 $this->PEAR_Error("DB Error: $code", DB_ERROR, 891 $mode, $level, $debuginfo); 892 } 893 } 894 895 // }}} 896 } 897 898 // }}} 899 // {{{ class DB_result 900 901 /** 902 * This class implements a wrapper for a DB result set 903 * 904 * A new instance of this class will be returned by the DB implementation 905 * after processing a query that returns data. 906 * 907 * @category Database 908 * @package DB 909 * @author Stig Bakken <ssb@php.net> 910 * @copyright 1997-2005 The PHP Group 911 * @license http://www.php.net/license/3_0.txt PHP License 3.0 912 * @version Release: @package_version@ 913 * @link http://pear.php.net/package/DB 914 */ 915 class DB_result 916 { 917 // {{{ properties 918 919 /** 920 * Should results be freed automatically when there are no more rows? 921 * @var boolean 922 * @see DB_common::$options 923 */ 924 var $autofree; 925 926 /** 927 * A reference to the DB_<driver> object 928 * @var object 929 */ 930 var $dbh; 931 932 /** 933 * The current default fetch mode 934 * @var integer 935 * @see DB_common::$fetchmode 936 */ 937 var $fetchmode; 938 939 /** 940 * The name of the class into which results should be fetched when 941 * DB_FETCHMODE_OBJECT is in effect 942 * 943 * @var string 944 * @see DB_common::$fetchmode_object_class 945 */ 946 var $fetchmode_object_class; 947 948 /** 949 * The number of rows to fetch from a limit query 950 * @var integer 951 */ 952 var $limit_count = null; 953 954 /** 955 * The row to start fetching from in limit queries 956 * @var integer 957 */ 958 var $limit_from = null; 959 960 /** 961 * The execute parameters that created this result 962 * @var array 963 * @since Property available since Release 1.7.0 964 */ 965 var $parameters; 966 967 /** 968 * The query string that created this result 969 * 970 * Copied here incase it changes in $dbh, which is referenced 971 * 972 * @var string 973 * @since Property available since Release 1.7.0 974 */ 975 var $query; 976 977 /** 978 * The query result resource id created by PHP 979 * @var resource 980 */ 981 var $result; 982 983 /** 984 * The present row being dealt with 985 * @var integer 986 */ 987 var $row_counter = null; 988 989 /** 990 * The prepared statement resource id created by PHP in $dbh 991 * 992 * This resource is only available when the result set was created using 993 * a driver's native execute() method, not PEAR DB's emulated one. 994 * 995 * Copied here incase it changes in $dbh, which is referenced 996 * 997 * {@internal Mainly here because the InterBase/Firebird API is only 998 * able to retrieve data from result sets if the statemnt handle is 999 * still in scope.}} 1000 * 1001 * @var resource 1002 * @since Property available since Release 1.7.0 1003 */ 1004 var $statement; 1005 1006 1007 // }}} 1008 // {{{ constructor 1009 1010 /** 1011 * This constructor sets the object's properties 1012 * 1013 * @param object &$dbh the DB object reference 1014 * @param resource $result the result resource id 1015 * @param array $options an associative array with result options 1016 * 1017 * @return void 1018 */ 1019 function DB_result(&$dbh, $result, $options = array()) 1020 { 1021 $this->autofree = $dbh->options['autofree']; 1022 $this->dbh = &$dbh; 1023 $this->fetchmode = $dbh->fetchmode; 1024 $this->fetchmode_object_class = $dbh->fetchmode_object_class; 1025 $this->parameters = $dbh->last_parameters; 1026 $this->query = $dbh->last_query; 1027 $this->result = $result; 1028 $this->statement = empty($dbh->last_stmt) ? null : $dbh->last_stmt; 1029 foreach ($options as $key => $value) { 1030 $this->setOption($key, $value); 1031 } 1032 } 1033 1034 /** 1035 * Set options for the DB_result object 1036 * 1037 * @param string $key the option to set 1038 * @param mixed $value the value to set the option to 1039 * 1040 * @return void 1041 */ 1042 function setOption($key, $value = null) 1043 { 1044 switch ($key) { 1045 case 'limit_from': 1046 $this->limit_from = $value; 1047 break; 1048 case 'limit_count': 1049 $this->limit_count = $value; 1050 } 1051 } 1052 1053 // }}} 1054 // {{{ fetchRow() 1055 1056 /** 1057 * Fetch a row of data and return it by reference into an array 1058 * 1059 * The type of array returned can be controlled either by setting this 1060 * method's <var>$fetchmode</var> parameter or by changing the default 1061 * fetch mode setFetchMode() before calling this method. 1062 * 1063 * There are two options for standardizing the information returned 1064 * from databases, ensuring their values are consistent when changing 1065 * DBMS's. These portability options can be turned on when creating a 1066 * new DB object or by using setOption(). 1067 * 1068 * + <var>DB_PORTABILITY_LOWERCASE</var> 1069 * convert names of fields to lower case 1070 * 1071 * + <var>DB_PORTABILITY_RTRIM</var> 1072 * right trim the data 1073 * 1074 * @param int $fetchmode the constant indicating how to format the data 1075 * @param int $rownum the row number to fetch (index starts at 0) 1076 * 1077 * @return mixed an array or object containing the row's data, 1078 * NULL when the end of the result set is reached 1079 * or a DB_Error object on failure. 1080 * 1081 * @see DB_common::setOption(), DB_common::setFetchMode() 1082 */ 1083 function &fetchRow($fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null) 1084 { 1085 if ($fetchmode === DB_FETCHMODE_DEFAULT) { 1086 $fetchmode = $this->fetchmode; 1087 } 1088 if ($fetchmode === DB_FETCHMODE_OBJECT) { 1089 $fetchmode = DB_FETCHMODE_ASSOC; 1090 $object_class = $this->fetchmode_object_class; 1091 } 1092 if ($this->limit_from !== null) { 1093 if ($this->row_counter === null) { 1094 $this->row_counter = $this->limit_from; 1095 // Skip rows 1096 if ($this->dbh->features['limit'] === false) { 1097 $i = 0; 1098 while ($i++ < $this->limit_from) { 1099 $this->dbh->fetchInto($this->result, $arr, $fetchmode); 1100 } 1101 } 1102 } 1103 if ($this->row_counter >= ($this->limit_from + $this->limit_count)) 1104 { 1105 if ($this->autofree) { 1106 $this->free(); 1107 } 1108 $tmp = null; 1109 return $tmp; 1110 } 1111 if ($this->dbh->features['limit'] === 'emulate') { 1112 $rownum = $this->row_counter; 1113 } 1114 $this->row_counter++; 1115 } 1116 $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); 1117 if ($res === DB_OK) { 1118 if (isset($object_class)) { 1119 // The default mode is specified in the 1120 // DB_common::fetchmode_object_class property 1121 if ($object_class == 'stdClass') { 1122 $arr = (object) $arr; 1123 } else { 1124 $arr = &new $object_class($arr); 1125 } 1126 } 1127 return $arr; 1128 } 1129 if ($res == null && $this->autofree) { 1130 $this->free(); 1131 } 1132 return $res; 1133 } 1134 1135 // }}} 1136 // {{{ fetchInto() 1137 1138 /** 1139 * Fetch a row of data into an array which is passed by reference 1140 * 1141 * The type of array returned can be controlled either by setting this 1142 * method's <var>$fetchmode</var> parameter or by changing the default 1143 * fetch mode setFetchMode() before calling this method. 1144 * 1145 * There are two options for standardizing the information returned 1146 * from databases, ensuring their values are consistent when changing 1147 * DBMS's. These portability options can be turned on when creating a 1148 * new DB object or by using setOption(). 1149 * 1150 * + <var>DB_PORTABILITY_LOWERCASE</var> 1151 * convert names of fields to lower case 1152 * 1153 * + <var>DB_PORTABILITY_RTRIM</var> 1154 * right trim the data 1155 * 1156 * @param array &$arr the variable where the data should be placed 1157 * @param int $fetchmode the constant indicating how to format the data 1158 * @param int $rownum the row number to fetch (index starts at 0) 1159 * 1160 * @return mixed DB_OK if a row is processed, NULL when the end of the 1161 * result set is reached or a DB_Error object on failure 1162 * 1163 * @see DB_common::setOption(), DB_common::setFetchMode() 1164 */ 1165 function fetchInto(&$arr, $fetchmode = DB_FETCHMODE_DEFAULT, $rownum = null) 1166 { 1167 if ($fetchmode === DB_FETCHMODE_DEFAULT) { 1168 $fetchmode = $this->fetchmode; 1169 } 1170 if ($fetchmode === DB_FETCHMODE_OBJECT) { 1171 $fetchmode = DB_FETCHMODE_ASSOC; 1172 $object_class = $this->fetchmode_object_class; 1173 } 1174 if ($this->limit_from !== null) { 1175 if ($this->row_counter === null) { 1176 $this->row_counter = $this->limit_from; 1177 // Skip rows 1178 if ($this->dbh->features['limit'] === false) { 1179 $i = 0; 1180 while ($i++ < $this->limit_from) { 1181 $this->dbh->fetchInto($this->result, $arr, $fetchmode); 1182 } 1183 } 1184 } 1185 if ($this->row_counter >= ( 1186 $this->limit_from + $this->limit_count)) 1187 { 1188 if ($this->autofree) { 1189 $this->free(); 1190 } 1191 return null; 1192 } 1193 if ($this->dbh->features['limit'] === 'emulate') { 1194 $rownum = $this->row_counter; 1195 } 1196 1197 $this->row_counter++; 1198 } 1199 $res = $this->dbh->fetchInto($this->result, $arr, $fetchmode, $rownum); 1200 if ($res === DB_OK) { 1201 if (isset($object_class)) { 1202 // default mode specified in the 1203 // DB_common::fetchmode_object_class property 1204 if ($object_class == 'stdClass') { 1205 $arr = (object) $arr; 1206 } else { 1207 $arr = new $object_class($arr); 1208 } 1209 } 1210 return DB_OK; 1211 } 1212 if ($res == null && $this->autofree) { 1213 $this->free(); 1214 } 1215 return $res; 1216 } 1217 1218 // }}} 1219 // {{{ numCols() 1220 1221 /** 1222 * Get the the number of columns in a result set 1223 * 1224 * @return int the number of columns. A DB_Error object on failure. 1225 */ 1226 function numCols() 1227 { 1228 return $this->dbh->numCols($this->result); 1229 } 1230 1231 // }}} 1232 // {{{ numRows() 1233 1234 /** 1235 * Get the number of rows in a result set 1236 * 1237 * @return int the number of rows. A DB_Error object on failure. 1238 */ 1239 function numRows() 1240 { 1241 if ($this->dbh->features['numrows'] === 'emulate' 1242 && $this->dbh->options['portability'] & DB_PORTABILITY_NUMROWS) 1243 { 1244 if ($this->dbh->features['prepare']) { 1245 $res = $this->dbh->query($this->query, $this->parameters); 1246 } else { 1247 $res = $this->dbh->query($this->query); 1248 } 1249 if (DB::isError($res)) { 1250 return $res; 1251 } 1252 $i = 0; 1253 while ($res->fetchInto($tmp, DB_FETCHMODE_ORDERED)) { 1254 $i++; 1255 } 1256 return $i; 1257 } else { 1258 return $this->dbh->numRows($this->result); 1259 } 1260 } 1261 1262 // }}} 1263 // {{{ nextResult() 1264 1265 /** 1266 * Get the next result if a batch of queries was executed 1267 * 1268 * @return bool true if a new result is available or false if not 1269 */ 1270 function nextResult() 1271 { 1272 return $this->dbh->nextResult($this->result); 1273 } 1274 1275 // }}} 1276 // {{{ free() 1277 1278 /** 1279 * Frees the resources allocated for this result set 1280 * 1281 * @return bool true on success. A DB_Error object on failure. 1282 */ 1283 function free() 1284 { 1285 $err = $this->dbh->freeResult($this->result); 1286 if (DB::isError($err)) { 1287 return $err; 1288 } 1289 $this->result = false; 1290 $this->statement = false; 1291 return true; 1292 } 1293 1294 // }}} 1295 // {{{ tableInfo() 1296 1297 /** 1298 * @see DB_common::tableInfo() 1299 * @deprecated Method deprecated some time before Release 1.2 1300 */ 1301 function tableInfo($mode = null) 1302 { 1303 if (is_string($mode)) { 1304 return $this->dbh->raiseError(DB_ERROR_NEED_MORE_DATA); 1305 } 1306 return $this->dbh->tableInfo($this, $mode); 1307 } 1308 1309 // }}} 1310 // {{{ getQuery() 1311 1312 /** 1313 * Determine the query string that created this result 1314 * 1315 * @return string the query string 1316 * 1317 * @since Method available since Release 1.7.0 1318 */ 1319 function getQuery() 1320 { 1321 return $this->query; 1322 } 1323 1324 // }}} 1325 // {{{ getRowCounter() 1326 1327 /** 1328 * Tells which row number is currently being processed 1329 * 1330 * @return integer the current row being looked at. Starts at 1. 1331 */ 1332 function getRowCounter() 1333 { 1334 return $this->row_counter; 1335 } 1336 1337 // }}} 1338 } 1339 1340 // }}} 1341 // {{{ class DB_row 1342 1343 /** 1344 * PEAR DB Row Object 1345 * 1346 * The object contains a row of data from a result set. Each column's data 1347 * is placed in a property named for the column. 1348 * 1349 * @category Database 1350 * @package DB 1351 * @author Stig Bakken <ssb@php.net> 1352 * @copyright 1997-2005 The PHP Group 1353 * @license http://www.php.net/license/3_0.txt PHP License 3.0 1354 * @version Release: @package_version@ 1355 * @link http://pear.php.net/package/DB 1356 * @see DB_common::setFetchMode() 1357 */ 1358 class DB_row 1359 { 1360 // {{{ constructor 1361 1362 /** 1363 * The constructor places a row's data into properties of this object 1364 * 1365 * @param array the array containing the row's data 1366 * 1367 * @return void 1368 */ 1369 function DB_row(&$arr) 1370 { 1371 foreach ($arr as $key => $value) { 1372 $this->$key = &$arr[$key]; 1373 } 1374 } 1375 1376 // }}} 1377 } 1378 1379 // }}} 1380 1381 /* 1382 * Local variables: 1383 * tab-width: 4 1384 * c-basic-offset: 4 1385 * End: 1386 */ 1387 1388 ?>
Testing
