r81266 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r81265‎ | r81266 | r81267 >
Date:20:00, 31 January 2011
Author:demon
Status:reverted (Comments)
Tags:
Comment:
(bug 26857) Fatal error during installation enabling 'Vector' extension (or any extension, really). The reason we're including extensions during setup is so they have a chance to register with LoadExtensionSchemaUpdates. Before including extensions, we now include DefaultSettings.php, so any operations on those variables won't result in the fatals described in the bug.

More importantly, this adds support for installing extension tables *at* install time. Previously, the best we could do was to add the require()s to LocalSettings. However, without a subsequent update, wikis will probably start having errors immediately after install (this is really bad!). So I've added an interface to the DatabaseUpdater passed to LoadExtensionSchemaUpdates. An extension can now call addNewExtension() which will allow the extension to be enabled on install and not just update. Example committed in CodeReview
Modified paths:
  • /trunk/extensions/CodeReview/CodeReview.php (modified) (history)
  • /trunk/phase3/includes/installer/DatabaseInstaller.php (modified) (history)
  • /trunk/phase3/includes/installer/DatabaseUpdater.php (modified) (history)
  • /trunk/phase3/includes/installer/Installer.i18n.php (modified) (history)
  • /trunk/phase3/includes/installer/Installer.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/installer/DatabaseUpdater.php
@@ -24,9 +24,19 @@
2525 */
2626 protected $updates = array();
2727
 28+ /**
 29+ * List of extension-provided database updates
 30+ * @var array
 31+ */
2832 protected $extensionUpdates = array();
2933
3034 /**
 35+ * Used to hold schema files during installation process
 36+ * @var array
 37+ */
 38+ protected $newExtensions = array();
 39+
 40+ /**
3141 * Handle to the database subclass
3242 *
3343 * @var DatabaseBase
@@ -83,7 +93,7 @@
8494 * @param DatabaseBase $db
8595 * @param bool $shared
8696 * @param null $maintenance
87 - * @return
 97+ * @return DatabaseUpdater
8898 */
8999 public static function newForDB( &$db, $shared = false, $maintenance = null ) {
90100 $type = $db->getType();
@@ -147,6 +157,23 @@
148158 }
149159
150160 /**
 161+ * Add a brand new extension to MediaWiki. Used during the initial install
 162+ * @param $ext String Name of extension
 163+ * @param $sqlPath String Full path to the schema file
 164+ */
 165+ public function addNewExtension( $ext, $sqlPath ) {
 166+ $this->newExtensions[ strtolower( $ext ) ] = $sqlPath;
 167+ }
 168+
 169+ /**
 170+ * Get the list of extensions that registered a schema with our DB type
 171+ * @return array
 172+ */
 173+ public function getNewExtensions() {
 174+ return $this->newExtensions;
 175+ }
 176+
 177+ /**
151178 * Get the list of extension-defined updates
152179 *
153180 * @return Array
Index: trunk/phase3/includes/installer/Installer.php
@@ -1192,9 +1192,22 @@
11931193 * @return Status
11941194 */
11951195 protected function includeExtensions() {
 1196+ global $IP;
11961197 $exts = $this->getVar( '_Extensions' );
1197 - $path = $this->getVar( 'IP' ) . '/extensions';
 1198+ $IP = $this->getVar( 'IP' );
 1199+ $path = $IP . '/extensions';
11981200
 1201+ /**
 1202+ * We need to include DefaultSettings before including extensions to avoid
 1203+ * warnings about unset variables. However, the only thing we really
 1204+ * want here is $wgHooks['LoadExtensionSchemaUpdates']. This won't work
 1205+ * if the extension has hidden hook registration in $wgExtensionFunctions,
 1206+ * but we're not opening that can of worms
 1207+ * @see https://bugzilla.wikimedia.org/show_bug.cgi?id=26857
 1208+ */
 1209+ global $wgHooks, $IP;
 1210+ require( "$IP/includes/DefaultSettings.php" );
 1211+
11991212 foreach( $exts as $e ) {
12001213 require( "$path/$e/$e.php" );
12011214 }
@@ -1251,6 +1264,10 @@
12521265 array_unshift( $this->installSteps,
12531266 array( 'name' => 'extensions', 'callback' => array( $this, 'includeExtensions' ) )
12541267 );
 1268+ $this->installSteps[] = array(
 1269+ 'name' => 'extension-tables',
 1270+ 'callback' => array( $installer, 'createExtensionTables' )
 1271+ );
12551272 }
12561273 return $this->installSteps;
12571274 }
Index: trunk/phase3/includes/installer/Installer.i18n.php
@@ -467,6 +467,7 @@
468468 'config-install-sysop' => 'Creating administrator user account',
469469 'config-install-subscribe-fail' => 'Unable to subscribe to mediawiki-announce',
470470 'config-install-mainpage' => 'Creating main page with default content',
 471+ 'config-install-extension-tables' => 'Creating tables for enabled extensions',
471472 'config-install-mainpage-failed' => 'Could not insert main page: $1',
472473 'config-install-done' => "'''Congratulations!'''
473474 You have successfully installed MediaWiki.
Index: trunk/phase3/includes/installer/DatabaseInstaller.php
@@ -171,6 +171,111 @@
172172 }
173173
174174 /**
 175+ * Create the tables for each extension the user enabled
 176+ * @return Status
 177+ */
 178+ public function createExtensionTables() {
 179+ $status = $this->getConnection();
 180+ if ( !$status->isOK() ) {
 181+ return $status;
 182+ }
 183+ $this->db;
 184+ $updater = DatabaseUpdater::newForDB( $this->db );
 185+ $extensionUpdates = $updater->getNewExtensions();
 186+
 187+ // No extensions need tables (or haven't updated to new installer support)
 188+ if( !count( $extensionUpdates ) ) {
 189+ return $status;
 190+ }
 191+
 192+ $ourExtensions = array_map( 'strtolower', $this->getVar( '_Extensions' ) );
 193+
 194+ foreach( $ourExtensions as $ext ) {
 195+ if( isset( $extensionUpdates[$ext] ) ) {
 196+ $this->db->begin( __METHOD__ );
 197+ $error = $this->db->sourceFile( $extensionUpdates[$ext] );
 198+ if( $error !== true ) {
 199+ $this->db->rollback( __METHOD__ );
 200+ $status->warning( 'config-install-tables-failed', $error );
 201+ } else {
 202+ $this->db->commit( __METHOD__ );
 203+ }
 204+ }
 205+ }
 206+ return $status;
 207+ }
 208+
 209+ /**
 210+ * Create the tables for each extension the user enabled
 211+ * @return Status
 212+ */
 213+ public function createExtensionTables() {
 214+ $status = $this->getConnection();
 215+ if ( !$status->isOK() ) {
 216+ return $status;
 217+ }
 218+ $this->db;
 219+ $updater = DatabaseUpdater::newForDB( $this->db );
 220+ $extensionUpdates = $updater->getNewExtensions();
 221+
 222+ // No extensions need tables (or haven't updated to new installer support)
 223+ if( !count( $extensionUpdates ) ) {
 224+ return $status;
 225+ }
 226+
 227+ $ourExtensions = array_map( 'strtolower', $this->getVar( '_Extensions' ) );
 228+
 229+ foreach( $ourExtensions as $ext ) {
 230+ if( isset( $extensionUpdates[$ext] ) ) {
 231+ $this->db->begin( __METHOD__ );
 232+ $error = $this->db->sourceFile( $extensionUpdates[$ext] );
 233+ if( $error !== true ) {
 234+ $this->db->rollback( __METHOD__ );
 235+ $status->warning( 'config-install-tables-failed', $error );
 236+ } else {
 237+ $this->db->commit( __METHOD__ );
 238+ }
 239+ }
 240+ }
 241+ return $status;
 242+ }
 243+
 244+ /**
 245+ * Create the tables for each extension the user enabled
 246+ * @return Status
 247+ */
 248+ public function createExtensionTables() {
 249+ $status = $this->getConnection();
 250+ if ( !$status->isOK() ) {
 251+ return $status;
 252+ }
 253+ $this->db;
 254+ $updater = DatabaseUpdater::newForDB( $this->db );
 255+ $extensionUpdates = $updater->getNewExtensions();
 256+
 257+ // No extensions need tables (or haven't updated to new installer support)
 258+ if( !count( $extensionUpdates ) ) {
 259+ return $status;
 260+ }
 261+
 262+ $ourExtensions = array_map( 'strtolower', $this->getVar( '_Extensions' ) );
 263+
 264+ foreach( $ourExtensions as $ext ) {
 265+ if( isset( $extensionUpdates[$ext] ) ) {
 266+ $this->db->begin( __METHOD__ );
 267+ $error = $this->db->sourceFile( $extensionUpdates[$ext] );
 268+ if( $error !== true ) {
 269+ $this->db->rollback( __METHOD__ );
 270+ $status->warning( 'config-install-tables-failed', $error );
 271+ } else {
 272+ $this->db->commit( __METHOD__ );
 273+ }
 274+ }
 275+ }
 276+ return $status;
 277+ }
 278+
 279+ /**
175280 * Get the DBMS-specific options for LocalSettings.php generation.
176281 *
177282 * @return String
Index: trunk/extensions/CodeReview/CodeReview.php
@@ -214,6 +214,7 @@
215215 $base = dirname( __FILE__ );
216216 switch ( $updater->getDB()->getType() ) {
217217 case 'mysql':
 218+ $updater->addNewExtension( 'CodeReview', "$base/codereview.sql" );
218219 $updater->addExtensionUpdate( array( 'addTable', 'code_rev',
219220 "$base/codereview.sql", true ) ); // Initial install tables
220221 $updater->addExtensionUpdate( array( 'addField', 'code_rev', 'cr_diff',
@@ -239,6 +240,7 @@
240241 "$base/archives/code_comment_author-index.sql", true ) );
241242 break;
242243 case 'sqlite':
 244+ $updater->addNewExtension( 'CodeReview', "$base/codereview.sql" );
243245 $updater->addExtensionUpdate( array( 'addTable', 'code_rev', "$base/codereview.sql", true ) );
244246 $updater->addExtensionUpdate( array( 'addTable', 'code_signoffs', "$base/archives/code_signoffs.sql", true ) );
245247 $updater->addExtensionUpdate( array( 'addField', 'code_signoffs', 'cs_user',

Sign-offs

UserFlagDate
Hasharinspected16:40, 6 June 2011

Follow-up revisions

RevisionCommit summaryAuthorDate
r81267Fixups to r81266demon20:09, 31 January 2011
r89660Get rid of addNewExtension()/getNewExtensions() method of adding new extensio...demon17:33, 7 June 2011

Comments

#Comment by Reedy (talk | contribs)   20:06, 31 January 2011
+		$this->db;

?

It also looks like you've added the method 3 times....

#Comment by 😂 (talk | contribs)   20:10, 31 January 2011

$this->db was leftover from testing, thanks.

I really don't know how I managed to have 3 of the function.

Both fixed in followup

Status & tagging log