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