MediaWiki
REL1_19
|
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 );