[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Fills the rev_sha1 and ar_sha1 columns of revision 4 * and archive tables for revisions created before MW 1.19. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * http://www.gnu.org/copyleft/gpl.html 20 * 21 * @file 22 * @ingroup Maintenance 23 */ 24 25 require_once __DIR__ . '/Maintenance.php'; 26 27 /** 28 * Maintenance script that fills the rev_sha1 and ar_sha1 columns of revision 29 * and archive tables for revisions created before MW 1.19. 30 * 31 * @ingroup Maintenance 32 */ 33 class PopulateRevisionSha1 extends LoggedUpdateMaintenance { 34 public function __construct() { 35 parent::__construct(); 36 $this->mDescription = "Populates the rev_sha1 and ar_sha1 fields"; 37 $this->setBatchSize( 200 ); 38 } 39 40 protected function getUpdateKey() { 41 return 'populate rev_sha1'; 42 } 43 44 protected function doDBUpdates() { 45 $db = $this->getDB( DB_MASTER ); 46 47 if ( !$db->tableExists( 'revision' ) ) { 48 $this->error( "revision table does not exist", true ); 49 } elseif ( !$db->tableExists( 'archive' ) ) { 50 $this->error( "archive table does not exist", true ); 51 } elseif ( !$db->fieldExists( 'revision', 'rev_sha1', __METHOD__ ) ) { 52 $this->output( "rev_sha1 column does not exist\n\n", true ); 53 54 return false; 55 } 56 57 $this->output( "Populating rev_sha1 column\n" ); 58 $rc = $this->doSha1Updates( 'revision', 'rev_id', 'rev' ); 59 60 $this->output( "Populating ar_sha1 column\n" ); 61 $ac = $this->doSha1Updates( 'archive', 'ar_rev_id', 'ar' ); 62 $this->output( "Populating ar_sha1 column legacy rows\n" ); 63 $ac += $this->doSha1LegacyUpdates(); 64 65 $this->output( "rev_sha1 and ar_sha1 population complete " 66 . "[$rc revision rows, $ac archive rows].\n" ); 67 68 return true; 69 } 70 71 /** 72 * @param string $table 73 * @param string $idCol 74 * @param string $prefix 75 * @return int Rows changed 76 */ 77 protected function doSha1Updates( $table, $idCol, $prefix ) { 78 $db = $this->getDB( DB_MASTER ); 79 $start = $db->selectField( $table, "MIN($idCol)", false, __METHOD__ ); 80 $end = $db->selectField( $table, "MAX($idCol)", false, __METHOD__ ); 81 if ( !$start || !$end ) { 82 $this->output( "...$table table seems to be empty.\n" ); 83 84 return 0; 85 } 86 87 $count = 0; 88 # Do remaining chunk 89 $end += $this->mBatchSize - 1; 90 $blockStart = $start; 91 $blockEnd = $start + $this->mBatchSize - 1; 92 while ( $blockEnd <= $end ) { 93 $this->output( "...doing $idCol from $blockStart to $blockEnd\n" ); 94 $cond = "$idCol BETWEEN $blockStart AND $blockEnd 95 AND $idCol IS NOT NULL AND {$prefix}_sha1 = ''"; 96 $res = $db->select( $table, '*', $cond, __METHOD__ ); 97 98 $db->begin( __METHOD__ ); 99 foreach ( $res as $row ) { 100 if ( $this->upgradeRow( $row, $table, $idCol, $prefix ) ) { 101 $count++; 102 } 103 } 104 $db->commit( __METHOD__ ); 105 106 $blockStart += $this->mBatchSize; 107 $blockEnd += $this->mBatchSize; 108 wfWaitForSlaves(); 109 } 110 111 return $count; 112 } 113 114 /** 115 * @return int 116 */ 117 protected function doSha1LegacyUpdates() { 118 $count = 0; 119 $db = $this->getDB( DB_MASTER ); 120 $res = $db->select( 'archive', '*', 121 array( 'ar_rev_id IS NULL', 'ar_sha1' => '' ), __METHOD__ ); 122 123 $updateSize = 0; 124 $db->begin( __METHOD__ ); 125 foreach ( $res as $row ) { 126 if ( $this->upgradeLegacyArchiveRow( $row ) ) { 127 ++$count; 128 } 129 if ( ++$updateSize >= 100 ) { 130 $updateSize = 0; 131 $db->commit( __METHOD__ ); 132 $this->output( "Commited row with ar_timestamp={$row->ar_timestamp}\n" ); 133 wfWaitForSlaves(); 134 $db->begin( __METHOD__ ); 135 } 136 } 137 $db->commit( __METHOD__ ); 138 139 return $count; 140 } 141 142 /** 143 * @param stdClass $row 144 * @param string $table 145 * @param string $idCol 146 * @param string $prefix 147 * @return bool 148 */ 149 protected function upgradeRow( $row, $table, $idCol, $prefix ) { 150 $db = $this->getDB( DB_MASTER ); 151 try { 152 $rev = ( $table === 'archive' ) 153 ? Revision::newFromArchiveRow( $row ) 154 : new Revision( $row ); 155 $text = $rev->getSerializedData(); 156 } catch ( MWException $e ) { 157 $this->output( "Data of revision with {$idCol}={$row->$idCol} unavailable!\n" ); 158 159 return false; // bug 22624? 160 } 161 if ( !is_string( $text ) ) { 162 # This should not happen, but sometimes does (bug 20757) 163 $this->output( "Data of revision with {$idCol}={$row->$idCol} unavailable!\n" ); 164 165 return false; 166 } else { 167 $db->update( $table, 168 array( "{$prefix}_sha1" => Revision::base36Sha1( $text ) ), 169 array( $idCol => $row->$idCol ), 170 __METHOD__ 171 ); 172 173 return true; 174 } 175 } 176 177 /** 178 * @param stdClass $row 179 * @return bool 180 */ 181 protected function upgradeLegacyArchiveRow( $row ) { 182 $db = $this->getDB( DB_MASTER ); 183 try { 184 $rev = Revision::newFromArchiveRow( $row ); 185 } catch ( MWException $e ) { 186 $this->output( "Text of revision with timestamp {$row->ar_timestamp} unavailable!\n" ); 187 188 return false; // bug 22624? 189 } 190 $text = $rev->getSerializedData(); 191 if ( !is_string( $text ) ) { 192 # This should not happen, but sometimes does (bug 20757) 193 $this->output( "Data of revision with timestamp {$row->ar_timestamp} unavailable!\n" ); 194 195 return false; 196 } else { 197 # Archive table as no PK, but (NS,title,time) should be near unique. 198 # Any duplicates on those should also have duplicated text anyway. 199 $db->update( 'archive', 200 array( 'ar_sha1' => Revision::base36Sha1( $text ) ), 201 array( 202 'ar_namespace' => $row->ar_namespace, 203 'ar_title' => $row->ar_title, 204 'ar_timestamp' => $row->ar_timestamp, 205 'ar_len' => $row->ar_len // extra sanity 206 ), 207 __METHOD__ 208 ); 209 210 return true; 211 } 212 } 213 } 214 215 $maintClass = "PopulateRevisionSha1"; 216 require_once RUN_MAINTENANCE_IF_MAIN;
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |