Index: trunk/phase3/maintenance/userDupes.inc |
— | — | @@ -33,21 +33,30 @@ |
34 | 34 | var $reassigned; |
35 | 35 | var $trimmed; |
36 | 36 | var $failed; |
| 37 | + private $outputCallback; |
37 | 38 | |
38 | | - function UserDupes( &$database ) { |
39 | | - $this->db =& $database; |
| 39 | + function __construct( &$database, $outputCallback ) { |
| 40 | + $this->db = $database; |
| 41 | + $this->outputCallback = $outputCallback; |
40 | 42 | } |
41 | 43 | |
42 | 44 | /** |
| 45 | + * Output some text via the output callback provided |
| 46 | + * @param $str String Text to print |
| 47 | + */ |
| 48 | + private function out( $str ) { |
| 49 | + call_user_func( $this->outputCallback, $str ); |
| 50 | + } |
| 51 | + |
| 52 | + /** |
43 | 53 | * Check if this database's user table has already had a unique |
44 | 54 | * user_name index applied. |
45 | 55 | * @return bool |
46 | 56 | */ |
47 | 57 | function hasUniqueIndex() { |
48 | | - $fname = 'UserDupes::hasUniqueIndex'; |
49 | | - $info = $this->db->indexInfo( 'user', 'user_name', $fname ); |
| 58 | + $info = $this->db->indexInfo( 'user', 'user_name', __METHOD__ ); |
50 | 59 | if ( !$info ) { |
51 | | - wfOut( "WARNING: doesn't seem to have user_name index at all!\n" ); |
| 60 | + $this->out( "WARNING: doesn't seem to have user_name index at all!\n" ); |
52 | 61 | return false; |
53 | 62 | } |
54 | 63 | |
— | — | @@ -94,11 +103,11 @@ |
95 | 104 | |
96 | 105 | $this->lock(); |
97 | 106 | |
98 | | - wfOut( "Checking for duplicate accounts...\n" ); |
| 107 | + $this->out( "Checking for duplicate accounts...\n" ); |
99 | 108 | $dupes = $this->getDupes(); |
100 | 109 | $count = count( $dupes ); |
101 | 110 | |
102 | | - wfOut( "Found $count accounts with duplicate records on " . wfWikiID() . ".\n" ); |
| 111 | + $this->out( "Found $count accounts with duplicate records on " . wfWikiID() . ".\n" ); |
103 | 112 | $this->trimmed = 0; |
104 | 113 | $this->reassigned = 0; |
105 | 114 | $this->failed = 0; |
— | — | @@ -108,34 +117,34 @@ |
109 | 118 | |
110 | 119 | $this->unlock(); |
111 | 120 | |
112 | | - wfOut( "\n" ); |
| 121 | + $this->out( "\n" ); |
113 | 122 | |
114 | 123 | if ( $this->reassigned > 0 ) { |
115 | 124 | if ( $doDelete ) { |
116 | | - wfOut( "$this->reassigned duplicate accounts had edits reassigned to a canonical record id.\n" ); |
| 125 | + $this->out( "$this->reassigned duplicate accounts had edits reassigned to a canonical record id.\n" ); |
117 | 126 | } else { |
118 | | - wfOut( "$this->reassigned duplicate accounts need to have edits reassigned.\n" ); |
| 127 | + $this->out( "$this->reassigned duplicate accounts need to have edits reassigned.\n" ); |
119 | 128 | } |
120 | 129 | } |
121 | 130 | |
122 | 131 | if ( $this->trimmed > 0 ) { |
123 | 132 | if ( $doDelete ) { |
124 | | - wfOut( "$this->trimmed duplicate user records were deleted from " . wfWikiID() . ".\n" ); |
| 133 | + $this->out( "$this->trimmed duplicate user records were deleted from " . wfWikiID() . ".\n" ); |
125 | 134 | } else { |
126 | | - wfOut( "$this->trimmed duplicate user accounts were found on " . wfWikiID() . " which can be removed safely.\n" ); |
| 135 | + $this->out( "$this->trimmed duplicate user accounts were found on " . wfWikiID() . " which can be removed safely.\n" ); |
127 | 136 | } |
128 | 137 | } |
129 | 138 | |
130 | 139 | if ( $this->failed > 0 ) { |
131 | | - wfOut( "Something terribly awry; $this->failed duplicate accounts were not removed.\n" ); |
| 140 | + $this->out( "Something terribly awry; $this->failed duplicate accounts were not removed.\n" ); |
132 | 141 | return false; |
133 | 142 | } |
134 | 143 | |
135 | 144 | if ( $this->trimmed == 0 || $doDelete ) { |
136 | | - wfOut( "It is now safe to apply the unique index on user_name.\n" ); |
| 145 | + $this->out( "It is now safe to apply the unique index on user_name.\n" ); |
137 | 146 | return true; |
138 | 147 | } else { |
139 | | - wfOut( "Run this script again with the --fix option to automatically delete them.\n" ); |
| 148 | + $this->out( "Run this script again with the --fix option to automatically delete them.\n" ); |
140 | 149 | return false; |
141 | 150 | } |
142 | 151 | } |
— | — | @@ -145,7 +154,6 @@ |
146 | 155 | * @access private |
147 | 156 | */ |
148 | 157 | function lock() { |
149 | | - $fname = 'UserDupes::lock'; |
150 | 158 | if ( $this->newSchema() ) { |
151 | 159 | $set = array( 'user', 'revision' ); |
152 | 160 | } else { |
— | — | @@ -154,7 +162,7 @@ |
155 | 163 | $names = array_map( array( $this, 'lockTable' ), $set ); |
156 | 164 | $tables = implode( ',', $names ); |
157 | 165 | |
158 | | - $this->db->query( "LOCK TABLES $tables", $fname ); |
| 166 | + $this->db->query( "LOCK TABLES $tables", __METHOD__ ); |
159 | 167 | } |
160 | 168 | |
161 | 169 | function lockTable( $table ) { |
— | — | @@ -173,8 +181,7 @@ |
174 | 182 | * @access private |
175 | 183 | */ |
176 | 184 | function unlock() { |
177 | | - $fname = 'UserDupes::unlock'; |
178 | | - $this->db->query( "UNLOCK TABLES", $fname ); |
| 185 | + $this->db->query( "UNLOCK TABLES", __METHOD__ ); |
179 | 186 | } |
180 | 187 | |
181 | 188 | /** |
— | — | @@ -183,13 +190,12 @@ |
184 | 191 | * @access private |
185 | 192 | */ |
186 | 193 | function getDupes() { |
187 | | - $fname = 'UserDupes::listDupes'; |
188 | 194 | $user = $this->db->tableName( 'user' ); |
189 | 195 | $result = $this->db->query( |
190 | 196 | "SELECT user_name,COUNT(*) AS n |
191 | 197 | FROM $user |
192 | 198 | GROUP BY user_name |
193 | | - HAVING n > 1", $fname ); |
| 199 | + HAVING n > 1", __METHOD__ ); |
194 | 200 | |
195 | 201 | $list = array(); |
196 | 202 | foreach ( $result as $row ) { |
— | — | @@ -207,44 +213,43 @@ |
208 | 214 | * @access private |
209 | 215 | */ |
210 | 216 | function examine( $name, $doDelete ) { |
211 | | - $fname = 'UserDupes::listDupes'; |
212 | 217 | $result = $this->db->select( 'user', |
213 | 218 | array( 'user_id' ), |
214 | 219 | array( 'user_name' => $name ), |
215 | | - $fname ); |
| 220 | + __METHOD__ ); |
216 | 221 | |
217 | 222 | $firstRow = $this->db->fetchObject( $result ); |
218 | 223 | $firstId = $firstRow->user_id; |
219 | | - wfOut( "Record that will be used for '$name' is user_id=$firstId\n" ); |
| 224 | + $this->out( "Record that will be used for '$name' is user_id=$firstId\n" ); |
220 | 225 | |
221 | 226 | foreach ( $result as $row ) { |
222 | 227 | $dupeId = $row->user_id; |
223 | | - wfOut( "... dupe id $dupeId: " ); |
| 228 | + $this->out( "... dupe id $dupeId: " ); |
224 | 229 | $edits = $this->editCount( $dupeId ); |
225 | 230 | if ( $edits > 0 ) { |
226 | 231 | $this->reassigned++; |
227 | | - wfOut( "has $edits edits! " ); |
| 232 | + $this->out( "has $edits edits! " ); |
228 | 233 | if ( $doDelete ) { |
229 | 234 | $this->reassignEdits( $dupeId, $firstId ); |
230 | 235 | $newEdits = $this->editCount( $dupeId ); |
231 | 236 | if ( $newEdits == 0 ) { |
232 | | - wfOut( "confirmed cleaned. " ); |
| 237 | + $this->out( "confirmed cleaned. " ); |
233 | 238 | } else { |
234 | 239 | $this->failed++; |
235 | | - wfOut( "WARNING! $newEdits remaining edits for $dupeId; NOT deleting user.\n" ); |
| 240 | + $this->out( "WARNING! $newEdits remaining edits for $dupeId; NOT deleting user.\n" ); |
236 | 241 | continue; |
237 | 242 | } |
238 | 243 | } else { |
239 | | - wfOut( "(will need to reassign edits on fix)" ); |
| 244 | + $this->out( "(will need to reassign edits on fix)" ); |
240 | 245 | } |
241 | 246 | } else { |
242 | | - wfOut( "ok, no edits. " ); |
| 247 | + $this->out( "ok, no edits. " ); |
243 | 248 | } |
244 | 249 | $this->trimmed++; |
245 | 250 | if ( $doDelete ) { |
246 | 251 | $this->trimAccount( $dupeId ); |
247 | 252 | } |
248 | | - wfOut( "\n" ); |
| 253 | + $this->out( "\n" ); |
249 | 254 | } |
250 | 255 | } |
251 | 256 | |
— | — | @@ -274,12 +279,11 @@ |
275 | 280 | * @access private |
276 | 281 | */ |
277 | 282 | function editCountOn( $table, $field, $userid ) { |
278 | | - $fname = 'UserDupes::editCountOn'; |
279 | 283 | return intval( $this->db->selectField( |
280 | 284 | $table, |
281 | 285 | 'COUNT(*)', |
282 | 286 | array( $field => $userid ), |
283 | | - $fname ) ); |
| 287 | + __METHOD__ ) ); |
284 | 288 | } |
285 | 289 | |
286 | 290 | /** |
— | — | @@ -304,13 +308,12 @@ |
305 | 309 | * @access private |
306 | 310 | */ |
307 | 311 | function reassignEditsOn( $table, $field, $from, $to ) { |
308 | | - $fname = 'UserDupes::reassignEditsOn'; |
309 | | - wfOut( "reassigning on $table... " ); |
| 312 | + $this->out( "reassigning on $table... " ); |
310 | 313 | $this->db->update( $table, |
311 | 314 | array( $field => $to ), |
312 | 315 | array( $field => $from ), |
313 | | - $fname ); |
314 | | - wfOut( "ok. " ); |
| 316 | + __METHOD__ ); |
| 317 | + $this->out( "ok. " ); |
315 | 318 | } |
316 | 319 | |
317 | 320 | /** |
— | — | @@ -319,10 +322,9 @@ |
320 | 323 | * @access private |
321 | 324 | */ |
322 | 325 | function trimAccount( $userid ) { |
323 | | - $fname = 'UserDupes::trimAccount'; |
324 | | - wfOut( "deleting..." ); |
325 | | - $this->db->delete( 'user', array( 'user_id' => $userid ), $fname ); |
326 | | - wfOut( " ok" ); |
| 326 | + $this->out( "deleting..." ); |
| 327 | + $this->db->delete( 'user', array( 'user_id' => $userid ), __METHOD__ ); |
| 328 | + $this->out( " ok" ); |
327 | 329 | } |
328 | 330 | |
329 | 331 | } |
Index: trunk/phase3/maintenance/upgrade1_5.php |
— | — | @@ -632,9 +632,13 @@ |
633 | 633 | $this->log( 'Done with links.' ); |
634 | 634 | } |
635 | 635 | |
| 636 | + function userDupeCallback( $str ) { |
| 637 | + echo $str; |
| 638 | + } |
| 639 | + |
636 | 640 | function upgradeUser() { |
637 | 641 | // Apply unique index, if necessary: |
638 | | - $duper = new UserDupes( $this->dbw ); |
| 642 | + $duper = new UserDupes( $this->dbw, array( $this, 'userDupeCallback' ) ); |
639 | 643 | if ( $duper->hasUniqueIndex() ) { |
640 | 644 | $this->log( "Already have unique user_name index." ); |
641 | 645 | } else { |
Index: trunk/phase3/includes/installer/DatabaseUpdater.php |
— | — | @@ -96,7 +96,7 @@ |
97 | 97 | * |
98 | 98 | * @param $str String: Text to output |
99 | 99 | */ |
100 | | - protected function output( $str ) { |
| 100 | + public function output( $str ) { |
101 | 101 | if ( $this->maintenance->isQuiet() ) { |
102 | 102 | return; |
103 | 103 | } |
Index: trunk/phase3/includes/installer/MysqlUpdater.php |
— | — | @@ -518,7 +518,7 @@ |
519 | 519 | } |
520 | 520 | |
521 | 521 | protected function doUserUniqueUpdate() { |
522 | | - $duper = new UserDupes( $this->db ); |
| 522 | + $duper = new UserDupes( $this->db, array( $this, 'output' ) ); |
523 | 523 | if ( $duper->hasUniqueIndex() ) { |
524 | 524 | $this->output( "...already have unique user_name index.\n" ); |
525 | 525 | return; |