From 50f54d99c9efc2d8064e6918d96849035364691b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bartosz=20Dziewo=C5=84ski?= Date: Tue, 19 Apr 2016 19:58:22 +0200 Subject: [PATCH] rebuildrecentchanges: Allow rebuilding specified time range only Bug: T133053 Change-Id: I8eef6e72f1105352116248548ab077fef818a8f9 --- maintenance/rebuildrecentchanges.php | 73 +++++++++++++++++++++------- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/maintenance/rebuildrecentchanges.php b/maintenance/rebuildrecentchanges.php index b50825a973..24e5b789ce 100644 --- a/maintenance/rebuildrecentchanges.php +++ b/maintenance/rebuildrecentchanges.php @@ -34,15 +34,37 @@ class RebuildRecentchanges extends Maintenance { public function __construct() { parent::__construct(); $this->addDescription( 'Rebuild recent changes' ); + + $this->addOption( + 'from', + "Don't empty the table, only insert rows in requested time range (in YYYYMMDDHHMMSS format)", + false, + true + ); + $this->addOption( + 'to', + "Don't empty the table, only insert rows in requested time range (in YYYYMMDDHHMMSS format)", + false, + true + ); } public function execute() { + if ( + ( $this->hasOption( 'from' ) && !$this->hasOption( 'to' ) ) || + ( !$this->hasOption( 'from' ) && $this->hasOption( 'to' ) ) + ) { + $this->error( "Both 'from' and 'to' must be given, or neither", 1 ); + } + $this->rebuildRecentChangesTablePass1(); $this->rebuildRecentChangesTablePass2(); $this->rebuildRecentChangesTablePass3(); $this->rebuildRecentChangesTablePass4(); $this->rebuildRecentChangesTablePass5(); - $this->purgeFeeds(); + if ( !( $this->hasOption( 'from' ) && $this->hasOption( 'to' ) ) ) { + $this->purgeFeeds(); + } $this->output( "Done.\n" ); } @@ -52,21 +74,29 @@ class RebuildRecentchanges extends Maintenance { private function rebuildRecentChangesTablePass1() { $dbw = $this->getDB( DB_MASTER ); - $dbw->delete( 'recentchanges', '*' ); + if ( $this->hasOption( 'from' ) && $this->hasOption( 'to' ) ) { + $this->cutoffFrom = wfTimestamp( TS_UNIX, $this->getOption( 'from' ) ); + $this->cutoffTo = wfTimestamp( TS_UNIX, $this->getOption( 'to' ) ); - $this->output( "Loading from page and revision tables...\n" ); + $sec = $this->cutoffTo - $this->cutoffFrom; + $days = $sec / 24 / 3600; + $this->output( "Rebuilding range of $sec seconds ($days days)\n" ); - global $wgRCMaxAge; - - $this->output( '$wgRCMaxAge=' . $wgRCMaxAge ); - $days = $wgRCMaxAge / 24 / 3600; - if ( intval( $days ) == $days ) { - $this->output( " (" . $days . " days)\n" ); } else { - $this->output( " (approx. " . intval( $days ) . " days)\n" ); + global $wgRCMaxAge; + + $days = $wgRCMaxAge / 24 / 3600; + $this->output( "Rebuilding \$wgRCMaxAge=$wgRCMaxAge seconds ($days days)\n" ); + + $this->cutoffFrom = time() - $wgRCMaxAge; + $this->cutoffTo = time(); + + $this->output( "Clearing recentchanges table...\n" ); + $dbw->delete( 'recentchanges', '*' ); } - $cutoff = time() - $wgRCMaxAge; + $this->output( "Loading from page and revision tables...\n" ); + $dbw->insertSelect( 'recentchanges', [ 'page', 'revision' ], [ 'rc_timestamp' => 'rev_timestamp', @@ -90,7 +120,8 @@ class RebuildRecentchanges extends Maintenance { 'rc_deleted' => 'rev_deleted' ], [ - 'rev_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $cutoff ) ), + 'rev_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffFrom ) ), + 'rev_timestamp < ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) ), 'rev_page=page_id' ], __METHOD__, @@ -111,6 +142,8 @@ class RebuildRecentchanges extends Maintenance { # Fill in the rc_last_oldid field, which points to the previous edit $sql = "SELECT rc_cur_id,rc_this_oldid,rc_timestamp FROM $recentchanges " . + "WHERE rc_timestamp > " . $dbw->addQuotes( $dbw->timestamp( $this->cutoffFrom ) ) . ' ' . + "AND rc_timestamp < " . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) ) . ' ' . "ORDER BY rc_cur_id,rc_timestamp"; $res = $dbw->query( $sql, DB_MASTER ); @@ -174,11 +207,10 @@ class RebuildRecentchanges extends Maintenance { $this->output( "Loading from user, page, and logging tables...\n" ); - global $wgRCMaxAge, $wgLogTypes, $wgLogRestrictions; + global $wgLogTypes, $wgLogRestrictions; // Some logs don't go in RC. This should check for that $basicRCLogs = array_diff( $wgLogTypes, array_keys( $wgLogRestrictions ) ); - $cutoff = time() - $wgRCMaxAge; list( $logging, $page ) = $dbw->tableNamesN( 'logging', 'page' ); $dbw->insertSelect( 'recentchanges', @@ -209,7 +241,8 @@ class RebuildRecentchanges extends Maintenance { 'rc_deleted' => 'log_deleted' ], [ - 'log_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $cutoff ) ), + 'log_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffFrom ) ), + 'log_timestamp < ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) ), 'log_user=user_id', 'log_type' => $basicRCLogs, ], @@ -251,7 +284,9 @@ class RebuildRecentchanges extends Maintenance { if ( !empty( $botusers ) ) { $botwhere = implode( ',', $botusers ); $sql2 = "UPDATE $recentchanges SET rc_bot=1 " . - "WHERE rc_user_text IN($botwhere)"; + "WHERE rc_user_text IN($botwhere) " . + "AND rc_timestamp > " . $dbw->addQuotes( $dbw->timestamp( $this->cutoffFrom ) ) . ' ' . + "AND rc_timestamp < " . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) ); $dbw->query( $sql2 ); } } @@ -276,7 +311,9 @@ class RebuildRecentchanges extends Maintenance { if ( !empty( $patrolusers ) ) { $patrolwhere = implode( ',', $patrolusers ); $sql2 = "UPDATE $recentchanges SET rc_patrolled=1 " . - "WHERE rc_user_text IN($patrolwhere)"; + "WHERE rc_user_text IN($patrolwhere) " . + "AND rc_timestamp > " . $dbw->addQuotes( $dbw->timestamp( $this->cutoffFrom ) ) . ' ' . + "AND rc_timestamp < " . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) ); $dbw->query( $sql2 ); } } @@ -298,6 +335,8 @@ class RebuildRecentchanges extends Maintenance { 'ls_log_id = log_id', 'ls_field' => 'associated_rev_id', 'log_type' => 'upload', + 'log_timestamp > ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffFrom ) ), + 'log_timestamp < ' . $dbw->addQuotes( $dbw->timestamp( $this->cutoffTo ) ), ], __METHOD__ ); -- 2.20.1