MediaWiki
REL1_24
|
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 }