From 18f5bf2c95b5cc540cdb6f125eeca131eeca76e0 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Fri, 12 Aug 2011 19:11:04 +0000 Subject: [PATCH] * Added LoggedUpdateMaintenance subclass * Moved PopulateRevisionLength/PopulateRevisionSha1 scripts to $postDatabaseUpdateMaintenance * Fixed bogus "{$prefix}_sha1 != ''" comparison (r94362) * Removed unneeded NOT NULL check (speeds up script a bit) from populateRevisionSha1 script * Various code cleanups --- includes/AutoLoader.php | 1 + includes/installer/DatabaseUpdater.php | 14 ++---- includes/installer/MysqlUpdater.php | 14 +----- maintenance/Maintenance.php | 57 ++++++++++++++++++++++++ maintenance/populateRevisionLength.php | 46 ++++++++++---------- maintenance/populateRevisionSha1.php | 60 ++++++++++++++++---------- 6 files changed, 123 insertions(+), 69 deletions(-) diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index c31e423d72..18a658b3a4 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -832,6 +832,7 @@ $wgAutoloadLocalClasses = array( 'DeleteArchivedRevisionsImplementation' => 'maintenance/deleteArchivedRevisions.inc', 'DeleteDefaultMessages' => 'maintenance/deleteDefaultMessages.php', 'FakeMaintenance' => 'maintenance/Maintenance.php', + 'LoggedUpdateMaintenance' => 'maintenance/Maintenance.php', 'Maintenance' => 'maintenance/Maintenance.php', 'PopulateCategory' => 'maintenance/populateCategory.php', 'PopulateLogSearch' => 'maintenance/populateLogSearch.php', diff --git a/includes/installer/DatabaseUpdater.php b/includes/installer/DatabaseUpdater.php index 4a939106a6..dd0e32384a 100644 --- a/includes/installer/DatabaseUpdater.php +++ b/includes/installer/DatabaseUpdater.php @@ -40,7 +40,9 @@ abstract class DatabaseUpdater { protected $shared = false; protected $postDatabaseUpdateMaintenance = array( - 'DeleteDefaultMessages' + 'DeleteDefaultMessages', + 'PopulateRevisionLength', + 'PopulateRevisionSha1' ); /** @@ -573,14 +575,4 @@ abstract class DatabaseUpdater { $task = $this->maintenance->runChild( 'UpdateCollation' ); $task->execute(); } - - protected function doPopulateRevSha1() { - if ( $this->updateRowExists( 'populate rev_sha1' ) ) { - $this->output( "...rev_sha1/ar_sha1 columns already populated.\n" ); - return; - } - - $task = $this->maintenance->runChild( 'PopulateRevisionSha1' ); - $task->execute(); - } } diff --git a/includes/installer/MysqlUpdater.php b/includes/installer/MysqlUpdater.php index 8acfce1b78..e5b868d08e 100644 --- a/includes/installer/MysqlUpdater.php +++ b/includes/installer/MysqlUpdater.php @@ -158,7 +158,6 @@ class MysqlUpdater extends DatabaseUpdater { array( 'doUpdateTranscacheField' ), array( 'renameEuWikiId' ), array( 'doUpdateMimeMinorField' ), - array( 'doPopulateRevLen' ), // 1.17 array( 'addTable', 'iwlinks', 'patch-iwlinks.sql' ), @@ -187,8 +186,7 @@ class MysqlUpdater extends DatabaseUpdater { array( 'addTable', 'config', 'patch-config.sql' ), array( 'addIndex', 'logging', 'type_action', 'patch-logging-type-action-index.sql'), array( 'addField', 'revision', 'rev_sha1', 'patch-rev_sha1.sql' ), - array( 'addField', 'archive', 'ar_sha1', 'patch-ar_sha1.sql' ), - array( 'doPopulateRevSha1' ) + array( 'addField', 'archive', 'ar_sha1', 'patch-ar_sha1.sql' ) ); } @@ -812,16 +810,6 @@ class MysqlUpdater extends DatabaseUpdater { $this->output( "done.\n" ); } - protected function doPopulateRevLen() { - if ( $this->updateRowExists( 'populate rev_len' ) ) { - $this->output( "...rev_len column already populated.\n" ); - return; - } - - $task = $this->maintenance->runChild( 'PopulateRevisionLength' ); - $task->execute(); - } - protected function doClFieldsUpdate() { if ( $this->updateRowExists( 'cl_fields_update' ) ) { $this->output( "...categorylinks up-to-date.\n" ); diff --git a/maintenance/Maintenance.php b/maintenance/Maintenance.php index 798610056d..586b727ef6 100644 --- a/maintenance/Maintenance.php +++ b/maintenance/Maintenance.php @@ -1271,3 +1271,60 @@ class FakeMaintenance extends Maintenance { return; } } + +abstract class LoggedUpdateMaintenance extends Maintenance { + public function __construct() { + parent::__construct(); + $this->addOption( 'force', 'Run the update even if it was completed already' ); + } + + public function execute() { + $db = $this->getDB( DB_MASTER ); + $key = $this->getUpdateKey(); + + if ( !$this->hasOption( 'force' ) && + $db->selectRow( 'updatelog', '1', array( 'ul_key' => $key ), __METHOD__ ) ) + { + $this->output( $this->updateSkippedMessage() . "\n" ); + return true; + } + + if ( !$this->doDBUpdates() ) { + return false; + } + + if ( + $db->insert( 'updatelog', array( 'ul_key' => $key ), __METHOD__, 'IGNORE' ) ) + { + return true; + } else { + $this->output( $this->updatelogFailedMessage() . "\n" ); + return false; + } + } + + /** + * Do the actual work. All child classes will need to implement this. + * Return true to log the update as done or false on failure. + * @return Bool + */ + abstract protected function doDBUpdates(); + + /** + * Get the update key name to go in the update log table + * @return String + */ + abstract protected function getUpdateKey(); + + /** + * Message to show that the update was done already and was just skipped + * @return String + */ + abstract protected function updateSkippedMessage(); + + /** + * Message to show the the update log was unable to log the completion of this update + * @return String + */ + abstract protected function updatelogFailedMessage(); +} diff --git a/maintenance/populateRevisionLength.php b/maintenance/populateRevisionLength.php index d020b4cba4..ff053d1d39 100644 --- a/maintenance/populateRevisionLength.php +++ b/maintenance/populateRevisionLength.php @@ -22,29 +22,39 @@ require_once( dirname( __FILE__ ) . '/Maintenance.php' ); -class PopulateRevisionLength extends Maintenance { +class PopulateRevisionLength extends LoggedUpdateMaintenance { public function __construct() { parent::__construct(); - $this->mDescription = "Populates rev_len"; + $this->mDescription = "Populates the rev_len field"; $this->setBatchSize( 200 ); } - public function execute() { + protected function getUpdateKey() { + return 'populate rev_len'; + } + + protected function updateSkippedMessage() { + return 'rev_len column of revision table already populated.'; + } + + protected function updatelogFailedMessage() { + return 'Could not insert rev_len population row.'; + } + + public function doDBUpdates() { $db = $this->getDB( DB_MASTER ); if ( !$db->tableExists( 'revision' ) ) { $this->error( "revision table does not exist", true ); } $this->output( "Populating rev_len column\n" ); - $start = $db->selectField( 'revision', 'MIN(rev_id)', false, __FUNCTION__ ); - $end = $db->selectField( 'revision', 'MAX(rev_id)', false, __FUNCTION__ ); - if ( is_null( $start ) || is_null( $end ) ) { + + $start = $db->selectField( 'revision', 'MIN(rev_id)', false, __METHOD__ ); + $end = $db->selectField( 'revision', 'MAX(rev_id)', false, __METHOD__ ); + if ( !$start || !$end ) { $this->output( "...revision table seems to be empty.\n" ); - $db->insert( 'updatelog', - array( 'ul_key' => 'populate rev_len' ), - __METHOD__, - 'IGNORE' ); - return; + return true; } + # Do remaining chunks $blockStart = intval( $start ); $blockEnd = intval( $start ) + $this->mBatchSize - 1; @@ -80,17 +90,9 @@ class PopulateRevisionLength extends Maintenance { $blockEnd += $this->mBatchSize; wfWaitForSlaves(); } - $logged = $db->insert( 'updatelog', - array( 'ul_key' => 'populate rev_len' ), - __METHOD__, - 'IGNORE' ); - if ( $logged ) { - $this->output( "rev_len population complete ... {$count} rows changed ({$missing} missing)\n" ); - return true; - } else { - $this->output( "Could not insert rev_len population row.\n" ); - return false; - } + + $this->output( "rev_len population complete ... {$count} rows changed ({$missing} missing)\n" ); + return true; } } diff --git a/maintenance/populateRevisionSha1.php b/maintenance/populateRevisionSha1.php index ff19cd3adc..6e11b2efea 100644 --- a/maintenance/populateRevisionSha1.php +++ b/maintenance/populateRevisionSha1.php @@ -1,6 +1,7 @@ mDescription = "Populates the rev_sha1 and ar_sha1 fields"; $this->setBatchSize( 200 ); } - public function execute() { + protected function getUpdateKey() { + return 'populate rev_sha1'; + } + + protected function updateSkippedMessage() { + return 'rev_sha1 column of revision table already populated.'; + } + + protected function updatelogFailedMessage() { + return 'Could not insert rev_sha1 population row.'; + } + + protected function doDBUpdates() { $db = $this->getDB( DB_MASTER ); + if ( !$db->tableExists( 'revision' ) ) { + $this->error( "revision table does not exist", true ); + } + if ( !$db->tableExists( 'archive' ) ) { + $this->error( "archive table does not exist", true ); + } $this->output( "Populating rev_sha1 column\n" ); - $this->doSha1Updates( $db, 'revision', 'rev_id', 'rev' ); + $rc = $this->doSha1Updates( $db, 'revision', 'rev_id', 'rev' ); $this->output( "Populating ar_sha1 column\n" ); - $this->doSha1Updates( $db, 'archive', 'ar_rev_id', 'ar' ); + $ac = $this->doSha1Updates( $db, 'archive', 'ar_rev_id', 'ar' ); - if ( $db->insert( - 'updatelog', - array( 'ul_key' => 'populate rev_sha1' ), - __METHOD__, - 'IGNORE' - ) - ) { - $this->output( "rev_sha1 and ar_sha1 population complete.\n" ); - return true; - } else { - $this->output( "Could not insert rev_sha1 population row.\n" ); - return false; - } + $this->output( "rev_sha1 and ar_sha1 population complete [$rc revision rows, $ac archive rows].\n" ); + return true; } + /** + * @return Integer Rows changed + */ protected function doSha1Updates( $db, $table, $idCol, $prefix ) { - $start = $db->selectField( $table, "MIN($idCol)", "$idCol IS NOT NULL", __METHOD__ ); - if ( !$start ) { - $this->output( "Nothing to do.\n" ); + $start = $db->selectField( $table, "MIN($idCol)", false, __METHOD__ ); + $end = $db->selectField( $table, "MAX($idCol)", false, __METHOD__ ); + if ( !$start || !$end ) { + $this->output( "...revision table seems to be empty.\n" ); return true; } - $end = $db->selectField( $table, "MAX($idCol)", "$idCol IS NOT NULL", __METHOD__ ); + $count = 0; # Do remaining chunk $end += $this->mBatchSize - 1; $blockStart = $start; @@ -68,7 +80,7 @@ class PopulateRevisionSha1 extends Maintenance { while ( $blockEnd <= $end ) { $this->output( "...doing $idCol from $blockStart to $blockEnd\n" ); $cond = "$idCol BETWEEN $blockStart AND $blockEnd - AND $idCol IS NOT NULL AND {$prefix}_sha1 != ''"; + AND $idCol IS NOT NULL AND {$prefix}_sha1 = ''"; $res = $db->select( $table, '*', $cond, __METHOD__ ); $db->begin(); @@ -87,6 +99,7 @@ class PopulateRevisionSha1 extends Maintenance { array( "{$prefix}_sha1" => Revision::base36Sha1( $text ) ), array( $idCol => $row->$idCol ), __METHOD__ ); + $count++; } } $db->commit(); @@ -95,6 +108,7 @@ class PopulateRevisionSha1 extends Maintenance { $blockEnd += $this->mBatchSize; wfWaitForSlaves(); } + return $count; } } -- 2.20.1