From 32b450426b1d385f0749aebd6f190b88a2825f94 Mon Sep 17 00:00:00 2001 From: Chad Horohoe Date: Tue, 7 Sep 2010 14:33:11 +0000 Subject: [PATCH] * do_all_updates() is dead * Less $wgDatabase * update.php now uses new Maintenance class --- includes/installer/DatabaseUpdater.php | 58 ++++++++++++++++- includes/installer/MysqlInstaller.php | 7 +-- includes/installer/SqliteInstaller.php | 6 +- maintenance/update.php | 86 ++++++++++++++++++-------- maintenance/updaters.inc | 57 +---------------- 5 files changed, 123 insertions(+), 91 deletions(-) diff --git a/includes/installer/DatabaseUpdater.php b/includes/installer/DatabaseUpdater.php index 9b9f67f60f..d2ea400adc 100644 --- a/includes/installer/DatabaseUpdater.php +++ b/includes/installer/DatabaseUpdater.php @@ -30,12 +30,45 @@ abstract class DatabaseUpdater { 'DeleteDefaultMessages' ); - protected function __construct( $db, $shared ) { + /** + * Constructor + * + * @param $db DatabaseBase object to perform updates on + * @param $shared bool Whether to perform updates on shared tables + * + * @TODO @FIXME Make $wgDatabase go away. + */ + protected function __construct( DatabaseBase &$db, $shared ) { + global $wgDatabase; + $wgDatabase = $db; $this->db = $db; $this->shared = $shared; + $this->initOldGlobals(); + wfRunHooks( 'LoadExtensionSchemaUpdates', array( $this ) ); + } + + /** + * Initialize all of the old globals. One day this should all become + * something much nicer + */ + private function initOldGlobals() { + global $wgUpdates, $wgExtNewTables, $wgExtNewFields, $wgExtPGNewFields, + $wgExtPGAlteredFields, $wgExtNewIndexes, $wgExtModifiedFields; + + // Deprecated. Do not use, ever. + $wgUpdates = array(); + + # For extensions only, should be populated via hooks + # $wgDBtype should be checked to specifiy the proper file + $wgExtNewTables = array(); // table, dir + $wgExtNewFields = array(); // table, column, dir + $wgExtPGNewFields = array(); // table, column, column attributes; for PostgreSQL + $wgExtPGAlteredFields = array(); // table, column, new type, conversion method; for PostgreSQL + $wgExtNewIndexes = array(); // table, index, dir + $wgExtModifiedFields = array(); // table, index, dir } - public static function newForDB( $db, $shared ) { + public static function newForDB( &$db, $shared = false ) { $type = $db->getType(); if( in_array( $type, Installer::getDBTypes() ) ) { $class = ucfirst( $type ) . 'Updater'; @@ -51,7 +84,11 @@ abstract class DatabaseUpdater { return $this->postDatabaseUpdateMaintenance; } - public function doUpdates() { + /** + * Do all the updates + * @param $purge bool Whether to clear the objectcache table after updates + */ + public function doUpdates( $purge = true ) { global $IP, $wgVersion; require_once( "$IP/maintenance/updaters.inc" ); $this->updates = array_merge( $this->getCoreUpdateList(), @@ -65,6 +102,10 @@ abstract class DatabaseUpdater { flush(); } $this->setAppliedUpdates( $wgVersion, $this->updates ); + + if( $purge ) { + $this->purgeCache(); + } } protected function setAppliedUpdates( $version, $updates = array() ) { @@ -236,4 +277,15 @@ abstract class DatabaseUpdater { wfOut( "...$table table does not contain $field field.\n" ); } } + + /** + * Purge the objectcache table + */ + protected function purgeCache() { + # We can't guarantee that the user will be able to use TRUNCATE, + # but we know that DELETE is available to us + wfOut( "Purging caches..." ); + $this->db->delete( 'objectcache', '*', __METHOD__ ); + wfOut( "done.\n" ); + } } diff --git a/includes/installer/MysqlInstaller.php b/includes/installer/MysqlInstaller.php index c6bea9c5fa..8d483bd5db 100644 --- a/includes/installer/MysqlInstaller.php +++ b/includes/installer/MysqlInstaller.php @@ -185,12 +185,10 @@ class MysqlInstaller extends DatabaseInstaller { * old and new code. */ public function doUpgrade() { - global $wgDatabase, $wgDBuser, $wgDBpassword; + global $wgDBuser, $wgDBpassword; # Some maintenance scripts like wfGetDB() LBFactory::enableBackend(); - # For do_all_updates() - $wgDatabase = $this->db; # Normal user and password are selected after this step, so for now # just copy these two $wgDBuser = $this->getVar( '_InstallUser' ); @@ -200,7 +198,8 @@ class MysqlInstaller extends DatabaseInstaller { ob_start( array( $this, 'outputHandler' ) ); try { - do_all_updates( false, true ); + $updater = DatabaseUpdater::newForDb( $this->db ); + $updater->doUpdates(); } catch ( MWException $e ) { echo "\nAn error occured:\n"; echo $e->getText(); diff --git a/includes/installer/SqliteInstaller.php b/includes/installer/SqliteInstaller.php index 640cf5a028..a06d4c8f99 100644 --- a/includes/installer/SqliteInstaller.php +++ b/includes/installer/SqliteInstaller.php @@ -171,11 +171,11 @@ class SqliteInstaller extends DatabaseInstaller { } public function doUpgrade() { - global $wgDatabase; LBFactory::enableBackend(); - $wgDatabase = wfGetDB( DB_MASTER ); + $db = wfGetDB( DB_MASTER ); ob_start( array( $this, 'outputHandler' ) ); - do_all_updates( false, true ); + $updater = DatabaseUpdater::newForDb( $this->db ); + $updater->doUpdates(); ob_end_flush(); return true; } diff --git a/maintenance/update.php b/maintenance/update.php index 681367c98c..a1cb8c4f0d 100644 --- a/maintenance/update.php +++ b/maintenance/update.php @@ -9,47 +9,80 @@ * @ingroup Maintenance */ -/** */ define( 'MW_CMDLINE_CALLBACK', 'wfSetupUpdateScript' ); $wgUseMasterForMaintenance = true; -require_once( dirname( __FILE__ ) . '/commandLine.inc' ); -require( "updaters.inc" ); +require_once( 'Maintenance.php' ); -$wgTitle = Title::newFromText( "MediaWiki database updater" ); +class UpdateMediaWiki extends Maintenance { -echo( "MediaWiki {$wgVersion} Updater\n\n" ); + public function __construct() { + parent::__construct(); + $this->mDescription = "MediaWiki database updater"; + $this->addOption( 'skip-compat-checks', 'Skips compatibility checks, mostly for developers' ); + $this->addOption( 'quick', 'Skip 5 second countdown before starting' ); + $this->addOption( 'doshared', 'Also update shared tables' ); + $this->addOption( 'nopurge', 'Do not purge the objectcache table after updates' ); + } -if ( !isset( $options['skip-compat-checks'] ) ) { - install_version_checks(); -} else { - print "Skipping compatibility checks, proceed at your own risk (Ctrl+C to abort)\n"; - wfCountdown( 5 ); -} + public function getDbType() { + return self::DB_ADMIN; + } -# Attempt to connect to the database as a privileged user -# This will vomit up an error if there are permissions problems -$wgDatabase = wfGetDB( DB_MASTER ); + public function execute() { + global $wgVersion, $wgTitle; -print "Going to run database updates for " . wfWikiID() . "\n"; -print "Depending on the size of your database this may take a while!\n"; + $wgTitle = Title::newFromText( "MediaWiki database updater" ); -if ( !isset( $options['quick'] ) ) { - print "Abort with control-c in the next five seconds (skip this countdown with --quick) ... "; - wfCountDown( 5 ); -} + $this->output( "MediaWiki {$wgVersion} Updater\n\n" ); + + if ( !isset( $options['skip-compat-checks'] ) ) { + install_version_checks(); + } else { + $this->output( "Skipping compatibility checks, proceed at your own risk (Ctrl+C to abort)\n" ); + wfCountdown( 5 ); + } + + # Attempt to connect to the database as a privileged user + # This will vomit up an error if there are permissions problems + $db = wfGetDB( DB_MASTER ); + + $this->output( "Going to run database updates for " . wfWikiID() . "\n" ); + $this->output( "Depending on the size of your database this may take a while!\n" ); + + if ( !$this->hasOption( 'quick' ) ) { + $this->output( "Abort with control-c in the next five seconds (skip this countdown with --quick) ... " ); + wfCountDown( 5 ); + } -$shared = isset( $options['doshared'] ); -$purge = !isset( $options['nopurge'] ); + $shared = $this->hasOption( 'doshared' ); + $purge = !$this->hasOption( 'nopurge' ); -do_all_updates( $shared, $purge ); + $updater = DatabaseUpdater::newForDb( $db, $shared ); + $updater->doUpdates( $purge ); -print "Done.\n"; + if ( !defined( 'MW_NO_SETUP' ) ) { + define( 'MW_NO_SETUP', true ); + } + + foreach( $updater->getPostDatabaseUpdateMaintenance() as $maint ) { + call_user_func_array( array( new $maint, 'execute' ), array() ); + } + + if ( $db->getType() === 'postgres' ) { + return; + } + + do_stats_init(); + + $this->output( "Done.\n" ); + } +} function wfSetupUpdateScript() { global $wgLocalisationCacheConf; # Don't try to access the database - # This needs to be disabled early since extensions will try to use the l10n + # This needs to be disabled early since extensions will try to use the l10n # cache from $wgExtensionSetupFunctions (bug 20471) $wgLocalisationCacheConf = array( 'class' => 'LocalisationCache', @@ -58,3 +91,6 @@ function wfSetupUpdateScript() { 'manualRecache' => false, ); } + +$maintClass = 'UpdateMediaWiki'; +require_once( DO_MAINTENANCE ); diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index ab990403d4..6057bf191b 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -9,25 +9,6 @@ if ( !defined( 'MEDIAWIKI' ) ) { exit( 1 ); } -require_once 'userDupes.inc'; -# Extension updates -require_once( "$IP/includes/Hooks.php" ); - -/** - * @deprecated. Do not use, ever. - */ -$wgUpdates = array(); - - -# For extensions only, should be populated via hooks -# $wgDBtype should be checked to specifiy the proper file -$wgExtNewTables = array(); // table, dir -$wgExtNewFields = array(); // table, column, dir -$wgExtPGNewFields = array(); // table, column, column attributes; for PostgreSQL -$wgExtPGAlteredFields = array(); // table, column, new type, conversion method; for PostgreSQL -$wgExtNewIndexes = array(); // table, index, dir -$wgExtModifiedFields = array(); // table, index, dir - # Helper function: check if the given key is present in the updatelog table. # Obviously, only use this for updates that occur after the updatelog table was # created! @@ -74,34 +55,6 @@ function drop_index_if_exists( $table, $index, $patch, $fullpath = false ) { } } -function do_all_updates( $shared = false, $purge = true ) { - global $wgDatabase, $wgDBtype; - - $updater = DatabaseUpdater::newForDb( $wgDatabase, $shared ); - - wfRunHooks( 'LoadExtensionSchemaUpdates', array( &$updater ) ); - - $updater->doUpdates(); - - if ( !defined( 'MW_NO_SETUP' ) ) { - define( 'MW_NO_SETUP', true ); - } - - foreach( $updater->getPostDatabaseUpdateMaintenance() as $maint ) { - call_user_func_array( array( new $maint, 'execute' ), array() ); - } - - if ( $wgDBtype === 'postgres' ) { - return; - } - - do_stats_init(); - - if ( $purge ) { - purge_cache(); - } -} - function archive( $name ) { return DatabaseBase::patchPath( $name ); } @@ -479,6 +432,7 @@ function fix_ancient_imagelinks() { function do_user_unique_update() { global $wgDatabase; + require_once( "userDupes.inc" ); $duper = new UserDupes( $wgDatabase ); if ( $duper->hasUniqueIndex() ) { wfOut( "...already have unique user_name index.\n" ); @@ -763,15 +717,6 @@ function do_active_users_init() { wfOut( "...ss_active_users user count set...\n" ); } -function purge_cache() { - global $wgDatabase; - # We can't guarantee that the user will be able to use TRUNCATE, - # but we know that DELETE is available to us - wfOut( "Purging caches..." ); - $wgDatabase->delete( 'objectcache', '*', __METHOD__ ); - wfOut( "done.\n" ); -} - /** * Adding page_restrictions table, obsoleting page.page_restrictions. * Migrating old restrictions to new table -- 2.20.1