MediaWiki  REL1_19
populateParentId.php
Go to the documentation of this file.
00001 <?php
00025 require_once( dirname( __FILE__ ) . '/Maintenance.php' );
00026 
00027 class PopulateParentId extends LoggedUpdateMaintenance {
00028         public function __construct() {
00029                 parent::__construct();
00030                 $this->mDescription = "Populates rev_parent_id";
00031         }
00032 
00033         protected function getUpdateKey() {
00034                 return 'populate rev_parent_id';
00035         }
00036 
00037         protected function updateSkippedMessage() {
00038                 return 'rev_parent_id column of revision table already populated.';
00039         }
00040 
00041         protected function doDBUpdates() {
00042                 $db = wfGetDB( DB_MASTER );
00043                 if ( !$db->tableExists( 'revision' ) ) {
00044                         $this->error( "revision table does not exist" );
00045                         return false;
00046                 }
00047                 $this->output( "Populating rev_parent_id column\n" );
00048                 $start = $db->selectField( 'revision', 'MIN(rev_id)', false, __FUNCTION__ );
00049                 $end = $db->selectField( 'revision', 'MAX(rev_id)', false, __FUNCTION__ );
00050                 if ( is_null( $start ) || is_null( $end ) ) {
00051                         $this->output( "...revision table seems to be empty, nothing to do.\n" );
00052                         return true;
00053                 }
00054                 # Do remaining chunk
00055                 $blockStart = intval( $start );
00056                 $blockEnd = intval( $start ) + $this->mBatchSize - 1;
00057                 $count = 0;
00058                 $changed = 0;
00059                 while ( $blockStart <= $end ) {
00060                         $this->output( "...doing rev_id from $blockStart to $blockEnd\n" );
00061                         $cond = "rev_id BETWEEN $blockStart AND $blockEnd";
00062                         $res = $db->select( 'revision',
00063                                 array( 'rev_id', 'rev_page', 'rev_timestamp', 'rev_parent_id' ),
00064                                 $cond, __METHOD__ );
00065                         # Go through and update rev_parent_id from these rows.
00066                         # Assume that the previous revision of the title was
00067                         # the original previous revision of the title when the
00068                         # edit was made...
00069                         foreach ( $res as $row ) {
00070                                 # First, check rows with the same timestamp other than this one
00071                                 # with a smaller rev ID. The highest ID "wins". This avoids loops
00072                                 # as timestamp can only decrease and never loops with IDs (from parent to parent)
00073                                 $previousID = $db->selectField( 'revision', 'rev_id',
00074                                         array( 'rev_page' => $row->rev_page, 'rev_timestamp' => $row->rev_timestamp,
00075                                                 "rev_id < " . intval( $row->rev_id ) ),
00076                                         __METHOD__,
00077                                         array( 'ORDER BY' => 'rev_id DESC' ) );
00078                                 # If there are none, check the the highest ID with a lower timestamp
00079                                 if ( !$previousID ) {
00080                                         # Get the highest older timestamp
00081                                         $lastTimestamp = $db->selectField( 'revision', 'rev_timestamp',
00082                                                 array( 'rev_page' => $row->rev_page, "rev_timestamp < " . $db->addQuotes( $row->rev_timestamp ) ),
00083                                                 __METHOD__,
00084                                                 array( 'ORDER BY' => 'rev_timestamp DESC' ) );
00085                                         # If there is one, let the highest rev ID win
00086                                         if ( $lastTimestamp ) {
00087                                                 $previousID = $db->selectField( 'revision', 'rev_id',
00088                                                         array( 'rev_page' => $row->rev_page, 'rev_timestamp' => $lastTimestamp ),
00089                                                         __METHOD__,
00090                                                         array( 'ORDER BY' => 'rev_id DESC' ) );
00091                                         }
00092                                 }
00093                                 $previousID = intval( $previousID );
00094                                 if ( $previousID != $row->rev_parent_id )
00095                                         $changed++;
00096                                 # Update the row...
00097                                 $db->update( 'revision',
00098                                         array( 'rev_parent_id' => $previousID ),
00099                                         array( 'rev_id' => $row->rev_id ),
00100                                         __METHOD__ );
00101                                 $count++;
00102                         }
00103                         $blockStart += $this->mBatchSize;
00104                         $blockEnd += $this->mBatchSize;
00105                         wfWaitForSlaves();
00106                 }
00107                 $this->output( "rev_parent_id population complete ... {$count} rows [{$changed} changed]\n" );
00108                 return true;
00109         }
00110 }
00111 
00112 $maintClass = "PopulateParentId";
00113 require_once( RUN_MAINTENANCE_IF_MAIN );