| [ PHPXref.com ] | [ Generated: Sun Jul 20 20:47:21 2008 ] | [ TPLN 2.6 ] |
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
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.109 2005/03/10 01:22:48 danielc 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: @package_version@ 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 if (!file_exists($dsn['database'])) { 209 if (!touch($dsn['database'])) { 210 return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); 211 } 212 if (!isset($dsn['mode']) || 213 !is_numeric($dsn['mode'])) 214 { 215 $mode = 0644; 216 } else { 217 $mode = octdec($dsn['mode']); 218 } 219 if (!chmod($dsn['database'], $mode)) { 220 return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); 221 } 222 if (!file_exists($dsn['database'])) { 223 return $this->sqliteRaiseError(DB_ERROR_NOT_FOUND); 224 } 225 } 226 if (!is_file($dsn['database'])) { 227 return $this->sqliteRaiseError(DB_ERROR_INVALID); 228 } 229 if (!is_readable($dsn['database'])) { 230 return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); 231 } 232 } else { 233 return $this->sqliteRaiseError(DB_ERROR_ACCESS_VIOLATION); 234 } 235 236 $connect_function = $persistent ? 'sqlite_popen' : 'sqlite_open'; 237 238 // track_errors must remain on for simpleQuery() 239 ini_set('track_errors', 1); 240 $php_errormsg = ''; 241 242 if (!$this->connection = @$connect_function($dsn['database'])) { 243 return $this->raiseError(DB_ERROR_NODBSELECTED, 244 null, null, null, 245 $php_errormsg); 246 } 247 return DB_OK; 248 } 249 250 // }}} 251 // {{{ disconnect() 252 253 /** 254 * Disconnects from the database server 255 * 256 * @return bool TRUE on success, FALSE on failure 257 */ 258 function disconnect() 259 { 260 $ret = @sqlite_close($this->connection); 261 $this->connection = null; 262 return $ret; 263 } 264 265 // }}} 266 // {{{ simpleQuery() 267 268 /** 269 * Sends a query to the database server 270 * 271 * NOTICE: This method needs PHP's track_errors ini setting to be on. 272 * It is automatically turned on when connecting to the database. 273 * Make sure your scripts don't turn it off. 274 * 275 * @param string the SQL query string 276 * 277 * @return mixed + a PHP result resrouce for successful SELECT queries 278 * + the DB_OK constant for other successful queries 279 * + a DB_Error object on failure 280 */ 281 function simpleQuery($query) 282 { 283 $ismanip = DB::isManip($query); 284 $this->last_query = $query; 285 $query = $this->modifyQuery($query); 286 287 $php_errormsg = ''; 288 289 $result = @sqlite_query($query, $this->connection); 290 $this->_lasterror = $php_errormsg ? $php_errormsg : ''; 291 292 $this->result = $result; 293 if (!$this->result) { 294 return $this->sqliteRaiseError(null); 295 } 296 297 // sqlite_query() seems to allways return a resource 298 // so cant use that. Using $ismanip instead 299 if (!$ismanip) { 300 $numRows = $this->numRows($result); 301 if (is_object($numRows)) { 302 // we've got PEAR_Error 303 return $numRows; 304 } 305 return $result; 306 } 307 return DB_OK; 308 } 309 310 // }}} 311 // {{{ nextResult() 312 313 /** 314 * Move the internal sqlite result pointer to the next available result 315 * 316 * @param resource $result the valid sqlite result resource 317 * 318 * @return bool true if a result is available otherwise return false 319 */ 320 function nextResult($result) 321 { 322 return false; 323 } 324 325 // }}} 326 // {{{ fetchInto() 327 328 /** 329 * Places a row from the result set into the given array 330 * 331 * Formating of the array and the data therein are configurable. 332 * See DB_result::fetchInto() for more information. 333 * 334 * This method is not meant to be called directly. Use 335 * DB_result::fetchInto() instead. It can't be declared "protected" 336 * because DB_result is a separate object. 337 * 338 * @param resource $result the query result resource 339 * @param array $arr the referenced array to put the data in 340 * @param int $fetchmode how the resulting array should be indexed 341 * @param int $rownum the row number to fetch (0 = first row) 342 * 343 * @return mixed DB_OK on success, NULL when the end of a result set is 344 * reached or on failure 345 * 346 * @see DB_result::fetchInto() 347 */ 348 function fetchInto($result, &$arr, $fetchmode, $rownum = null) 349 { 350 if ($rownum !== null) { 351 if (!@sqlite_seek($this->result, $rownum)) { 352 return null; 353 } 354 } 355 if ($fetchmode & DB_FETCHMODE_ASSOC) { 356 $arr = @sqlite_fetch_array($result, SQLITE_ASSOC); 357 if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE && $arr) { 358 $arr = array_change_key_case($arr, CASE_LOWER); 359 } 360 } else { 361 $arr = @sqlite_fetch_array($result, SQLITE_NUM); 362 } 363 if (!$arr) { 364 return null; 365 } 366 if ($this->options['portability'] & DB_PORTABILITY_RTRIM) { 367 /* 368 * Even though this DBMS already trims output, we do this because 369 * a field might have intentional whitespace at the end that 370 * gets removed by DB_PORTABILITY_RTRIM under another driver. 371 */ 372 $this->_rtrimArrayValues($arr); 373 } 374 if ($this->options['portability'] & DB_PORTABILITY_NULL_TO_EMPTY) { 375 $this->_convertNullArrayValuesToEmpty($arr); 376 } 377 return DB_OK; 378 } 379 380 // }}} 381 // {{{ freeResult() 382 383 /** 384 * Deletes the result set and frees the memory occupied by the result set 385 * 386 * This method is not meant to be called directly. Use 387 * DB_result::free() instead. It can't be declared "protected" 388 * because DB_result is a separate object. 389 * 390 * @param resource $result PHP's query result resource 391 * 392 * @return bool TRUE on success, FALSE if $result is invalid 393 * 394 * @see DB_result::free() 395 */ 396 function freeResult(&$result) 397 { 398 // XXX No native free? 399 if (!is_resource($result)) { 400 return false; 401 } 402 $result = null; 403 return true; 404 } 405 406 // }}} 407 // {{{ numCols() 408 409 /** 410 * Gets the number of columns in a result set 411 * 412 * This method is not meant to be called directly. Use 413 * DB_result::numCols() instead. It can't be declared "protected" 414 * because DB_result is a separate object. 415 * 416 * @param resource $result PHP's query result resource 417 * 418 * @return int the number of columns. A DB_Error object on failure. 419 * 420 * @see DB_result::numCols() 421 */ 422 function numCols($result) 423 { 424 $cols = @sqlite_num_fields($result); 425 if (!$cols) { 426 return $this->sqliteRaiseError(); 427 } 428 return $cols; 429 } 430 431 // }}} 432 // {{{ numRows() 433 434 /** 435 * Gets the number of rows in a result set 436 * 437 * This method is not meant to be called directly. Use 438 * DB_result::numRows() instead. It can't be declared "protected" 439 * because DB_result is a separate object. 440 * 441 * @param resource $result PHP's query result resource 442 * 443 * @return int the number of rows. A DB_Error object on failure. 444 * 445 * @see DB_result::numRows() 446 */ 447 function numRows($result) 448 { 449 $rows = @sqlite_num_rows($result); 450 if ($rows === null) { 451 return $this->sqliteRaiseError(); 452 } 453 return $rows; 454 } 455 456 // }}} 457 // {{{ affected() 458 459 /** 460 * Determines the number of rows affected by a data maniuplation query 461 * 462 * 0 is returned for queries that don't manipulate data. 463 * 464 * @return int the number of rows. A DB_Error object on failure. 465 */ 466 function affectedRows() 467 { 468 return @sqlite_changes($this->connection); 469 } 470 471 // }}} 472 // {{{ dropSequence() 473 474 /** 475 * Deletes a sequence 476 * 477 * @param string $seq_name name of the sequence to be deleted 478 * 479 * @return int DB_OK on success. A DB_Error object on failure. 480 * 481 * @see DB_common::dropSequence(), DB_common::getSequenceName(), 482 * DB_sqlite::nextID(), DB_sqlite::createSequence() 483 */ 484 function dropSequence($seq_name) 485 { 486 return $this->query('DROP TABLE ' . $this->getSequenceName($seq_name)); 487 } 488 489 /** 490 * Creates a new sequence 491 * 492 * @param string $seq_name name of the new sequence 493 * 494 * @return int DB_OK on success. A DB_Error object on failure. 495 * 496 * @see DB_common::createSequence(), DB_common::getSequenceName(), 497 * DB_sqlite::nextID(), DB_sqlite::dropSequence() 498 */ 499 function createSequence($seq_name) 500 { 501 $seqname = $this->getSequenceName($seq_name); 502 $query = 'CREATE TABLE ' . $seqname . 503 ' (id INTEGER UNSIGNED PRIMARY KEY) '; 504 $result = $this->query($query); 505 if (DB::isError($result)) { 506 return($result); 507 } 508 $query = "CREATE TRIGGER $seqname}_cleanup AFTER INSERT ON $seqname 509 BEGIN 510 DELETE FROM $seqname WHERE id<LAST_INSERT_ROWID(); 511 END "; 512 $result = $this->query($query); 513 if (DB::isError($result)) { 514 return($result); 515 } 516 } 517 518 // }}} 519 // {{{ nextId() 520 521 /** 522 * Returns the next free id in a sequence 523 * 524 * @param string $seq_name name of the sequence 525 * @param boolean $ondemand when true, the seqence is automatically 526 * created if it does not exist 527 * 528 * @return int the next id number in the sequence. 529 * A DB_Error object on failure. 530 * 531 * @see DB_common::nextID(), DB_common::getSequenceName(), 532 * DB_sqlite::createSequence(), DB_sqlite::dropSequence() 533 */ 534 function nextId($seq_name, $ondemand = true) 535 { 536 $seqname = $this->getSequenceName($seq_name); 537 538 do { 539 $repeat = 0; 540 $this->pushErrorHandling(PEAR_ERROR_RETURN); 541 $result = $this->query("INSERT INTO $seqname (id) VALUES (NULL)"); 542 $this->popErrorHandling(); 543 if ($result === DB_OK) { 544 $id = @sqlite_last_insert_rowid($this->connection); 545 if ($id != 0) { 546 return $id; 547 } 548 } elseif ($ondemand && DB::isError($result) && 549 $result->getCode() == DB_ERROR_NOSUCHTABLE) 550 { 551 $result = $this->createSequence($seq_name); 552 if (DB::isError($result)) { 553 return $this->raiseError($result); 554 } else { 555 $repeat = 1; 556 } 557 } 558 } while ($repeat); 559 560 return $this->raiseError($result); 561 } 562 563 // }}} 564 // {{{ getDbFileStats() 565 566 /** 567 * Get the file stats for the current database 568 * 569 * Possible arguments are dev, ino, mode, nlink, uid, gid, rdev, size, 570 * atime, mtime, ctime, blksize, blocks or a numeric key between 571 * 0 and 12. 572 * 573 * @param string $arg the array key for stats() 574 * 575 * @return mixed an array on an unspecified key, integer on a passed 576 * arg and false at a stats error 577 */ 578 function getDbFileStats($arg = '') 579 { 580 $stats = stat($this->dsn['database']); 581 if ($stats == false) { 582 return false; 583 } 584 if (is_array($stats)) { 585 if (is_numeric($arg)) { 586 if (((int)$arg <= 12) & ((int)$arg >= 0)) { 587 return false; 588 } 589 return $stats[$arg ]; 590 } 591 if (array_key_exists(trim($arg), $stats)) { 592 return $stats[$arg ]; 593 } 594 } 595 return $stats; 596 } 597 598 // }}} 599 // {{{ escapeSimple() 600 601 /** 602 * Escapes a string according to the current DBMS's standards 603 * 604 * In SQLite, this makes things safe for inserts/updates, but may 605 * cause problems when performing text comparisons against columns 606 * containing binary data. See the 607 * {@link http://php.net/sqlite_escape_string PHP manual} for more info. 608 * 609 * @param string $str the string to be escaped 610 * 611 * @return string the escaped string 612 * 613 * @since Method available since Release 1.6.1 614 * @see DB_common::escapeSimple() 615 */ 616 function escapeSimple($str) 617 { 618 return @sqlite_escape_string($str); 619 } 620 621 // }}} 622 // {{{ modifyLimitQuery() 623 624 /** 625 * Adds LIMIT clauses to a query string according to current DBMS standards 626 * 627 * @param string $query the query to modify 628 * @param int $from the row to start to fetching (0 = the first row) 629 * @param int $count the numbers of rows to fetch 630 * @param mixed $params array, string or numeric data to be used in 631 * execution of the statement. Quantity of items 632 * passed must match quantity of placeholders in 633 * query: meaning 1 placeholder for non-array 634 * parameters or 1 placeholder per array element. 635 * 636 * @return string the query string with LIMIT clauses added 637 * 638 * @access protected 639 */ 640 function modifyLimitQuery($query, $from, $count, $params = array()) 641 { 642 return "$query LIMIT $count OFFSET $from"; 643 } 644 645 // }}} 646 // {{{ modifyQuery() 647 648 /** 649 * Changes a query string for various DBMS specific reasons 650 * 651 * This little hack lets you know how many rows were deleted 652 * when running a "DELETE FROM table" query. Only implemented 653 * if the DB_PORTABILITY_DELETE_COUNT portability option is on. 654 * 655 * @param string $query the query string to modify 656 * 657 * @return string the modified query string 658 * 659 * @access protected 660 * @see DB_common::setOption() 661 */ 662 function modifyQuery($query) 663 { 664 if ($this->options['portability'] & DB_PORTABILITY_DELETE_COUNT) { 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 // {{{ sqliteRaiseError() 675 676 /** 677 * Produces a DB_Error object regarding the current problem 678 * 679 * @param int $errno if the error is being manually raised pass a 680 * DB_ERROR* constant here. If this isn't passed 681 * the error information gathered from the DBMS. 682 * 683 * @return object the DB_Error object 684 * 685 * @see DB_common::raiseError(), 686 * DB_sqlite::errorNative(), DB_sqlite::errorCode() 687 */ 688 function sqliteRaiseError($errno = null) 689 { 690 $native = $this->errorNative(); 691 if ($errno === null) { 692 $errno = $this->errorCode($native); 693 } 694 695 $errorcode = @sqlite_last_error($this->connection); 696 $userinfo = "$errorcode ** $this->last_query"; 697 698 return $this->raiseError($errno, null, null, $userinfo, $native); 699 } 700 701 // }}} 702 // {{{ errorNative() 703 704 /** 705 * Gets the DBMS' native error message produced by the last query 706 * 707 * {@internal This is used to retrieve more meaningfull error messages 708 * because sqlite_last_error() does not provide adequate info.}} 709 * 710 * @return string the DBMS' error message 711 */ 712 function errorNative() 713 { 714 return $this->_lasterror; 715 } 716 717 // }}} 718 // {{{ errorCode() 719 720 /** 721 * Determines PEAR::DB error code from the database's text error message 722 * 723 * @param string $errormsg the error message returned from the database 724 * 725 * @return integer the DB error number 726 */ 727 function errorCode($errormsg) 728 { 729 static $error_regexps; 730 if (!isset($error_regexps)) { 731 $error_regexps = array( 732 '/^no such table:/' => DB_ERROR_NOSUCHTABLE, 733 '/^no such index:/' => DB_ERROR_NOT_FOUND, 734 '/^(table|index) .* already exists$/' => DB_ERROR_ALREADY_EXISTS, 735 '/PRIMARY KEY must be unique/i' => DB_ERROR_CONSTRAINT, 736 '/is not unique/' => DB_ERROR_CONSTRAINT, 737 '/columns .* are not unique/i' => DB_ERROR_CONSTRAINT, 738 '/uniqueness constraint failed/' => DB_ERROR_CONSTRAINT, 739 '/may not be NULL/' => DB_ERROR_CONSTRAINT_NOT_NULL, 740 '/^no such column:/' => DB_ERROR_NOSUCHFIELD, 741 '/column not present in both tables/i' => DB_ERROR_NOSUCHFIELD, 742 '/^near ".*": syntax error$/' => DB_ERROR_SYNTAX, 743 '/[0-9]+ values for [0-9]+ columns/i' => DB_ERROR_VALUE_COUNT_ON_ROW, 744 ); 745 } 746 foreach ($error_regexps as $regexp => $code) { 747 if (preg_match($regexp, $errormsg)) { 748 return $code; 749 } 750 } 751 // Fall back to DB_ERROR if there was no mapping. 752 return DB_ERROR; 753 } 754 755 // }}} 756 // {{{ tableInfo() 757 758 /** 759 * Returns information about a table 760 * 761 * @param string $result a string containing the name of a table 762 * @param int $mode a valid tableInfo mode 763 * 764 * @return array an associative array with the information requested. 765 * A DB_Error object on failure. 766 * 767 * @see DB_common::tableInfo() 768 * @since Method available since Release 1.7.0 769 */ 770 function tableInfo($result, $mode = null) 771 { 772 if (is_string($result)) { 773 /* 774 * Probably received a table name. 775 * Create a result resource identifier. 776 */ 777 $id = @sqlite_array_query($this->connection, 778 "PRAGMA table_info('$result');", 779 SQLITE_ASSOC); 780 $got_string = true; 781 } else { 782 $this->last_query = ''; 783 return $this->raiseError(DB_ERROR_NOT_CAPABLE, null, null, null, 784 'This DBMS can not obtain tableInfo' . 785 ' from result sets'); 786 } 787 788 if ($this->options['portability'] & DB_PORTABILITY_LOWERCASE) { 789 $case_func = 'strtolower'; 790 } else { 791 $case_func = 'strval'; 792 } 793 794 $count = count($id); 795 $res = array(); 796 797 if ($mode) { 798 $res['num_fields'] = $count; 799 } 800 801 for ($i = 0; $i < $count; $i++) { 802 if (strpos($id[$i]['type'], '(') !== false) { 803 $bits = explode('(', $id[$i]['type']); 804 $type = $bits[0]; 805 $len = rtrim($bits[1],')'); 806 } else { 807 $type = $id[$i]['type']; 808 $len = 0; 809 } 810 811 $flags = ''; 812 if ($id[$i]['pk']) { 813 $flags .= 'primary_key '; 814 } 815 if ($id[$i]['notnull']) { 816 $flags .= 'not_null '; 817 } 818 if ($id[$i]['dflt_value'] !== null) { 819 $flags .= 'default_' . rawurlencode($id[$i]['dflt_value']); 820 } 821 $flags = trim($flags); 822 823 $res[$i] = array( 824 'table' => $case_func($result), 825 'name' => $case_func($id[$i]['name']), 826 'type' => $type, 827 'len' => $len, 828 'flags' => $flags, 829 ); 830 831 if ($mode & DB_TABLEINFO_ORDER) { 832 $res['order'][$res[$i]['name']] = $i; 833 } 834 if ($mode & DB_TABLEINFO_ORDERTABLE) { 835 $res['ordertable'][$res[$i]['table']][$res[$i]['name']] = $i; 836 } 837 } 838 839 return $res; 840 } 841 842 // }}} 843 // {{{ getSpecialQuery() 844 845 /** 846 * Obtains the query string needed for listing a given type of objects 847 * 848 * @param string $type the kind of objects you want to retrieve 849 * @param array $args SQLITE DRIVER ONLY: a private array of arguments 850 * used by the getSpecialQuery(). Do not use 851 * this directly. 852 * 853 * @return string the SQL query string or null if the driver doesn't 854 * support the object type requested 855 * 856 * @access protected 857 * @see DB_common::getListOf() 858 */ 859 function getSpecialQuery($type, $args = array()) 860 { 861 if (!is_array($args)) { 862 return $this->raiseError('no key specified', null, null, null, 863 'Argument has to be an array.'); 864 } 865 866 switch ($type) { 867 case 'master': 868 return 'SELECT * FROM sqlite_master;'; 869 case 'tables': 870 return "SELECT name FROM sqlite_master WHERE type='table' " 871 . 'UNION ALL SELECT name FROM sqlite_temp_master ' 872 . "WHERE type='table' ORDER BY name;"; 873 case 'schema': 874 return 'SELECT sql FROM (SELECT * FROM sqlite_master ' 875 . 'UNION ALL SELECT * FROM sqlite_temp_master) ' 876 . "WHERE type!='meta' " 877 . 'ORDER BY tbl_name, type DESC, name;'; 878 case 'schemax': 879 case 'schema_x': 880 /* 881 * Use like: 882 * $res = $db->query($db->getSpecialQuery('schema_x', 883 * array('table' => 'table3'))); 884 */ 885 return 'SELECT sql FROM (SELECT * FROM sqlite_master ' 886 . 'UNION ALL SELECT * FROM sqlite_temp_master) ' 887 . "WHERE tbl_name LIKE '{$args['table']}' " 888 . "AND type!='meta' " 889 . 'ORDER BY type DESC, name;'; 890 case 'alter': 891 /* 892 * SQLite does not support ALTER TABLE; this is a helper query 893 * to handle this. 'table' represents the table name, 'rows' 894 * the news rows to create, 'save' the row(s) to keep _with_ 895 * the data. 896 * 897 * Use like: 898 * $args = array( 899 * 'table' => $table, 900 * 'rows' => "id INTEGER PRIMARY KEY, firstname TEXT, surname TEXT, datetime TEXT", 901 * 'save' => "NULL, titel, content, datetime" 902 * ); 903 * $res = $db->query( $db->getSpecialQuery('alter', $args)); 904 */ 905 $rows = strtr($args['rows'], $this->keywords); 906 907 $q = array( 908 'BEGIN TRANSACTION', 909 "CREATE TEMPORARY TABLE {$args['table']}_backup ({$args['rows']})", 910 "INSERT INTO {$args['table']}_backup SELECT {$args['save']} FROM {$args['table']}", 911 "DROP TABLE {$args['table']}", 912 "CREATE TABLE {$args['table']} ({$args['rows']})", 913 "INSERT INTO {$args['table']} SELECT {$rows} FROM {$args['table']}_backup", 914 "DROP TABLE {$args['table']}_backup", 915 'COMMIT', 916 ); 917 918 /* 919 * This is a dirty hack, since the above query will not get 920 * executed with a single query call so here the query method 921 * will be called directly and return a select instead. 922 */ 923 foreach ($q as $query) { 924 $this->query($query); 925 } 926 return "SELECT * FROM {$args['table']};"; 927 default: 928 return null; 929 } 930 } 931 932 // }}} 933 } 934 935 /* 936 * Local variables: 937 * tab-width: 4 938 * c-basic-offset: 4 939 * End: 940 */ 941 942 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| [ Powered by PHPXref - Served by Debian GNU/Linux ] |