[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 4 5 /** 6 * The PEAR DB driver for PHP's sqlite extension 7 * for interacting with SQLite databases 8 * 9 * PHP versions 4 and 5 10 * 11 * LICENSE: This source file is subject to version 3.0 of the PHP license 12 * that is available through the world-wide-web at the following URI: 13 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 14 * the PHP License and are unable to obtain it through the web, please 15 * send a note to license@php.net so we can mail you a copy immediately. 16 * 17 * @category Database 18 * @package DB 19 * @author Urs Gehrig <urs@circle.ch> 20 * @author Mika Tuupola <tuupola@appelsiini.net> 21 * @author Daniel Convissor <danielc@php.net> 22 * @copyright 1997-2005 The PHP Group 23 * @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0 24 * @version CVS: $Id: sqlite.php,v 1.114 2007/01/12 02:41:07 aharvey Exp $ 25 * @link http://pear.php.net/package/DB 26 */ 27 28 /** 29 * Obtain the DB_common class so it can be extended from 30 */ 31 require_once 'DB/common.php'; 32 33 /** 34 * The methods PEAR DB uses to interact with PHP's sqlite extension 35 * for interacting with SQLite databases 36 * 37 * These methods overload the ones declared in DB_common. 38 * 39 * NOTICE: This driver needs PHP's track_errors ini setting to be on. 40 * It is automatically turned on when connecting to the database. 41 * Make sure your scripts don't turn it off. 42 * 43 * @category Database 44 * @package DB 45 * @author Urs Gehrig <urs@circle.ch> 46 * @author Mika Tuupola <tuupola@appelsiini.net> 47 * @author Daniel Convissor <danielc@php.net> 48 * @copyright 1997-2005 The PHP Group 49 * @license http://www.php.net/license/3_0.txt PHP License 3.0 3.0 50 * @version Release: 1.7.9 51 * @link http://pear.php.net/package/DB 52 */ 53 class DB_sqlite extends DB_common 54 { 55 // {{{ properties 56 57 /** 58 * The DB driver type (mysql, oci8, odbc, etc.) 59 * @var string 60 */ 61 var $phptype = 'sqlite'; 62 63 /** 64 * The database syntax variant to be used (db2, access, etc.), if any 65 * @var string 66 */ 67 var $dbsyntax = 'sqlite'; 68 69 /** 70 * The capabilities of this DB implementation 71 * 72 * The 'new_link' element contains the PHP version that first provided 73 * new_link support for this DBMS. Contains false if it's unsupported. 74 * 75 * Meaning of the 'limit' element: 76 * + 'emulate' = emulate with fetch row by number 77 * + 'alter' = alter the query 78 * + false = skip rows 79 * 80 * @var array 81 */ 82 var $features = array( 83 'limit' => 'alter', 84 'new_link' => false, 85 'numrows' => true, 86 'pconnect' => true, 87 'prepare' => false, 88 'ssl' => false, 89 'transactions' => false, 90 ); 91 92 /** 93 * A mapping of native error codes to DB error codes 94 * 95 * {@internal Error codes according to sqlite_exec. See the online 96 * manual at http://sqlite.org/c_interface.html for info. 97 * This error handling based on sqlite_exec is not yet implemented.}} 98 * 99 * @var array 100 */ 101 var $errorcode_map = array( 102 ); 103 104 /** 105 * The raw database connection created by PHP 106 * @var resource 107 */ 108 var $connection; 109 110 /** 111 * The DSN information for connecting to a database 112 * @var array 113 */ 114 var $dsn = array(); 115 116 117 /** 118 * SQLite data types 119 * 120 * @link http://www.sqlite.org/datatypes.html 121 * 122 * @var array 123 */ 124 var $keywords = array ( 125 'BLOB' => '', 126 'BOOLEAN' => '', 127 'CHARACTER' => '', 128 'CLOB' => '', 129 'FLOAT' => '', 130 'INTEGER' => '', 131 'KEY' => '', 132 'NATIONAL' => '', 133 'NUMERIC' => '', 134 'NVARCHAR' => '', 135 'PRIMARY' => '', 136 'TEXT' => '', 137 'TIMESTAMP' => '', 138 'UNIQUE' => '', 139 'VARCHAR' => '', 140 'VARYING' => '', 141 ); 142 143 /** 144 * The most recent error message from $php_errormsg 145 * @var string 146 * @access private 147 */ 148 var $_lasterror = ''; 149 150 151 // }}} 152 // {{{ constructor 153 154 /** 155 * This constructor calls <kbd>$this->DB_common()</kbd> 156 * 157 * @return void 158 */ 159 function DB_sqlite() 160 { 161 $this->DB_common(); 162 } 163 164 // }}} 165 // {{{ connect() 166 167 /** 168 * Connect to the database server, log in and open the database 169 * 170 * Don't call this method directly. Use DB::connect() instead. 171 * 172 * PEAR DB's sqlite driver supports the following extra DSN options: 173 * + mode The permissions for the database file, in four digit 174 * chmod octal format (eg "0600"). 175 * 176 * Example of connecting to a database in read-only mode: 177 * <code> 178 * require_once 'DB.php'; 179 * 180 * $dsn = 'sqlite:///path/and/name/of/db/file?mode=0400'; 181 * $options = array( 182 * 'portability' => DB_PORTABILITY_ALL, 183 * ); 184 * 185 * $db =& DB::connect($dsn, $options); 186 * if (PEAR::isError($db)) { 187 * die($db->getMessage()); 188 * } 189 * </code> 190 * 191 * @param array $dsn the data source name 192 * @param bool $persistent should the connection be persistent? 193 * 194 * @return int DB_OK on success. A DB_Error object on failure. 195 */ 196 function connect($dsn, $persistent = false) 197 { 198 if (!PEAR::loadExtension('sqlite')) { 199 return $this->raiseError(DB_ERROR_EXTENSION_NOT_FOUND); 200 } 201 202 $this->dsn = $dsn; 203 if ($dsn['dbsyntax']) { 204 $this->dbsyntax = $dsn['dbsyntax']; 205 } 206 207 if (!$dsn['database']) { 208 return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); 209 } 210 211 if ($dsn['database'] !== ':memory:') { 212 if (!file_exists($dsn['database'])) { 213 if (!touch($dsn['database'])) { 214 return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); 215 } 216 if (!isset($dsn['mode']) || 217 !is_numeric($dsn['mode'])) 218 { 219 $mode = 0644; 220 } else { 221 $mode = octdec($dsn['mode']); 222 } 223 if (!chmod($dsn['database'], $mode)) { 224 return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); 225 } 226 if (!file_exists($dsn['database'])) { 227 return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); 228 } 229 } 230 if (!is_file($dsn['database'])) { 231 return $this->sqliteRaiseError(DB_ERROR_INVALID); 232 } 233 if (!is_readable($dsn['database'])) { 234 return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); 235 } 236 } 237 238 $connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open'; 239 240 // track_errors must remain on for simpleQuery() 241 @ini_set('track_errors', 1); 242 $php_errormsg = ''; 243 244 if (!$this->connection = @$connect_function($dsn['database'])) { 245 return $this->raiseError(DB_ERROR_NODBSELECTED, 246 null, null, null, 247 $php_errormsg); 248 } 249 return DB_OK; 250 } 251 252 // }}} 253 // {{{ disconnect() 254 255 /** 256 * Disconnects from the database server 257 * 258 * @return bool TRUE on success, FALSE on failure 259 */ 260 function disconnect() 261 { 262 $ret = @sqlite_close($this->connection); 263 $this->connection = null; 264 return $ret; 265 } 266 267 // }}} 268 // {{{ simpleQuery() 269 270 /** 271 * Sends a query to the database server 272 * 273 * NOTICE: This method needs PHP's track_errors ini setting to be on. 274 * It is automatically turned on when connecting to the database. 275 * Make sure your scripts don't turn it off. 276 * 277 * @param string the SQL query string 278 * 279 * @return mixed + a PHP result resrouce for successful SELECT queries 280 * + the DB_OK constant for other successful queries 281 * + a DB_Error object on failure 282 */ 283 function simpleQuery($query) 284 { 285 $ismanip = $this->_checkManip($query); 286 $this->last_query = $query; 287 $query = $this->modifyQuery($query); 288 289 $php_errormsg = ''; 290 291 $result = @sqlite_query($query, $this->connection); 292 $this->_lasterror = $php_errormsg ? $php_errormsg : ''; 293 294 $this->result = $result; 295 if (!$this->result) { 296 return $this->sqliteRaiseError(null); 297 } 298 299 // sqlite_query() seems to allways return a resource 300 // so cant use that. Using $ismanip instead 301 if (!$ismanip) { 302 $numRows = $this->numRows($result); 303 if (is_object($numRows)) { 304 // we've got PEAR_Error 305 return $numRows; 306 } 307 return $result; 308 } 309 return DB_OK; 310 } 311 312 // }}} 313 // {{{ nextResult() 314 315 /** 316 * Move the internal sqlite result pointer to the next available result 317 * 318 * @param resource $result the valid sqlite result resource 319 * 320 * @return bool true if a result is available otherwise return false 321 */ 322 function nextResult($result) 323 { 324 return false; 325 } 326 327 // }}} 328 // {{{ fetchInto() 329 330 /** 331 * Places a row from the result set into the given array 332 * 333 * Formating of the array and the data therein are configurable. 334 * See DB_result::fetchInto() for more information. 335 * 336 * This method is not meant to be called directly. Use 337 * DB_result::fetchInto() instead. It can't be declared "protected" 338 * because DB_result is a separate object. 339 * 340 * @param resource $result the query result resource 341 * @param array $arr the referenced array to put the data in 342 * @param int $fetchmode how the resulting array should be indexed 343 * @param int $rownum the row number to fetch (0 = first row) 344 * 345 * @return mixed DB_OK on success, NULL when the end of a result set is 346 * reached or on failure 347 * 348 * @see DB_result::fetchInto() 349 */ 350 function fetchInto($result, &$arr, $fetchmode, $rownum = null) 351 { 352 if ($rownum !== null) { 353 if (!@sqlite_seek($this->result, $rownum)) { 354 return null; 355 } 356 } 357 if ($fetchmode & DB_FETCHMODE_ASSOC) { 358 $arr = @sqlite_fetch_array($result, SQLITE_ASSOC); 359 if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { 360 $arr = array_change_key_case($arr, CASE_LOWER); 361 } 362 } else { 363 $arr = @sqlite_fetch_array($result, SQLITE_NUM); 364 } 365 if (!$arr) { 366 return null; 367 } 368 if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { 369 /* 370 * Even though this DBMS already trims output, we do this because 371 * a field might have intentional whitespace at the end that 372 * gets removed by DB_PORTABILITY_RTRIM under another driver. 373 */ 374 $this->_rtrimArrayValues($arr); 375 } 376 if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { 377 $this->_convertNullArrayValuesToEmpty($arr); 378 } 379 return DB_OK; 380 } 381 382 // }}} 383 // {{{ freeResult() 384 385 /** 386 * Deletes the result set and frees the memory occupied by the result set 387 * 388 * This method is not meant to be called directly. Use 389 * DB_result::free() instead. It can't be declared "protected" 390 * because DB_result is a separate object. 391 * 392 * @param resource $result PHP's query result resource 393 * 394 * @return bool TRUE on success, FALSE if $result is invalid 395 * 396 * @see DB_result::free() 397 */ 398 function freeResult(&$result) 399 { 400 // XXX No native free? 401 if (!is_resource($result)) { 402 return false; 403 } 404 $result = null; 405 return true; 406 } 407 408 // }}} 409 // {{{ numCols() 410 411 /** 412 * Gets the number of columns in a result set 413 * 414 * This method is not meant to be called directly. Use 415 * DB_result::numCols() instead. It can't be declared "protected" 416 * because DB_result is a separate object. 417 * 418 * @param resource $result PHP's query result resource 419 * 420 * @return int the number of columns. A DB_Error object on failure. 421 * 422 * @see DB_result::numCols() 423 */ 424 function numCols($result) 425 { 426 $cols = @sqlite_num_fields($result); 427 if (!$cols) { 428 return $this->sqliteRaiseError(); 429 } 430 return $cols; 431 } 432 433 // }}} 434 // {{{ numRows() 435 436 /** 437 * Gets the number of rows in a result set 438 * 439 * This method is not meant to be called directly. Use 440 * DB_result::numRows() instead. It can't be declared "protected" 441 * because DB_result is a separate object. 442 * 443 * @param resource $result PHP's query result resource 444 * 445 * @return int the number of rows. A DB_Error object on failure. 446 * 447 * @see DB_result::numRows() 448 */ 449 function numRows($result) 450 { 451 $rows = @sqlite_num_rows($result); 452 if ($rows === null) { 453 return $this->sqliteRaiseError(); 454 } 455 return $rows; 456 } 457 458 // }}} 459 // {{{ affected() 460 461 /** 462 * Determines the number of rows affected by a data maniuplation query 463 * 464 * 0 is returned for queries that don't manipulate data. 465 * 466 * @return int the number of rows. A DB_Error object on failure. 467 */ 468 function affectedRows() 469 { 470 return @sqlite_changes($this->connection); 471 } 472 473 // }}} 474 // {{{ dropSequence() 475 476 /** 477 * Deletes a sequence 478 * 479 * @param string $seq_name name of the sequence to be deleted 480 * 481 * @return int DB_OK on success. A DB_Error object on failure. 482 * 483 * @see DB_common::dropSequence(), DB_common::getSequenceName(), 484 * DB_sqlite::nextID(), DB_sqlite::createSequence() 485 */ 486 function dropSequence($seq_name) 487 { 488 return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); 489 } 490 491 /** 492 * Creates a new sequence 493 * 494 * @param string $seq_name name of the new sequence 495 * 496 * @return int DB_OK on success. A DB_Error object on failure. 497 * 498 * @see DB_common::createSequence(), DB_common::getSequenceName(), 499 * DB_sqlite::nextID(), DB_sqlite::dropSequence() 500 */ 501 function createSequence($seq_name) 502 { 503 $seqname = $this->getSequenceName($seq_name); 504 $query = 'CREATE TABLE ' . $seqname . 505 ' (id INTEGER UNSIGNED PRIMARY KEY) '; 506 $result = $this->query($query); 507 if (DB::isError($result)) { 508 return($result); 509 } 510 $query = "CREATE TRIGGER $seqname}_cleanup AFTER INSERT ON $seqname 511 BEGIN 512 DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID(); 513 END "; 514 $result = $this->query($query); 515 if (DB::isError($result)) { 516 return($result); 517 } 518 } 519 520 // }}} 521 // {{{ nextId() 522 523 /** 524 * Returns the next free id in a sequence 525 * 526 * @param string $seq_name name of the sequence 527 * @param boolean $ondemand when true, the seqence is automatically 528 * created if it does not exist 529 * 530 * @return int the next id number in the sequence. 531 * A DB_Error object on failure. 532 * 533 * @see DB_common::nextID(), DB_common::getSequenceName(), 534 * DB_sqlite::createSequence(), DB_sqlite::dropSequence() 535 */ 536 function nextId($seq_name, $ondemand = true) 537 { 538 $seqname = $this->getSequenceName($seq_name); 539 540 do { 541 $repeat = 0; 542 $this->pushErrorHandling(PEAR_ERROR_RETURN); 543 $result = $this->query("INSERT INTO $seqname (id) VALUES (NULL)"); 544 $this->popErrorHandling(); 545 if ($result === DB_OK) { 546 $id = @sqlite_last_insert_rowid($this->connection); 547 if ($id != 0) { 548 return $id; 549 } 550 } elseif ($ondemand && DB::isError($result) && 551 $result->getCode() == DB_ERROR_NOSUCHTABLE) 552 { 553 $result = $this->createSequence($seq_name); 554 if (DB::isError($result)) { 555 return $this->raiseError($result); 556 } else { 557 $repeat = 1; 558 } 559 } 560 } while ($repeat); 561 562 return $this->raiseError($result); 563 } 564 565 // }}} 566 // {{{ getDbFileStats() 567 568 /** 569 * Get the file stats for the current database 570 * 571 * Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size, 572 * atime, mtime, ctime, blksize, blocks or a numeric key between 573 * 0 and 12. 574 * 575 * @param string $arg the array key for stats() 576 * 577 * @return mixed an array on an unspecified key, integer on a passed 578 * arg and false at a stats error 579 */ 580 function getDbFileStats($arg = '') 581 { 582 $stats = stat($this->dsn['database']); 583 if ($stats == false) { 584 return false; 585 } 586 if (is_array($stats)) { 587 if (is_numeric($arg)) { 588 if (((int)$arg <= 12) & ((int)$arg >= 0)) { 589 return false; 590 } 591 return $stats[$arg ]; 592 } 593 if (array_key_exists(trim($arg), $stats)) { 594 return $stats[$arg ]; 595 } 596 } 597 return $stats; 598 } 599 600 // }}} 601 // {{{ escapeSimple() 602 603 /** 604 * Escapes a string according to the current DBMS's standards 605 * 606 * In SQLite, this makes things safe for inserts/updates, but may 607 * cause problems when performing text comparisons against columns 608 * containing binary data. See the 609 * {@link http://php.net/sqlite_escape_string PHP manual} for more info. 610 * 611 * @param string $str the string to be escaped 612 * 613 * @return string the escaped string 614 * 615 * @since Method available since Release 1.6.1 616 * @see DB_common::escapeSimple() 617 */ 618 function escapeSimple($str) 619 { 620 return @sqlite_escape_string($str); 621 } 622 623 // }}} 624 // {{{ modifyLimitQuery() 625 626 /** 627 * Adds LIMIT clauses to a query string according to current DBMS standards 628 * 629 * @param string $query the query to modify 630 * @param int $from the row to start to fetching (0 = the first row) 631 * @param int $count the numbers of rows to fetch 632 * @param mixed $params array, string or numeric data to be used in 633 * execution of the statement. Quantity of items 634 * passed must match quantity of placeholders in 635 * query: meaning 1 placeholder for non-array 636 * parameters or 1 placeholder per array element. 637 * 638 * @return string the query string with LIMIT clauses added 639 * 640 * @access protected 641 */ 642 function modifyLimitQuery($query, $from, $count, $params = array()) 643 { 644 return "$query LIMIT $count OFFSET $from"; 645 } 646 647 // }}} 648 // {{{ modifyQuery() 649 650 /** 651 * Changes a query string for various DBMS specific reasons 652 * 653 * This little hack lets you know how many rows were deleted 654 * when running a "DELETE FROM table" query. Only implemented 655 * if the DB_PORTABILITY_DELETE_COUNT portability option is on. 656 * 657 * @param string $query the query string to modify 658 * 659 * @return string the modified query string 660 * 661 * @access protected 662 * @see DB_common::setOption() 663 */ 664 function modifyQuery($query) 665 { 666 if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { 667 if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $query)) { 668 $query = preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', 669 'DELETE FROM \1 WHERE 1=1', $query); 670 } 671 } 672 return $query; 673 } 674 675 // }}} 676 // {{{ sqliteRaiseError() 677 678 /** 679 * Produces a DB_Error object regarding the current problem 680 * 681 * @param int $errno if the error is being manually raised pass a 682 * DB_ERROR* constant here. If this isn't passed 683 * the error information gathered from the DBMS. 684 * 685 * @return object the DB_Error object 686 * 687 * @see DB_common::raiseError(), 688 * DB_sqlite::errorNative(), DB_sqlite::errorCode() 689 */ 690 function sqliteRaiseError($errno = null) 691 { 692 $native = $this->errorNative(); 693 if ($errno === null) { 694 $errno = $this->errorCode($native); 695 } 696 697 $errorcode = @sqlite_last_error($this->connection); 698 $userinfo = "$errorcode ** $this->last_query"; 699 700 return $this->raiseError($errno, null, null, $userinfo, $native); 701 } 702 703 // }}} 704 // {{{ errorNative() 705 706 /** 707 * Gets the DBMS' native error message produced by the last query 708 * 709 * {@internal This is used to retrieve more meaningfull error messages 710 * because sqlite_last_error() does not provide adequate info.}} 711 * 712 * @return string the DBMS' error message 713 */ 714 function errorNative() 715 { 716 return $this->_lasterror; 717 } 718 719 // }}} 720 // {{{ errorCode() 721 722 /** 723 * Determines PEAR::DB error code from the database's text error message 724 * 725 * @param string $errormsg the error message returned from the database 726 * 727 * @return integer the DB error number 728 */ 729 function errorCode($errormsg) 730 { 731 static $error_regexps; 732 733 // PHP 5.2+ prepends the function name to $php_errormsg, so we need 734 // this hack to work around it, per bug #9599. 735 $errormsg = preg_replace('/^sqlite[a-z_]+\(\): /', '', $errormsg); 736 737 if (!isset($error_regexps)) { 738 $error_regexps = array( 739 '/^no such table:/' => DB_ERROR_NOSUCHTABLE, 740 '/^no such index:/' => DB_ERROR_NOT_FOUND, 741 '/^(table|index) .* already exists$/' => DB_ERROR_ALREADY_EXISTS, 742 '/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT, 743 '/is not unique/' => DB_ERROR_CONSTRAINT, 744 '/columns .* are not unique/i' => DB_ERROR_CONSTRAINT, 745 '/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT, 746 '/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL, 747 '/^no such column:/' => DB_ERROR_NOSUCHFIELD, 748 '/column not present in both tables/i' => DB_ERROR_NOSUCHFIELD, 749 '/^near ".*": syntax error$/' => DB_ERROR_SYNTAX, 750 '/[0-9]+ values for [0-9]+ columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW, 751 ); 752 } 753 foreach ($error_regexps as $regexp => $code) { 754 if (preg_match($regexp, $errormsg)) { 755 return $code; 756 } 757 } 758 // Fall back to DB_ERROR if there was no mapping. 759 return DB_ERROR; 760 } 761 762 // }}} 763 // {{{ tableInfo() 764 765 /** 766 * Returns information about a table 767 * 768 * @param string $result a string containing the name of a table 769 * @param int $mode a valid tableInfo mode 770 * 771 * @return array an associative array with the information requested. 772 * A DB_Error object on failure. 773 * 774 * @see DB_common::tableInfo() 775 * @since Method available since Release 1.7.0 776 */ 777 function tableInfo($result, $mode = null) 778 { 779 if (is_string($result)) { 780 /* 781 * Probably received a table name. 782 * Create a result resource identifier. 783 */ 784 $id = @sqlite_array_query($this->connection, 785 "PRAGMA table_info('$result');", 786 SQLITE_ASSOC); 787 $got_string = true; 788 } else { 789 $this->last_query = ''; 790 return $this->raiseError(DB_ERROR_NOT_CAPABLE, null, null, null, 791 'This DBMS can not obtain tableInfo' . 792 ' from result sets'); 793 } 794 795 if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { 796 $case_func = 'strtolower'; 797 } else { 798 $case_func = 'strval'; 799 } 800 801 $count = count($id); 802 $res = array(); 803 804 if ($mode) { 805 $res['num_fields'] = $count; 806 } 807 808 for ($i = 0; $i < $count; $i++) { 809 if (strpos($id[$i]['type'], '(') !== false) { 810 $bits = explode('(', $id[$i]['type']); 811 $type = $bits[0]; 812 $len = rtrim($bits[1],')'); 813 } else { 814 $type = $id[$i]['type']; 815 $len = 0; 816 } 817 818 $flags = ''; 819 if ($id[$i]['pk']) { 820 $flags .= 'primary_key '; 821 } 822 if ($id[$i]['notnull']) { 823 $flags .= 'not_null '; 824 } 825 if ($id[$i]['dflt_value'] !== null) { 826 $flags .= 'default_' . rawurlencode($id[$i]['dflt_value']); 827 } 828 $flags = trim($flags); 829 830 $res[$i] = array( 831 'table' => $case_func($result), 832 'name' => $case_func($id[$i]['name']), 833 'type' => $type, 834 'len' => $len, 835 'flags' => $flags, 836 ); 837 838 if ($mode & DB_TABLEINFO_ORDER) { 839 $res['order'][$res[$i]['name']] = $i; 840 } 841 if ($mode & DB_TABLEINFO_ORDERTABLE) { 842 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; 843 } 844 } 845 846 return $res; 847 } 848 849 // }}} 850 // {{{ getSpecialQuery() 851 852 /** 853 * Obtains the query string needed for listing a given type of objects 854 * 855 * @param string $type the kind of objects you want to retrieve 856 * @param array $args SQLITE DRIVER ONLY: a private array of arguments 857 * used by the getSpecialQuery(). Do not use 858 * this directly. 859 * 860 * @return string the SQL query string or null if the driver doesn't 861 * support the object type requested 862 * 863 * @access protected 864 * @see DB_common::getListOf() 865 */ 866 function getSpecialQuery($type, $args = array()) 867 { 868 if (!is_array($args)) { 869 return $this->raiseError('no key specified', null, null, null, 870 'Argument has to be an array.'); 871 } 872 873 switch ($type) { 874 case 'master': 875 return 'SELECT * FROM sqlite_master;'; 876 case 'tables': 877 return "SELECT name FROM sqlite_master WHERE type='table' " 878 . 'UNION ALL SELECT name FROM sqlite_temp_master ' 879 . "WHERE type='table' ORDER BY name;"; 880 case 'schema': 881 return 'SELECT sql FROM (SELECT * FROM sqlite_master ' 882 . 'UNION ALL SELECT * FROM sqlite_temp_master) ' 883 . "WHERE type!='meta' " 884 . 'ORDER BY tbl_name, type DESC, name;'; 885 case 'schemax': 886 case 'schema_x': 887 /* 888 * Use like: 889 * $res = $db->query($db->getSpecialQuery('schema_x', 890 * array('table' => 'table3'))); 891 */ 892 return 'SELECT sql FROM (SELECT * FROM sqlite_master ' 893 . 'UNION ALL SELECT * FROM sqlite_temp_master) ' 894 . "WHERE tbl_name LIKE '{$args['table']}' " 895 . "AND type!='meta' " 896 . 'ORDER BY type DESC, name;'; 897 case 'alter': 898 /* 899 * SQLite does not support ALTER TABLE; this is a helper query 900 * to handle this. 'table' represents the table name, 'rows' 901 * the news rows to create, 'save' the row(s) to keep _with_ 902 * the data. 903 * 904 * Use like: 905 * $args = array( 906 * 'table' => $table, 907 * 'rows' => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT", 908 * 'save' => "NULL, titel, content, datetime" 909 * ); 910 * $res = $db->query( $db->getSpecialQuery('alter', $args)); 911 */ 912 $rows = strtr($args['rows'], $this->keywords); 913 914 $q = array( 915 'BEGIN TRANSACTION', 916 "CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})", 917 "INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}", 918 "DROP TABLE {$args['table']}", 919 "CREATE TABLE {$args['table']} ({$args['rows']})", 920 "INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup", 921 "DROP TABLE {$args['table']}_backup", 922 'COMMIT', 923 ); 924 925 /* 926 * This is a dirty hack, since the above query will not get 927 * executed with a single query call so here the query method 928 * will be called directly and return a select instead. 929 */ 930 foreach ($q as $query) { 931 $this->query($query); 932 } 933 return "SELECT * FROM {$args['table']};"; 934 default: 935 return null; 936 } 937 } 938 939 // }}} 940 } 941 942 /* 943 * Local variables: 944 * tab-width: 4 945 * c-basic-offset: 4 946 * End: 947 */ 948 949 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |