MediaWiki  REL1_24
DatabaseUpdater.php
Go to the documentation of this file.
00001 <?php
00024 require_once __DIR__ . '/../../maintenance/Maintenance.php';
00025 
00033 abstract class DatabaseUpdater {
00034 
00040     protected $updates = array();
00041 
00047     protected $updatesSkipped = array();
00048 
00053     protected $extensionUpdates = array();
00054 
00060     protected $db;
00061 
00062     protected $shared = false;
00063 
00068     protected $postDatabaseUpdateMaintenance = array(
00069         'DeleteDefaultMessages',
00070         'PopulateRevisionLength',
00071         'PopulateRevisionSha1',
00072         'PopulateImageSha1',
00073         'FixExtLinksProtocolRelative',
00074         'PopulateFilearchiveSha1',
00075         'PopulateBacklinkNamespace'
00076     );
00077 
00083     protected $fileHandle = null;
00084 
00090     protected $skipSchema = false;
00091 
00095     protected $holdContentHandlerUseDB = true;
00096 
00104     protected function __construct( DatabaseBase &$db, $shared, Maintenance $maintenance = null ) {
00105         $this->db = $db;
00106         $this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files
00107         $this->shared = $shared;
00108         if ( $maintenance ) {
00109             $this->maintenance = $maintenance;
00110             $this->fileHandle = $maintenance->fileHandle;
00111         } else {
00112             $this->maintenance = new FakeMaintenance;
00113         }
00114         $this->maintenance->setDB( $db );
00115         $this->initOldGlobals();
00116         $this->loadExtensions();
00117         wfRunHooks( 'LoadExtensionSchemaUpdates', array( $this ) );
00118     }
00119 
00124     private function initOldGlobals() {
00125         global $wgExtNewTables, $wgExtNewFields, $wgExtPGNewFields,
00126             $wgExtPGAlteredFields, $wgExtNewIndexes, $wgExtModifiedFields;
00127 
00128         # For extensions only, should be populated via hooks
00129         # $wgDBtype should be checked to specifiy the proper file
00130         $wgExtNewTables = array(); // table, dir
00131         $wgExtNewFields = array(); // table, column, dir
00132         $wgExtPGNewFields = array(); // table, column, column attributes; for PostgreSQL
00133         $wgExtPGAlteredFields = array(); // table, column, new type, conversion method; for PostgreSQL
00134         $wgExtNewIndexes = array(); // table, index, dir
00135         $wgExtModifiedFields = array(); // table, index, dir
00136     }
00137 
00142     private function loadExtensions() {
00143         if ( !defined( 'MEDIAWIKI_INSTALL' ) ) {
00144             return; // already loaded
00145         }
00146         $vars = Installer::getExistingLocalSettings();
00147         if ( !$vars ) {
00148             return; // no LocalSettings found
00149         }
00150         if ( !isset( $vars['wgHooks'] ) || !isset( $vars['wgHooks']['LoadExtensionSchemaUpdates'] ) ) {
00151             return;
00152         }
00153         global $wgHooks, $wgAutoloadClasses;
00154         $wgHooks['LoadExtensionSchemaUpdates'] = $vars['wgHooks']['LoadExtensionSchemaUpdates'];
00155         $wgAutoloadClasses = $wgAutoloadClasses + $vars['wgAutoloadClasses'];
00156     }
00157 
00166     public static function newForDB( &$db, $shared = false, $maintenance = null ) {
00167         $type = $db->getType();
00168         if ( in_array( $type, Installer::getDBTypes() ) ) {
00169             $class = ucfirst( $type ) . 'Updater';
00170 
00171             return new $class( $db, $shared, $maintenance );
00172         } else {
00173             throw new MWException( __METHOD__ . ' called for unsupported $wgDBtype' );
00174         }
00175     }
00176 
00182     public function getDB() {
00183         return $this->db;
00184     }
00185 
00191     public function output( $str ) {
00192         if ( $this->maintenance->isQuiet() ) {
00193             return;
00194         }
00195         global $wgCommandLineMode;
00196         if ( !$wgCommandLineMode ) {
00197             $str = htmlspecialchars( $str );
00198         }
00199         echo $str;
00200         flush();
00201     }
00202 
00216     public function addExtensionUpdate( array $update ) {
00217         $this->extensionUpdates[] = $update;
00218     }
00219 
00229     public function addExtensionTable( $tableName, $sqlPath ) {
00230         $this->extensionUpdates[] = array( 'addTable', $tableName, $sqlPath, true );
00231     }
00232 
00240     public function addExtensionIndex( $tableName, $indexName, $sqlPath ) {
00241         $this->extensionUpdates[] = array( 'addIndex', $tableName, $indexName, $sqlPath, true );
00242     }
00243 
00252     public function addExtensionField( $tableName, $columnName, $sqlPath ) {
00253         $this->extensionUpdates[] = array( 'addField', $tableName, $columnName, $sqlPath, true );
00254     }
00255 
00264     public function dropExtensionField( $tableName, $columnName, $sqlPath ) {
00265         $this->extensionUpdates[] = array( 'dropField', $tableName, $columnName, $sqlPath, true );
00266     }
00267 
00277     public function dropExtensionIndex( $tableName, $indexName, $sqlPath ) {
00278         $this->extensionUpdates[] = array( 'dropIndex', $tableName, $indexName, $sqlPath, true );
00279     }
00280 
00288     public function dropExtensionTable( $tableName, $sqlPath ) {
00289         $this->extensionUpdates[] = array( 'dropTable', $tableName, $sqlPath, true );
00290     }
00291 
00304     public function renameExtensionIndex( $tableName, $oldIndexName, $newIndexName,
00305         $sqlPath, $skipBothIndexExistWarning = false
00306     ) {
00307         $this->extensionUpdates[] = array(
00308             'renameIndex',
00309             $tableName,
00310             $oldIndexName,
00311             $newIndexName,
00312             $skipBothIndexExistWarning,
00313             $sqlPath,
00314             true
00315         );
00316     }
00317 
00325     public function modifyExtensionField( $tableName, $fieldName, $sqlPath ) {
00326         $this->extensionUpdates[] = array( 'modifyField', $tableName, $fieldName, $sqlPath, true );
00327     }
00328 
00336     public function tableExists( $tableName ) {
00337         return ( $this->db->tableExists( $tableName, __METHOD__ ) );
00338     }
00339 
00349     public function addPostDatabaseUpdateMaintenance( $class ) {
00350         $this->postDatabaseUpdateMaintenance[] = $class;
00351     }
00352 
00358     protected function getExtensionUpdates() {
00359         return $this->extensionUpdates;
00360     }
00361 
00367     public function getPostDatabaseUpdateMaintenance() {
00368         return $this->postDatabaseUpdateMaintenance;
00369     }
00370 
00377     private function writeSchemaUpdateFile( $schemaUpdate = array() ) {
00378         $updates = $this->updatesSkipped;
00379         $this->updatesSkipped = array();
00380 
00381         foreach ( $updates as $funcList ) {
00382             $func = $funcList[0];
00383             $arg = $funcList[1];
00384             $origParams = $funcList[2];
00385             call_user_func_array( $func, $arg );
00386             flush();
00387             $this->updatesSkipped[] = $origParams;
00388         }
00389     }
00390 
00396     public function doUpdates( $what = array( 'core', 'extensions', 'stats' ) ) {
00397         global $wgVersion;
00398 
00399         $this->db->begin( __METHOD__ );
00400         $what = array_flip( $what );
00401         $this->skipSchema = isset( $what['noschema'] ) || $this->fileHandle !== null;
00402         if ( isset( $what['core'] ) ) {
00403             $this->runUpdates( $this->getCoreUpdateList(), false );
00404         }
00405         if ( isset( $what['extensions'] ) ) {
00406             $this->runUpdates( $this->getOldGlobalUpdates(), false );
00407             $this->runUpdates( $this->getExtensionUpdates(), true );
00408         }
00409 
00410         if ( isset( $what['stats'] ) ) {
00411             $this->checkStats();
00412         }
00413 
00414         $this->setAppliedUpdates( $wgVersion, $this->updates );
00415 
00416         if ( $this->fileHandle ) {
00417             $this->skipSchema = false;
00418             $this->writeSchemaUpdateFile();
00419             $this->setAppliedUpdates( "$wgVersion-schema", $this->updatesSkipped );
00420         }
00421 
00422         $this->db->commit( __METHOD__ );
00423     }
00424 
00431     private function runUpdates( array $updates, $passSelf ) {
00432         $updatesDone = array();
00433         $updatesSkipped = array();
00434         foreach ( $updates as $params ) {
00435             $origParams = $params;
00436             $func = array_shift( $params );
00437             if ( !is_array( $func ) && method_exists( $this, $func ) ) {
00438                 $func = array( $this, $func );
00439             } elseif ( $passSelf ) {
00440                 array_unshift( $params, $this );
00441             }
00442             $ret = call_user_func_array( $func, $params );
00443             flush();
00444             if ( $ret !== false ) {
00445                 $updatesDone[] = $origParams;
00446             } else {
00447                 $updatesSkipped[] = array( $func, $params, $origParams );
00448             }
00449         }
00450         $this->updatesSkipped = array_merge( $this->updatesSkipped, $updatesSkipped );
00451         $this->updates = array_merge( $this->updates, $updatesDone );
00452     }
00453 
00458     protected function setAppliedUpdates( $version, $updates = array() ) {
00459         $this->db->clearFlag( DBO_DDLMODE );
00460         if ( !$this->canUseNewUpdatelog() ) {
00461             return;
00462         }
00463         $key = "updatelist-$version-" . time();
00464         $this->db->insert( 'updatelog',
00465             array( 'ul_key' => $key, 'ul_value' => serialize( $updates ) ),
00466             __METHOD__ );
00467         $this->db->setFlag( DBO_DDLMODE );
00468     }
00469 
00477     public function updateRowExists( $key ) {
00478         $row = $this->db->selectRow(
00479             'updatelog',
00480             # Bug 65813
00481             '1 AS X',
00482             array( 'ul_key' => $key ),
00483             __METHOD__
00484         );
00485 
00486         return (bool)$row;
00487     }
00488 
00496     public function insertUpdateRow( $key, $val = null ) {
00497         $this->db->clearFlag( DBO_DDLMODE );
00498         $values = array( 'ul_key' => $key );
00499         if ( $val && $this->canUseNewUpdatelog() ) {
00500             $values['ul_value'] = $val;
00501         }
00502         $this->db->insert( 'updatelog', $values, __METHOD__, 'IGNORE' );
00503         $this->db->setFlag( DBO_DDLMODE );
00504     }
00505 
00514     protected function canUseNewUpdatelog() {
00515         return $this->db->tableExists( 'updatelog', __METHOD__ ) &&
00516             $this->db->fieldExists( 'updatelog', 'ul_value', __METHOD__ );
00517     }
00518 
00527     protected function doTable( $name ) {
00528         global $wgSharedDB, $wgSharedTables;
00529 
00530         // Don't bother to check $wgSharedTables if there isn't a shared database
00531         // or the user actually also wants to do updates on the shared database.
00532         if ( $wgSharedDB === null || $this->shared ) {
00533             return true;
00534         }
00535 
00536         if ( in_array( $name, $wgSharedTables ) ) {
00537             $this->output( "...skipping update to shared table $name.\n" );
00538             return false;
00539         } else {
00540             return true;
00541         }
00542     }
00543 
00552     protected function getOldGlobalUpdates() {
00553         global $wgExtNewFields, $wgExtNewTables, $wgExtModifiedFields,
00554             $wgExtNewIndexes;
00555 
00556         $updates = array();
00557 
00558         foreach ( $wgExtNewTables as $tableRecord ) {
00559             $updates[] = array(
00560                 'addTable', $tableRecord[0], $tableRecord[1], true
00561             );
00562         }
00563 
00564         foreach ( $wgExtNewFields as $fieldRecord ) {
00565             $updates[] = array(
00566                 'addField', $fieldRecord[0], $fieldRecord[1],
00567                 $fieldRecord[2], true
00568             );
00569         }
00570 
00571         foreach ( $wgExtNewIndexes as $fieldRecord ) {
00572             $updates[] = array(
00573                 'addIndex', $fieldRecord[0], $fieldRecord[1],
00574                 $fieldRecord[2], true
00575             );
00576         }
00577 
00578         foreach ( $wgExtModifiedFields as $fieldRecord ) {
00579             $updates[] = array(
00580                 'modifyField', $fieldRecord[0], $fieldRecord[1],
00581                 $fieldRecord[2], true
00582             );
00583         }
00584 
00585         return $updates;
00586     }
00587 
00596     abstract protected function getCoreUpdateList();
00597 
00603     public function copyFile( $filename ) {
00604         $this->db->sourceFile( $filename, false, false, false,
00605             array( $this, 'appendLine' )
00606         );
00607     }
00608 
00619     public function appendLine( $line ) {
00620         $line = rtrim( $line ) . ";\n";
00621         if ( fwrite( $this->fileHandle, $line ) === false ) {
00622             throw new MWException( "trouble writing file" );
00623         }
00624 
00625         return false;
00626     }
00627 
00636     protected function applyPatch( $path, $isFullPath = false, $msg = null ) {
00637         if ( $msg === null ) {
00638             $msg = "Applying $path patch";
00639         }
00640         if ( $this->skipSchema ) {
00641             $this->output( "...skipping schema change ($msg).\n" );
00642 
00643             return false;
00644         }
00645 
00646         $this->output( "$msg ..." );
00647 
00648         if ( !$isFullPath ) {
00649             $path = $this->db->patchPath( $path );
00650         }
00651         if ( $this->fileHandle !== null ) {
00652             $this->copyFile( $path );
00653         } else {
00654             $this->db->sourceFile( $path );
00655         }
00656         $this->output( "done.\n" );
00657 
00658         return true;
00659     }
00660 
00669     protected function addTable( $name, $patch, $fullpath = false ) {
00670         if ( !$this->doTable( $name ) ) {
00671             return true;
00672         }
00673 
00674         if ( $this->db->tableExists( $name, __METHOD__ ) ) {
00675             $this->output( "...$name table already exists.\n" );
00676         } else {
00677             return $this->applyPatch( $patch, $fullpath, "Creating $name table" );
00678         }
00679 
00680         return true;
00681     }
00682 
00692     protected function addField( $table, $field, $patch, $fullpath = false ) {
00693         if ( !$this->doTable( $table ) ) {
00694             return true;
00695         }
00696 
00697         if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
00698             $this->output( "...$table table does not exist, skipping new field patch.\n" );
00699         } elseif ( $this->db->fieldExists( $table, $field, __METHOD__ ) ) {
00700             $this->output( "...have $field field in $table table.\n" );
00701         } else {
00702             return $this->applyPatch( $patch, $fullpath, "Adding $field field to table $table" );
00703         }
00704 
00705         return true;
00706     }
00707 
00717     protected function addIndex( $table, $index, $patch, $fullpath = false ) {
00718         if ( !$this->doTable( $table ) ) {
00719             return true;
00720         }
00721 
00722         if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
00723             $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
00724         } elseif ( $this->db->indexExists( $table, $index, __METHOD__ ) ) {
00725             $this->output( "...index $index already set on $table table.\n" );
00726         } else {
00727             return $this->applyPatch( $patch, $fullpath, "Adding index $index to table $table" );
00728         }
00729 
00730         return true;
00731     }
00732 
00742     protected function dropField( $table, $field, $patch, $fullpath = false ) {
00743         if ( !$this->doTable( $table ) ) {
00744             return true;
00745         }
00746 
00747         if ( $this->db->fieldExists( $table, $field, __METHOD__ ) ) {
00748             return $this->applyPatch( $patch, $fullpath, "Table $table contains $field field. Dropping" );
00749         } else {
00750             $this->output( "...$table table does not contain $field field.\n" );
00751         }
00752 
00753         return true;
00754     }
00755 
00765     protected function dropIndex( $table, $index, $patch, $fullpath = false ) {
00766         if ( !$this->doTable( $table ) ) {
00767             return true;
00768         }
00769 
00770         if ( $this->db->indexExists( $table, $index, __METHOD__ ) ) {
00771             return $this->applyPatch( $patch, $fullpath, "Dropping $index index from table $table" );
00772         } else {
00773             $this->output( "...$index key doesn't exist.\n" );
00774         }
00775 
00776         return true;
00777     }
00778 
00791     protected function renameIndex( $table, $oldIndex, $newIndex,
00792         $skipBothIndexExistWarning, $patch, $fullpath = false
00793     ) {
00794         if ( !$this->doTable( $table ) ) {
00795             return true;
00796         }
00797 
00798         // First requirement: the table must exist
00799         if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
00800             $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
00801 
00802             return true;
00803         }
00804 
00805         // Second requirement: the new index must be missing
00806         if ( $this->db->indexExists( $table, $newIndex, __METHOD__ ) ) {
00807             $this->output( "...index $newIndex already set on $table table.\n" );
00808             if ( !$skipBothIndexExistWarning &&
00809                 $this->db->indexExists( $table, $oldIndex, __METHOD__ )
00810             ) {
00811                 $this->output( "...WARNING: $oldIndex still exists, despite it has " .
00812                     "been renamed into $newIndex (which also exists).\n" .
00813                     "            $oldIndex should be manually removed if not needed anymore.\n" );
00814             }
00815 
00816             return true;
00817         }
00818 
00819         // Third requirement: the old index must exist
00820         if ( !$this->db->indexExists( $table, $oldIndex, __METHOD__ ) ) {
00821             $this->output( "...skipping: index $oldIndex doesn't exist.\n" );
00822 
00823             return true;
00824         }
00825 
00826         // Requirements have been satisfied, patch can be applied
00827         return $this->applyPatch(
00828             $patch,
00829             $fullpath,
00830             "Renaming index $oldIndex into $newIndex to table $table"
00831         );
00832     }
00833 
00845     public function dropTable( $table, $patch = false, $fullpath = false ) {
00846         if ( !$this->doTable( $table ) ) {
00847             return true;
00848         }
00849 
00850         if ( $this->db->tableExists( $table, __METHOD__ ) ) {
00851             $msg = "Dropping table $table";
00852 
00853             if ( $patch === false ) {
00854                 $this->output( "$msg ..." );
00855                 $this->db->dropTable( $table, __METHOD__ );
00856                 $this->output( "done.\n" );
00857             } else {
00858                 return $this->applyPatch( $patch, $fullpath, $msg );
00859             }
00860         } else {
00861             $this->output( "...$table doesn't exist.\n" );
00862         }
00863 
00864         return true;
00865     }
00866 
00876     public function modifyField( $table, $field, $patch, $fullpath = false ) {
00877         if ( !$this->doTable( $table ) ) {
00878             return true;
00879         }
00880 
00881         $updateKey = "$table-$field-$patch";
00882         if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
00883             $this->output( "...$table table does not exist, skipping modify field patch.\n" );
00884         } elseif ( !$this->db->fieldExists( $table, $field, __METHOD__ ) ) {
00885             $this->output( "...$field field does not exist in $table table, " .
00886                 "skipping modify field patch.\n" );
00887         } elseif ( $this->updateRowExists( $updateKey ) ) {
00888             $this->output( "...$field in table $table already modified by patch $patch.\n" );
00889         } else {
00890             $this->insertUpdateRow( $updateKey );
00891 
00892             return $this->applyPatch( $patch, $fullpath, "Modifying $field field of table $table" );
00893         }
00894 
00895         return true;
00896     }
00897 
00901     public function purgeCache() {
00902         global $wgLocalisationCacheConf;
00903         # We can't guarantee that the user will be able to use TRUNCATE,
00904         # but we know that DELETE is available to us
00905         $this->output( "Purging caches..." );
00906         $this->db->delete( 'objectcache', '*', __METHOD__ );
00907         if ( $wgLocalisationCacheConf['manualRecache'] ) {
00908             $this->rebuildLocalisationCache();
00909         }
00910         MessageBlobStore::getInstance()->clear();
00911         $this->output( "done.\n" );
00912     }
00913 
00917     protected function checkStats() {
00918         $this->output( "...site_stats is populated..." );
00919         $row = $this->db->selectRow( 'site_stats', '*', array( 'ss_row_id' => 1 ), __METHOD__ );
00920         if ( $row === false ) {
00921             $this->output( "data is missing! rebuilding...\n" );
00922         } elseif ( isset( $row->site_stats ) && $row->ss_total_pages == -1 ) {
00923             $this->output( "missing ss_total_pages, rebuilding...\n" );
00924         } else {
00925             $this->output( "done.\n" );
00926 
00927             return;
00928         }
00929         SiteStatsInit::doAllAndCommit( $this->db );
00930     }
00931 
00932     # Common updater functions
00933 
00937     protected function doActiveUsersInit() {
00938         $activeUsers = $this->db->selectField( 'site_stats', 'ss_active_users', false, __METHOD__ );
00939         if ( $activeUsers == -1 ) {
00940             $activeUsers = $this->db->selectField( 'recentchanges',
00941                 'COUNT( DISTINCT rc_user_text )',
00942                 array( 'rc_user != 0', 'rc_bot' => 0, "rc_log_type != 'newusers'" ), __METHOD__
00943             );
00944             $this->db->update( 'site_stats',
00945                 array( 'ss_active_users' => intval( $activeUsers ) ),
00946                 array( 'ss_row_id' => 1 ), __METHOD__, array( 'LIMIT' => 1 )
00947             );
00948         }
00949         $this->output( "...ss_active_users user count set...\n" );
00950     }
00951 
00955     protected function doLogUsertextPopulation() {
00956         if ( !$this->updateRowExists( 'populate log_usertext' ) ) {
00957             $this->output(
00958                 "Populating log_user_text field, printing progress markers. For large\n" .
00959                 "databases, you may want to hit Ctrl-C and do this manually with\n" .
00960                 "maintenance/populateLogUsertext.php.\n"
00961             );
00962 
00963             $task = $this->maintenance->runChild( 'PopulateLogUsertext' );
00964             $task->execute();
00965             $this->output( "done.\n" );
00966         }
00967     }
00968 
00972     protected function doLogSearchPopulation() {
00973         if ( !$this->updateRowExists( 'populate log_search' ) ) {
00974             $this->output(
00975                 "Populating log_search table, printing progress markers. For large\n" .
00976                 "databases, you may want to hit Ctrl-C and do this manually with\n" .
00977                 "maintenance/populateLogSearch.php.\n" );
00978 
00979             $task = $this->maintenance->runChild( 'PopulateLogSearch' );
00980             $task->execute();
00981             $this->output( "done.\n" );
00982         }
00983     }
00984 
00989     protected function doUpdateTranscacheField() {
00990         if ( $this->updateRowExists( 'convert transcache field' ) ) {
00991             $this->output( "...transcache tc_time already converted.\n" );
00992 
00993             return true;
00994         }
00995 
00996         return $this->applyPatch( 'patch-tc-timestamp.sql', false,
00997             "Converting tc_time from UNIX epoch to MediaWiki timestamp" );
00998     }
00999 
01003     protected function doCollationUpdate() {
01004         global $wgCategoryCollation;
01005         if ( $this->db->fieldExists( 'categorylinks', 'cl_collation', __METHOD__ ) ) {
01006             if ( $this->db->selectField(
01007                 'categorylinks',
01008                 'COUNT(*)',
01009                 'cl_collation != ' . $this->db->addQuotes( $wgCategoryCollation ),
01010                 __METHOD__
01011                 ) == 0
01012             ) {
01013                 $this->output( "...collations up-to-date.\n" );
01014 
01015                 return;
01016             }
01017 
01018             $this->output( "Updating category collations..." );
01019             $task = $this->maintenance->runChild( 'UpdateCollation' );
01020             $task->execute();
01021             $this->output( "...done.\n" );
01022         }
01023     }
01024 
01028     protected function doMigrateUserOptions() {
01029         if ( $this->db->tableExists( 'user_properties' ) ) {
01030             $cl = $this->maintenance->runChild( 'ConvertUserOptions', 'convertUserOptions.php' );
01031             $cl->execute();
01032             $this->output( "done.\n" );
01033         }
01034     }
01035 
01039     protected function rebuildLocalisationCache() {
01043         $cl = $this->maintenance->runChild( 'RebuildLocalisationCache', 'rebuildLocalisationCache.php' );
01044         $this->output( "Rebuilding localisation cache...\n" );
01045         $cl->setForce();
01046         $cl->execute();
01047         $this->output( "done.\n" );
01048     }
01049 
01054     protected function disableContentHandlerUseDB() {
01055         global $wgContentHandlerUseDB;
01056 
01057         if ( $wgContentHandlerUseDB ) {
01058             $this->output( "Turning off Content Handler DB fields for this part of upgrade.\n" );
01059             $this->holdContentHandlerUseDB = $wgContentHandlerUseDB;
01060             $wgContentHandlerUseDB = false;
01061         }
01062     }
01063 
01067     protected function enableContentHandlerUseDB() {
01068         global $wgContentHandlerUseDB;
01069 
01070         if ( $this->holdContentHandlerUseDB ) {
01071             $this->output( "Content Handler DB fields should be usable now.\n" );
01072             $wgContentHandlerUseDB = $this->holdContentHandlerUseDB;
01073         }
01074     }
01075 }