Index: trunk/phase3/maintenance/update.php |
— | — | @@ -9,47 +9,80 @@ |
10 | 10 | * @ingroup Maintenance |
11 | 11 | */ |
12 | 12 | |
13 | | -/** */ |
14 | 13 | define( 'MW_CMDLINE_CALLBACK', 'wfSetupUpdateScript' ); |
15 | 14 | $wgUseMasterForMaintenance = true; |
16 | | -require_once( dirname( __FILE__ ) . '/commandLine.inc' ); |
17 | | -require( "updaters.inc" ); |
| 15 | +require_once( 'Maintenance.php' ); |
18 | 16 | |
19 | | -$wgTitle = Title::newFromText( "MediaWiki database updater" ); |
| 17 | +class UpdateMediaWiki extends Maintenance { |
20 | 18 | |
21 | | -echo( "MediaWiki {$wgVersion} Updater\n\n" ); |
| 19 | + public function __construct() { |
| 20 | + parent::__construct(); |
| 21 | + $this->mDescription = "MediaWiki database updater"; |
| 22 | + $this->addOption( 'skip-compat-checks', 'Skips compatibility checks, mostly for developers' ); |
| 23 | + $this->addOption( 'quick', 'Skip 5 second countdown before starting' ); |
| 24 | + $this->addOption( 'doshared', 'Also update shared tables' ); |
| 25 | + $this->addOption( 'nopurge', 'Do not purge the objectcache table after updates' ); |
| 26 | + } |
22 | 27 | |
23 | | -if ( !isset( $options['skip-compat-checks'] ) ) { |
24 | | - install_version_checks(); |
25 | | -} else { |
26 | | - print "Skipping compatibility checks, proceed at your own risk (Ctrl+C to abort)\n"; |
27 | | - wfCountdown( 5 ); |
28 | | -} |
| 28 | + public function getDbType() { |
| 29 | + return self::DB_ADMIN; |
| 30 | + } |
29 | 31 | |
30 | | -# Attempt to connect to the database as a privileged user |
31 | | -# This will vomit up an error if there are permissions problems |
32 | | -$wgDatabase = wfGetDB( DB_MASTER ); |
| 32 | + public function execute() { |
| 33 | + global $wgVersion, $wgTitle; |
33 | 34 | |
34 | | -print "Going to run database updates for " . wfWikiID() . "\n"; |
35 | | -print "Depending on the size of your database this may take a while!\n"; |
| 35 | + $wgTitle = Title::newFromText( "MediaWiki database updater" ); |
36 | 36 | |
37 | | -if ( !isset( $options['quick'] ) ) { |
38 | | - print "Abort with control-c in the next five seconds (skip this countdown with --quick) ... "; |
39 | | - wfCountDown( 5 ); |
40 | | -} |
| 37 | + $this->output( "MediaWiki {$wgVersion} Updater\n\n" ); |
41 | 38 | |
42 | | -$shared = isset( $options['doshared'] ); |
43 | | -$purge = !isset( $options['nopurge'] ); |
| 39 | + if ( !isset( $options['skip-compat-checks'] ) ) { |
| 40 | + install_version_checks(); |
| 41 | + } else { |
| 42 | + $this->output( "Skipping compatibility checks, proceed at your own risk (Ctrl+C to abort)\n" ); |
| 43 | + wfCountdown( 5 ); |
| 44 | + } |
44 | 45 | |
45 | | -do_all_updates( $shared, $purge ); |
| 46 | + # Attempt to connect to the database as a privileged user |
| 47 | + # This will vomit up an error if there are permissions problems |
| 48 | + $db = wfGetDB( DB_MASTER ); |
46 | 49 | |
47 | | -print "Done.\n"; |
| 50 | + $this->output( "Going to run database updates for " . wfWikiID() . "\n" ); |
| 51 | + $this->output( "Depending on the size of your database this may take a while!\n" ); |
48 | 52 | |
| 53 | + if ( !$this->hasOption( 'quick' ) ) { |
| 54 | + $this->output( "Abort with control-c in the next five seconds (skip this countdown with --quick) ... " ); |
| 55 | + wfCountDown( 5 ); |
| 56 | + } |
| 57 | + |
| 58 | + $shared = $this->hasOption( 'doshared' ); |
| 59 | + $purge = !$this->hasOption( 'nopurge' ); |
| 60 | + |
| 61 | + $updater = DatabaseUpdater::newForDb( $db, $shared ); |
| 62 | + $updater->doUpdates( $purge ); |
| 63 | + |
| 64 | + if ( !defined( 'MW_NO_SETUP' ) ) { |
| 65 | + define( 'MW_NO_SETUP', true ); |
| 66 | + } |
| 67 | + |
| 68 | + foreach( $updater->getPostDatabaseUpdateMaintenance() as $maint ) { |
| 69 | + call_user_func_array( array( new $maint, 'execute' ), array() ); |
| 70 | + } |
| 71 | + |
| 72 | + if ( $db->getType() === 'postgres' ) { |
| 73 | + return; |
| 74 | + } |
| 75 | + |
| 76 | + do_stats_init(); |
| 77 | + |
| 78 | + $this->output( "Done.\n" ); |
| 79 | + } |
| 80 | +} |
| 81 | + |
49 | 82 | function wfSetupUpdateScript() { |
50 | 83 | global $wgLocalisationCacheConf; |
51 | 84 | |
52 | 85 | # Don't try to access the database |
53 | | - # This needs to be disabled early since extensions will try to use the l10n |
| 86 | + # This needs to be disabled early since extensions will try to use the l10n |
54 | 87 | # cache from $wgExtensionSetupFunctions (bug 20471) |
55 | 88 | $wgLocalisationCacheConf = array( |
56 | 89 | 'class' => 'LocalisationCache', |
— | — | @@ -58,3 +91,6 @@ |
59 | 92 | 'manualRecache' => false, |
60 | 93 | ); |
61 | 94 | } |
| 95 | + |
| 96 | +$maintClass = 'UpdateMediaWiki'; |
| 97 | +require_once( DO_MAINTENANCE ); |
Index: trunk/phase3/maintenance/updaters.inc |
— | — | @@ -9,25 +9,6 @@ |
10 | 10 | exit( 1 ); |
11 | 11 | } |
12 | 12 | |
13 | | -require_once 'userDupes.inc'; |
14 | | -# Extension updates |
15 | | -require_once( "$IP/includes/Hooks.php" ); |
16 | | - |
17 | | -/** |
18 | | - * @deprecated. Do not use, ever. |
19 | | - */ |
20 | | -$wgUpdates = array(); |
21 | | - |
22 | | - |
23 | | -# For extensions only, should be populated via hooks |
24 | | -# $wgDBtype should be checked to specifiy the proper file |
25 | | -$wgExtNewTables = array(); // table, dir |
26 | | -$wgExtNewFields = array(); // table, column, dir |
27 | | -$wgExtPGNewFields = array(); // table, column, column attributes; for PostgreSQL |
28 | | -$wgExtPGAlteredFields = array(); // table, column, new type, conversion method; for PostgreSQL |
29 | | -$wgExtNewIndexes = array(); // table, index, dir |
30 | | -$wgExtModifiedFields = array(); // table, index, dir |
31 | | - |
32 | 13 | # Helper function: check if the given key is present in the updatelog table. |
33 | 14 | # Obviously, only use this for updates that occur after the updatelog table was |
34 | 15 | # created! |
— | — | @@ -74,34 +55,6 @@ |
75 | 56 | } |
76 | 57 | } |
77 | 58 | |
78 | | -function do_all_updates( $shared = false, $purge = true ) { |
79 | | - global $wgDatabase, $wgDBtype; |
80 | | - |
81 | | - $updater = DatabaseUpdater::newForDb( $wgDatabase, $shared ); |
82 | | - |
83 | | - wfRunHooks( 'LoadExtensionSchemaUpdates', array( &$updater ) ); |
84 | | - |
85 | | - $updater->doUpdates(); |
86 | | - |
87 | | - if ( !defined( 'MW_NO_SETUP' ) ) { |
88 | | - define( 'MW_NO_SETUP', true ); |
89 | | - } |
90 | | - |
91 | | - foreach( $updater->getPostDatabaseUpdateMaintenance() as $maint ) { |
92 | | - call_user_func_array( array( new $maint, 'execute' ), array() ); |
93 | | - } |
94 | | - |
95 | | - if ( $wgDBtype === 'postgres' ) { |
96 | | - return; |
97 | | - } |
98 | | - |
99 | | - do_stats_init(); |
100 | | - |
101 | | - if ( $purge ) { |
102 | | - purge_cache(); |
103 | | - } |
104 | | -} |
105 | | - |
106 | 59 | function archive( $name ) { |
107 | 60 | return DatabaseBase::patchPath( $name ); |
108 | 61 | } |
— | — | @@ -479,6 +432,7 @@ |
480 | 433 | |
481 | 434 | function do_user_unique_update() { |
482 | 435 | global $wgDatabase; |
| 436 | + require_once( "userDupes.inc" ); |
483 | 437 | $duper = new UserDupes( $wgDatabase ); |
484 | 438 | if ( $duper->hasUniqueIndex() ) { |
485 | 439 | wfOut( "...already have unique user_name index.\n" ); |
— | — | @@ -763,15 +717,6 @@ |
764 | 718 | wfOut( "...ss_active_users user count set...\n" ); |
765 | 719 | } |
766 | 720 | |
767 | | -function purge_cache() { |
768 | | - global $wgDatabase; |
769 | | - # We can't guarantee that the user will be able to use TRUNCATE, |
770 | | - # but we know that DELETE is available to us |
771 | | - wfOut( "Purging caches..." ); |
772 | | - $wgDatabase->delete( 'objectcache', '*', __METHOD__ ); |
773 | | - wfOut( "done.\n" ); |
774 | | -} |
775 | | - |
776 | 721 | /** |
777 | 722 | * Adding page_restrictions table, obsoleting page.page_restrictions. |
778 | 723 | * Migrating old restrictions to new table |
Index: trunk/phase3/includes/installer/DatabaseUpdater.php |
— | — | @@ -30,12 +30,45 @@ |
31 | 31 | 'DeleteDefaultMessages' |
32 | 32 | ); |
33 | 33 | |
34 | | - protected function __construct( $db, $shared ) { |
| 34 | + /** |
| 35 | + * Constructor |
| 36 | + * |
| 37 | + * @param $db DatabaseBase object to perform updates on |
| 38 | + * @param $shared bool Whether to perform updates on shared tables |
| 39 | + * |
| 40 | + * @TODO @FIXME Make $wgDatabase go away. |
| 41 | + */ |
| 42 | + protected function __construct( DatabaseBase &$db, $shared ) { |
| 43 | + global $wgDatabase; |
| 44 | + $wgDatabase = $db; |
35 | 45 | $this->db = $db; |
36 | 46 | $this->shared = $shared; |
| 47 | + $this->initOldGlobals(); |
| 48 | + wfRunHooks( 'LoadExtensionSchemaUpdates', array( $this ) ); |
37 | 49 | } |
38 | 50 | |
39 | | - public static function newForDB( $db, $shared ) { |
| 51 | + /** |
| 52 | + * Initialize all of the old globals. One day this should all become |
| 53 | + * something much nicer |
| 54 | + */ |
| 55 | + private function initOldGlobals() { |
| 56 | + global $wgUpdates, $wgExtNewTables, $wgExtNewFields, $wgExtPGNewFields, |
| 57 | + $wgExtPGAlteredFields, $wgExtNewIndexes, $wgExtModifiedFields; |
| 58 | + |
| 59 | + // Deprecated. Do not use, ever. |
| 60 | + $wgUpdates = array(); |
| 61 | + |
| 62 | + # For extensions only, should be populated via hooks |
| 63 | + # $wgDBtype should be checked to specifiy the proper file |
| 64 | + $wgExtNewTables = array(); // table, dir |
| 65 | + $wgExtNewFields = array(); // table, column, dir |
| 66 | + $wgExtPGNewFields = array(); // table, column, column attributes; for PostgreSQL |
| 67 | + $wgExtPGAlteredFields = array(); // table, column, new type, conversion method; for PostgreSQL |
| 68 | + $wgExtNewIndexes = array(); // table, index, dir |
| 69 | + $wgExtModifiedFields = array(); // table, index, dir |
| 70 | + } |
| 71 | + |
| 72 | + public static function newForDB( &$db, $shared = false ) { |
40 | 73 | $type = $db->getType(); |
41 | 74 | if( in_array( $type, Installer::getDBTypes() ) ) { |
42 | 75 | $class = ucfirst( $type ) . 'Updater'; |
— | — | @@ -51,7 +84,11 @@ |
52 | 85 | return $this->postDatabaseUpdateMaintenance; |
53 | 86 | } |
54 | 87 | |
55 | | - public function doUpdates() { |
| 88 | + /** |
| 89 | + * Do all the updates |
| 90 | + * @param $purge bool Whether to clear the objectcache table after updates |
| 91 | + */ |
| 92 | + public function doUpdates( $purge = true ) { |
56 | 93 | global $IP, $wgVersion; |
57 | 94 | require_once( "$IP/maintenance/updaters.inc" ); |
58 | 95 | $this->updates = array_merge( $this->getCoreUpdateList(), |
— | — | @@ -65,6 +102,10 @@ |
66 | 103 | flush(); |
67 | 104 | } |
68 | 105 | $this->setAppliedUpdates( $wgVersion, $this->updates ); |
| 106 | + |
| 107 | + if( $purge ) { |
| 108 | + $this->purgeCache(); |
| 109 | + } |
69 | 110 | } |
70 | 111 | |
71 | 112 | protected function setAppliedUpdates( $version, $updates = array() ) { |
— | — | @@ -236,4 +277,15 @@ |
237 | 278 | wfOut( "...$table table does not contain $field field.\n" ); |
238 | 279 | } |
239 | 280 | } |
| 281 | + |
| 282 | + /** |
| 283 | + * Purge the objectcache table |
| 284 | + */ |
| 285 | + protected function purgeCache() { |
| 286 | + # We can't guarantee that the user will be able to use TRUNCATE, |
| 287 | + # but we know that DELETE is available to us |
| 288 | + wfOut( "Purging caches..." ); |
| 289 | + $this->db->delete( 'objectcache', '*', __METHOD__ ); |
| 290 | + wfOut( "done.\n" ); |
| 291 | + } |
240 | 292 | } |
Index: trunk/phase3/includes/installer/SqliteInstaller.php |
— | — | @@ -171,11 +171,11 @@ |
172 | 172 | } |
173 | 173 | |
174 | 174 | public function doUpgrade() { |
175 | | - global $wgDatabase; |
176 | 175 | LBFactory::enableBackend(); |
177 | | - $wgDatabase = wfGetDB( DB_MASTER ); |
| 176 | + $db = wfGetDB( DB_MASTER ); |
178 | 177 | ob_start( array( $this, 'outputHandler' ) ); |
179 | | - do_all_updates( false, true ); |
| 178 | + $updater = DatabaseUpdater::newForDb( $this->db ); |
| 179 | + $updater->doUpdates(); |
180 | 180 | ob_end_flush(); |
181 | 181 | return true; |
182 | 182 | } |
Index: trunk/phase3/includes/installer/MysqlInstaller.php |
— | — | @@ -185,12 +185,10 @@ |
186 | 186 | * old and new code. |
187 | 187 | */ |
188 | 188 | public function doUpgrade() { |
189 | | - global $wgDatabase, $wgDBuser, $wgDBpassword; |
| 189 | + global $wgDBuser, $wgDBpassword; |
190 | 190 | |
191 | 191 | # Some maintenance scripts like wfGetDB() |
192 | 192 | LBFactory::enableBackend(); |
193 | | - # For do_all_updates() |
194 | | - $wgDatabase = $this->db; |
195 | 193 | # Normal user and password are selected after this step, so for now |
196 | 194 | # just copy these two |
197 | 195 | $wgDBuser = $this->getVar( '_InstallUser' ); |
— | — | @@ -200,7 +198,8 @@ |
201 | 199 | |
202 | 200 | ob_start( array( $this, 'outputHandler' ) ); |
203 | 201 | try { |
204 | | - do_all_updates( false, true ); |
| 202 | + $updater = DatabaseUpdater::newForDb( $this->db ); |
| 203 | + $updater->doUpdates(); |
205 | 204 | } catch ( MWException $e ) { |
206 | 205 | echo "\nAn error occured:\n"; |
207 | 206 | echo $e->getText(); |