MediaWiki  1.32.0
DatabaseSqlite.php
Go to the documentation of this file.
1 <?php
24 namespace Wikimedia\Rdbms;
25 
26 use PDO;
27 use PDOException;
30 use InvalidArgumentException;
31 use RuntimeException;
32 use stdClass;
33 
37 class DatabaseSqlite extends Database {
39  private static $fulltextEnabled = null;
40 
42  protected $dbDir;
44  protected $dbPath;
46  protected $trxMode;
47 
51  protected $lastResultHandle;
52 
54  protected $conn;
55 
57  protected $lockMgr;
58 
60  private $alreadyAttached = [];
61 
70  function __construct( array $p ) {
71  if ( isset( $p['dbFilePath'] ) ) {
72  $this->dbPath = $p['dbFilePath'];
73  $lockDomain = md5( $this->dbPath );
74  // Use "X" for things like X.sqlite and ":memory:" for RAM-only DBs
75  if ( !isset( $p['dbname'] ) || !strlen( $p['dbname'] ) ) {
76  $p['dbname'] = preg_replace( '/\.sqlite\d?$/', '', basename( $this->dbPath ) );
77  }
78  } elseif ( isset( $p['dbDirectory'] ) ) {
79  $this->dbDir = $p['dbDirectory'];
80  $lockDomain = $p['dbname'];
81  } else {
82  throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." );
83  }
84 
85  $this->trxMode = isset( $p['trxMode'] ) ? strtoupper( $p['trxMode'] ) : null;
86  if ( $this->trxMode &&
87  !in_array( $this->trxMode, [ 'DEFERRED', 'IMMEDIATE', 'EXCLUSIVE' ] )
88  ) {
89  $this->trxMode = null;
90  $this->queryLogger->warning( "Invalid SQLite transaction mode provided." );
91  }
92 
93  $this->lockMgr = new FSLockManager( [
94  'domain' => $lockDomain,
95  'lockDirectory' => "{$this->dbDir}/locks"
96  ] );
97 
98  parent::__construct( $p );
99  }
100 
101  protected static function getAttributes() {
102  return [ self::ATTR_DB_LEVEL_LOCKING => true ];
103  }
104 
114  public static function newStandaloneInstance( $filename, array $p = [] ) {
115  $p['dbFilePath'] = $filename;
116  $p['schema'] = null;
117  $p['tablePrefix'] = '';
119  $db = Database::factory( 'sqlite', $p );
120 
121  return $db;
122  }
123 
124  protected function doInitConnection() {
125  if ( $this->dbPath !== null ) {
126  // Standalone .sqlite file mode.
127  $this->openFile(
128  $this->dbPath,
129  $this->connectionParams['dbname'],
130  $this->connectionParams['tablePrefix']
131  );
132  } elseif ( $this->dbDir !== null ) {
133  // Stock wiki mode using standard file names per DB
134  if ( strlen( $this->connectionParams['dbname'] ) ) {
135  $this->open(
136  $this->connectionParams['host'],
137  $this->connectionParams['user'],
138  $this->connectionParams['password'],
139  $this->connectionParams['dbname'],
140  $this->connectionParams['schema'],
141  $this->connectionParams['tablePrefix']
142  );
143  } else {
144  // Caller will manually call open() later?
145  $this->connLogger->debug( __METHOD__ . ': no database opened.' );
146  }
147  } else {
148  throw new InvalidArgumentException( "Need 'dbDirectory' or 'dbFilePath' parameter." );
149  }
150  }
151 
155  function getType() {
156  return 'sqlite';
157  }
158 
164  function implicitGroupby() {
165  return false;
166  }
167 
168  protected function open( $server, $user, $pass, $dbName, $schema, $tablePrefix ) {
169  $this->close();
170  $fileName = self::generateFileName( $this->dbDir, $dbName );
171  if ( !is_readable( $fileName ) ) {
172  $this->conn = false;
173  throw new DBConnectionError( $this, "SQLite database not accessible" );
174  }
175  // Only $dbName is used, the other parameters are irrelevant for SQLite databases
176  $this->openFile( $fileName, $dbName, $tablePrefix );
177 
178  return (bool)$this->conn;
179  }
180 
190  protected function openFile( $fileName, $dbName, $tablePrefix ) {
191  $err = false;
192 
193  $this->dbPath = $fileName;
194  try {
195  if ( $this->flags & self::DBO_PERSISTENT ) {
196  $this->conn = new PDO( "sqlite:$fileName", '', '',
197  [ PDO::ATTR_PERSISTENT => true ] );
198  } else {
199  $this->conn = new PDO( "sqlite:$fileName", '', '' );
200  }
201  } catch ( PDOException $e ) {
202  $err = $e->getMessage();
203  }
204 
205  if ( !$this->conn ) {
206  $this->queryLogger->debug( "DB connection error: $err\n" );
207  throw new DBConnectionError( $this, $err );
208  }
209 
210  $this->opened = is_object( $this->conn );
211  if ( $this->opened ) {
212  $this->currentDomain = new DatabaseDomain( $dbName, null, $tablePrefix );
213  # Set error codes only, don't raise exceptions
214  $this->conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
215  # Enforce LIKE to be case sensitive, just like MySQL
216  $this->query( 'PRAGMA case_sensitive_like = 1' );
217 
218  return $this->conn;
219  }
220 
221  return false;
222  }
223 
228  public function getDbFilePath() {
229  return $this->dbPath;
230  }
231 
236  protected function closeConnection() {
237  $this->conn = null;
238 
239  return true;
240  }
241 
248  public static function generateFileName( $dir, $dbName ) {
249  return "$dir/$dbName.sqlite";
250  }
251 
257  if ( self::$fulltextEnabled === null ) {
258  self::$fulltextEnabled = false;
259  $table = $this->tableName( 'searchindex' );
260  $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name = '$table'", __METHOD__ );
261  if ( $res ) {
262  $row = $res->fetchRow();
263  self::$fulltextEnabled = stristr( $row['sql'], 'fts' ) !== false;
264  }
265  }
266 
267  return self::$fulltextEnabled;
268  }
269 
274  static function getFulltextSearchModule() {
275  static $cachedResult = null;
276  if ( $cachedResult !== null ) {
277  return $cachedResult;
278  }
279  $cachedResult = false;
280  $table = 'dummy_search_test';
281 
282  $db = self::newStandaloneInstance( ':memory:' );
283  if ( $db->query( "CREATE VIRTUAL TABLE $table USING FTS3(dummy_field)", __METHOD__, true ) ) {
284  $cachedResult = 'FTS3';
285  }
286  $db->close();
287 
288  return $cachedResult;
289  }
290 
302  function attachDatabase( $name, $file = false, $fname = __METHOD__ ) {
303  if ( !$file ) {
304  $file = self::generateFileName( $this->dbDir, $name );
305  }
306  $file = $this->addQuotes( $file );
307 
308  return $this->query( "ATTACH DATABASE $file AS $name", $fname );
309  }
310 
311  protected function isWriteQuery( $sql ) {
312  return parent::isWriteQuery( $sql ) && !preg_match( '/^(ATTACH|PRAGMA)\b/i', $sql );
313  }
314 
315  protected function isTransactableQuery( $sql ) {
316  return parent::isTransactableQuery( $sql ) && !in_array(
317  $this->getQueryVerb( $sql ),
318  [ 'ATTACH', 'PRAGMA' ],
319  true
320  );
321  }
322 
329  protected function doQuery( $sql ) {
330  $res = $this->getBindingHandle()->query( $sql );
331  if ( $res === false ) {
332  return false;
333  }
334 
335  $r = $res instanceof ResultWrapper ? $res->result : $res;
336  $this->lastAffectedRowCount = $r->rowCount();
337  $res = new ResultWrapper( $this, $r->fetchAll() );
338 
339  return $res;
340  }
341 
345  function freeResult( $res ) {
346  if ( $res instanceof ResultWrapper ) {
347  $res->result = null;
348  } else {
349  $res = null;
350  }
351  }
352 
357  function fetchObject( $res ) {
358  if ( $res instanceof ResultWrapper ) {
359  $r =& $res->result;
360  } else {
361  $r =& $res;
362  }
363 
364  $cur = current( $r );
365  if ( is_array( $cur ) ) {
366  next( $r );
367  $obj = new stdClass;
368  foreach ( $cur as $k => $v ) {
369  if ( !is_numeric( $k ) ) {
370  $obj->$k = $v;
371  }
372  }
373 
374  return $obj;
375  }
376 
377  return false;
378  }
379 
384  function fetchRow( $res ) {
385  if ( $res instanceof ResultWrapper ) {
386  $r =& $res->result;
387  } else {
388  $r =& $res;
389  }
390  $cur = current( $r );
391  if ( is_array( $cur ) ) {
392  next( $r );
393 
394  return $cur;
395  }
396 
397  return false;
398  }
399 
406  function numRows( $res ) {
407  // false does not implement Countable
408  $r = $res instanceof ResultWrapper ? $res->result : $res;
409 
410  return is_array( $r ) ? count( $r ) : 0;
411  }
412 
417  function numFields( $res ) {
418  $r = $res instanceof ResultWrapper ? $res->result : $res;
419  if ( is_array( $r ) && count( $r ) > 0 ) {
420  // The size of the result array is twice the number of fields. (T67578)
421  return count( $r[0] ) / 2;
422  } else {
423  // If the result is empty return 0
424  return 0;
425  }
426  }
427 
433  function fieldName( $res, $n ) {
434  $r = $res instanceof ResultWrapper ? $res->result : $res;
435  if ( is_array( $r ) ) {
436  $keys = array_keys( $r[0] );
437 
438  return $keys[$n];
439  }
440 
441  return false;
442  }
443 
451  function tableName( $name, $format = 'quoted' ) {
452  // table names starting with sqlite_ are reserved
453  if ( strpos( $name, 'sqlite_' ) === 0 ) {
454  return $name;
455  }
456 
457  return str_replace( '"', '', parent::tableName( $name, $format ) );
458  }
459 
465  function insertId() {
466  // PDO::lastInsertId yields a string :(
467  return intval( $this->getBindingHandle()->lastInsertId() );
468  }
469 
474  function dataSeek( $res, $row ) {
475  if ( $res instanceof ResultWrapper ) {
476  $r =& $res->result;
477  } else {
478  $r =& $res;
479  }
480  reset( $r );
481  if ( $row > 0 ) {
482  for ( $i = 0; $i < $row; $i++ ) {
483  next( $r );
484  }
485  }
486  }
487 
491  function lastError() {
492  if ( !is_object( $this->conn ) ) {
493  return "Cannot return last error, no db connection";
494  }
495  $e = $this->conn->errorInfo();
496 
497  return $e[2] ?? '';
498  }
499 
503  function lastErrno() {
504  if ( !is_object( $this->conn ) ) {
505  return "Cannot return last error, no db connection";
506  } else {
507  $info = $this->conn->errorInfo();
508 
509  return $info[1];
510  }
511  }
512 
516  protected function fetchAffectedRowCount() {
518  }
519 
520  function tableExists( $table, $fname = __METHOD__ ) {
521  $tableRaw = $this->tableName( $table, 'raw' );
522  if ( isset( $this->sessionTempTables[$tableRaw] ) ) {
523  return true; // already known to exist
524  }
525 
526  $encTable = $this->addQuotes( $tableRaw );
527  $res = $this->query(
528  "SELECT 1 FROM sqlite_master WHERE type='table' AND name=$encTable" );
529 
530  return $res->numRows() ? true : false;
531  }
532 
543  function indexInfo( $table, $index, $fname = __METHOD__ ) {
544  $sql = 'PRAGMA index_info(' . $this->addQuotes( $this->indexName( $index ) ) . ')';
545  $res = $this->query( $sql, $fname );
546  if ( !$res || $res->numRows() == 0 ) {
547  return false;
548  }
549  $info = [];
550  foreach ( $res as $row ) {
551  $info[] = $row->name;
552  }
553 
554  return $info;
555  }
556 
563  function indexUnique( $table, $index, $fname = __METHOD__ ) {
564  $row = $this->selectRow( 'sqlite_master', '*',
565  [
566  'type' => 'index',
567  'name' => $this->indexName( $index ),
568  ], $fname );
569  if ( !$row || !isset( $row->sql ) ) {
570  return null;
571  }
572 
573  // $row->sql will be of the form CREATE [UNIQUE] INDEX ...
574  $indexPos = strpos( $row->sql, 'INDEX' );
575  if ( $indexPos === false ) {
576  return null;
577  }
578  $firstPart = substr( $row->sql, 0, $indexPos );
579  $options = explode( ' ', $firstPart );
580 
581  return in_array( 'UNIQUE', $options );
582  }
583 
591  foreach ( $options as $k => $v ) {
592  if ( is_numeric( $k ) && ( $v == 'FOR UPDATE' || $v == 'LOCK IN SHARE MODE' ) ) {
593  $options[$k] = '';
594  }
595  }
596 
597  return parent::makeSelectOptions( $options );
598  }
599 
604  protected function makeUpdateOptionsArray( $options ) {
605  $options = parent::makeUpdateOptionsArray( $options );
607 
608  return $options;
609  }
610 
615  static function fixIgnore( $options ) {
616  # SQLite uses OR IGNORE not just IGNORE
617  foreach ( $options as $k => $v ) {
618  if ( $v == 'IGNORE' ) {
619  $options[$k] = 'OR IGNORE';
620  }
621  }
622 
623  return $options;
624  }
625 
632 
633  return parent::makeInsertOptions( $options );
634  }
635 
644  function insert( $table, $a, $fname = __METHOD__, $options = [] ) {
645  if ( !count( $a ) ) {
646  return true;
647  }
648 
649  # SQLite can't handle multi-row inserts, so divide up into multiple single-row inserts
650  if ( isset( $a[0] ) && is_array( $a[0] ) ) {
651  $ret = true;
652  foreach ( $a as $v ) {
653  if ( !parent::insert( $table, $v, "$fname/multi-row", $options ) ) {
654  $ret = false;
655  }
656  }
657  } else {
658  $ret = parent::insert( $table, $a, "$fname/single-row", $options );
659  }
660 
661  return $ret;
662  }
663 
671  function replace( $table, $uniqueIndexes, $rows, $fname = __METHOD__ ) {
672  if ( !count( $rows ) ) {
673  return true;
674  }
675 
676  # SQLite can't handle multi-row replaces, so divide up into multiple single-row queries
677  if ( isset( $rows[0] ) && is_array( $rows[0] ) ) {
678  $ret = true;
679  foreach ( $rows as $v ) {
680  if ( !$this->nativeReplace( $table, $v, "$fname/multi-row" ) ) {
681  $ret = false;
682  }
683  }
684  } else {
685  $ret = $this->nativeReplace( $table, $rows, "$fname/single-row" );
686  }
687 
688  return $ret;
689  }
690 
699  function textFieldSize( $table, $field ) {
700  return -1;
701  }
702 
707  return false;
708  }
709 
715  function unionQueries( $sqls, $all ) {
716  $glue = $all ? ' UNION ALL ' : ' UNION ';
717 
718  return implode( $glue, $sqls );
719  }
720 
724  function wasDeadlock() {
725  return $this->lastErrno() == 5; // SQLITE_BUSY
726  }
727 
731  function wasReadOnlyError() {
732  return $this->lastErrno() == 8; // SQLITE_READONLY;
733  }
734 
735  public function wasConnectionError( $errno ) {
736  return $errno == 17; // SQLITE_SCHEMA;
737  }
738 
739  protected function wasKnownStatementRollbackError() {
740  // ON CONFLICT ROLLBACK clauses make it so that SQLITE_CONSTRAINT error is
741  // ambiguous with regard to whether it implies a ROLLBACK or an ABORT happened.
742  // https://sqlite.org/lang_createtable.html#uniqueconst
743  // https://sqlite.org/lang_conflict.html
744  return false;
745  }
746 
750  public function getSoftwareLink() {
751  return "[{{int:version-db-sqlite-url}} SQLite]";
752  }
753 
757  function getServerVersion() {
758  $ver = $this->getBindingHandle()->getAttribute( PDO::ATTR_SERVER_VERSION );
759 
760  return $ver;
761  }
762 
771  function fieldInfo( $table, $field ) {
772  $tableName = $this->tableName( $table );
773  $sql = 'PRAGMA table_info(' . $this->addQuotes( $tableName ) . ')';
774  $res = $this->query( $sql, __METHOD__ );
775  foreach ( $res as $row ) {
776  if ( $row->name == $field ) {
777  return new SQLiteField( $row, $tableName );
778  }
779  }
780 
781  return false;
782  }
783 
784  protected function doBegin( $fname = '' ) {
785  if ( $this->trxMode ) {
786  $this->query( "BEGIN {$this->trxMode}", $fname );
787  } else {
788  $this->query( 'BEGIN', $fname );
789  }
790  $this->trxLevel = 1;
791  }
792 
797  function strencode( $s ) {
798  return substr( $this->addQuotes( $s ), 1, -1 );
799  }
800 
805  function encodeBlob( $b ) {
806  return new Blob( $b );
807  }
808 
813  function decodeBlob( $b ) {
814  if ( $b instanceof Blob ) {
815  $b = $b->fetch();
816  }
817 
818  return $b;
819  }
820 
825  function addQuotes( $s ) {
826  if ( $s instanceof Blob ) {
827  return "x'" . bin2hex( $s->fetch() ) . "'";
828  } elseif ( is_bool( $s ) ) {
829  return (int)$s;
830  } elseif ( strpos( (string)$s, "\0" ) !== false ) {
831  // SQLite doesn't support \0 in strings, so use the hex representation as a workaround.
832  // This is a known limitation of SQLite's mprintf function which PDO
833  // should work around, but doesn't. I have reported this to php.net as bug #63419:
834  // https://bugs.php.net/bug.php?id=63419
835  // There was already a similar report for SQLite3::escapeString, bug #62361:
836  // https://bugs.php.net/bug.php?id=62361
837  // There is an additional bug regarding sorting this data after insert
838  // on older versions of sqlite shipped with ubuntu 12.04
839  // https://phabricator.wikimedia.org/T74367
840  $this->queryLogger->debug(
841  __FUNCTION__ .
842  ': Quoting value containing null byte. ' .
843  'For consistency all binary data should have been ' .
844  'first processed with self::encodeBlob()'
845  );
846  return "x'" . bin2hex( (string)$s ) . "'";
847  } else {
848  return $this->getBindingHandle()->quote( (string)$s );
849  }
850  }
851 
852  public function buildSubstring( $input, $startPosition, $length = null ) {
853  $this->assertBuildSubstringParams( $startPosition, $length );
854  $params = [ $input, $startPosition ];
855  if ( $length !== null ) {
856  $params[] = $length;
857  }
858  return 'SUBSTR(' . implode( ',', $params ) . ')';
859  }
860 
866  public function buildStringCast( $field ) {
867  return 'CAST ( ' . $field . ' AS TEXT )';
868  }
869 
875  public function deadlockLoop( /*...*/ ) {
876  $args = func_get_args();
877  $function = array_shift( $args );
878 
879  return $function( ...$args );
880  }
881 
886  protected function replaceVars( $s ) {
887  $s = parent::replaceVars( $s );
888  if ( preg_match( '/^\s*(CREATE|ALTER) TABLE/i', $s ) ) {
889  // CREATE TABLE hacks to allow schema file sharing with MySQL
890 
891  // binary/varbinary column type -> blob
892  $s = preg_replace( '/\b(var)?binary(\(\d+\))/i', 'BLOB', $s );
893  // no such thing as unsigned
894  $s = preg_replace( '/\b(un)?signed\b/i', '', $s );
895  // INT -> INTEGER
896  $s = preg_replace( '/\b(tiny|small|medium|big|)int(\s*\(\s*\d+\s*\)|\b)/i', 'INTEGER', $s );
897  // floating point types -> REAL
898  $s = preg_replace(
899  '/\b(float|double(\s+precision)?)(\s*\(\s*\d+\s*(,\s*\d+\s*)?\)|\b)/i',
900  'REAL',
901  $s
902  );
903  // varchar -> TEXT
904  $s = preg_replace( '/\b(var)?char\s*\(.*?\)/i', 'TEXT', $s );
905  // TEXT normalization
906  $s = preg_replace( '/\b(tiny|medium|long)text\b/i', 'TEXT', $s );
907  // BLOB normalization
908  $s = preg_replace( '/\b(tiny|small|medium|long|)blob\b/i', 'BLOB', $s );
909  // BOOL -> INTEGER
910  $s = preg_replace( '/\bbool(ean)?\b/i', 'INTEGER', $s );
911  // DATETIME -> TEXT
912  $s = preg_replace( '/\b(datetime|timestamp)\b/i', 'TEXT', $s );
913  // No ENUM type
914  $s = preg_replace( '/\benum\s*\([^)]*\)/i', 'TEXT', $s );
915  // binary collation type -> nothing
916  $s = preg_replace( '/\bbinary\b/i', '', $s );
917  // auto_increment -> autoincrement
918  $s = preg_replace( '/\bauto_increment\b/i', 'AUTOINCREMENT', $s );
919  // No explicit options
920  $s = preg_replace( '/\)[^);]*(;?)\s*$/', ')\1', $s );
921  // AUTOINCREMENT should immedidately follow PRIMARY KEY
922  $s = preg_replace( '/primary key (.*?) autoincrement/i', 'PRIMARY KEY AUTOINCREMENT $1', $s );
923  } elseif ( preg_match( '/^\s*CREATE (\s*(?:UNIQUE|FULLTEXT)\s+)?INDEX/i', $s ) ) {
924  // No truncated indexes
925  $s = preg_replace( '/\(\d+\)/', '', $s );
926  // No FULLTEXT
927  $s = preg_replace( '/\bfulltext\b/i', '', $s );
928  } elseif ( preg_match( '/^\s*DROP INDEX/i', $s ) ) {
929  // DROP INDEX is database-wide, not table-specific, so no ON <table> clause.
930  $s = preg_replace( '/\sON\s+[^\s]*/i', '', $s );
931  } elseif ( preg_match( '/^\s*INSERT IGNORE\b/i', $s ) ) {
932  // INSERT IGNORE --> INSERT OR IGNORE
933  $s = preg_replace( '/^\s*INSERT IGNORE\b/i', 'INSERT OR IGNORE', $s );
934  }
935 
936  return $s;
937  }
938 
939  public function lock( $lockName, $method, $timeout = 5 ) {
940  if ( !is_dir( "{$this->dbDir}/locks" ) ) { // create dir as needed
941  if ( !is_writable( $this->dbDir ) || !mkdir( "{$this->dbDir}/locks" ) ) {
942  throw new DBError( $this, "Cannot create directory \"{$this->dbDir}/locks\"." );
943  }
944  }
945 
946  return $this->lockMgr->lock( [ $lockName ], LockManager::LOCK_EX, $timeout )->isOK();
947  }
948 
949  public function unlock( $lockName, $method ) {
950  return $this->lockMgr->unlock( [ $lockName ], LockManager::LOCK_EX )->isOK();
951  }
952 
959  function buildConcat( $stringList ) {
960  return '(' . implode( ') || (', $stringList ) . ')';
961  }
962 
963  public function buildGroupConcatField(
964  $delim, $table, $field, $conds = '', $join_conds = []
965  ) {
966  $fld = "group_concat($field," . $this->addQuotes( $delim ) . ')';
967 
968  return '(' . $this->selectSQLText( $table, $fld, $conds, null, [], $join_conds ) . ')';
969  }
970 
979  function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = __METHOD__ ) {
980  $res = $this->query( "SELECT sql FROM sqlite_master WHERE tbl_name=" .
981  $this->addQuotes( $oldName ) . " AND type='table'", $fname );
982  $obj = $this->fetchObject( $res );
983  if ( !$obj ) {
984  throw new RuntimeException( "Couldn't retrieve structure for table $oldName" );
985  }
986  $sql = $obj->sql;
987  $sql = preg_replace(
988  '/(?<=\W)"?' .
989  preg_quote( trim( $this->addIdentifierQuotes( $oldName ), '"' ), '/' ) .
990  '"?(?=\W)/',
991  $this->addIdentifierQuotes( $newName ),
992  $sql,
993  1
994  );
995  if ( $temporary ) {
996  if ( preg_match( '/^\\s*CREATE\\s+VIRTUAL\\s+TABLE\b/i', $sql ) ) {
997  $this->queryLogger->debug(
998  "Table $oldName is virtual, can't create a temporary duplicate.\n" );
999  } else {
1000  $sql = str_replace( 'CREATE TABLE', 'CREATE TEMPORARY TABLE', $sql );
1001  }
1002  }
1003 
1004  $res = $this->query( $sql, $fname );
1005 
1006  // Take over indexes
1007  $indexList = $this->query( 'PRAGMA INDEX_LIST(' . $this->addQuotes( $oldName ) . ')' );
1008  foreach ( $indexList as $index ) {
1009  if ( strpos( $index->name, 'sqlite_autoindex' ) === 0 ) {
1010  continue;
1011  }
1012 
1013  if ( $index->unique ) {
1014  $sql = 'CREATE UNIQUE INDEX';
1015  } else {
1016  $sql = 'CREATE INDEX';
1017  }
1018  // Try to come up with a new index name, given indexes have database scope in SQLite
1019  $indexName = $newName . '_' . $index->name;
1020  $sql .= ' ' . $indexName . ' ON ' . $newName;
1021 
1022  $indexInfo = $this->query( 'PRAGMA INDEX_INFO(' . $this->addQuotes( $index->name ) . ')' );
1023  $fields = [];
1024  foreach ( $indexInfo as $indexInfoRow ) {
1025  $fields[$indexInfoRow->seqno] = $indexInfoRow->name;
1026  }
1027 
1028  $sql .= '(' . implode( ',', $fields ) . ')';
1029 
1030  $this->query( $sql );
1031  }
1032 
1033  return $res;
1034  }
1035 
1044  function listTables( $prefix = null, $fname = __METHOD__ ) {
1045  $result = $this->select(
1046  'sqlite_master',
1047  'name',
1048  "type='table'"
1049  );
1050 
1051  $endArray = [];
1052 
1053  foreach ( $result as $table ) {
1054  $vars = get_object_vars( $table );
1055  $table = array_pop( $vars );
1056 
1057  if ( !$prefix || strpos( $table, $prefix ) === 0 ) {
1058  if ( strpos( $table, 'sqlite_' ) !== 0 ) {
1059  $endArray[] = $table;
1060  }
1061  }
1062  }
1063 
1064  return $endArray;
1065  }
1066 
1075  public function dropTable( $tableName, $fName = __METHOD__ ) {
1076  if ( !$this->tableExists( $tableName, $fName ) ) {
1077  return false;
1078  }
1079  $sql = "DROP TABLE " . $this->tableName( $tableName );
1080 
1081  return $this->query( $sql, $fName );
1082  }
1083 
1084  public function setTableAliases( array $aliases ) {
1085  parent::setTableAliases( $aliases );
1086  foreach ( $this->tableAliases as $params ) {
1087  if ( isset( $this->alreadyAttached[$params['dbname']] ) ) {
1088  continue;
1089  }
1090  $this->attachDatabase( $params['dbname'] );
1091  $this->alreadyAttached[$params['dbname']] = true;
1092  }
1093  }
1094 
1095  public function resetSequenceForTable( $table, $fname = __METHOD__ ) {
1096  $encTable = $this->addIdentifierQuotes( 'sqlite_sequence' );
1097  $encName = $this->addQuotes( $this->tableName( $table, 'raw' ) );
1098  $this->query( "DELETE FROM $encTable WHERE name = $encName", $fname );
1099  }
1100 
1101  public function databasesAreIndependent() {
1102  return true;
1103  }
1104 
1108  public function __toString() {
1109  return is_object( $this->conn )
1110  ? 'SQLite ' . (string)$this->conn->getAttribute( PDO::ATTR_SERVER_VERSION )
1111  : '(not connected)';
1112  }
1113 
1117  protected function getBindingHandle() {
1118  return parent::getBindingHandle();
1119  }
1120 }
1121 
1125 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:39
Wikimedia\Rdbms\SQLiteField
Definition: SQLiteField.php:5
Wikimedia\Rdbms\DatabaseSqlite\$trxMode
string $trxMode
Transaction mode.
Definition: DatabaseSqlite.php:46
Wikimedia\Rdbms\DatabaseSqlite\fieldInfo
fieldInfo( $table, $field)
Get information about a given field Returns false if the field does not exist.
Definition: DatabaseSqlite.php:771
Wikimedia\Rdbms\DatabaseSqlite\$lockMgr
FSLockManager $lockMgr
(hopefully on the same server as the DB)
Definition: DatabaseSqlite.php:57
insert
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and insert
Definition: hooks.txt:2115
LockManager
Class for handling resource locking.
Definition: LockManager.php:46
Wikimedia\Rdbms\DatabaseSqlite\getBindingHandle
getBindingHandle()
Definition: DatabaseSqlite.php:1117
Wikimedia\Rdbms\DatabaseSqlite\addQuotes
addQuotes( $s)
Definition: DatabaseSqlite.php:825
Wikimedia\Rdbms\DatabaseSqlite\fetchRow
fetchRow( $res)
Definition: DatabaseSqlite.php:384
Wikimedia\Rdbms\Database
Relational database abstraction object.
Definition: Database.php:48
Wikimedia\Rdbms\DatabaseSqlite
Definition: DatabaseSqlite.php:37
Wikimedia\Rdbms\DatabaseSqlite\$dbDir
string $dbDir
Directory.
Definition: DatabaseSqlite.php:42
Wikimedia\Rdbms\DatabaseSqlite\wasKnownStatementRollbackError
wasKnownStatementRollbackError()
Definition: DatabaseSqlite.php:739
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:426
Wikimedia\Rdbms\DatabaseSqlite\listTables
listTables( $prefix=null, $fname=__METHOD__)
List all tables on the database.
Definition: DatabaseSqlite.php:1044
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:949
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:168
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:2829
Wikimedia\Rdbms\DatabaseSqlite\unionSupportsOrderAndLimit
unionSupportsOrderAndLimit()
Definition: DatabaseSqlite.php:706
Wikimedia\Rdbms\DatabaseSqlite\implicitGroupby
implicitGroupby()
Definition: DatabaseSqlite.php:164
$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. 'LanguageGetMagic':DEPRECATED since 1.16! Use $magicWords in a file listed in $wgExtensionMessagesFiles instead. Use this to define synonyms of magic words depending of the language & $magicExtensions:associative array of magic words synonyms $lang:language code(string) '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 'LanguageGetSpecialPageAliases':DEPRECATED! Use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead. Use to define aliases of special pages names depending of the language & $specialPageAliases:associative array of magic words synonyms $lang:language code(string) '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:2034
Wikimedia\Rdbms\DatabaseSqlite\databasesAreIndependent
databasesAreIndependent()
Returns true if DBs are assumed to be on potentially different servers.
Definition: DatabaseSqlite.php:1101
Wikimedia\Rdbms\DatabaseSqlite\$dbPath
string $dbPath
File name for SQLite database file.
Definition: DatabaseSqlite.php:44
Wikimedia\Rdbms\Database\indexName
indexName( $index)
Allows for index remapping in queries where this is not consistent across DBMS.
Definition: Database.php:2642
Wikimedia\Rdbms\DatabaseSqlite\fetchAffectedRowCount
fetchAffectedRowCount()
Definition: DatabaseSqlite.php:516
Wikimedia\Rdbms\DatabaseSqlite\replace
replace( $table, $uniqueIndexes, $rows, $fname=__METHOD__)
Definition: DatabaseSqlite.php:671
Wikimedia\Rdbms\DatabaseSqlite\encodeBlob
encodeBlob( $b)
Definition: DatabaseSqlite.php:805
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:1084
Wikimedia\Rdbms
Definition: ChronologyProtector.php:24
$params
$params
Definition: styleTest.css.php:44
Wikimedia\Rdbms\DatabaseSqlite\lastError
lastError()
Definition: DatabaseSqlite.php:491
Wikimedia\Rdbms\DatabaseSqlite\getServerVersion
getServerVersion()
Definition: DatabaseSqlite.php:757
$s
$s
Definition: mergeMessageFileList.php:187
Wikimedia\Rdbms\DatabaseSqlite\dataSeek
dataSeek( $res, $row)
Definition: DatabaseSqlite.php:474
Wikimedia\Rdbms\DatabaseSqlite\strencode
strencode( $s)
Definition: DatabaseSqlite.php:797
Wikimedia\Rdbms\DatabaseSqlite\$lastResultHandle
resource $lastResultHandle
Definition: DatabaseSqlite.php:51
Wikimedia\Rdbms\DatabaseSqlite\buildSubstring
buildSubstring( $input, $startPosition, $length=null)
Definition: DatabaseSqlite.php:852
$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:236
Wikimedia\Rdbms\DBError
Database error base class.
Definition: DBError.php:30
Wikimedia\Rdbms\DatabaseSqlite\buildStringCast
buildStringCast( $field)
Definition: DatabaseSqlite.php:866
Wikimedia\Rdbms\DatabaseSqlite\makeInsertOptions
makeInsertOptions( $options)
Definition: DatabaseSqlite.php:630
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:715
Wikimedia\Rdbms\DatabaseSqlite\openFile
openFile( $fileName, $dbName, $tablePrefix)
Opens a database file.
Definition: DatabaseSqlite.php:190
Wikimedia\Rdbms\DatabaseSqlite\$lastAffectedRowCount
int $lastAffectedRowCount
The number of rows affected as an integer.
Definition: DatabaseSqlite.php:49
Wikimedia\Rdbms\Database\assertBuildSubstringParams
assertBuildSubstringParams( $startPosition, $length)
Check type and bounds for parameters to self::buildSubstring()
Definition: Database.php:2263
Wikimedia\Rdbms\DatabaseSqlite\wasDeadlock
wasDeadlock()
Definition: DatabaseSqlite.php:724
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:579
$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:248
Wikimedia\Rdbms\DatabaseSqlite\doBegin
doBegin( $fname='')
Issues the BEGIN command to the database server.
Definition: DatabaseSqlite.php:784
Wikimedia\Rdbms\DatabaseSqlite\$conn
PDO $conn
Definition: DatabaseSqlite.php:54
Wikimedia\Rdbms\DatabaseSqlite\resetSequenceForTable
resetSequenceForTable( $table, $fname=__METHOD__)
Definition: DatabaseSqlite.php:1095
Wikimedia\Rdbms\DatabaseSqlite\fixIgnore
static fixIgnore( $options)
Definition: DatabaseSqlite.php:615
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:1696
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:81
Wikimedia\Rdbms\DatabaseSqlite\tableExists
tableExists( $table, $fname=__METHOD__)
Query whether a given table exists.
Definition: DatabaseSqlite.php:520
Wikimedia\Rdbms\DatabaseSqlite\getDbFilePath
getDbFilePath()
Definition: DatabaseSqlite.php:228
Wikimedia\Rdbms\DatabaseSqlite\numRows
numRows( $res)
The PDO::Statement class implements the array interface so count() will work.
Definition: DatabaseSqlite.php:406
$vars
static configuration should be added through ResourceLoaderGetConfigVars instead & $vars
Definition: hooks.txt:2270
Wikimedia\Rdbms\DatabaseSqlite\replaceVars
replaceVars( $s)
Definition: DatabaseSqlite.php:886
Wikimedia\Rdbms\DatabaseSqlite\deadlockLoop
deadlockLoop()
No-op version of deadlockLoop.
Definition: DatabaseSqlite.php:875
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:433
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:1779
$fname
if(defined( 'MW_SETUP_CALLBACK')) $fname
Customization point after all loading (constants, functions, classes, DefaultSettings,...
Definition: Setup.php:121
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:302
Wikimedia\Rdbms\DatabaseSqlite\lock
lock( $lockName, $method, $timeout=5)
Acquire a named lock.
Definition: DatabaseSqlite.php:939
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2213
Wikimedia\Rdbms\DatabaseSqlite\fetchObject
fetchObject( $res)
Definition: DatabaseSqlite.php:357
Wikimedia\Rdbms\DatabaseSqlite\__toString
__toString()
Definition: DatabaseSqlite.php:1108
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:329
Wikimedia\Rdbms\DatabaseSqlite\getAttributes
static getAttributes()
Definition: DatabaseSqlite.php:101
$ret
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 & $ret
Definition: hooks.txt:2036
Wikimedia\Rdbms\DatabaseSqlite\getType
getType()
Definition: DatabaseSqlite.php:155
Wikimedia\Rdbms\DatabaseSqlite\$alreadyAttached
array $alreadyAttached
List of shared database already attached to this connection.
Definition: DatabaseSqlite.php:60
Wikimedia\Rdbms\Database\query
query( $sql, $fname=__METHOD__, $tempIgnore=false)
Run an SQL query and return the result.
Definition: Database.php:1126
Wikimedia\Rdbms\DatabaseSqlite\buildGroupConcatField
buildGroupConcatField( $delim, $table, $field, $conds='', $join_conds=[])
Build a GROUP_CONCAT or equivalent statement for a query.
Definition: DatabaseSqlite.php:963
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:302
Wikimedia\Rdbms\DatabaseSqlite\isTransactableQuery
isTransactableQuery( $sql)
Determine whether a SQL statement is sensitive to isolation level.
Definition: DatabaseSqlite.php:315
Wikimedia\Rdbms\DatabaseSqlite\insert
insert( $table, $a, $fname=__METHOD__, $options=[])
Based on generic method (parent) with some prior SQLite-sepcific adjustments.
Definition: DatabaseSqlite.php:644
Wikimedia\Rdbms\DatabaseSqlite\newStandaloneInstance
static newStandaloneInstance( $filename, array $p=[])
Definition: DatabaseSqlite.php:114
Wikimedia\Rdbms\Database\addIdentifierQuotes
addIdentifierQuotes( $s)
Quotes an identifier using backticks or "double quotes" depending on the database type.
Definition: Database.php:2672
$args
if( $line===false) $args
Definition: cdb.php:64
Wikimedia\Rdbms\Database\close
close()
Close the database connection.
Definition: Database.php:917
Wikimedia\Rdbms\DatabaseSqlite\getFulltextSearchModule
static getFulltextSearchModule()
Returns version of currently supported SQLite fulltext search module or false if none present.
Definition: DatabaseSqlite.php:274
Wikimedia\Rdbms\Database\getQueryVerb
getQueryVerb( $sql)
Definition: Database.php:1062
Wikimedia\Rdbms\DatabaseSqlite\makeUpdateOptionsArray
makeUpdateOptionsArray( $options)
Definition: DatabaseSqlite.php:604
Wikimedia\Rdbms\DatabaseSqlite\getSoftwareLink
getSoftwareLink()
Definition: DatabaseSqlite.php:750
Wikimedia\Rdbms\DatabaseSqlite\doInitConnection
doInitConnection()
Actually connect to the database over the wire (or to local files)
Definition: DatabaseSqlite.php:124
$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:2675
$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:2036
Wikimedia\Rdbms\DatabaseSqlite\insertId
insertId()
This must be called after nextSequenceVal.
Definition: DatabaseSqlite.php:465
Wikimedia\Rdbms\DatabaseSqlite\makeSelectOptions
makeSelectOptions( $options)
Filter the options used in SELECT statements.
Definition: DatabaseSqlite.php:590
Wikimedia\Rdbms\DatabaseSqlite\freeResult
freeResult( $res)
Definition: DatabaseSqlite.php:345
Wikimedia\Rdbms\DatabaseSqlite\lastErrno
lastErrno()
Definition: DatabaseSqlite.php:503
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:563
Wikimedia\Rdbms\DBConnectionError
Definition: DBConnectionError.php:26
Wikimedia\Rdbms\DatabaseSqlite\wasReadOnlyError
wasReadOnlyError()
Definition: DatabaseSqlite.php:731
Wikimedia\Rdbms\Database\$server
string $server
Server that this instance is currently connected to.
Definition: Database.php:79
$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:2036
Wikimedia\Rdbms\DatabaseSqlite\buildConcat
buildConcat( $stringList)
Build a concatenation list to feed into a SQL query.
Definition: DatabaseSqlite.php:959
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:1688
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:311
Wikimedia\Rdbms\DatabaseSqlite\wasConnectionError
wasConnectionError( $errno)
Do not use this method outside of Database/DBError classes.
Definition: DatabaseSqlite.php:735
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:70
Wikimedia\Rdbms\DatabaseSqlite\decodeBlob
decodeBlob( $b)
Definition: DatabaseSqlite.php:813
Wikimedia\Rdbms\DatabaseSqlite\dropTable
dropTable( $tableName, $fName=__METHOD__)
Override due to no CASCADE support.
Definition: DatabaseSqlite.php:1075
Wikimedia\Rdbms\DatabaseSqlite\checkForEnabledSearch
checkForEnabledSearch()
Check if the searchindext table is FTS enabled.
Definition: DatabaseSqlite.php:256
Wikimedia\Rdbms\DatabaseSqlite\duplicateTableStructure
duplicateTableStructure( $oldName, $newName, $temporary=false, $fname=__METHOD__)
Definition: DatabaseSqlite.php:979
Wikimedia\Rdbms\DatabaseSqlite\numFields
numFields( $res)
Definition: DatabaseSqlite.php:417
Wikimedia\Rdbms\DatabaseSqlite\tableName
tableName( $name, $format='quoted')
Use MySQL's naming (accounts for prefix etc) but remove surrounding backticks.
Definition: DatabaseSqlite.php:451
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:543
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:699
Wikimedia\Rdbms\Blob
Definition: Blob.php:5