MediaWiki  1.33.0
DatabaseSqlite.php
Go to the documentation of this file.
1 <?php
24 namespace Wikimedia\Rdbms;
25 
26 use PDO;
27 use PDOException;
28 use Exception;
31 use InvalidArgumentException;
32 use RuntimeException;
33 use stdClass;
34 
38 class DatabaseSqlite extends Database {
40  private static $fulltextEnabled = null;
41 
43  protected $dbDir;
45  protected $dbPath;
47  protected $trxMode;
48 
52  protected $lastResultHandle;
53 
55  protected $conn;
56 
58  protected $lockMgr;
59 
61  private $alreadyAttached = [];
62 
71  function __construct( array $p ) {
72  if ( isset( $p['dbFilePath'] ) ) {
73  $this->dbPath = $p['dbFilePath'];
74  $lockDomain = md5( $this->dbPath );
75  // Use "X" for things like X.sqlite and ":memory:" for RAM-only DBs
76  if ( !isset( $p['dbname'] ) || !strlen( $p['dbname'] ) ) {
77  $p['dbname'] = preg_replace( '/\.sqlite\d?$/', '', basename( $this->dbPath ) );
78  }
79  } elseif ( isset( $p['dbDirectory'] ) ) {
80  $this->dbDir = $p['dbDirectory'];
81  $lockDomain = $p['dbname'];
82  } else {
83  throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." );
84  }
85 
86  $this->trxMode = isset( $p['trxMode'] ) ? strtoupper( $p['trxMode'] ) : null;
87  if ( $this->trxMode &&
88  !in_array( $this->trxMode, [ 'DEFERRED', 'IMMEDIATE', 'EXCLUSIVE' ] )
89  ) {
90  $this->trxMode = null;
91  $this->queryLogger->warning( "Invalid SQLite transaction mode provided." );
92  }
93 
94  $this->lockMgr = new FSLockManager( [
95  'domain' => $lockDomain,
96  'lockDirectory' => "{$this->dbDir}/locks"
97  ] );
98 
99  parent::__construct( $p );
100  }
101 
102  protected static function getAttributes() {
103  return [ self::ATTR_DB_LEVEL_LOCKING => true ];
104  }
105 
115  public static function newStandaloneInstance( $filename, array $p = [] ) {
116  $p['dbFilePath'] = $filename;
117  $p['schema'] = null;
118  $p['tablePrefix'] = '';
120  $db = Database::factory( 'sqlite', $p );
121 
122  return $db;
123  }
124 
125  protected function doInitConnection() {
126  if ( $this->dbPath !== null ) {
127  // Standalone .sqlite file mode.
128  $this->openFile(
129  $this->dbPath,
130  $this->connectionParams['dbname'],
131  $this->connectionParams['tablePrefix']
132  );
133  } elseif ( $this->dbDir !== null ) {
134  // Stock wiki mode using standard file names per DB
135  if ( strlen( $this->connectionParams['dbname'] ) ) {
136  $this->open(
137  $this->connectionParams['host'],
138  $this->connectionParams['user'],
139  $this->connectionParams['password'],
140  $this->connectionParams['dbname'],
141  $this->connectionParams['schema'],
142  $this->connectionParams['tablePrefix']
143  );
144  } else {
145  // Caller will manually call open() later?
146  $this->connLogger->debug( __METHOD__ . ': no database opened.' );
147  }
148  } else {
149  throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." );
150  }
151  }
152 
156  function getType() {
157  return 'sqlite';
158  }
159 
165  function implicitGroupby() {
166  return false;
167  }
168 
169  protected function open( $server, $user, $pass, $dbName, $schema, $tablePrefix ) {
170  $this->close();
171  $fileName = self::generateFileName( $this->dbDir, $dbName );
172  if ( !is_readable( $fileName ) ) {
173  $this->conn = false;
174  throw new DBConnectionError( $this, "SQLite database not accessible" );
175  }
176  // Only $dbName is used, the other parameters are irrelevant for SQLite databases
177  $this->openFile( $fileName, $dbName, $tablePrefix );
178 
179  return (bool)$this->conn;
180  }
181 
191  protected function openFile( $fileName, $dbName, $tablePrefix ) {
192  $err = false;
193 
194  $this->dbPath = $fileName;
195  try {
196  if ( $this->flags & self::DBO_PERSISTENT ) {
197  $this->conn = new PDO( "sqlite:$fileName", '', '',
198  [ PDO::ATTR_PERSISTENT => true ] );
199  } else {
200  $this->conn = new PDO( "sqlite:$fileName", '', '' );
201  }
202  } catch ( PDOException $e ) {
203  $err = $e->getMessage();
204  }
205 
206  if ( !$this->conn ) {
207  $this->queryLogger->debug( "DB connection error: $err\n" );
208  throw new DBConnectionError( $this, $err );
209  }
210 
211  $this->opened = is_object( $this->conn );
212  if ( $this->opened ) {
213  $this->currentDomain = new DatabaseDomain( $dbName, null, $tablePrefix );
214  # Set error codes only, don't raise exceptions
215  $this->conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
216  # Enforce LIKE to be case sensitive, just like MySQL
217  $this->query( 'PRAGMA case_sensitive_like = 1' );
218 
219  $sync = $this->sessionVars['synchronous'] ?? null;
220  if ( in_array( $sync, [ 'EXTRA', 'FULL', 'NORMAL' ], true ) ) {
221  $this->query( "PRAGMA synchronous = $sync" );
222  }
223 
224  return $this->conn;
225  }
226 
227  return false;
228  }
229 
234  public function getDbFilePath() {
235  return $this->dbPath;
236  }
237 
242  protected function closeConnection() {
243  $this->conn = null;
244 
245  return true;
246  }
247 
254  public static function generateFileName( $dir, $dbName ) {
255  return "$dir/$dbName.sqlite";
256  }
257 
263  if ( self::$fulltextEnabled === null ) {
264  self::$fulltextEnabled = false;
265  $table = $this->tableName( 'searchindex' );
266  $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name = '$table'", __METHOD__ );
267  if ( $res ) {
268  $row = $res->fetchRow();
269  self::$fulltextEnabled = stristr( $row['sql'], 'fts' ) !== false;
270  }
271  }
272 
273  return self::$fulltextEnabled;
274  }
275 
280  static function getFulltextSearchModule() {
281  static $cachedResult = null;
282  if ( $cachedResult !== null ) {
283  return $cachedResult;
284  }
285  $cachedResult = false;
286  $table = 'dummy_search_test';
287 
288  $db = self::newStandaloneInstance( ':memory:' );
289  if ( $db->query( "CREATE VIRTUAL TABLE $table USING FTS3(dummy_field)", __METHOD__, true ) ) {
290  $cachedResult = 'FTS3';
291  }
292  $db->close();
293 
294  return $cachedResult;
295  }
296 
308  function attachDatabase( $name, $file = false, $fname = __METHOD__ ) {
309  if ( !$file ) {
310  $file = self::generateFileName( $this->dbDir, $name );
311  }
312  $file = $this->addQuotes( $file );
313 
314  return $this->query( "ATTACH DATABASE $file AS $name", $fname );
315  }
316 
317  protected function isWriteQuery( $sql ) {
318  return parent::isWriteQuery( $sql ) && !preg_match( '/^(ATTACH|PRAGMA)\b/i', $sql );
319  }
320 
321  protected function isTransactableQuery( $sql ) {
322  return parent::isTransactableQuery( $sql ) && !in_array(
323  $this->getQueryVerb( $sql ),
324  [ 'ATTACH', 'PRAGMA' ],
325  true
326  );
327  }
328 
335  protected function doQuery( $sql ) {
336  $res = $this->getBindingHandle()->query( $sql );
337  if ( $res === false ) {
338  return false;
339  }
340 
341  $r = $res instanceof ResultWrapper ? $res->result : $res;
342  $this->lastAffectedRowCount = $r->rowCount();
343  $res = new ResultWrapper( $this, $r->fetchAll() );
344 
345  return $res;
346  }
347 
351  function freeResult( $res ) {
352  if ( $res instanceof ResultWrapper ) {
353  $res->result = null;
354  } else {
355  $res = null;
356  }
357  }
358 
363  function fetchObject( $res ) {
364  if ( $res instanceof ResultWrapper ) {
365  $r =& $res->result;
366  } else {
367  $r =& $res;
368  }
369 
370  $cur = current( $r );
371  if ( is_array( $cur ) ) {
372  next( $r );
373  $obj = new stdClass;
374  foreach ( $cur as $k => $v ) {
375  if ( !is_numeric( $k ) ) {
376  $obj->$k = $v;
377  }
378  }
379 
380  return $obj;
381  }
382 
383  return false;
384  }
385 
390  function fetchRow( $res ) {
391  if ( $res instanceof ResultWrapper ) {
392  $r =& $res->result;
393  } else {
394  $r =& $res;
395  }
396  $cur = current( $r );
397  if ( is_array( $cur ) ) {
398  next( $r );
399 
400  return $cur;
401  }
402 
403  return false;
404  }
405 
412  function numRows( $res ) {
413  // false does not implement Countable
414  $r = $res instanceof ResultWrapper ? $res->result : $res;
415 
416  return is_array( $r ) ? count( $r ) : 0;
417  }
418 
423  function numFields( $res ) {
424  $r = $res instanceof ResultWrapper ? $res->result : $res;
425  if ( is_array( $r ) && count( $r ) > 0 ) {
426  // The size of the result array is twice the number of fields. (T67578)
427  return count( $r[0] ) / 2;
428  } else {
429  // If the result is empty return 0
430  return 0;
431  }
432  }
433 
439  function fieldName( $res, $n ) {
440  $r = $res instanceof ResultWrapper ? $res->result : $res;
441  if ( is_array( $r ) ) {
442  $keys = array_keys( $r[0] );
443 
444  return $keys[$n];
445  }
446 
447  return false;
448  }
449 
457  function tableName( $name, $format = 'quoted' ) {
458  // table names starting with sqlite_ are reserved
459  if ( strpos( $name, 'sqlite_' ) === 0 ) {
460  return $name;
461  }
462 
463  return str_replace( '"', '', parent::tableName( $name, $format ) );
464  }
465 
471  function insertId() {
472  // PDO::lastInsertId yields a string :(
473  return intval( $this->getBindingHandle()->lastInsertId() );
474  }
475 
480  function dataSeek( $res, $row ) {
481  if ( $res instanceof ResultWrapper ) {
482  $r =& $res->result;
483  } else {
484  $r =& $res;
485  }
486  reset( $r );
487  if ( $row > 0 ) {
488  for ( $i = 0; $i < $row; $i++ ) {
489  next( $r );
490  }
491  }
492  }
493 
497  function lastError() {
498  if ( !is_object( $this->conn ) ) {
499  return "Cannot return last error, no db connection";
500  }
501  $e = $this->conn->errorInfo();
502 
503  return $e[2] ?? '';
504  }
505 
509  function lastErrno() {
510  if ( !is_object( $this->conn ) ) {
511  return "Cannot return last error, no db connection";
512  } else {
513  $info = $this->conn->errorInfo();
514 
515  return $info[1];
516  }
517  }
518 
522  protected function fetchAffectedRowCount() {
524  }
525 
526  function tableExists( $table, $fname = __METHOD__ ) {
527  $tableRaw = $this->tableName( $table, 'raw' );
528  if ( isset( $this->sessionTempTables[$tableRaw] ) ) {
529  return true; // already known to exist
530  }
531 
532  $encTable = $this->addQuotes( $tableRaw );
533  $res = $this->query(
534  "SELECT 1 FROM sqlite_master WHERE type='table' AND name=$encTable" );
535 
536  return $res->numRows() ? true : false;
537  }
538 
549  function indexInfo( $table, $index, $fname = __METHOD__ ) {
550  $sql = 'PRAGMA index_info(' . $this->addQuotes( $this->indexName( $index ) ) . ')';
551  $res = $this->query( $sql, $fname );
552  if ( !$res || $res->numRows() == 0 ) {
553  return false;
554  }
555  $info = [];
556  foreach ( $res as $row ) {
557  $info[] = $row->name;
558  }
559 
560  return $info;
561  }
562 
569  function indexUnique( $table, $index, $fname = __METHOD__ ) {
570  $row = $this->selectRow( 'sqlite_master', '*',
571  [
572  'type' => 'index',
573  'name' => $this->indexName( $index ),
574  ], $fname );
575  if ( !$row || !isset( $row->sql ) ) {
576  return null;
577  }
578 
579  // $row->sql will be of the form CREATE [UNIQUE] INDEX ...
580  $indexPos = strpos( $row->sql, 'INDEX' );
581  if ( $indexPos === false ) {
582  return null;
583  }
584  $firstPart = substr( $row->sql, 0, $indexPos );
585  $options = explode( ' ', $firstPart );
586 
587  return in_array( 'UNIQUE', $options );
588  }
589 
597  foreach ( $options as $k => $v ) {
598  if ( is_numeric( $k ) && ( $v == 'FOR UPDATE' || $v == 'LOCK IN SHARE MODE' ) ) {
599  $options[$k] = '';
600  }
601  }
602 
603  return parent::makeSelectOptions( $options );
604  }
605 
610  protected function makeUpdateOptionsArray( $options ) {
611  $options = parent::makeUpdateOptionsArray( $options );
613 
614  return $options;
615  }
616 
621  static function fixIgnore( $options ) {
622  # SQLite uses OR IGNORE not just IGNORE
623  foreach ( $options as $k => $v ) {
624  if ( $v == 'IGNORE' ) {
625  $options[$k] = 'OR IGNORE';
626  }
627  }
628 
629  return $options;
630  }
631 
638 
639  return parent::makeInsertOptions( $options );
640  }
641 
650  function insert( $table, $a, $fname = __METHOD__, $options = [] ) {
651  if ( !count( $a ) ) {
652  return true;
653  }
654 
655  # SQLite can't handle multi-row inserts, so divide up into multiple single-row inserts
656  if ( isset( $a[0] ) && is_array( $a[0] ) ) {
657  $affectedRowCount = 0;
658  try {
659  $this->startAtomic( $fname, self::ATOMIC_CANCELABLE );
660  foreach ( $a as $v ) {
661  parent::insert( $table, $v, "$fname/multi-row", $options );
662  $affectedRowCount += $this->affectedRows();
663  }
664  $this->endAtomic( $fname );
665  } catch ( Exception $e ) {
666  $this->cancelAtomic( $fname );
667  throw $e;
668  }
669  $this->affectedRowCount = $affectedRowCount;
670  } else {
671  parent::insert( $table, $a, "$fname/single-row", $options );
672  }
673 
674  return true;
675  }
676 
683  function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
684  if ( !count( $rows ) ) {
685  return;
686  }
687 
688  # SQLite can't handle multi-row replaces, so divide up into multiple single-row queries
689  if ( isset( $rows[0] ) && is_array( $rows[0] ) ) {
690  $affectedRowCount = 0;
691  try {
692  $this->startAtomic( $fname, self::ATOMIC_CANCELABLE );
693  foreach ( $rows as $v ) {
694  $this->nativeReplace( $table, $v, "$fname/multi-row" );
695  $affectedRowCount += $this->affectedRows();
696  }
697  $this->endAtomic( $fname );
698  } catch ( Exception $e ) {
699  $this->cancelAtomic( $fname );
700  throw $e;
701  }
702  $this->affectedRowCount = $affectedRowCount;
703  } else {
704  $this->nativeReplace( $table, $rows, "$fname/single-row" );
705  }
706  }
707 
716  function textFieldSize( $table, $field ) {
717  return -1;
718  }
719 
724  return false;
725  }
726 
732  function unionQueries( $sqls, $all ) {
733  $glue = $all ? ' UNION ALL ' : ' UNION ';
734 
735  return implode( $glue, $sqls );
736  }
737 
741  function wasDeadlock() {
742  return $this->lastErrno() == 5; // SQLITE_BUSY
743  }
744 
748  function wasReadOnlyError() {
749  return $this->lastErrno() == 8; // SQLITE_READONLY;
750  }
751 
752  public function wasConnectionError( $errno ) {
753  return $errno == 17; // SQLITE_SCHEMA;
754  }
755 
756  protected function wasKnownStatementRollbackError() {
757  // ON CONFLICT ROLLBACK clauses make it so that SQLITE_CONSTRAINT error is
758  // ambiguous with regard to whether it implies a ROLLBACK or an ABORT happened.
759  // https://sqlite.org/lang_createtable.html#uniqueconst
760  // https://sqlite.org/lang_conflict.html
761  return false;
762  }
763 
767  public function getSoftwareLink() {
768  return "[{{int:version-db-sqlite-url}} SQLite]";
769  }
770 
774  function getServerVersion() {
775  $ver = $this->getBindingHandle()->getAttribute( PDO::ATTR_SERVER_VERSION );
776 
777  return $ver;
778  }
779 
788  function fieldInfo( $table, $field ) {
789  $tableName = $this->tableName( $table );
790  $sql = 'PRAGMA table_info(' . $this->addQuotes( $tableName ) . ')';
791  $res = $this->query( $sql, __METHOD__ );
792  foreach ( $res as $row ) {
793  if ( $row->name == $field ) {
794  return new SQLiteField( $row, $tableName );
795  }
796  }
797 
798  return false;
799  }
800 
801  protected function doBegin( $fname = '' ) {
802  if ( $this->trxMode ) {
803  $this->query( "BEGIN {$this->trxMode}", $fname );
804  } else {
805  $this->query( 'BEGIN', $fname );
806  }
807  $this->trxLevel = 1;
808  }
809 
814  function strencode( $s ) {
815  return substr( $this->addQuotes( $s ), 1, -1 );
816  }
817 
822  function encodeBlob( $b ) {
823  return new Blob( $b );
824  }
825 
830  function decodeBlob( $b ) {
831  if ( $b instanceof Blob ) {
832  $b = $b->fetch();
833  }
834 
835  return $b;
836  }
837 
842  function addQuotes( $s ) {
843  if ( $s instanceof Blob ) {
844  return "x'" . bin2hex( $s->fetch() ) . "'";
845  } elseif ( is_bool( $s ) ) {
846  return (int)$s;
847  } elseif ( strpos( (string)$s, "\0" ) !== false ) {
848  // SQLite doesn't support \0 in strings, so use the hex representation as a workaround.
849  // This is a known limitation of SQLite's mprintf function which PDO
850  // should work around, but doesn't. I have reported this to php.net as bug #63419:
851  // https://bugs.php.net/bug.php?id=63419
852  // There was already a similar report for SQLite3::escapeString, bug #62361:
853  // https://bugs.php.net/bug.php?id=62361
854  // There is an additional bug regarding sorting this data after insert
855  // on older versions of sqlite shipped with ubuntu 12.04
856  // https://phabricator.wikimedia.org/T74367
857  $this->queryLogger->debug(
858  __FUNCTION__ .
859  ': Quoting value containing null byte. ' .
860  'For consistency all binary data should have been ' .
861  'first processed with self::encodeBlob()'
862  );
863  return "x'" . bin2hex( (string)$s ) . "'";
864  } else {
865  return $this->getBindingHandle()->quote( (string)$s );
866  }
867  }
868 
869  public function buildSubstring( $input, $startPosition, $length = null ) {
870  $this->assertBuildSubstringParams( $startPosition, $length );
871  $params = [ $input, $startPosition ];
872  if ( $length !== null ) {
873  $params[] = $length;
874  }
875  return 'SUBSTR(' . implode( ',', $params ) . ')';
876  }
877 
883  public function buildStringCast( $field ) {
884  return 'CAST ( ' . $field . ' AS TEXT )';
885  }
886 
892  public function deadlockLoop( /*...*/ ) {
893  $args = func_get_args();
894  $function = array_shift( $args );
895 
896  return $function( ...$args );
897  }
898 
903  protected function replaceVars( $s ) {
904  $s = parent::replaceVars( $s );
905  if ( preg_match( '/^\s*(CREATE|ALTER) TABLE/i', $s ) ) {
906  // CREATE TABLE hacks to allow schema file sharing with MySQL
907 
908  // binary/varbinary column type -> blob
909  $s = preg_replace( '/\b(var)?binary(\(\d+\))/i', 'BLOB', $s );
910  // no such thing as unsigned
911  $s = preg_replace( '/\b(un)?signed\b/i', '', $s );
912  // INT -> INTEGER
913  $s = preg_replace( '/\b(tiny|small|medium|big|)int(\s*\(\s*\d+\s*\)|\b)/i', 'INTEGER', $s );
914  // floating point types -> REAL
915  $s = preg_replace(
916  '/\b(float|double(\s+precision)?)(\s*\(\s*\d+\s*(,\s*\d+\s*)?\)|\b)/i',
917  'REAL',
918  $s
919  );
920  // varchar -> TEXT
921  $s = preg_replace( '/\b(var)?char\s*\(.*?\)/i', 'TEXT', $s );
922  // TEXT normalization
923  $s = preg_replace( '/\b(tiny|medium|long)text\b/i', 'TEXT', $s );
924  // BLOB normalization
925  $s = preg_replace( '/\b(tiny|small|medium|long|)blob\b/i', 'BLOB', $s );
926  // BOOL -> INTEGER
927  $s = preg_replace( '/\bbool(ean)?\b/i', 'INTEGER', $s );
928  // DATETIME -> TEXT
929  $s = preg_replace( '/\b(datetime|timestamp)\b/i', 'TEXT', $s );
930  // No ENUM type
931  $s = preg_replace( '/\benum\s*\([^)]*\)/i', 'TEXT', $s );
932  // binary collation type -> nothing
933  $s = preg_replace( '/\bbinary\b/i', '', $s );
934  // auto_increment -> autoincrement
935  $s = preg_replace( '/\bauto_increment\b/i', 'AUTOINCREMENT', $s );
936  // No explicit options
937  $s = preg_replace( '/\)[^);]*(;?)\s*$/', ')\1', $s );
938  // AUTOINCREMENT should immedidately follow PRIMARY KEY
939  $s = preg_replace( '/primary key (.*?) autoincrement/i', 'PRIMARY KEY AUTOINCREMENT $1', $s );
940  } elseif ( preg_match( '/^\s*CREATE (\s*(?:UNIQUE|FULLTEXT)\s+)?INDEX/i', $s ) ) {
941  // No truncated indexes
942  $s = preg_replace( '/\(\d+\)/', '', $s );
943  // No FULLTEXT
944  $s = preg_replace( '/\bfulltext\b/i', '', $s );
945  } elseif ( preg_match( '/^\s*DROP INDEX/i', $s ) ) {
946  // DROP INDEX is database-wide, not table-specific, so no ON <table> clause.
947  $s = preg_replace( '/\sON\s+[^\s]*/i', '', $s );
948  } elseif ( preg_match( '/^\s*INSERT IGNORE\b/i', $s ) ) {
949  // INSERT IGNORE --> INSERT OR IGNORE
950  $s = preg_replace( '/^\s*INSERT IGNORE\b/i', 'INSERT OR IGNORE', $s );
951  }
952 
953  return $s;
954  }
955 
956  public function lock( $lockName, $method, $timeout = 5 ) {
957  if ( !is_dir( "{$this->dbDir}/locks" ) ) { // create dir as needed
958  if ( !is_writable( $this->dbDir ) || !mkdir( "{$this->dbDir}/locks" ) ) {
959  throw new DBError( $this, "Cannot create directory \"{$this->dbDir}/locks\"." );
960  }
961  }
962 
963  return $this->lockMgr->lock( [ $lockName ], LockManager::LOCK_EX, $timeout )->isOK();
964  }
965 
966  public function unlock( $lockName, $method ) {
967  return $this->lockMgr->unlock( [ $lockName ], LockManager::LOCK_EX )->isOK();
968  }
969 
976  function buildConcat( $stringList ) {
977  return '(' . implode( ') || (', $stringList ) . ')';
978  }
979 
980  public function buildGroupConcatField(
981  $delim, $table, $field, $conds = '', $join_conds = []
982  ) {
983  $fld = "group_concat($field," . $this->addQuotes( $delim ) . ')';
984 
985  return '(' . $this->selectSQLText( $table, $fld, $conds, null, [], $join_conds ) . ')';
986  }
987 
996  function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = __METHOD__ ) {
997  $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name=" .
998  $this->addQuotes( $oldName ) . " AND type='table'", $fname );
999  $obj = $this->fetchObject( $res );
1000  if ( !$obj ) {
1001  throw new RuntimeException( "Couldn't retrieve structure for table $oldName" );
1002  }
1003  $sql = $obj->sql;
1004  $sql = preg_replace(
1005  '/(?<=\W)"?' .
1006  preg_quote( trim( $this->addIdentifierQuotes( $oldName ), '"' ), '/' ) .
1007  '"?(?=\W)/',
1008  $this->addIdentifierQuotes( $newName ),
1009  $sql,
1010  1
1011  );
1012  if ( $temporary ) {
1013  if ( preg_match( '/^\\s*CREATE\\s+VIRTUAL\\s+TABLE\b/i', $sql ) ) {
1014  $this->queryLogger->debug(
1015  "Table $oldName is virtual, can't create a temporary duplicate.\n" );
1016  } else {
1017  $sql = str_replace( 'CREATE TABLE', 'CREATE TEMPORARY TABLE', $sql );
1018  }
1019  }
1020 
1021  $res = $this->query( $sql, $fname, self::QUERY_PSEUDO_PERMANENT );
1022 
1023  // Take over indexes
1024  $indexList = $this->query( 'PRAGMA INDEX_LIST(' . $this->addQuotes( $oldName ) . ')' );
1025  foreach ( $indexList as $index ) {
1026  if ( strpos( $index->name, 'sqlite_autoindex' ) === 0 ) {
1027  continue;
1028  }
1029 
1030  if ( $index->unique ) {
1031  $sql = 'CREATE UNIQUE INDEX';
1032  } else {
1033  $sql = 'CREATE INDEX';
1034  }
1035  // Try to come up with a new index name, given indexes have database scope in SQLite
1036  $indexName = $newName . '_' . $index->name;
1037  $sql .= ' ' . $indexName . ' ON ' . $newName;
1038 
1039  $indexInfo = $this->query( 'PRAGMA INDEX_INFO(' . $this->addQuotes( $index->name ) . ')' );
1040  $fields = [];
1041  foreach ( $indexInfo as $indexInfoRow ) {
1042  $fields[$indexInfoRow->seqno] = $indexInfoRow->name;
1043  }
1044 
1045  $sql .= '(' . implode( ',', $fields ) . ')';
1046 
1047  $this->query( $sql );
1048  }
1049 
1050  return $res;
1051  }
1052 
1061  function listTables( $prefix = null, $fname = __METHOD__ ) {
1062  $result = $this->select(
1063  'sqlite_master',
1064  'name',
1065  "type='table'"
1066  );
1067 
1068  $endArray = [];
1069 
1070  foreach ( $result as $table ) {
1071  $vars = get_object_vars( $table );
1072  $table = array_pop( $vars );
1073 
1074  if ( !$prefix || strpos( $table, $prefix ) === 0 ) {
1075  if ( strpos( $table, 'sqlite_' ) !== 0 ) {
1076  $endArray[] = $table;
1077  }
1078  }
1079  }
1080 
1081  return $endArray;
1082  }
1083 
1092  public function dropTable( $tableName, $fName = __METHOD__ ) {
1093  if ( !$this->tableExists( $tableName, $fName ) ) {
1094  return false;
1095  }
1096  $sql = "DROP TABLE " . $this->tableName( $tableName );
1097 
1098  return $this->query( $sql, $fName );
1099  }
1100 
1101  public function setTableAliases( array $aliases ) {
1102  parent::setTableAliases( $aliases );
1103  foreach ( $this->tableAliases as $params ) {
1104  if ( isset( $this->alreadyAttached[$params['dbname']] ) ) {
1105  continue;
1106  }
1107  $this->attachDatabase( $params['dbname'] );
1108  $this->alreadyAttached[$params['dbname']] = true;
1109  }
1110  }
1111 
1112  public function resetSequenceForTable( $table, $fname = __METHOD__ ) {
1113  $encTable = $this->addIdentifierQuotes( 'sqlite_sequence' );
1114  $encName = $this->addQuotes( $this->tableName( $table, 'raw' ) );
1115  $this->query( "DELETE FROM $encTable WHERE name = $encName", $fname );
1116  }
1117 
1118  public function databasesAreIndependent() {
1119  return true;
1120  }
1121 
1125  public function __toString() {
1126  return is_object( $this->conn )
1127  ? 'SQLite ' . (string)$this->conn->getAttribute( PDO::ATTR_SERVER_VERSION )
1128  : '(not connected)';
1129  }
1130 
1134  protected function getBindingHandle() {
1135  return parent::getBindingHandle();
1136  }
1137 }
1138 
1142 class_alias( DatabaseSqlite::class, 'DatabaseSqlite' );
DBO_PERSISTENT
const DBO_PERSISTENT
Definition: defines.php:14
Wikimedia\Rdbms\DatabaseSqlite\$fulltextEnabled
static bool $fulltextEnabled
Whether full text is enabled.
Definition: DatabaseSqlite.php:40
Wikimedia\Rdbms\SQLiteField
Definition: SQLiteField.php:5
Wikimedia\Rdbms\DatabaseSqlite\$trxMode
string $trxMode
Transaction mode.
Definition: DatabaseSqlite.php:47
Wikimedia\Rdbms\DatabaseSqlite\fieldInfo
fieldInfo( $table, $field)
Get information about a given field Returns false if the field does not exist.
Definition: DatabaseSqlite.php:788
Wikimedia\Rdbms\DatabaseSqlite\$lockMgr
FSLockManager $lockMgr
(hopefully on the same server as the DB)
Definition: DatabaseSqlite.php:58
insert
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and insert
Definition: hooks.txt:2064
LockManager
Class for handling resource locking.
Definition: LockManager.php:46
Wikimedia\Rdbms\DatabaseSqlite\getBindingHandle
getBindingHandle()
Definition: DatabaseSqlite.php:1134
Wikimedia\Rdbms\DatabaseSqlite\addQuotes
addQuotes( $s)
Definition: DatabaseSqlite.php:842
Wikimedia\Rdbms\DatabaseSqlite\fetchRow
fetchRow( $res)
Definition: DatabaseSqlite.php:390
Wikimedia\Rdbms\Database
Relational database abstraction object.
Definition: Database.php:48
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Definition: router.php:42
Wikimedia\Rdbms\DatabaseSqlite
Definition: DatabaseSqlite.php:38
Wikimedia\Rdbms\DatabaseSqlite\$dbDir
string $dbDir
Directory.
Definition: DatabaseSqlite.php:43
Wikimedia\Rdbms\DatabaseSqlite\wasKnownStatementRollbackError
wasKnownStatementRollbackError()
Definition: DatabaseSqlite.php:756
Wikimedia\Rdbms\Database\factory
static factory( $dbType, $p=[], $connect=self::NEW_CONNECTED)
Construct a Database subclass instance given a database type and parameters.
Definition: Database.php:434
Wikimedia\Rdbms\DatabaseSqlite\listTables
listTables( $prefix=null, $fname=__METHOD__)
List all tables on the database.
Definition: DatabaseSqlite.php:1061
FSLockManager
Simple version of LockManager based on using FS lock files.
Definition: FSLockManager.php:36
Wikimedia\Rdbms\DatabaseSqlite\unlock
unlock( $lockName, $method)
Release a lock.
Definition: DatabaseSqlite.php:966
Wikimedia\Rdbms\DatabaseSqlite\open
open( $server, $user, $pass, $dbName, $schema, $tablePrefix)
Open a new connection to the database (closing any existing one)
Definition: DatabaseSqlite.php:169
captcha-old.count
count
Definition: captcha-old.py:249
Wikimedia\Rdbms\Database\nativeReplace
nativeReplace( $table, $rows, $fname)
REPLACE query wrapper for MySQL and SQLite, which have a native REPLACE statement.
Definition: Database.php:2906
Wikimedia\Rdbms\DatabaseSqlite\unionSupportsOrderAndLimit
unionSupportsOrderAndLimit()
Definition: DatabaseSqlite.php:723
Wikimedia\Rdbms\DatabaseSqlite\implicitGroupby
implicitGroupby()
Definition: DatabaseSqlite.php:165
$result
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message. Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item. Return false to stop further processing of the tag $reader:XMLReader object $logInfo:Array of information 'ImportHandlePageXMLTag':When parsing a XML tag in a page. Return false to stop further processing of the tag $reader:XMLReader object & $pageInfo:Array of information 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision. Return false to stop further processing of the tag $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information 'ImportHandleToplevelXMLTag':When parsing a top level XML tag. Return false to stop further processing of the tag $reader:XMLReader object 'ImportHandleUnknownUser':When a user doesn 't exist locally, this hook is called to give extensions an opportunity to auto-create it. If the auto-creation is successful, return false. $name:User name 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload. Return false to stop further processing of the tag $reader:XMLReader object $revisionInfo:Array of information 'ImportLogInterwikiLink':Hook to change the interwiki link used in log entries and edit summaries for transwiki imports. & $fullInterwikiPrefix:Interwiki prefix, may contain colons. & $pageTitle:String that contains page title. 'ImportSources':Called when reading from the $wgImportSources configuration variable. Can be used to lazy-load the import sources list. & $importSources:The value of $wgImportSources. Modify as necessary. See the comment in DefaultSettings.php for the detail of how to structure this array. 'InfoAction':When building information to display on the action=info page. $context:IContextSource object & $pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect. & $title:Title object for the current page & $request:WebRequest & $ignoreRedirect:boolean to skip redirect check & $target:Title/string of redirect target & $article:Article object 'InternalParseBeforeLinks':during Parser 's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InternalParseBeforeSanitize':during Parser 's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings. Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not. Return true without providing an interwiki to continue interwiki search. $prefix:interwiki prefix we are looking for. & $iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete':Called after a user 's email has been invalidated successfully. $user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification. Callee may modify $url and $query, URL will be constructed as $url . $query & $url:URL to index.php & $query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) & $article:article(object) being checked 'IsTrustedProxy':Override the result of IP::isTrustedProxy() & $ip:IP being check & $result:Change this value to override the result of IP::isTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from & $allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of Sanitizer::validateEmail(), for instance to return false if the domain name doesn 't match your organization. $addr:The e-mail address entered by the user & $result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user & $result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we 're looking for a messages file for & $file:The messages file path, you can override this to change the location. 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces. Do not use this hook to add namespaces. Use CanonicalNamespaces for that. & $namespaces:Array of namespaces indexed by their numbers 'LanguageGetTranslatedLanguageNames':Provide translated language names. & $names:array of language code=> language name $code:language of the preferred translations 'LanguageLinks':Manipulate a page 's language links. This is called in various places to allow extensions to define the effective language links for a page. $title:The page 's Title. & $links:Array with elements of the form "language:title" in the order that they will be output. & $linkFlags:Associative array mapping prefixed links to arrays of flags. Currently unused, but planned to provide support for marking individual language links in the UI, e.g. for featured articles. 'LanguageSelector':Hook to change the language selector available on a page. $out:The output page. $cssClassName:CSS class name of the language selector. 'LinkBegin':DEPRECATED since 1.28! Use HtmlPageLinkRendererBegin instead. Used when generating internal and interwiki links in Linker::link(), before processing starts. Return false to skip default processing and return $ret. See documentation for Linker::link() for details on the expected meanings of parameters. $skin:the Skin object $target:the Title that the link is pointing to & $html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1983
Wikimedia\Rdbms\DatabaseSqlite\databasesAreIndependent
databasesAreIndependent()
Returns true if DBs are assumed to be on potentially different servers.
Definition: DatabaseSqlite.php:1118
Wikimedia\Rdbms\DatabaseSqlite\$dbPath
string $dbPath
File name for SQLite database file.
Definition: DatabaseSqlite.php:45
Wikimedia\Rdbms\Database\endAtomic
endAtomic( $fname=__METHOD__)
Ends an atomic section of SQL statements.
Definition: Database.php:3771
Wikimedia\Rdbms\Database\indexName
indexName( $index)
Allows for index remapping in queries where this is not consistent across DBMS.
Definition: Database.php:2729
Wikimedia\Rdbms\DatabaseSqlite\fetchAffectedRowCount
fetchAffectedRowCount()
Definition: DatabaseSqlite.php:522
Wikimedia\Rdbms\DatabaseSqlite\replace
replace( $table, $uniqueIndexes, $rows, $fname=__METHOD__)
Definition: DatabaseSqlite.php:683
Wikimedia\Rdbms\DatabaseSqlite\encodeBlob
encodeBlob( $b)
Definition: DatabaseSqlite.php:822
Wikimedia\Rdbms\DatabaseSqlite\setTableAliases
setTableAliases(array $aliases)
Make certain table names use their own database, schema, and table prefix when passed into SQL querie...
Definition: DatabaseSqlite.php:1101
Wikimedia\Rdbms
Definition: ChronologyProtector.php:24
$params
$params
Definition: styleTest.css.php:44
Wikimedia\Rdbms\DatabaseSqlite\lastError
lastError()
Definition: DatabaseSqlite.php:497
Wikimedia\Rdbms\DatabaseSqlite\getServerVersion
getServerVersion()
Definition: DatabaseSqlite.php:774
$s
$s
Definition: mergeMessageFileList.php:186
Wikimedia\Rdbms\DatabaseSqlite\dataSeek
dataSeek( $res, $row)
Definition: DatabaseSqlite.php:480
Wikimedia\Rdbms\DatabaseSqlite\strencode
strencode( $s)
Definition: DatabaseSqlite.php:814
Wikimedia\Rdbms\DatabaseSqlite\$lastResultHandle
resource $lastResultHandle
Definition: DatabaseSqlite.php:52
Wikimedia\Rdbms\DatabaseSqlite\buildSubstring
buildSubstring( $input, $startPosition, $length=null)
Definition: DatabaseSqlite.php:869
$res
$res
Definition: database.txt:21
Wikimedia\Rdbms\ResultWrapper
Result wrapper for grabbing data queried from an IDatabase object.
Definition: ResultWrapper.php:24
Wikimedia\Rdbms\DatabaseSqlite\closeConnection
closeConnection()
Does not actually close the connection, just destroys the reference for GC to do its work.
Definition: DatabaseSqlite.php:242
Wikimedia\Rdbms\Database\cancelAtomic
cancelAtomic( $fname=__METHOD__, AtomicSectionIdentifier $sectionId=null)
Cancel an atomic section of SQL statements.
Definition: Database.php:3805
Wikimedia\Rdbms\DBError
Database error base class.
Definition: DBError.php:30
Wikimedia\Rdbms\DatabaseSqlite\buildStringCast
buildStringCast( $field)
Definition: DatabaseSqlite.php:883
Wikimedia\Rdbms\DatabaseSqlite\makeInsertOptions
makeInsertOptions( $options)
Definition: DatabaseSqlite.php:636
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
Wikimedia\Rdbms\DatabaseSqlite\unionQueries
unionQueries( $sqls, $all)
Definition: DatabaseSqlite.php:732
Wikimedia\Rdbms\Database\$affectedRowCount
integer null $affectedRowCount
Rows affected by the last query to query() or its CRUD wrappers.
Definition: Database.php:140
Wikimedia\Rdbms\DatabaseSqlite\openFile
openFile( $fileName, $dbName, $tablePrefix)
Opens a database file.
Definition: DatabaseSqlite.php:191
Wikimedia\Rdbms\DatabaseSqlite\$lastAffectedRowCount
int $lastAffectedRowCount
The number of rows affected as an integer.
Definition: DatabaseSqlite.php:50
Wikimedia\Rdbms\Database\assertBuildSubstringParams
assertBuildSubstringParams( $startPosition, $length)
Check type and bounds for parameters to self::buildSubstring()
Definition: Database.php:2348
Wikimedia\Rdbms\Database\startAtomic
startAtomic( $fname=__METHOD__, $cancelable=self::ATOMIC_NOT_CANCELABLE)
Begin an atomic section of SQL statements.
Definition: Database.php:3741
Wikimedia\Rdbms\DatabaseSqlite\wasDeadlock
wasDeadlock()
Definition: DatabaseSqlite.php:741
tableName
We use the convention $dbr for read and $dbw for write to help you keep track of whether the database object is a the world will explode Or to be a subsequent write query which succeeded on the master may fail when replicated to the slave due to a unique key collision Replication on the slave will stop and it may take hours to repair the database and get it back online Setting read_only in my cnf on the slave will avoid this but given the dire we prefer to have as many checks as possible We provide a but the wrapper functions like please read the documentation for tableName() and addQuotes(). You will need both of them. ------------------------------------------------------------------------ Basic query optimisation ------------------------------------------------------------------------ MediaWiki developers who need to write DB queries should have some understanding of databases and the performance issues associated with them. Patches containing unacceptably slow features will not be accepted. Unindexed queries are generally not welcome in MediaWiki
Wikimedia\Rdbms\Database\trxLevel
trxLevel()
Gets the current transaction level.
Definition: Database.php:588
$input
if(is_array( $mode)) switch( $mode) $input
Definition: postprocess-phan.php:141
Wikimedia\Rdbms\DatabaseSqlite\generateFileName
static generateFileName( $dir, $dbName)
Generates a database file name.
Definition: DatabaseSqlite.php:254
Wikimedia\Rdbms\DatabaseSqlite\doBegin
doBegin( $fname='')
Issues the BEGIN command to the database server.
Definition: DatabaseSqlite.php:801
Wikimedia\Rdbms\DatabaseSqlite\$conn
PDO $conn
Definition: DatabaseSqlite.php:55
Wikimedia\Rdbms\DatabaseSqlite\resetSequenceForTable
resetSequenceForTable( $table, $fname=__METHOD__)
Definition: DatabaseSqlite.php:1112
Wikimedia\Rdbms\DatabaseSqlite\fixIgnore
static fixIgnore( $options)
Definition: DatabaseSqlite.php:621
Wikimedia\Rdbms\Database\selectSQLText
selectSQLText( $table, $vars, $conds='', $fname=__METHOD__, $options=[], $join_conds=[])
The equivalent of IDatabase::select() except that the constructed SQL is returned,...
Definition: Database.php:1787
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
Wikimedia\Rdbms\Database\$user
string $user
User that this instance is currently connected under the name of.
Definition: Database.php:83
Wikimedia\Rdbms\DatabaseSqlite\tableExists
tableExists( $table, $fname=__METHOD__)
Query whether a given table exists.
Definition: DatabaseSqlite.php:526
Wikimedia\Rdbms\DatabaseSqlite\getDbFilePath
getDbFilePath()
Definition: DatabaseSqlite.php:234
Wikimedia\Rdbms\DatabaseSqlite\numRows
numRows( $res)
The PDO::Statement class implements the array interface so count() will work.
Definition: DatabaseSqlite.php:412
$vars
static configuration should be added through ResourceLoaderGetConfigVars instead & $vars
Definition: hooks.txt:2220
Wikimedia\Rdbms\DatabaseSqlite\replaceVars
replaceVars( $s)
Definition: DatabaseSqlite.php:903
Wikimedia\Rdbms\DatabaseSqlite\deadlockLoop
deadlockLoop()
No-op version of deadlockLoop.
Definition: DatabaseSqlite.php:892
array
The wiki should then use memcached to cache various data To use multiple just add more items to the array To increase the weight of a make its entry a array("192.168.0.1:11211", 2))
Wikimedia\Rdbms\DatabaseSqlite\fieldName
fieldName( $res, $n)
Definition: DatabaseSqlite.php:439
string
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
Definition: hooks.txt:175
Wikimedia\Rdbms\Database\selectRow
selectRow( $table, $vars, $conds, $fname=__METHOD__, $options=[], $join_conds=[])
Single row SELECT wrapper.
Definition: Database.php:1870
$fname
if(defined( 'MW_SETUP_CALLBACK')) $fname
Customization point after all loading (constants, functions, classes, DefaultSettings,...
Definition: Setup.php:123
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:271
Wikimedia\Rdbms\DatabaseSqlite\lock
lock( $lockName, $method, $timeout=5)
Acquire a named lock.
Definition: DatabaseSqlite.php:956
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2162
Wikimedia\Rdbms\DatabaseSqlite\fetchObject
fetchObject( $res)
Definition: DatabaseSqlite.php:363
Wikimedia\Rdbms\DatabaseSqlite\__toString
__toString()
Definition: DatabaseSqlite.php:1125
Wikimedia\Rdbms\DatabaseSqlite\doQuery
doQuery( $sql)
SQLite doesn't allow buffered results or data seeking etc, so we'll use fetchAll as the result.
Definition: DatabaseSqlite.php:335
Wikimedia\Rdbms\DatabaseSqlite\getAttributes
static getAttributes()
Definition: DatabaseSqlite.php:102
Wikimedia\Rdbms\DatabaseSqlite\getType
getType()
Definition: DatabaseSqlite.php:156
Wikimedia\Rdbms\DatabaseSqlite\$alreadyAttached
array $alreadyAttached
List of shared database already attached to this connection.
Definition: DatabaseSqlite.php:61
Wikimedia\Rdbms\DatabaseSqlite\buildGroupConcatField
buildGroupConcatField( $delim, $table, $field, $conds='', $join_conds=[])
Build a GROUP_CONCAT or equivalent statement for a query.
Definition: DatabaseSqlite.php:980
Wikimedia\Rdbms\DatabaseSqlite\attachDatabase
attachDatabase( $name, $file=false, $fname=__METHOD__)
Attaches external database to our connection, see https://sqlite.org/lang_attach.html for details.
Definition: DatabaseSqlite.php:308
Wikimedia\Rdbms\DatabaseSqlite\isTransactableQuery
isTransactableQuery( $sql)
Determine whether a SQL statement is sensitive to isolation level.
Definition: DatabaseSqlite.php:321
Wikimedia\Rdbms\DatabaseSqlite\insert
insert( $table, $a, $fname=__METHOD__, $options=[])
Based on generic method (parent) with some prior SQLite-sepcific adjustments.
Definition: DatabaseSqlite.php:650
Wikimedia\Rdbms\DatabaseSqlite\newStandaloneInstance
static newStandaloneInstance( $filename, array $p=[])
Definition: DatabaseSqlite.php:115
Wikimedia\Rdbms\Database\addIdentifierQuotes
addIdentifierQuotes( $s)
Quotes an identifier, in order to make user controlled input safe.
Definition: Database.php:2750
$args
if( $line===false) $args
Definition: cdb.php:64
Wikimedia\Rdbms\Database\close
close()
Close the database connection.
Definition: Database.php:938
Wikimedia\Rdbms\DatabaseSqlite\getFulltextSearchModule
static getFulltextSearchModule()
Returns version of currently supported SQLite fulltext search module or false if none present.
Definition: DatabaseSqlite.php:280
Wikimedia\Rdbms\Database\getQueryVerb
getQueryVerb( $sql)
Definition: Database.php:1123
Wikimedia\Rdbms\DatabaseSqlite\makeUpdateOptionsArray
makeUpdateOptionsArray( $options)
Definition: DatabaseSqlite.php:610
Wikimedia\Rdbms\DatabaseSqlite\getSoftwareLink
getSoftwareLink()
Definition: DatabaseSqlite.php:767
Wikimedia\Rdbms\DatabaseSqlite\doInitConnection
doInitConnection()
Actually connect to the database over the wire (or to local files)
Definition: DatabaseSqlite.php:125
$rows
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction $rows
Definition: hooks.txt:2636
$options
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition: hooks.txt:1985
Wikimedia\Rdbms\DatabaseSqlite\insertId
insertId()
This must be called after nextSequenceVal.
Definition: DatabaseSqlite.php:471
Wikimedia\Rdbms\DatabaseSqlite\makeSelectOptions
makeSelectOptions( $options)
Filter the options used in SELECT statements.
Definition: DatabaseSqlite.php:596
Wikimedia\Rdbms\DatabaseSqlite\freeResult
freeResult( $res)
Definition: DatabaseSqlite.php:351
Wikimedia\Rdbms\DatabaseSqlite\lastErrno
lastErrno()
Definition: DatabaseSqlite.php:509
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
Wikimedia\Rdbms\DatabaseSqlite\indexUnique
indexUnique( $table, $index, $fname=__METHOD__)
Definition: DatabaseSqlite.php:569
Wikimedia\Rdbms\DBConnectionError
Definition: DBConnectionError.php:26
Wikimedia\Rdbms\DatabaseSqlite\wasReadOnlyError
wasReadOnlyError()
Definition: DatabaseSqlite.php:748
Wikimedia\Rdbms\Database\$server
string $server
Server that this instance is currently connected to.
Definition: Database.php:81
$keys
$keys
Definition: testCompression.php:67
true
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Definition: hooks.txt:1985
Wikimedia\Rdbms\DatabaseSqlite\buildConcat
buildConcat( $stringList)
Build a concatenation list to feed into a SQL query.
Definition: DatabaseSqlite.php:976
Wikimedia\Rdbms\Database\select
select( $table, $vars, $conds='', $fname=__METHOD__, $options=[], $join_conds=[])
Execute a SELECT query constructed using the various parameters provided.
Definition: Database.php:1779
class
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
Wikimedia\Rdbms\DatabaseSqlite\isWriteQuery
isWriteQuery( $sql)
Determine whether a query writes to the DB.
Definition: DatabaseSqlite.php:317
Wikimedia\Rdbms\Database\affectedRows
affectedRows()
Get the number of rows affected by the last write query.
Definition: Database.php:4146
Wikimedia\Rdbms\DatabaseSqlite\wasConnectionError
wasConnectionError( $errno)
Do not use this method outside of Database/DBError classes.
Definition: DatabaseSqlite.php:752
Wikimedia\Rdbms\DatabaseDomain
Class to handle database/prefix specification for IDatabase domains.
Definition: DatabaseDomain.php:28
LockManager\LOCK_EX
const LOCK_EX
Definition: LockManager.php:69
Wikimedia\Rdbms\DatabaseSqlite\__construct
__construct(array $p)
Additional params include:
Definition: DatabaseSqlite.php:71
Wikimedia\Rdbms\DatabaseSqlite\decodeBlob
decodeBlob( $b)
Definition: DatabaseSqlite.php:830
Wikimedia\Rdbms\DatabaseSqlite\dropTable
dropTable( $tableName, $fName=__METHOD__)
Override due to no CASCADE support.
Definition: DatabaseSqlite.php:1092
Wikimedia\Rdbms\DatabaseSqlite\checkForEnabledSearch
checkForEnabledSearch()
Check if the searchindext table is FTS enabled.
Definition: DatabaseSqlite.php:262
Wikimedia\Rdbms\Database\query
query( $sql, $fname=__METHOD__, $flags=0)
Run an SQL query and return the result.
Definition: Database.php:1191
Wikimedia\Rdbms\DatabaseSqlite\duplicateTableStructure
duplicateTableStructure( $oldName, $newName, $temporary=false, $fname=__METHOD__)
Definition: DatabaseSqlite.php:996
Wikimedia\Rdbms\DatabaseSqlite\numFields
numFields( $res)
Definition: DatabaseSqlite.php:423
Wikimedia\Rdbms\DatabaseSqlite\tableName
tableName( $name, $format='quoted')
Use MySQL's naming (accounts for prefix etc) but remove surrounding backticks.
Definition: DatabaseSqlite.php:457
Wikimedia\Rdbms\DatabaseSqlite\indexInfo
indexInfo( $table, $index, $fname=__METHOD__)
Returns information about an index Returns false if the index does not exist.
Definition: DatabaseSqlite.php:549
Wikimedia\Rdbms\DatabaseSqlite\textFieldSize
textFieldSize( $table, $field)
Returns the size of a text field, or -1 for "unlimited" In SQLite this is SQLITE_MAX_LENGTH,...
Definition: DatabaseSqlite.php:716
Wikimedia\Rdbms\Blob
Definition: Blob.php:5