[ PHPXref.com ] [ Generated: Sun Jul 20 20:47:21 2008 ] [ TPLN 2.6 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/TPLN/pear/DB/ -> sqlite.php (source)

   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  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]