33require_once __DIR__ .
'/../../maintenance/Maintenance.php';
50 protected $updates = [];
57 protected $updatesSkipped = [];
63 protected $extensionUpdates = [];
86 protected $postDatabaseUpdateMaintenance = [
87 DeleteDefaultMessages::class,
88 PopulateRevisionLength::class,
89 PopulateRevisionSha1::class,
90 PopulateImageSha1::class,
91 FixExtLinksProtocolRelative::class,
92 PopulateFilearchiveSha1::class,
93 PopulateBacklinkNamespace::class,
94 FixDefaultJsonContentPages::class,
95 CleanupEmptyCategories::class,
96 AddRFCandPMIDInterwiki::class,
97 PopulatePPSortKey::class,
98 PopulateIpChanges::class,
99 RefreshExternallinksIndex::class,
114 protected $skipSchema =
false;
130 if ( $maintenance ) {
131 $this->maintenance = $maintenance;
132 $this->fileHandle = $maintenance->fileHandle;
136 $this->maintenance->
setDB( $db );
142 private function loadExtensionSchemaUpdates() {
143 $hookContainer = $this->loadExtensions();
144 (
new HookRunner( $hookContainer ) )->onLoadExtensionSchemaUpdates( $this );
153 private function loadExtensions() {
154 if ( $this->autoExtensionHookContainer ) {
156 return $this->autoExtensionHookContainer;
158 if ( defined(
'MW_EXTENSIONS_LOADED' ) ) {
159 throw new Exception( __METHOD__ .
160 ' apparently called from installer but no hook container was injected' );
162 if ( !defined(
'MEDIAWIKI_INSTALL' ) ) {
164 return MediaWikiServices::getInstance()->getHookContainer();
169 $queue = $registry->getQueue();
171 $registry->clearQueue();
174 $extInfo = $registry->readFromQueue(
$queue );
178 $legacySchemaHooks = $extInfo[
'globals'][
'wgHooks'][
'LoadExtensionSchemaUpdates'] ?? [];
179 if ( $vars && isset( $vars[
'wgHooks'][
'LoadExtensionSchemaUpdates'] ) ) {
180 $legacySchemaHooks = array_merge( $legacySchemaHooks, $vars[
'wgHooks'][
'LoadExtensionSchemaUpdates'] );
185 if ( $vars && isset( $vars[
'wgAutoloadClasses'] ) ) {
190 if ( !isset( $extInfo[
'autoloaderPaths'] )
191 || !isset( $extInfo[
'autoloaderClasses'] )
192 || !isset( $extInfo[
'autoloaderNS'] )
195 throw new LogicException(
'Missing autoloader keys from extracted extension info' );
203 [
'LoadExtensionSchemaUpdates' => $legacySchemaHooks ],
204 $extInfo[
'attributes'][
'Hooks'] ?? [],
205 $extInfo[
'attributes'][
'DeprecatedHooks'] ?? []
207 MediaWikiServices::getInstance()->getObjectFactory()
226 $class = ucfirst(
$type ) .
'Updater';
228 return new $class( $db,
$shared, $maintenance );
230 throw new MWException( __METHOD__ .
' called for unsupported $wgDBtype' );
242 $this->autoExtensionHookContainer = $hookContainer;
261 if ( $this->maintenance->isQuiet() ) {
266 $str = htmlspecialchars( $str );
285 $this->extensionUpdates[] = $update;
299 $this->extensionUpdates[] = [
'addTable', $tableName, $sqlPath,
true ];
313 $this->extensionUpdates[] = [
'addIndex', $tableName, $indexName, $sqlPath,
true ];
327 $this->extensionUpdates[] = [
'addField', $tableName, $columnName, $sqlPath,
true ];
341 $this->extensionUpdates[] = [
'dropField', $tableName, $columnName, $sqlPath,
true ];
355 $this->extensionUpdates[] = [
'dropIndex', $tableName, $indexName, $sqlPath,
true ];
368 $this->extensionUpdates[] = [
'dropTable', $tableName, $sqlPath,
true ];
385 $sqlPath, $skipBothIndexExistWarning =
false
387 $this->extensionUpdates[] = [
392 $skipBothIndexExistWarning,
409 $this->extensionUpdates[] = [
'modifyField', $tableName, $fieldName, $sqlPath,
true ];
422 $this->extensionUpdates[] = [
'modifyTable', $tableName, $sqlPath,
true ];
432 return ( $this->db->tableExists( $tableName, __METHOD__ ) );
445 $this->postDatabaseUpdateMaintenance[] = $class;
454 return $this->extensionUpdates;
463 return $this->postDatabaseUpdateMaintenance;
472 private function writeSchemaUpdateFile( array $schemaUpdate = [] ) {
473 $updates = $this->updatesSkipped;
474 $this->updatesSkipped = [];
476 foreach ( $updates as [ $func,
$args, $origParams ] ) {
480 $this->updatesSkipped[] = $origParams;
504 public function doUpdates( array $what = [
'core',
'extensions',
'stats' ] ) {
507 $what = array_fill_keys( $what,
true );
508 $this->skipSchema = isset( $what[
'noschema'] ) || $this->fileHandle !==
null;
509 if ( isset( $what[
'core'] ) ) {
513 if ( isset( $what[
'extensions'] ) ) {
514 $this->loadExtensionSchemaUpdates();
518 if ( isset( $what[
'stats'] ) ) {
522 if ( $this->fileHandle ) {
523 $this->skipSchema =
false;
524 $this->writeSchemaUpdateFile();
534 private function runUpdates( array $updates, $passSelf ) {
535 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
538 $updatesSkipped = [];
539 foreach ( $updates as $params ) {
540 $origParams = $params;
541 $func = array_shift( $params );
542 if ( !is_array( $func ) && method_exists( $this, $func ) ) {
543 $func = [ $this, $func ];
544 } elseif ( $passSelf ) {
545 array_unshift( $params, $this );
547 $ret = $func( ...$params );
549 if ( $ret !==
false ) {
550 $updatesDone[] = $origParams;
551 $lbFactory->waitForReplication( [
'timeout' => self::REPLICATION_WAIT_TIMEOUT ] );
553 $updatesSkipped[] = [ $func, $params, $origParams ];
556 $this->updatesSkipped = array_merge( $this->updatesSkipped, $updatesSkipped );
557 $this->updates = array_merge( $this->updates, $updatesDone );
568 $row = $this->db->selectRow(
572 [
'ul_key' => $key ],
594 $values = [
'ul_key' => $key ];
596 $values[
'ul_value'] = $val;
598 $this->db->insert(
'updatelog', $values, __METHOD__, [
'IGNORE' ] );
611 return $this->db->tableExists(
'updatelog', __METHOD__ ) &&
612 $this->db->fieldExists(
'updatelog',
'ul_value', __METHOD__ );
633 $this->
output(
"...skipping update to shared table $name.\n" );
657 $this->db->sourceFile(
682 if ( fwrite( $this->fileHandle,
$line ) ===
false ) {
701 if ( $msg ===
null ) {
702 $msg =
"Applying $path patch";
704 if ( $this->skipSchema ) {
705 $this->
output(
"...skipping schema change ($msg).\n" );
710 $this->
output(
"{$msg}..." );
712 if ( !$isFullPath ) {
715 if ( $this->fileHandle !==
null ) {
718 $this->db->sourceFile(
$path );
720 $this->
output(
"done.\n" );
734 $baseDir = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::BaseDirectory );
737 if ( file_exists(
"$baseDir/maintenance/$dbType/archives/$patch" ) ) {
738 return "$baseDir/maintenance/$dbType/archives/$patch";
740 return "$baseDir/maintenance/archives/$patch";
755 protected function addTable( $name, $patch, $fullpath =
false ) {
756 if ( !$this->
doTable( $name ) ) {
760 if ( $this->db->tableExists( $name, __METHOD__ ) ) {
761 $this->
output(
"...$name table already exists.\n" );
763 return $this->
applyPatch( $patch, $fullpath,
"Creating $name table" );
781 protected function addField( $table, $field, $patch, $fullpath =
false ) {
782 if ( !$this->
doTable( $table ) ) {
786 if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
787 $this->
output(
"...$table table does not exist, skipping new field patch.\n" );
788 } elseif ( $this->db->fieldExists( $table, $field, __METHOD__ ) ) {
789 $this->
output(
"...have $field field in $table table.\n" );
791 return $this->
applyPatch( $patch, $fullpath,
"Adding $field field to table $table" );
809 protected function addIndex( $table, $index, $patch, $fullpath =
false ) {
810 if ( !$this->
doTable( $table ) ) {
814 if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
815 $this->
output(
"...skipping: '$table' table doesn't exist yet.\n" );
816 } elseif ( $this->db->indexExists( $table, $index, __METHOD__ ) ) {
817 $this->
output(
"...index $index already set on $table table.\n" );
819 return $this->
applyPatch( $patch, $fullpath,
"Adding index $index to table $table" );
837 protected function dropField( $table, $field, $patch, $fullpath =
false ) {
838 if ( !$this->
doTable( $table ) ) {
842 if ( $this->db->fieldExists( $table, $field, __METHOD__ ) ) {
843 return $this->
applyPatch( $patch, $fullpath,
"Table $table contains $field field. Dropping" );
845 $this->
output(
"...$table table does not contain $field field.\n" );
863 protected function dropIndex( $table, $index, $patch, $fullpath =
false ) {
864 if ( !$this->
doTable( $table ) ) {
868 if ( $this->db->indexExists( $table, $index, __METHOD__ ) ) {
869 return $this->
applyPatch( $patch, $fullpath,
"Dropping $index index from table $table" );
871 $this->
output(
"...$index key doesn't exist.\n" );
894 $skipBothIndexExistWarning, $patch, $fullpath =
false
896 if ( !$this->
doTable( $table ) ) {
901 if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
902 $this->
output(
"...skipping: '$table' table doesn't exist yet.\n" );
908 if ( $this->db->indexExists( $table, $newIndex, __METHOD__ ) ) {
909 $this->
output(
"...index $newIndex already set on $table table.\n" );
910 if ( !$skipBothIndexExistWarning &&
911 $this->db->indexExists( $table, $oldIndex, __METHOD__ )
913 $this->
output(
"...WARNING: $oldIndex still exists, despite it has " .
914 "been renamed into $newIndex (which also exists).\n" .
915 " $oldIndex should be manually removed if not needed anymore.\n" );
922 if ( !$this->db->indexExists( $table, $oldIndex, __METHOD__ ) ) {
923 $this->
output(
"...skipping: index $oldIndex doesn't exist.\n" );
932 "Renaming index $oldIndex into $newIndex to table $table"
950 protected function dropTable( $table, $patch =
false, $fullpath =
false ) {
951 if ( !$this->
doTable( $table ) ) {
955 if ( $this->db->tableExists( $table, __METHOD__ ) ) {
956 $msg =
"Dropping table $table";
958 if ( $patch ===
false ) {
959 $this->
output(
"$msg ..." );
960 $this->db->dropTable( $table, __METHOD__ );
961 $this->
output(
"done.\n" );
963 return $this->
applyPatch( $patch, $fullpath, $msg );
966 $this->
output(
"...$table doesn't exist.\n" );
986 protected function modifyField( $table, $field, $patch, $fullpath =
false ) {
987 if ( !$this->
doTable( $table ) ) {
991 $updateKey =
"$table-$field-$patch";
992 if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
993 $this->
output(
"...$table table does not exist, skipping modify field patch.\n" );
994 } elseif ( !$this->db->fieldExists( $table, $field, __METHOD__ ) ) {
995 $this->
output(
"...$field field does not exist in $table table, " .
996 "skipping modify field patch.\n" );
998 $this->
output(
"...$field in table $table already modified by patch $patch.\n" );
1000 $apply = $this->
applyPatch( $patch, $fullpath,
"Modifying $field field of table $table" );
1024 if ( !$this->
doTable( $table ) ) {
1028 $updateKey =
"$table-$patch";
1029 if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
1030 $this->
output(
"...$table table does not exist, skipping modify table patch.\n" );
1032 $this->
output(
"...table $table already modified by patch $patch.\n" );
1034 $apply = $this->
applyPatch( $patch, $fullpath,
"Modifying table $table" );
1064 $this->
output(
"Running $class...\n" );
1065 $task = $this->maintenance->runChild( $class );
1066 $ok = $task->execute();
1068 throw new RuntimeException(
"Execution of $class did not complete successfully." );
1070 $this->
output(
"done.\n" );
1079 $repo = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo();
1080 $zonePath = $repo->getZonePath(
'temp' );
1081 if ( $repo->getBackend()->directoryExists( [
'dir' => $zonePath ] ) ) {
1083 $status = $repo->getBackend()->secure( [
1088 if ( $status->isOK() ) {
1089 $this->
output(
"Set the local repo temp zone container to be private.\n" );
1091 $this->
output(
"Failed to set the local repo temp zone container to be private.\n" );
1103 $this->
output(
"Purging caches..." );
1106 $this->db->delete(
'objectcache',
'*', __METHOD__ );
1114 $services = MediaWikiServices::getInstance();
1116 $services->getResourceLoader(),
1118 $services->getMainWANObjectCache()
1120 $blobStore->clear();
1123 $this->db->delete(
'module_deps',
'*', __METHOD__ );
1124 $this->
output(
"done.\n" );
1131 $this->
output(
"...site_stats is populated..." );
1132 $row = $this->db->selectRow(
'site_stats',
'*', [
'ss_row_id' => 1 ], __METHOD__ );
1133 if ( $row ===
false ) {
1134 $this->
output(
"data is missing! rebuilding...\n" );
1135 } elseif ( isset( $row->site_stats ) && $row->ss_total_pages == -1 ) {
1136 $this->
output(
"missing ss_total_pages, rebuilding...\n" );
1138 $this->
output(
"done.\n" );
1145 # Common updater functions
1152 if ( $this->db->selectField(
1159 $this->
output(
"...collations up-to-date.\n" );
1164 $this->
output(
"Updating category collations..." );
1165 $task = $this->maintenance->runChild( UpdateCollation::class );
1167 $this->
output(
"...done.\n" );
1174 $this->
output(
"Converting djvu metadata..." );
1175 $task = $this->maintenance->runChild( RefreshImageMetadata::class );
1176 '@phan-var RefreshImageMetadata $task';
1177 $task->loadParamsAndArgs( RefreshImageMetadata::class, [
1179 'mediatype' =>
'OFFICE',
1180 'mime' =>
'image/*',
1184 $ok = $task->execute();
1185 if ( $ok !==
false ) {
1186 $this->
output(
"...done.\n" );
1198 $cl = $this->maintenance->runChild(
1199 RebuildLocalisationCache::class,
'rebuildLocalisationCache.php'
1201 '@phan-var RebuildLocalisationCache $cl';
1202 $this->
output(
"Rebuilding localisation cache...\n" );
1205 $this->
output(
"done.\n" );
1209 if ( $this->
updateRowExists( MigrateLinksTable::class .
'templatelinks' ) ) {
1210 $this->
output(
"...templatelinks table has already been migrated.\n" );
1216 $task = $this->maintenance->runChild(
1217 MigrateLinksTable::class,
'migrateLinksTable.php'
1219 '@phan-var MigrateLinksTable $task';
1220 $task->loadParamsAndArgs( MigrateLinksTable::class, [
1222 'table' =>
'templatelinks'
1224 $this->
output(
"Running migrateLinksTable.php on templatelinks...\n" );
1226 $this->
output(
"done.\n" );
1236 "Migrating comments to the 'comments' table, printing progress markers. For large\n" .
1237 "databases, you may want to hit Ctrl-C and do this manually with\n" .
1238 "maintenance/migrateComments.php.\n"
1240 $task = $this->maintenance->runChild( MigrateComments::class,
'migrateComments.php' );
1241 $ok = $task->execute();
1242 $this->
output( $ok ?
"done.\n" :
"errors were encountered.\n" );
1251 if ( $this->
tableExists(
'image_comment_temp' ) ) {
1252 $this->
output(
"Merging image_comment_temp into the image table\n" );
1253 $task = $this->maintenance->runChild(
1254 MigrateImageCommentTemp::class,
'migrateImageCommentTemp.php'
1258 $ok = $task->execute();
1259 $this->
output( $ok ?
"done.\n" :
"errors were encountered.\n" );
1261 $this->
dropTable(
'image_comment_temp' );
1273 "Migrating actors to the 'actor' table, printing progress markers. For large\n" .
1274 "databases, you may want to hit Ctrl-C and do this manually with\n" .
1275 "maintenance/migrateActors.php.\n"
1277 $task = $this->maintenance->runChild( MigrateActors::class,
'migrateActors.php' );
1278 $ok = $task->execute();
1279 $this->
output( $ok ?
"done.\n" :
"errors were encountered.\n" );
1288 if ( $this->db->fieldExists(
'archive',
'ar_text', __METHOD__ ) ) {
1289 $this->
output(
"Migrating archive ar_text to modern storage.\n" );
1290 $task = $this->maintenance->runChild( MigrateArchiveText::class,
'migrateArchiveText.php' );
1293 if ( $task->execute() ) {
1294 $this->
applyPatch(
'patch-drop-ar_text.sql',
false,
1295 'Dropping ar_text and ar_flags columns' );
1305 $info = $this->db->fieldInfo(
'archive',
'ar_rev_id' );
1307 throw new MWException(
'Missing ar_rev_id field of archive table. Should not happen.' );
1309 if ( $info->isNullable() ) {
1310 $this->
output(
"Populating ar_rev_id.\n" );
1311 $task = $this->maintenance->runChild( PopulateArchiveRevId::class,
'populateArchiveRevId.php' );
1312 if ( $task->execute() ) {
1313 $this->
applyPatch(
'patch-ar_rev_id-not-null.sql',
false,
1314 'Making ar_rev_id not nullable' );
1324 if ( !$this->
updateRowExists(
'populate externallinks.el_index_60' ) ) {
1326 "Populating el_index_60 field, printing progress markers. For large\n" .
1327 "databases, you may want to hit Ctrl-C and do this manually with\n" .
1328 "maintenance/populateExternallinksIndex60.php.\n"
1330 $task = $this->maintenance->runChild( PopulateExternallinksIndex60::class,
1331 'populateExternallinksIndex60.php' );
1333 $this->
output(
"done.\n" );
1344 "Migrating revision data to the MCR 'slot' and 'content' tables, printing progress markers.\n" .
1345 "For large databases, you may want to hit Ctrl-C and do this manually with\n" .
1346 "maintenance/populateContentTables.php.\n"
1348 $task = $this->maintenance->runChild(
1349 PopulateContentTables::class,
'populateContentTables.php'
1351 $ok = $task->execute();
1352 $this->
output( $ok ?
"done.\n" :
"errors were encountered.\n" );
1375 if ( $table === $this ) {
1378 $func = array_shift( $params );
1381 if ( $this->db->tableExists( $table, __METHOD__ ) ) {
1385 if ( !is_array( $func ) && method_exists( $this, $func ) ) {
1386 $func = [ $this, $func ];
1387 } elseif ( $passSelf ) {
1388 array_unshift( $params, $this );
1392 return $func( ...$params );
1412 if ( $table === $this ) {
1416 $func = array_shift( $params );
1419 if ( !$this->db->tableExists( $table, __METHOD__ ) ||
1420 !$this->db->fieldExists( $table, $field, __METHOD__ )
1425 if ( !is_array( $func ) && method_exists( $this, $func ) ) {
1426 $func = [ $this, $func ];
1427 } elseif ( $passSelf ) {
1428 array_unshift( $params, $this );
1432 return $func( ...$params );
global $wgCommandLineMode
static registerClasses(array $files)
Register a file to load the given class from.
static loadFiles(array $files)
Batch version of loadFile()
static registerNamespaces(array $dirs)
Register a directory to load the classes of a given namespace from, per PSR4.
Class for handling database updates.
purgeCache()
Purge various database caches.
addExtensionTable( $tableName, $sqlPath)
Convenience wrapper for addExtensionUpdate() when adding a new table (which is the most common usage ...
getDB()
Get a database connection to run updates.
setFileAccess()
Set any .htaccess files or equivalent for storage repos.
migrateImageCommentTemp()
Merge image_comment_temp into the image table.
addIndex( $table, $index, $patch, $fullpath=false)
Add a new index to an existing table.
array $updates
Array of updates to perform on the database.
modifyExtensionTable( $tableName, $sqlPath)
Modify an existing extension table.
bool $skipSchema
Flag specifying whether or not to skip schema (e.g.
populateArchiveRevId()
Populate ar_rev_id, then make it not nullable.
runMaintenance( $class, $unused='')
Run a maintenance script.
migrateArchiveText()
Migrate ar_text to modern storage.
addField( $table, $field, $patch, $fullpath=false)
Add a new field to an existing table.
addExtensionIndex( $tableName, $indexName, $sqlPath)
Add an index to an existing extension table.
modifyTable( $table, $patch, $fullpath=false)
Modify an existing table, similar to modifyField.
doUpdates(array $what=[ 'core', 'extensions', 'stats'])
Do all the updates.
ifTableNotExists( $table, $func,... $params)
Only run a function if a table does not exist.
updateRowExists( $key)
Helper function: check if the given key is present in the updatelog table.
const REPLICATION_WAIT_TIMEOUT
getCoreUpdateList()
Get an array of updates to perform on the database.
populateExternallinksIndex60()
Populates the externallinks.el_index_60 field.
output( $str)
Output some text.
getPostDatabaseUpdateMaintenance()
getExtensionUpdates()
Get the list of extension-defined updates.
insertUpdateRow( $key, $val=null)
Helper function: Add a key to the updatelog table.
setAutoExtensionHookContainer(HookContainer $hookContainer)
Set the HookContainer to use for loading extension schema updates.
canUseNewUpdatelog()
Updatelog was changed in 1.17 to have a ul_value column so we can record more information about what ...
patchPath(IDatabase $db, $patch)
Get the full path of a patch file.
copyFile( $filename)
Append an SQL fragment to the open file handle.
string[] $postDatabaseUpdateMaintenance
Scripts to run after database update Should be a subclass of LoggedUpdateMaintenance.
HookContainer null $autoExtensionHookContainer
dropExtensionTable( $tableName, $sqlPath=false)
Drop an extension table.
resource null $fileHandle
File handle for SQL output.
renameIndex( $table, $oldIndex, $newIndex, $skipBothIndexExistWarning, $patch, $fullpath=false)
Rename an index from an existing table.
rebuildLocalisationCache()
Rebuilds the localisation cache.
addExtensionField( $tableName, $columnName, $sqlPath)
Add a field to an existing extension table.
IMaintainableDatabase $db
Handle to the database subclass.
ifFieldExists( $table, $field, $func,... $params)
Only run a function if the named field exists.
addTable( $name, $patch, $fullpath=false)
Add a new table to the database.
modifyField( $table, $field, $patch, $fullpath=false)
Modify an existing field.
dropExtensionField( $tableName, $columnName, $sqlPath)
Drop a field from an extension table.
static newForDB(IMaintainableDatabase $db, $shared=false, Maintenance $maintenance=null)
addPostDatabaseUpdateMaintenance( $class)
Add a maintenance script to be run after the database updates are complete.
dropField( $table, $field, $patch, $fullpath=false)
Drop a field from an existing table.
doCollationUpdate()
Update CategoryLinks collation.
renameExtensionIndex( $tableName, $oldIndexName, $newIndexName, $sqlPath, $skipBothIndexExistWarning=false)
Rename an index on an extension table Intended for use in LoadExtensionSchemaUpdates hook handlers.
migrateActors()
Migrate actors to the new 'actor' table.
addExtensionUpdate(array $update)
Add a new update coming from an extension.
array $updatesSkipped
Array of updates that were skipped.
appendLine( $line)
Append a line to the open filehandle.
dropExtensionIndex( $tableName, $indexName, $sqlPath)
Drop an index from an extension table Intended for use in LoadExtensionSchemaUpdates hook handlers.
array $extensionUpdates
List of extension-provided database updates.
checkStats()
Check the site_stats table is not properly populated.
modifyExtensionField( $tableName, $fieldName, $sqlPath)
Modify an existing field in an extension table.
applyPatch( $path, $isFullPath=false, $msg=null)
Applies a SQL patch.
dropIndex( $table, $index, $patch, $fullpath=false)
Drop an index from an existing table.
populateContentTables()
Populates the MCR content tables.
__construct(IMaintainableDatabase &$db, $shared, Maintenance $maintenance=null)
dropTable( $table, $patch=false, $fullpath=false)
If the specified table exists, drop it, or execute the patch if one is provided.
migrateComments()
Migrate comments to the new 'comment' table.
getSchemaVars()
Get appropriate schema variables in the current database connection.
doTable( $name)
Returns whether updates should be executed on the database table $name.
Fake maintenance wrapper, mostly used for the web installer/updater.
static getExistingLocalSettings()
Determine if LocalSettings.php exists.
static getDBTypes()
Get a list of known DB types.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
setDB(IMaintainableDatabase $db)
Sets database object to be returned by getDB().
A class containing constants representing the names of configuration variables.
static doAllAndCommit( $database, array $options=[])
Do all updates and commit them.
$wgSharedTables
Config variable stub for the SharedTables setting, for use by phpdoc and IDEs.
$wgCategoryCollation
Config variable stub for the CategoryCollation setting, for use by phpdoc and IDEs.
$wgSharedDB
Config variable stub for the SharedDB setting, for use by phpdoc and IDEs.
$wgLocalisationCacheConf
Config variable stub for the LocalisationCacheConf setting, for use by phpdoc and IDEs.
Advanced database interface for IDatabase handles that include maintenance methods.