MediaWiki  REL1_23
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     );
00076 
00082     protected $fileHandle = null;
00083 
00089     protected $skipSchema = false;
00090 
00094     protected $holdContentHandlerUseDB = true;
00095 
00103     protected function __construct( DatabaseBase &$db, $shared, Maintenance $maintenance = null ) {
00104         $this->db = $db;
00105         $this->db->setFlag( DBO_DDLMODE ); // For Oracle's handling of schema files
00106         $this->shared = $shared;
00107         if ( $maintenance ) {
00108             $this->maintenance = $maintenance;
00109             $this->fileHandle = $maintenance->fileHandle;
00110         } else {
00111             $this->maintenance = new FakeMaintenance;
00112         }
00113         $this->maintenance->setDB( $db );
00114         $this->initOldGlobals();
00115         $this->loadExtensions();
00116         wfRunHooks( 'LoadExtensionSchemaUpdates', array( $this ) );
00117     }
00118 
00123     private function initOldGlobals() {
00124         global $wgExtNewTables, $wgExtNewFields, $wgExtPGNewFields,
00125             $wgExtPGAlteredFields, $wgExtNewIndexes, $wgExtModifiedFields;
00126 
00127         # For extensions only, should be populated via hooks
00128         # $wgDBtype should be checked to specifiy the proper file
00129         $wgExtNewTables = array(); // table, dir
00130         $wgExtNewFields = array(); // table, column, dir
00131         $wgExtPGNewFields = array(); // table, column, column attributes; for PostgreSQL
00132         $wgExtPGAlteredFields = array(); // table, column, new type, conversion method; for PostgreSQL
00133         $wgExtNewIndexes = array(); // table, index, dir
00134         $wgExtModifiedFields = array(); // table, index, dir
00135     }
00136 
00141     private function loadExtensions() {
00142         if ( !defined( 'MEDIAWIKI_INSTALL' ) ) {
00143             return; // already loaded
00144         }
00145         $vars = Installer::getExistingLocalSettings();
00146         if ( !$vars ) {
00147             return; // no LocalSettings found
00148         }
00149         if ( !isset( $vars['wgHooks'] ) || !isset( $vars['wgHooks']['LoadExtensionSchemaUpdates'] ) ) {
00150             return;
00151         }
00152         global $wgHooks, $wgAutoloadClasses;
00153         $wgHooks['LoadExtensionSchemaUpdates'] = $vars['wgHooks']['LoadExtensionSchemaUpdates'];
00154         $wgAutoloadClasses = $wgAutoloadClasses + $vars['wgAutoloadClasses'];
00155     }
00156 
00165     public static function newForDB( &$db, $shared = false, $maintenance = null ) {
00166         $type = $db->getType();
00167         if ( in_array( $type, Installer::getDBTypes() ) ) {
00168             $class = ucfirst( $type ) . 'Updater';
00169 
00170             return new $class( $db, $shared, $maintenance );
00171         } else {
00172             throw new MWException( __METHOD__ . ' called for unsupported $wgDBtype' );
00173         }
00174     }
00175 
00181     public function getDB() {
00182         return $this->db;
00183     }
00184 
00190     public function output( $str ) {
00191         if ( $this->maintenance->isQuiet() ) {
00192             return;
00193         }
00194         global $wgCommandLineMode;
00195         if ( !$wgCommandLineMode ) {
00196             $str = htmlspecialchars( $str );
00197         }
00198         echo $str;
00199         flush();
00200     }
00201 
00215     public function addExtensionUpdate( array $update ) {
00216         $this->extensionUpdates[] = $update;
00217     }
00218 
00228     public function addExtensionTable( $tableName, $sqlPath ) {
00229         $this->extensionUpdates[] = array( 'addTable', $tableName, $sqlPath, true );
00230     }
00231 
00239     public function addExtensionIndex( $tableName, $indexName, $sqlPath ) {
00240         $this->extensionUpdates[] = array( 'addIndex', $tableName, $indexName, $sqlPath, true );
00241     }
00242 
00251     public function addExtensionField( $tableName, $columnName, $sqlPath ) {
00252         $this->extensionUpdates[] = array( 'addField', $tableName, $columnName, $sqlPath, true );
00253     }
00254 
00263     public function dropExtensionField( $tableName, $columnName, $sqlPath ) {
00264         $this->extensionUpdates[] = array( 'dropField', $tableName, $columnName, $sqlPath, true );
00265     }
00266 
00276     public function dropExtensionIndex( $tableName, $indexName, $sqlPath ) {
00277         $this->extensionUpdates[] = array( 'dropIndex', $tableName, $indexName, $sqlPath, true );
00278     }
00279 
00287     public function dropExtensionTable( $tableName, $sqlPath ) {
00288         $this->extensionUpdates[] = array( 'dropTable', $tableName, $sqlPath, true );
00289     }
00290 
00303     public function renameExtensionIndex( $tableName, $oldIndexName, $newIndexName,
00304         $sqlPath, $skipBothIndexExistWarning = false
00305     ) {
00306         $this->extensionUpdates[] = array(
00307             'renameIndex',
00308             $tableName,
00309             $oldIndexName,
00310             $newIndexName,
00311             $skipBothIndexExistWarning,
00312             $sqlPath,
00313             true
00314         );
00315     }
00316 
00324     public function modifyExtensionField( $tableName, $fieldName, $sqlPath ) {
00325         $this->extensionUpdates[] = array( 'modifyField', $tableName, $fieldName, $sqlPath, true );
00326     }
00327 
00335     public function tableExists( $tableName ) {
00336         return ( $this->db->tableExists( $tableName, __METHOD__ ) );
00337     }
00338 
00348     public function addPostDatabaseUpdateMaintenance( $class ) {
00349         $this->postDatabaseUpdateMaintenance[] = $class;
00350     }
00351 
00357     protected function getExtensionUpdates() {
00358         return $this->extensionUpdates;
00359     }
00360 
00366     public function getPostDatabaseUpdateMaintenance() {
00367         return $this->postDatabaseUpdateMaintenance;
00368     }
00369 
00375     private function writeSchemaUpdateFile( $schemaUpdate = array() ) {
00376         $updates = $this->updatesSkipped;
00377         $this->updatesSkipped = array();
00378 
00379         foreach ( $updates as $funcList ) {
00380             $func = $funcList[0];
00381             $arg = $funcList[1];
00382             $origParams = $funcList[2];
00383             call_user_func_array( $func, $arg );
00384             flush();
00385             $this->updatesSkipped[] = $origParams;
00386         }
00387     }
00388 
00394     public function doUpdates( $what = array( 'core', 'extensions', 'stats' ) ) {
00395         global $wgVersion;
00396 
00397         $this->db->begin( __METHOD__ );
00398         $what = array_flip( $what );
00399         $this->skipSchema = isset( $what['noschema'] ) || $this->fileHandle !== null;
00400         if ( isset( $what['core'] ) ) {
00401             $this->runUpdates( $this->getCoreUpdateList(), false );
00402         }
00403         if ( isset( $what['extensions'] ) ) {
00404             $this->runUpdates( $this->getOldGlobalUpdates(), false );
00405             $this->runUpdates( $this->getExtensionUpdates(), true );
00406         }
00407 
00408         if ( isset( $what['stats'] ) ) {
00409             $this->checkStats();
00410         }
00411 
00412         $this->setAppliedUpdates( $wgVersion, $this->updates );
00413 
00414         if ( $this->fileHandle ) {
00415             $this->skipSchema = false;
00416             $this->writeSchemaUpdateFile();
00417             $this->setAppliedUpdates( "$wgVersion-schema", $this->updatesSkipped );
00418         }
00419 
00420         $this->db->commit( __METHOD__ );
00421     }
00422 
00430     private function runUpdates( array $updates, $passSelf ) {
00431         $updatesDone = array();
00432         $updatesSkipped = array();
00433         foreach ( $updates as $params ) {
00434             $origParams = $params;
00435             $func = array_shift( $params );
00436             if ( !is_array( $func ) && method_exists( $this, $func ) ) {
00437                 $func = array( $this, $func );
00438             } elseif ( $passSelf ) {
00439                 array_unshift( $params, $this );
00440             }
00441             $ret = call_user_func_array( $func, $params );
00442             flush();
00443             if ( $ret !== false ) {
00444                 $updatesDone[] = $origParams;
00445             } else {
00446                 $updatesSkipped[] = array( $func, $params, $origParams );
00447             }
00448         }
00449         $this->updatesSkipped = array_merge( $this->updatesSkipped, $updatesSkipped );
00450         $this->updates = array_merge( $this->updates, $updatesDone );
00451     }
00452 
00457     protected function setAppliedUpdates( $version, $updates = array() ) {
00458         $this->db->clearFlag( DBO_DDLMODE );
00459         if ( !$this->canUseNewUpdatelog() ) {
00460             return;
00461         }
00462         $key = "updatelist-$version-" . time();
00463         $this->db->insert( 'updatelog',
00464             array( 'ul_key' => $key, 'ul_value' => serialize( $updates ) ),
00465             __METHOD__ );
00466         $this->db->setFlag( DBO_DDLMODE );
00467     }
00468 
00476     public function updateRowExists( $key ) {
00477         $row = $this->db->selectRow(
00478             'updatelog',
00479             '1',
00480             array( 'ul_key' => $key ),
00481             __METHOD__
00482         );
00483 
00484         return (bool)$row;
00485     }
00486 
00494     public function insertUpdateRow( $key, $val = null ) {
00495         $this->db->clearFlag( DBO_DDLMODE );
00496         $values = array( 'ul_key' => $key );
00497         if ( $val && $this->canUseNewUpdatelog() ) {
00498             $values['ul_value'] = $val;
00499         }
00500         $this->db->insert( 'updatelog', $values, __METHOD__, 'IGNORE' );
00501         $this->db->setFlag( DBO_DDLMODE );
00502     }
00503 
00512     protected function canUseNewUpdatelog() {
00513         return $this->db->tableExists( 'updatelog', __METHOD__ ) &&
00514             $this->db->fieldExists( 'updatelog', 'ul_value', __METHOD__ );
00515     }
00516 
00525     protected function doTable( $name ) {
00526         global $wgSharedDB, $wgSharedTables;
00527 
00528         // Don't bother to check $wgSharedTables if there isn't a shared database
00529         // or the user actually also wants to do updates on the shared database.
00530         if ( $wgSharedDB === null || $this->shared ) {
00531             return true;
00532         }
00533 
00534         return !in_array( $name, $wgSharedTables );
00535     }
00536 
00545     protected function getOldGlobalUpdates() {
00546         global $wgExtNewFields, $wgExtNewTables, $wgExtModifiedFields,
00547             $wgExtNewIndexes;
00548 
00549         $updates = array();
00550 
00551         foreach ( $wgExtNewTables as $tableRecord ) {
00552             $updates[] = array(
00553                 'addTable', $tableRecord[0], $tableRecord[1], true
00554             );
00555         }
00556 
00557         foreach ( $wgExtNewFields as $fieldRecord ) {
00558             $updates[] = array(
00559                 'addField', $fieldRecord[0], $fieldRecord[1],
00560                 $fieldRecord[2], true
00561             );
00562         }
00563 
00564         foreach ( $wgExtNewIndexes as $fieldRecord ) {
00565             $updates[] = array(
00566                 'addIndex', $fieldRecord[0], $fieldRecord[1],
00567                 $fieldRecord[2], true
00568             );
00569         }
00570 
00571         foreach ( $wgExtModifiedFields as $fieldRecord ) {
00572             $updates[] = array(
00573                 'modifyField', $fieldRecord[0], $fieldRecord[1],
00574                 $fieldRecord[2], true
00575             );
00576         }
00577 
00578         return $updates;
00579     }
00580 
00589     abstract protected function getCoreUpdateList();
00590 
00596     public function copyFile( $filename ) {
00597         $this->db->sourceFile( $filename, false, false, false,
00598             array( $this, 'appendLine' )
00599         );
00600     }
00601 
00612     public function appendLine( $line ) {
00613         $line = rtrim( $line ) . ";\n";
00614         if ( fwrite( $this->fileHandle, $line ) === false ) {
00615             throw new MWException( "trouble writing file" );
00616         }
00617 
00618         return false;
00619     }
00620 
00629     protected function applyPatch( $path, $isFullPath = false, $msg = null ) {
00630         if ( $msg === null ) {
00631             $msg = "Applying $path patch";
00632         }
00633         if ( $this->skipSchema ) {
00634             $this->output( "...skipping schema change ($msg).\n" );
00635 
00636             return false;
00637         }
00638 
00639         $this->output( "$msg ..." );
00640 
00641         if ( !$isFullPath ) {
00642             $path = $this->db->patchPath( $path );
00643         }
00644         if ( $this->fileHandle !== null ) {
00645             $this->copyFile( $path );
00646         } else {
00647             $this->db->sourceFile( $path );
00648         }
00649         $this->output( "done.\n" );
00650 
00651         return true;
00652     }
00653 
00662     protected function addTable( $name, $patch, $fullpath = false ) {
00663         if ( !$this->doTable( $name ) ) {
00664             return true;
00665         }
00666 
00667         if ( $this->db->tableExists( $name, __METHOD__ ) ) {
00668             $this->output( "...$name table already exists.\n" );
00669         } else {
00670             return $this->applyPatch( $patch, $fullpath, "Creating $name table" );
00671         }
00672 
00673         return true;
00674     }
00675 
00685     protected function addField( $table, $field, $patch, $fullpath = false ) {
00686         if ( !$this->doTable( $table ) ) {
00687             return true;
00688         }
00689 
00690         if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
00691             $this->output( "...$table table does not exist, skipping new field patch.\n" );
00692         } elseif ( $this->db->fieldExists( $table, $field, __METHOD__ ) ) {
00693             $this->output( "...have $field field in $table table.\n" );
00694         } else {
00695             return $this->applyPatch( $patch, $fullpath, "Adding $field field to table $table" );
00696         }
00697 
00698         return true;
00699     }
00700 
00710     protected function addIndex( $table, $index, $patch, $fullpath = false ) {
00711         if ( !$this->doTable( $table ) ) {
00712             return true;
00713         }
00714 
00715         if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
00716             $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
00717         } elseif ( $this->db->indexExists( $table, $index, __METHOD__ ) ) {
00718             $this->output( "...index $index already set on $table table.\n" );
00719         } else {
00720             return $this->applyPatch( $patch, $fullpath, "Adding index $index to table $table" );
00721         }
00722 
00723         return true;
00724     }
00725 
00735     protected function dropField( $table, $field, $patch, $fullpath = false ) {
00736         if ( !$this->doTable( $table ) ) {
00737             return true;
00738         }
00739 
00740         if ( $this->db->fieldExists( $table, $field, __METHOD__ ) ) {
00741             return $this->applyPatch( $patch, $fullpath, "Table $table contains $field field. Dropping" );
00742         } else {
00743             $this->output( "...$table table does not contain $field field.\n" );
00744         }
00745 
00746         return true;
00747     }
00748 
00758     protected function dropIndex( $table, $index, $patch, $fullpath = false ) {
00759         if ( !$this->doTable( $table ) ) {
00760             return true;
00761         }
00762 
00763         if ( $this->db->indexExists( $table, $index, __METHOD__ ) ) {
00764             return $this->applyPatch( $patch, $fullpath, "Dropping $index index from table $table" );
00765         } else {
00766             $this->output( "...$index key doesn't exist.\n" );
00767         }
00768 
00769         return true;
00770     }
00771 
00784     protected function renameIndex( $table, $oldIndex, $newIndex,
00785         $skipBothIndexExistWarning, $patch, $fullpath = false
00786     ) {
00787         if ( !$this->doTable( $table ) ) {
00788             return true;
00789         }
00790 
00791         // First requirement: the table must exist
00792         if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
00793             $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
00794 
00795             return true;
00796         }
00797 
00798         // Second requirement: the new index must be missing
00799         if ( $this->db->indexExists( $table, $newIndex, __METHOD__ ) ) {
00800             $this->output( "...index $newIndex already set on $table table.\n" );
00801             if ( !$skipBothIndexExistWarning &&
00802                 $this->db->indexExists( $table, $oldIndex, __METHOD__ )
00803             ) {
00804                 $this->output( "...WARNING: $oldIndex still exists, despite it has " .
00805                     "been renamed into $newIndex (which also exists).\n" .
00806                     "            $oldIndex should be manually removed if not needed anymore.\n" );
00807             }
00808 
00809             return true;
00810         }
00811 
00812         // Third requirement: the old index must exist
00813         if ( !$this->db->indexExists( $table, $oldIndex, __METHOD__ ) ) {
00814             $this->output( "...skipping: index $oldIndex doesn't exist.\n" );
00815 
00816             return true;
00817         }
00818 
00819         // Requirements have been satisfied, patch can be applied
00820         return $this->applyPatch(
00821             $patch,
00822             $fullpath,
00823             "Renaming index $oldIndex into $newIndex to table $table"
00824         );
00825     }
00826 
00838     public function dropTable( $table, $patch = false, $fullpath = false ) {
00839         if ( !$this->doTable( $table ) ) {
00840             return true;
00841         }
00842 
00843         if ( $this->db->tableExists( $table, __METHOD__ ) ) {
00844             $msg = "Dropping table $table";
00845 
00846             if ( $patch === false ) {
00847                 $this->output( "$msg ..." );
00848                 $this->db->dropTable( $table, __METHOD__ );
00849                 $this->output( "done.\n" );
00850             } else {
00851                 return $this->applyPatch( $patch, $fullpath, $msg );
00852             }
00853         } else {
00854             $this->output( "...$table doesn't exist.\n" );
00855         }
00856 
00857         return true;
00858     }
00859 
00869     public function modifyField( $table, $field, $patch, $fullpath = false ) {
00870         if ( !$this->doTable( $table ) ) {
00871             return true;
00872         }
00873 
00874         $updateKey = "$table-$field-$patch";
00875         if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
00876             $this->output( "...$table table does not exist, skipping modify field patch.\n" );
00877         } elseif ( !$this->db->fieldExists( $table, $field, __METHOD__ ) ) {
00878             $this->output( "...$field field does not exist in $table table, " .
00879                 "skipping modify field patch.\n" );
00880         } elseif ( $this->updateRowExists( $updateKey ) ) {
00881             $this->output( "...$field in table $table already modified by patch $patch.\n" );
00882         } else {
00883             $this->insertUpdateRow( $updateKey );
00884 
00885             return $this->applyPatch( $patch, $fullpath, "Modifying $field field of table $table" );
00886         }
00887 
00888         return true;
00889     }
00890 
00894     public function purgeCache() {
00895         global $wgLocalisationCacheConf;
00896         # We can't guarantee that the user will be able to use TRUNCATE,
00897         # but we know that DELETE is available to us
00898         $this->output( "Purging caches..." );
00899         $this->db->delete( 'objectcache', '*', __METHOD__ );
00900         if ( $wgLocalisationCacheConf['manualRecache'] ) {
00901             $this->rebuildLocalisationCache();
00902         }
00903         MessageBlobStore::clear();
00904         $this->output( "done.\n" );
00905     }
00906 
00910     protected function checkStats() {
00911         $this->output( "...site_stats is populated..." );
00912         $row = $this->db->selectRow( 'site_stats', '*', array( 'ss_row_id' => 1 ), __METHOD__ );
00913         if ( $row === false ) {
00914             $this->output( "data is missing! rebuilding...\n" );
00915         } elseif ( isset( $row->site_stats ) && $row->ss_total_pages == -1 ) {
00916             $this->output( "missing ss_total_pages, rebuilding...\n" );
00917         } else {
00918             $this->output( "done.\n" );
00919 
00920             return;
00921         }
00922         SiteStatsInit::doAllAndCommit( $this->db );
00923     }
00924 
00925     # Common updater functions
00926 
00930     protected function doActiveUsersInit() {
00931         $activeUsers = $this->db->selectField( 'site_stats', 'ss_active_users', false, __METHOD__ );
00932         if ( $activeUsers == -1 ) {
00933             $activeUsers = $this->db->selectField( 'recentchanges',
00934                 'COUNT( DISTINCT rc_user_text )',
00935                 array( 'rc_user != 0', 'rc_bot' => 0, "rc_log_type != 'newusers'" ), __METHOD__
00936             );
00937             $this->db->update( 'site_stats',
00938                 array( 'ss_active_users' => intval( $activeUsers ) ),
00939                 array( 'ss_row_id' => 1 ), __METHOD__, array( 'LIMIT' => 1 )
00940             );
00941         }
00942         $this->output( "...ss_active_users user count set...\n" );
00943     }
00944 
00948     protected function doLogUsertextPopulation() {
00949         if ( !$this->updateRowExists( 'populate log_usertext' ) ) {
00950             $this->output(
00951                 "Populating log_user_text field, printing progress markers. For large\n" .
00952                 "databases, you may want to hit Ctrl-C and do this manually with\n" .
00953                 "maintenance/populateLogUsertext.php.\n"
00954             );
00955 
00956             $task = $this->maintenance->runChild( 'PopulateLogUsertext' );
00957             $task->execute();
00958             $this->output( "done.\n" );
00959         }
00960     }
00961 
00965     protected function doLogSearchPopulation() {
00966         if ( !$this->updateRowExists( 'populate log_search' ) ) {
00967             $this->output(
00968                 "Populating log_search table, printing progress markers. For large\n" .
00969                 "databases, you may want to hit Ctrl-C and do this manually with\n" .
00970                 "maintenance/populateLogSearch.php.\n" );
00971 
00972             $task = $this->maintenance->runChild( 'PopulateLogSearch' );
00973             $task->execute();
00974             $this->output( "done.\n" );
00975         }
00976     }
00977 
00981     protected function doUpdateTranscacheField() {
00982         if ( $this->updateRowExists( 'convert transcache field' ) ) {
00983             $this->output( "...transcache tc_time already converted.\n" );
00984 
00985             return true;
00986         }
00987 
00988         return $this->applyPatch( 'patch-tc-timestamp.sql', false,
00989             "Converting tc_time from UNIX epoch to MediaWiki timestamp" );
00990     }
00991 
00995     protected function doCollationUpdate() {
00996         global $wgCategoryCollation;
00997         if ( $this->db->fieldExists( 'categorylinks', 'cl_collation', __METHOD__ ) ) {
00998             if ( $this->db->selectField(
00999                 'categorylinks',
01000                 'COUNT(*)',
01001                 'cl_collation != ' . $this->db->addQuotes( $wgCategoryCollation ),
01002                 __METHOD__
01003                 ) == 0
01004             ) {
01005                 $this->output( "...collations up-to-date.\n" );
01006 
01007                 return;
01008             }
01009 
01010             $this->output( "Updating category collations..." );
01011             $task = $this->maintenance->runChild( 'UpdateCollation' );
01012             $task->execute();
01013             $this->output( "...done.\n" );
01014         }
01015     }
01016 
01020     protected function doMigrateUserOptions() {
01021         if ( $this->db->tableExists( 'user_properties' ) ) {
01022             $cl = $this->maintenance->runChild( 'ConvertUserOptions', 'convertUserOptions.php' );
01023             $cl->execute();
01024             $this->output( "done.\n" );
01025         }
01026     }
01027 
01031     protected function rebuildLocalisationCache() {
01035         $cl = $this->maintenance->runChild( 'RebuildLocalisationCache', 'rebuildLocalisationCache.php' );
01036         $this->output( "Rebuilding localisation cache...\n" );
01037         $cl->setForce();
01038         $cl->execute();
01039         $this->output( "done.\n" );
01040     }
01041 
01046     protected function disableContentHandlerUseDB() {
01047         global $wgContentHandlerUseDB;
01048 
01049         if ( $wgContentHandlerUseDB ) {
01050             $this->output( "Turning off Content Handler DB fields for this part of upgrade.\n" );
01051             $this->holdContentHandlerUseDB = $wgContentHandlerUseDB;
01052             $wgContentHandlerUseDB = false;
01053         }
01054     }
01055 
01059     protected function enableContentHandlerUseDB() {
01060         global $wgContentHandlerUseDB;
01061 
01062         if ( $this->holdContentHandlerUseDB ) {
01063             $this->output( "Content Handler DB fields should be usable now.\n" );
01064             $wgContentHandlerUseDB = $this->holdContentHandlerUseDB;
01065         }
01066     }
01067 }