Index: branches/maintenance-work/maintenance/populateLogUsertext.inc |
— | — | @@ -1,54 +0,0 @@ |
2 | | -<?php
|
3 | | -/**
|
4 | | - * Makes the required database updates for the log_user_text column
|
5 | | - *
|
6 | | - * Run via update.php or directly through populateLogUsertext.php
|
7 | | - *
|
8 | | - * @file
|
9 | | - * @ingroup Maintenance
|
10 | | - */
|
11 | | -
|
12 | | -define( 'LOG_USERTEXT_BATCH_SIZE', 100 );
|
13 | | -
|
14 | | -function populate_logusertext( $db ) {
|
15 | | - $start = $db->selectField( 'logging', 'MIN(log_id)', false, __FUNCTION__ );
|
16 | | - if( !$start ) {
|
17 | | - echo "Nothing to do.\n";
|
18 | | - return true;
|
19 | | - }
|
20 | | - $end = $db->selectField( 'logging', 'MAX(log_id)', false, __FUNCTION__ );
|
21 | | -
|
22 | | - # Do remaining chunk
|
23 | | - $end += LOG_USERTEXT_BATCH_SIZE - 1;
|
24 | | - $blockStart = $start;
|
25 | | - $blockEnd = $start + LOG_USERTEXT_BATCH_SIZE - 1;
|
26 | | - while( $blockEnd <= $end ) {
|
27 | | - echo "...doing log_id from $blockStart to $blockEnd\n";
|
28 | | - $cond = "log_id BETWEEN $blockStart AND $blockEnd AND log_user = user_id";
|
29 | | - $res = $db->select( array('logging','user'),
|
30 | | - array('log_id','user_name'), $cond, __FUNCTION__ );
|
31 | | - $batch = array();
|
32 | | - $db->begin();
|
33 | | - while( $row = $db->fetchObject( $res ) ) {
|
34 | | - $db->update( 'logging', array('log_user_text' => $row->user_name),
|
35 | | - array('log_id' => $row->log_id), __FUNCTION__ );
|
36 | | - }
|
37 | | - $db->commit();
|
38 | | - $blockStart += LOG_USERTEXT_BATCH_SIZE;
|
39 | | - $blockEnd += LOG_USERTEXT_BATCH_SIZE;
|
40 | | - wfWaitForSlaves( 5 );
|
41 | | - }
|
42 | | - if( $db->insert(
|
43 | | - 'updatelog',
|
44 | | - array( 'ul_key' => 'populate log_usertext' ),
|
45 | | - __FUNCTION__,
|
46 | | - 'IGNORE'
|
47 | | - )
|
48 | | - ) {
|
49 | | - wfOut( "log_usertext population complete.\n" );
|
50 | | - return true;
|
51 | | - } else {
|
52 | | - wfOut( "Could not insert log_usertext population row.\n" );
|
53 | | - return false;
|
54 | | - }
|
55 | | -}
|
Index: branches/maintenance-work/maintenance/renamewiki.php |
— | — | @@ -7,56 +7,62 @@ |
8 | 8 | * @ingroup Maintenance |
9 | 9 | */ |
10 | 10 | |
11 | | -require_once( "commandLine.inc" ); |
| 11 | +require_once( "Maintenance.php" ); |
12 | 12 | |
13 | | -if ( count( $args ) != 2 ) { |
14 | | - wfDie( "Rename external storage dbs and leave a new one...\n" . |
15 | | - "Usage: php renamewiki.php <olddb> <newdb>\n" ); |
16 | | -} |
| 13 | +class RenameWiki extends Maintenance { |
| 14 | + public function __construct() { |
| 15 | + parent::__construct(); |
| 16 | + $this->mDescription = "Rename external storage dbs and leave a new one"; |
| 17 | + $this->addArgs( array( 'olddb', 'newdb' ) ); |
| 18 | + } |
17 | 19 | |
18 | | -list( $from, $to ) = $args; |
| 20 | + public function execute() { |
| 21 | + global $wgDefaultExternalStore; |
19 | 22 | |
20 | | -echo "Renaming blob tables in ES from $from to $to...\n"; |
21 | | -echo "Sleeping 5 seconds..."; |
22 | | -sleep(5); |
23 | | -echo "\n"; |
| 23 | + # Setup |
| 24 | + $from = $this->getArg( 0 ); |
| 25 | + $to = $this->getArg( 1 ); |
| 26 | + $this->output( "Renaming blob tables in ES from $from to $to...\n" ); |
| 27 | + $this->output( "Sleeping 5 seconds...\n" ); |
| 28 | + sleep(5); |
24 | 29 | |
25 | | -$maintenance = "$IP/maintenance"; |
| 30 | + # Initialise external storage |
| 31 | + if ( is_array( $wgDefaultExternalStore ) ) { |
| 32 | + $stores = $wgDefaultExternalStore; |
| 33 | + } elseif ( $wgDefaultExternalStore ) { |
| 34 | + $stores = array( $wgDefaultExternalStore ); |
| 35 | + } else { |
| 36 | + $stores = array(); |
| 37 | + } |
26 | 38 | |
27 | | -# Initialise external storage |
28 | | -if ( is_array( $wgDefaultExternalStore ) ) { |
29 | | - $stores = $wgDefaultExternalStore; |
30 | | -} elseif ( $wgDefaultExternalStore ) { |
31 | | - $stores = array( $wgDefaultExternalStore ); |
32 | | -} else { |
33 | | - $stores = array(); |
34 | | -} |
35 | | -if ( count( $stores ) ) { |
36 | | - require_once( 'ExternalStoreDB.php' ); |
37 | | - print "Initialising external storage $store...\n"; |
38 | | - global $wgDBuser, $wgDBpassword, $wgExternalServers; |
39 | | - foreach ( $stores as $storeURL ) { |
40 | | - $m = array(); |
41 | | - if ( !preg_match( '!^DB://(.*)$!', $storeURL, $m ) ) { |
42 | | - continue; |
| 39 | + if ( count( $stores ) ) { |
| 40 | + $this->output( "Initialising external storage $store...\n" ); |
| 41 | + global $wgDBuser, $wgDBpassword, $wgExternalServers; |
| 42 | + foreach ( $stores as $storeURL ) { |
| 43 | + $m = array(); |
| 44 | + if ( !preg_match( '!^DB://(.*)$!', $storeURL, $m ) ) { |
| 45 | + continue; |
| 46 | + } |
| 47 | + |
| 48 | + $cluster = $m[1]; |
| 49 | + |
| 50 | + # Hack |
| 51 | + $wgExternalServers[$cluster][0]['user'] = $wgDBuser; |
| 52 | + $wgExternalServers[$cluster][0]['password'] = $wgDBpassword; |
| 53 | + |
| 54 | + $store = new ExternalStoreDB; |
| 55 | + $extdb =& $store->getMaster( $cluster ); |
| 56 | + $extdb->query( "SET table_type=InnoDB" ); |
| 57 | + $extdb->query( "CREATE DATABASE {$to}" ); |
| 58 | + $extdb->query( "ALTER TABLE {$from}.blobs RENAME TO {$to}.blobs" ); |
| 59 | + $extdb->selectDB( $from ); |
| 60 | + $extdb->sourceFile( $this->getDir() . '/storage/blobs.sql' ); |
| 61 | + $extdb->immediateCommit(); |
| 62 | + } |
43 | 63 | } |
44 | | - |
45 | | - $cluster = $m[1]; |
46 | | - |
47 | | - # Hack |
48 | | - $wgExternalServers[$cluster][0]['user'] = $wgDBuser; |
49 | | - $wgExternalServers[$cluster][0]['password'] = $wgDBpassword; |
50 | | - |
51 | | - $store = new ExternalStoreDB; |
52 | | - $extdb =& $store->getMaster( $cluster ); |
53 | | - $extdb->query( "SET table_type=InnoDB" ); |
54 | | - $extdb->query( "CREATE DATABASE {$to}" ); |
55 | | - $extdb->query( "ALTER TABLE {$from}.blobs RENAME TO {$to}.blobs" ); |
56 | | - $extdb->selectDB( $from ); |
57 | | - dbsource( "$maintenance/storage/blobs.sql", $extdb ); |
58 | | - $extdb->immediateCommit(); |
| 64 | + $this->output( "done.\n" ); |
59 | 65 | } |
60 | 66 | } |
61 | 67 | |
62 | | -echo "done.\n"; |
63 | | - |
| 68 | +$maintClass = "RenameWiki"; |
| 69 | +require_once( DO_MAINTENANCE ); |
Index: branches/maintenance-work/maintenance/updaters.inc |
— | — | @@ -215,7 +215,7 @@ |
216 | 216 | wfOut( "...can't move table $from to $to, $to already exists.\n" ); |
217 | 217 | } else { |
218 | 218 | wfOut( "Moving table $from to $to..." ); |
219 | | - dbsource( archive($patch), $wgDatabase ); |
| 219 | + $wgDatabase->sourceFile( archive($patch) ); |
220 | 220 | wfOut( "ok\n" ); |
221 | 221 | } |
222 | 222 | } else { |
— | — | @@ -232,9 +232,9 @@ |
233 | 233 | } else { |
234 | 234 | wfOut( "Creating $name table..." ); |
235 | 235 | if( $fullpath ) { |
236 | | - dbsource( $patch, $wgDatabase ); |
| 236 | + $wgDatabase->sourceFile( $patch ); |
237 | 237 | } else { |
238 | | - dbsource( archive($patch), $wgDatabase ); |
| 238 | + $wgDatabase->sourceFile( archive($patch) ); |
239 | 239 | } |
240 | 240 | wfOut( "ok\n" ); |
241 | 241 | } |
— | — | @@ -249,9 +249,9 @@ |
250 | 250 | } else { |
251 | 251 | wfOut( "Adding $field field to table $table..." ); |
252 | 252 | if( $fullpath ) { |
253 | | - dbsource( $patch, $wgDatabase ); |
| 253 | + $wgDatabase->sourceFile( $patch ); |
254 | 254 | } else { |
255 | | - dbsource( archive($patch), $wgDatabase ); |
| 255 | + $wgDatabase->sourceFile( archive($patch) ); |
256 | 256 | } |
257 | 257 | wfOut( "ok\n" ); |
258 | 258 | } |
— | — | @@ -264,9 +264,9 @@ |
265 | 265 | } else { |
266 | 266 | wfOut( "Adding $index key to table $table... " ); |
267 | 267 | if( $fullpath ) { |
268 | | - dbsource( $patch, $wgDatabase ); |
| 268 | + $wgDatabase->sourceFile( $patch ); |
269 | 269 | } else { |
270 | | - dbsource( archive($patch), $wgDatabase ); |
| 270 | + $wgDatabase->sourceFile( archive($patch) ); |
271 | 271 | } |
272 | 272 | wfOut( "ok\n" ); |
273 | 273 | } |
— | — | @@ -280,10 +280,10 @@ |
281 | 281 | return true; |
282 | 282 | } |
283 | 283 | wfOut( "Creating interwiki table: " ); |
284 | | - dbsource( archive("patch-interwiki.sql") ); |
| 284 | + $wgDatabase->sourceFile( archive("patch-interwiki.sql") ); |
285 | 285 | wfOut( "ok\n" ); |
286 | 286 | wfOut( "Adding default interwiki definitions: " ); |
287 | | - dbsource( "$IP/maintenance/interwiki.sql" ); |
| 287 | + $wgDatabase->sourceFile( "$IP/maintenance/interwiki.sql" ); |
288 | 288 | wfOut( "ok\n" ); |
289 | 289 | } |
290 | 290 | |
— | — | @@ -293,7 +293,7 @@ |
294 | 294 | $meta = $wgDatabase->fieldInfo( "recentchanges", "rc_timestamp" ); |
295 | 295 | if( !$meta->isMultipleKey() ) { |
296 | 296 | wfOut( "Updating indexes to 20031107: " ); |
297 | | - dbsource( archive("patch-indexes.sql") ); |
| 297 | + $wgDatabase->sourceFile( archive("patch-indexes.sql") ); |
298 | 298 | wfOut( "ok\n" ); |
299 | 299 | return true; |
300 | 300 | } |
— | — | @@ -307,7 +307,7 @@ |
308 | 308 | $meta = $wgDatabase->fieldInfo( "image", "img_major_mime" ); |
309 | 309 | if( !$meta->isMultipleKey() ) { |
310 | 310 | wfOut( "Updating indexes to 20050912: " ); |
311 | | - dbsource( archive("patch-mimesearch-indexes.sql") ); |
| 311 | + $wgDatabase->sourceFile( archive("patch-mimesearch-indexes.sql") ); |
312 | 312 | wfOut( "ok\n" ); |
313 | 313 | return true; |
314 | 314 | } |
— | — | @@ -321,7 +321,7 @@ |
322 | 322 | wfOut( "...image primary key already set.\n" ); |
323 | 323 | } else { |
324 | 324 | wfOut( "Making img_name the primary key... " ); |
325 | | - dbsource( archive("patch-image_name_primary.sql"), $wgDatabase ); |
| 325 | + $wgDatabase->sourceFile( archive("patch-image_name_primary.sql") ); |
326 | 326 | wfOut( "ok\n" ); |
327 | 327 | } |
328 | 328 | } |
— | — | @@ -332,7 +332,7 @@ |
333 | 333 | wfOut( "...timestamp key on logging already exists.\n" ); |
334 | 334 | } else { |
335 | 335 | wfOut( "Adding timestamp key on logging table... " ); |
336 | | - dbsource( archive("patch-logging-times-index.sql"), $wgDatabase ); |
| 336 | + $wgDatabase->sourceFile( archive("patch-logging-times-index.sql") ); |
337 | 337 | wfOut( "ok\n" ); |
338 | 338 | } |
339 | 339 | } |
— | — | @@ -343,7 +343,7 @@ |
344 | 344 | wfOut( "...usertext,timestamp key on archive already exists.\n" ); |
345 | 345 | } else { |
346 | 346 | wfOut( "Adding usertext,timestamp key on archive table... " ); |
347 | | - dbsource( archive("patch-archive-user-index.sql"), $wgDatabase ); |
| 347 | + $wgDatabase->sourceFile( archive("patch-archive-user-index.sql") ); |
348 | 348 | wfOut( "ok\n" ); |
349 | 349 | } |
350 | 350 | } |
— | — | @@ -354,7 +354,7 @@ |
355 | 355 | wfOut( "...usertext,timestamp key on image already exists.\n" ); |
356 | 356 | } else { |
357 | 357 | wfOut( "Adding usertext,timestamp key on image table... " ); |
358 | | - dbsource( archive("patch-image-user-index.sql"), $wgDatabase ); |
| 358 | + $wgDatabase->sourceFile( archive("patch-image-user-index.sql") ); |
359 | 359 | wfOut( "ok\n" ); |
360 | 360 | } |
361 | 361 | } |
— | — | @@ -365,7 +365,7 @@ |
366 | 366 | wfOut( "...usertext,timestamp key on oldimage already exists.\n" ); |
367 | 367 | } else { |
368 | 368 | wfOut( "Adding usertext,timestamp key on oldimage table... " ); |
369 | | - dbsource( archive("patch-oldimage-user-index.sql"), $wgDatabase ); |
| 369 | + $wgDatabase->sourceFile( archive("patch-oldimage-user-index.sql") ); |
370 | 370 | wfOut( "ok\n" ); |
371 | 371 | } |
372 | 372 | } |
— | — | @@ -378,7 +378,7 @@ |
379 | 379 | } else { |
380 | 380 | wfOut( "Adding wl_notificationtimestamp field for email notification management." ); |
381 | 381 | /* ALTER TABLE watchlist ADD (wl_notificationtimestamp varchar(14) binary NOT NULL default '0'); */ |
382 | | - dbsource( archive( 'patch-email-notification.sql' ), $wgDatabase ); |
| 382 | + $wgDatabase->sourceFile( archive( 'patch-email-notification.sql' ) ); |
383 | 383 | wfOut( "ok\n" ); |
384 | 384 | } |
385 | 385 | # Check if we need to add talk page rows to the watchlist |
— | — | @@ -444,7 +444,7 @@ |
445 | 445 | global $wgDatabase; |
446 | 446 | if( $wgDatabase->fieldExists( 'user', 'user_emailauthenticationtimestamp' ) ) { |
447 | 447 | wfOut( "User table contains old email authentication field. Dropping... " ); |
448 | | - dbsource( archive( 'patch-email-authentication.sql' ), $wgDatabase ); |
| 448 | + $wgDatabase->sourceFile( archive( 'patch-email-authentication.sql' ) ); |
449 | 449 | wfOut( "ok\n" ); |
450 | 450 | } else { |
451 | 451 | wfOut( "...user table does not contain old email authentication field.\n" ); |
— | — | @@ -468,7 +468,7 @@ |
469 | 469 | wfOut( "$table table has correct $field encoding.\n" ); |
470 | 470 | } else { |
471 | 471 | wfOut( "Fixing $field encoding on $table table... " ); |
472 | | - dbsource( archive( $patchFile ), $wgDatabase ); |
| 472 | + $wgDatabase->sourceFile( archive( $patchFile ) ); |
473 | 473 | wfOut( "ok\n" ); |
474 | 474 | } |
475 | 475 | } |
— | — | @@ -643,7 +643,7 @@ |
644 | 644 | global $wgDatabase; |
645 | 645 | if( $wgDatabase->fieldExists( 'revision', 'inverse_timestamp' ) ) { |
646 | 646 | wfOut( "Removing revision.inverse_timestamp and fixing indexes... " ); |
647 | | - dbsource( archive( 'patch-inverse_timestamp.sql' ), $wgDatabase ); |
| 647 | + $wgDatabase->sourceFile( archive( 'patch-inverse_timestamp.sql' ) ); |
648 | 648 | wfOut( "ok\n" ); |
649 | 649 | } else { |
650 | 650 | wfOut( "revision timestamp indexes already up to 2005-03-13\n" ); |
— | — | @@ -656,7 +656,7 @@ |
657 | 657 | wfOut( "...rev_text_id already in place.\n" ); |
658 | 658 | } else { |
659 | 659 | wfOut( "Adding rev_text_id field... " ); |
660 | | - dbsource( archive( 'patch-rev_text_id.sql' ), $wgDatabase ); |
| 660 | + $wgDatabase->sourceFile( archive( 'patch-rev_text_id.sql' ) ); |
661 | 661 | wfOut( "ok\n" ); |
662 | 662 | } |
663 | 663 | } |
— | — | @@ -705,7 +705,7 @@ |
706 | 706 | wfOut( "...already have pagelinks table.\n" ); |
707 | 707 | } else { |
708 | 708 | wfOut( "Converting links and brokenlinks tables to pagelinks... " ); |
709 | | - dbsource( archive( 'patch-pagelinks.sql' ), $wgDatabase ); |
| 709 | + $wgDatabase->sourceFile( archive( 'patch-pagelinks.sql' ) ); |
710 | 710 | wfOut( "ok\n" ); |
711 | 711 | flush(); |
712 | 712 | |
— | — | @@ -744,7 +744,7 @@ |
745 | 745 | |
746 | 746 | if( $wgDatabase->fieldExists( 'image', 'img_type' ) ) { |
747 | 747 | wfOut( "Dropping unused img_type field in image table... " ); |
748 | | - dbsource( archive( 'patch-drop_img_type.sql' ), $wgDatabase ); |
| 748 | + $wgDatabase->sourceFile( archive( 'patch-drop_img_type.sql' ) ); |
749 | 749 | wfOut( "ok\n" ); |
750 | 750 | } else { |
751 | 751 | wfOut( "No img_type field in image table; Good.\n" ); |
— | — | @@ -766,7 +766,7 @@ |
767 | 767 | if ( $info && $info->type() === 'string' ) { |
768 | 768 | wfOut( "Fixing ancient broken imagelinks table.\n" ); |
769 | 769 | wfOut( "NOTE: you will have to run maintenance/refreshLinks.php after this.\n" ); |
770 | | - dbsource( archive( 'patch-fix-il_from.sql' ) ); |
| 770 | + $wgDatabase->sourceFile( archive( 'patch-fix-il_from.sql' ) ); |
771 | 771 | wfOut( "ok\n" ); |
772 | 772 | } else { |
773 | 773 | wfOut( "...il_from OK\n" ); |
— | — | @@ -783,7 +783,7 @@ |
784 | 784 | wfOut( "WARNING: This next step will probably fail due to unfixed duplicates...\n" ); |
785 | 785 | } |
786 | 786 | wfOut( "Adding unique index on user_name... " ); |
787 | | - dbsource( archive( 'patch-user_nameindex.sql' ), $wgDatabase ); |
| 787 | + $wgDatabase->sourceFile( archive( 'patch-user_nameindex.sql' ) ); |
788 | 788 | wfOut( "ok\n" ); |
789 | 789 | } |
790 | 790 | } |
— | — | @@ -798,13 +798,13 @@ |
799 | 799 | } |
800 | 800 | |
801 | 801 | wfOut( "Adding user_groups table... " ); |
802 | | - dbsource( archive( 'patch-user_groups.sql' ), $wgDatabase ); |
| 802 | + $wgDatabase->sourceFile( archive( 'patch-user_groups.sql' ) ); |
803 | 803 | wfOut( "ok\n" ); |
804 | 804 | |
805 | 805 | if( !$wgDatabase->tableExists( 'user_rights' ) ) { |
806 | 806 | if( $wgDatabase->fieldExists( 'user', 'user_rights' ) ) { |
807 | 807 | wfOut( "Upgrading from a 1.3 or older database? Breaking out user_rights for conversion..." ); |
808 | | - dbsource( archive( 'patch-user_rights.sql' ), $wgDatabase ); |
| 808 | + $wgDatabase->sourceFile( archive( 'patch-user_rights.sql' ) ); |
809 | 809 | wfOut( "ok\n" ); |
810 | 810 | } else { |
811 | 811 | wfOut( "*** WARNING: couldn't locate user_rights table or field for upgrade.\n" ); |
— | — | @@ -850,7 +850,7 @@ |
851 | 851 | wfOut( "ok\n" ); |
852 | 852 | |
853 | 853 | wfOut( "Re-adding fresh user_groups table... " ); |
854 | | - dbsource( archive( 'patch-user_groups.sql' ), $wgDatabase ); |
| 854 | + $wgDatabase->sourceFile( archive( 'patch-user_groups.sql' ) ); |
855 | 855 | wfOut( "ok\n" ); |
856 | 856 | |
857 | 857 | wfOut( "***\n" ); |
— | — | @@ -871,7 +871,7 @@ |
872 | 872 | |
873 | 873 | if( !$info->nullable() ) { |
874 | 874 | wfOut( "Making wl_notificationtimestamp nullable... " ); |
875 | | - dbsource( archive( 'patch-watchlist-null.sql' ), $wgDatabase ); |
| 875 | + $wgDatabase->sourceFile( archive( 'patch-watchlist-null.sql' ) ); |
876 | 876 | wfOut( "ok\n" ); |
877 | 877 | } else { |
878 | 878 | wfOut( "...wl_notificationtimestamp is already nullable.\n" ); |
— | — | @@ -903,7 +903,7 @@ |
904 | 904 | return; |
905 | 905 | } |
906 | 906 | wfOut( "Creating templatelinks table...\n" ); |
907 | | - dbsource( archive('patch-templatelinks.sql'), $wgDatabase ); |
| 907 | + $wgDatabase->sourceFile( archive('patch-templatelinks.sql') ); |
908 | 908 | wfOut( "Populating...\n" ); |
909 | 909 | if ( isset( $wgLoadBalancer ) && $wgLoadBalancer->getServerCount() > 1 ) { |
910 | 910 | // Slow, replication-friendly update |
— | — | @@ -959,7 +959,7 @@ |
960 | 960 | $info = $wgDatabase->indexInfo( 'recentchanges', $index, __METHOD__ ); |
961 | 961 | if( !$info ) { |
962 | 962 | wfOut( "...index `{$index}` not found; adding..." ); |
963 | | - dbsource( archive( $patch ) ); |
| 963 | + $wgDatabase->sourceFile( archive( $patch ) ); |
964 | 964 | wfOut( "done.\n" ); |
965 | 965 | } else { |
966 | 966 | wfOut( "...index `{$index}` seems ok.\n" ); |
— | — | @@ -989,7 +989,7 @@ |
990 | 990 | !index_has_field('templatelinks', 'tl_namespace', 'tl_from') || |
991 | 991 | !index_has_field('imagelinks', 'il_to', 'il_from')) |
992 | 992 | { |
993 | | - dbsource( archive( 'patch-backlinkindexes.sql' ) ); |
| 993 | + $wgDatabase->sourceFile( archive( 'patch-backlinkindexes.sql' ) ); |
994 | 994 | wfOut( "...backlinking indices updated\n" ); |
995 | 995 | } |
996 | 996 | } |
— | — | @@ -998,7 +998,7 @@ |
999 | 999 | wfOut( "Checking for categorylinks indices...\n" ); |
1000 | 1000 | if (!index_has_field('categorylinks', 'cl_sortkey', 'cl_from')) |
1001 | 1001 | { |
1002 | | - dbsource( archive( 'patch-categorylinksindex.sql' ) ); |
| 1002 | + $wgDatabase->sourceFile( archive( 'patch-categorylinksindex.sql' ) ); |
1003 | 1003 | wfOut( "...categorylinks indices updated\n" ); |
1004 | 1004 | } |
1005 | 1005 | } |
— | — | @@ -1009,7 +1009,7 @@ |
1010 | 1010 | $info = $wgDatabase->indexInfo( 'filearchive', 'fa_user_timestamp', __METHOD__ ); |
1011 | 1011 | if ( !$info ) |
1012 | 1012 | { |
1013 | | - dbsource( archive( 'patch-filearchive-user-index.sql' ) ); |
| 1013 | + $wgDatabase->sourceFile( archive( 'patch-filearchive-user-index.sql' ) ); |
1014 | 1014 | wfOut( "...filearchive indices updated\n" ); |
1015 | 1015 | } |
1016 | 1016 | } |
— | — | @@ -1022,7 +1022,7 @@ |
1023 | 1023 | wfOut( "profiling table has pf_memory field.\n" ); |
1024 | 1024 | } else { |
1025 | 1025 | wfOut( "Adding pf_memory field to table profiling..." ); |
1026 | | - dbsource( archive( 'patch-profiling-memory.sql' ), $wgDatabase ); |
| 1026 | + $wgDatabase->sourceFile( archive( 'patch-profiling-memory.sql' ) ); |
1027 | 1027 | wfOut( "ok\n" ); |
1028 | 1028 | } |
1029 | 1029 | } |
— | — | @@ -1146,8 +1146,8 @@ |
1147 | 1147 | wfOut( "...$name table already exists.\n" ); |
1148 | 1148 | } else { |
1149 | 1149 | wfOut( "Creating $name table..." ); |
1150 | | - dbsource( archive($patch), $wgDatabase ); |
1151 | | - dbsource( archive($patch2), $wgDatabase ); |
| 1150 | + $wgDatabase->sourceFile( archive($patch) ); |
| 1151 | + $wgDatabase->sourceFile( archive($patch2) ); |
1152 | 1152 | wfOut( "ok\n" ); |
1153 | 1153 | |
1154 | 1154 | wfOut( "Migrating old restrictions to new table..." ); |
— | — | @@ -1249,7 +1249,7 @@ |
1250 | 1250 | wfOut( "...pl_namespace, tl_namespace, il_to indices are already UNIQUE.\n" ); |
1251 | 1251 | } else { |
1252 | 1252 | wfOut( "Making pl_namespace, tl_namespace and il_to indices UNIQUE... " ); |
1253 | | - dbsource( archive( 'patch-pl-tl-il-unique.sql' ), $wgDatabase ); |
| 1253 | + $wgDatabase->sourceFile( archive( 'patch-pl-tl-il-unique.sql' ) ); |
1254 | 1254 | wfOut( "ok\n" ); |
1255 | 1255 | } |
1256 | 1256 | } |
— | — | @@ -1619,7 +1619,7 @@ |
1620 | 1620 | } |
1621 | 1621 | |
1622 | 1622 | wfOut( "Creating table \"$nt[0]\"\n" ); |
1623 | | - dbsource(archive($nt[1])); |
| 1623 | + $wgDatabase->sourceFile(archive($nt[1])); |
1624 | 1624 | } |
1625 | 1625 | |
1626 | 1626 | ## Needed before newcols |
— | — | @@ -1633,7 +1633,7 @@ |
1634 | 1634 | wfOut( "Dropping rule \"archive_delete\"\n" ); |
1635 | 1635 | $wgDatabase->query("DROP RULE archive_delete ON archive"); |
1636 | 1636 | } |
1637 | | - dbsource(archive("patch-remove-archive2.sql")); |
| 1637 | + $wgDatabase->sourceFile(archive("patch-remove-archive2.sql")); |
1638 | 1638 | } |
1639 | 1639 | else |
1640 | 1640 | wfOut( "... obsolete table \"archive2\" does not exist\n" ); |
— | — | @@ -1728,7 +1728,7 @@ |
1729 | 1729 | continue; |
1730 | 1730 | } |
1731 | 1731 | wfOut( "Adding rule \"$nr[1]\" to table \"$nr[0]\"\n" ); |
1732 | | - dbsource(archive($nr[2])); |
| 1732 | + $wgDatabase->sourceFile(archive($nr[2])); |
1733 | 1733 | } |
1734 | 1734 | |
1735 | 1735 | if ($wgDatabase->hasConstraint("oldimage_oi_name_fkey")) { |
— | — | @@ -1742,7 +1742,7 @@ |
1743 | 1743 | |
1744 | 1744 | if (!$wgDatabase->triggerExists("page", "page_deleted")) { |
1745 | 1745 | wfOut( "Adding function and trigger \"page_deleted\" to table \"page\"\n" ); |
1746 | | - dbsource(archive('patch-page_deleted.sql')); |
| 1746 | + $wgDatabase->sourceFile(archive('patch-page_deleted.sql')); |
1747 | 1747 | } |
1748 | 1748 | else |
1749 | 1749 | wfOut( "... table \"page\" has \"page_deleted\" trigger\n" ); |
— | — | @@ -1750,7 +1750,7 @@ |
1751 | 1751 | $fi = $wgDatabase->fieldInfo("recentchanges", "rc_cur_id"); |
1752 | 1752 | if (!$fi->nullable()) { |
1753 | 1753 | wfOut( "Removing NOT NULL constraint from \"recentchanges.rc_cur_id\"\n" ); |
1754 | | - dbsource(archive('patch-rc_cur_id-not-null.sql')); |
| 1754 | + $wgDatabase->sourceFile(archive('patch-rc_cur_id-not-null.sql')); |
1755 | 1755 | } |
1756 | 1756 | else |
1757 | 1757 | wfOut( "... column \"recentchanges.rc_cur_id\" has a NOT NULL constraint\n" ); |
— | — | @@ -1776,7 +1776,7 @@ |
1777 | 1777 | } |
1778 | 1778 | else { |
1779 | 1779 | wfOut( "Changing constraint \"revision_rev_user_fkey\" to ON DELETE RESTRICT\n" ); |
1780 | | - dbsource(archive('patch-revision_rev_user_fkey.sql')); |
| 1780 | + $wgDatabase->sourceFile(archive('patch-revision_rev_user_fkey.sql')); |
1781 | 1781 | } |
1782 | 1782 | |
1783 | 1783 | # Fix ipb_address index |
— | — | @@ -1789,7 +1789,7 @@ |
1790 | 1790 | } |
1791 | 1791 | else { |
1792 | 1792 | wfOut( "Adding ipb_address_unique index\n" ); |
1793 | | - dbsource(archive('patch-ipb_address_unique.sql')); |
| 1793 | + $wgDatabase->sourceFile(archive('patch-ipb_address_unique.sql')); |
1794 | 1794 | } |
1795 | 1795 | |
1796 | 1796 | global $wgExtNewTables, $wgExtPGNewFields, $wgExtPGAlteredFields, $wgExtNewIndexes; |
— | — | @@ -1800,7 +1800,7 @@ |
1801 | 1801 | continue; |
1802 | 1802 | } |
1803 | 1803 | wfOut( "Creating table \"$nt[0]\"\n" ); |
1804 | | - dbsource($nt[1]); |
| 1804 | + $wgDatabase->sourceFile($nt[1]); |
1805 | 1805 | } |
1806 | 1806 | # Add missing extension fields |
1807 | 1807 | foreach ( $wgExtPGNewFields as $nc ) { |
— | — | @@ -1843,18 +1843,18 @@ |
1844 | 1844 | $wgDatabase->query( "CREATE INDEX $ni[1] ON $ni[0] $ni[2]" ); |
1845 | 1845 | } |
1846 | 1846 | else { |
1847 | | - dbsource($ni[2]); |
| 1847 | + $wgDatabase->sourceFile($ni[2]); |
1848 | 1848 | } |
1849 | 1849 | } |
1850 | 1850 | |
1851 | 1851 | # Tweak the page_title tsearch2 trigger to filter out slashes |
1852 | 1852 | # This is create or replace, so harmless to call if not needed |
1853 | | - dbsource(archive('patch-ts2pagetitle.sql')); |
| 1853 | + $wgDatabase->sourceFile(archive('patch-ts2pagetitle.sql')); |
1854 | 1854 | |
1855 | 1855 | ## If the server is 8.3 or higher, rewrite the tsearch2 triggers |
1856 | 1856 | ## in case they have the old 'default' versions |
1857 | 1857 | if ( $numver >= 8.3 ) |
1858 | | - dbsource(archive('patch-tsearch2funcs.sql')); |
| 1858 | + $wgDatabase->sourceFile(archive('patch-tsearch2funcs.sql')); |
1859 | 1859 | |
1860 | 1860 | ## Put a new row in the mediawiki_version table |
1861 | 1861 | $wgDatabase->insert( 'mediawiki_version', |
Index: branches/maintenance-work/maintenance/addwiki.php |
— | — | @@ -7,250 +7,254 @@ |
8 | 8 | * @ingroup Maintenance |
9 | 9 | */ |
10 | 10 | |
11 | | -$wgNoDBParam = true; |
| 11 | +require_once( "Maintenance.php" ); |
12 | 12 | |
13 | | -require_once( "commandLine.inc" ); |
14 | | -require_once( "rebuildInterwiki.inc" ); |
15 | | -require_once( "languages/Names.php" ); |
16 | | -if ( count( $args ) != 3 ) { |
17 | | - wfDie( "Usage: php addwiki.php <language> <site> <dbname>\nThe site for Wikipedia is 'wikipedia'.\n" ); |
18 | | -} |
| 13 | +class AddWiki extends Maintenance { |
| 14 | + public function __construct() { |
| 15 | + parent::__construct(); |
| 16 | + $this->mDescription = "Add a new wiki to the family. Wikimedia specific!"; |
| 17 | + $this->addArgs( 'language', 'site', 'dbname' ); |
| 18 | + } |
| 19 | + |
| 20 | + public function execute() { |
| 21 | + global $IP, $wgLanguageNames, $wgDefaultExternalStore, $wgNoDBParam; |
19 | 22 | |
20 | | -addWiki( $args[0], $args[1], $args[2] ); |
| 23 | + $wgNoDBParam = true; |
| 24 | + $lang = $this->getArg(0); |
| 25 | + $site = $this->getArg(1); |
| 26 | + $dbName = $this->getArg(2); |
21 | 27 | |
22 | | -# ----------------------------------------------------------------- |
| 28 | + if ( !isset( $wgLanguageNames[$lang] ) ) { |
| 29 | + $this->error( "Language $lang not found in \$wgLanguageNames\n", true ); |
| 30 | + } |
| 31 | + $name = $wgLanguageNames[$lang]; |
23 | 32 | |
24 | | -function addWiki( $lang, $site, $dbName ) |
25 | | -{ |
26 | | - global $IP, $wgLanguageNames, $wgDefaultExternalStore; |
| 33 | + $dbw = wfGetDB( DB_MASTER ); |
| 34 | + $common = "/home/wikipedia/common"; |
27 | 35 | |
28 | | - if ( !isset( $wgLanguageNames[$lang] ) ) { |
29 | | - print "Language $lang not found in \$wgLanguageNames\n"; |
30 | | - return; |
31 | | - } |
32 | | - $name = $wgLanguageNames[$lang]; |
| 36 | + $this->output( "Creating database $dbName for $lang.$site ($name)\n" ); |
33 | 37 | |
34 | | - $dbw = wfGetDB( DB_MASTER ); |
35 | | - $common = "/home/wikipedia/common"; |
36 | | - $maintenance = "$IP/maintenance"; |
| 38 | + # Set up the database |
| 39 | + $dbw->query( "SET table_type=Innodb" ); |
| 40 | + $dbw->query( "CREATE DATABASE $dbName" ); |
| 41 | + $dbw->selectDB( $dbName ); |
37 | 42 | |
38 | | - print "Creating database $dbName for $lang.$site ($name)\n"; |
39 | | - |
40 | | - # Set up the database |
41 | | - $dbw->query( "SET table_type=Innodb" ); |
42 | | - $dbw->query( "CREATE DATABASE $dbName" ); |
43 | | - $dbw->selectDB( $dbName ); |
| 43 | + $this->output( "Initialising tables\n" ); |
| 44 | + $dbw->sourceFile( $this->getDir() . '/tables.sql' ); |
| 45 | + $dbw->sourceFile( "$IP/extensions/OAI/update_table.sql" ); |
| 46 | + $dbw->sourceFile( "$IP/extensions/AntiSpoof/sql/patch-antispoof.mysql.sql" ); |
| 47 | + $dbw->sourceFile( "$IP/extensions/CheckUser/cu_changes.sql" ); |
| 48 | + $dbw->sourceFile( "$IP/extensions/CheckUser/cu_log.sql" ); |
| 49 | + $dbw->sourceFile( "$IP/extensions/TitleKey/titlekey.sql" ); |
| 50 | + $dbw->sourceFile( "$IP/extensions/Oversight/hidden.sql" ); |
| 51 | + $dbw->sourceFile( "$IP/extensions/GlobalBlocking/localdb_patches/setup-global_block_whitelist.sql" ); |
| 52 | + $dbw->sourceFile( "$IP/extensions/AbuseFilter/abusefilter.tables.sql" ); |
44 | 53 | |
45 | | - print "Initialising tables\n"; |
46 | | - dbsource( "$maintenance/tables.sql", $dbw ); |
47 | | - dbsource( "$IP/extensions/OAI/update_table.sql", $dbw ); |
48 | | - dbsource( "$IP/extensions/AntiSpoof/sql/patch-antispoof.mysql.sql", $dbw ); |
49 | | - dbsource( "$IP/extensions/CheckUser/cu_changes.sql", $dbw ); |
50 | | - dbsource( "$IP/extensions/CheckUser/cu_log.sql", $dbw ); |
51 | | - dbsource( "$IP/extensions/TitleKey/titlekey.sql", $dbw ); |
52 | | - dbsource( "$IP/extensions/Oversight/hidden.sql", $dbw ); |
53 | | - dbsource( "$IP/extensions/GlobalBlocking/localdb_patches/setup-global_block_whitelist.sql", $dbw ); |
54 | | - dbsource( "$IP/extensions/AbuseFilter/abusefilter.tables.sql", $dbw ); |
| 54 | + $dbw->query( "INSERT INTO site_stats(ss_row_id) VALUES (1)" ); |
55 | 55 | |
56 | | - $dbw->query( "INSERT INTO site_stats(ss_row_id) VALUES (1)" ); |
| 56 | + # Initialise external storage |
| 57 | + if ( is_array( $wgDefaultExternalStore ) ) { |
| 58 | + $stores = $wgDefaultExternalStore; |
| 59 | + } elseif ( $stores ) { |
| 60 | + $stores = array( $wgDefaultExternalStore ); |
| 61 | + } else { |
| 62 | + $stores = array(); |
| 63 | + } |
| 64 | + if ( count( $stores ) ) { |
| 65 | + global $wgDBuser, $wgDBpassword, $wgExternalServers; |
| 66 | + foreach ( $stores as $storeURL ) { |
| 67 | + $m = array(); |
| 68 | + if ( !preg_match( '!^DB://(.*)$!', $storeURL, $m ) ) { |
| 69 | + continue; |
| 70 | + } |
57 | 71 | |
58 | | - # Initialise external storage |
59 | | - if ( is_array( $wgDefaultExternalStore ) ) { |
60 | | - $stores = $wgDefaultExternalStore; |
61 | | - } elseif ( $stores ) { |
62 | | - $stores = array( $wgDefaultExternalStore ); |
63 | | - } else { |
64 | | - $stores = array(); |
65 | | - } |
66 | | - if ( count( $stores ) ) { |
67 | | - require_once( 'ExternalStoreDB.php' ); |
68 | | - global $wgDBuser, $wgDBpassword, $wgExternalServers; |
69 | | - foreach ( $stores as $storeURL ) { |
70 | | - $m = array(); |
71 | | - if ( !preg_match( '!^DB://(.*)$!', $storeURL, $m ) ) { |
72 | | - continue; |
73 | | - } |
74 | | - |
75 | | - $cluster = $m[1]; |
76 | | - print "Initialising external storage $cluster...\n"; |
77 | | - |
78 | | - # Hack |
79 | | - $wgExternalServers[$cluster][0]['user'] = $wgDBuser; |
80 | | - $wgExternalServers[$cluster][0]['password'] = $wgDBpassword; |
| 72 | + $cluster = $m[1]; |
| 73 | + $this->output( "Initialising external storage $cluster...\n" ); |
81 | 74 | |
82 | | - $store = new ExternalStoreDB; |
83 | | - $extdb = $store->getMaster( $cluster ); |
84 | | - $extdb->query( "SET table_type=InnoDB" ); |
85 | | - $extdb->query( "CREATE DATABASE $dbName" ); |
86 | | - $extdb->selectDB( $dbName ); |
| 75 | + # Hack |
| 76 | + $wgExternalServers[$cluster][0]['user'] = $wgDBuser; |
| 77 | + $wgExternalServers[$cluster][0]['password'] = $wgDBpassword; |
87 | 78 | |
88 | | - # Hack x2 |
89 | | - $blobsTable = $store->getTable( $extdb ); |
90 | | - $blobsFile = popen( "sed s/blobs\\\\\\>/$blobsTable/ $maintenance/storage/blobs.sql", 'r' ); |
91 | | - $extdb->sourceStream( $blobsFile ); |
92 | | - pclose( $blobsFile ); |
93 | | - $extdb->immediateCommit(); |
| 79 | + $store = new ExternalStoreDB; |
| 80 | + $extdb = $store->getMaster( $cluster ); |
| 81 | + $extdb->query( "SET table_type=InnoDB" ); |
| 82 | + $extdb->query( "CREATE DATABASE $dbName" ); |
| 83 | + $extdb->selectDB( $dbName ); |
| 84 | + |
| 85 | + # Hack x2 |
| 86 | + $blobsTable = $store->getTable( $extdb ); |
| 87 | + $sedCmd = "sed s/blobs\\\\\\>/$blobsTable/ " . $this->getDir() . "/storage/blobs.sql"; |
| 88 | + $blobsFile = popen( $sedCmd, 'r' ); |
| 89 | + $extdb->sourceStream( $blobsFile ); |
| 90 | + pclose( $blobsFile ); |
| 91 | + $extdb->immediateCommit(); |
| 92 | + } |
94 | 93 | } |
95 | | - } |
96 | 94 | |
97 | | - global $wgTitle, $wgArticle; |
98 | | - $wgTitle = Title::newFromText( wfMsgWeirdKey( "mainpage/$lang" ) ); |
99 | | - print "Writing main page to " . $wgTitle->getPrefixedDBkey() . "\n"; |
100 | | - $wgArticle = new Article( $wgTitle ); |
101 | | - $ucsite = ucfirst( $site ); |
| 95 | + global $wgTitle, $wgArticle; |
| 96 | + $wgTitle = Title::newFromText( wfMsgWeirdKey( "mainpage/$lang" ) ); |
| 97 | + $this->output( "Writing main page to " . $wgTitle->getPrefixedDBkey() . "\n" ); |
| 98 | + $wgArticle = new Article( $wgTitle ); |
| 99 | + $ucsite = ucfirst( $site ); |
102 | 100 | |
103 | | - $wgArticle->insertNewArticle( <<<EOT |
104 | | -==This subdomain is reserved for the creation of a [[wikimedia:Our projects|$ucsite]] in '''[[w:en:{$name}|{$name}]]''' language== |
| 101 | + $wgArticle->insertNewArticle( $this->getFirstArticle( $ucsite, $name ), '', false, false ); |
105 | 102 | |
106 | | -* Please '''do not start editing''' this new site. This site has a test project on the [[incubator:|Wikimedia Incubator]] (or on the [[betawikiversity:|BetaWikiversity]] or on the [[oldwikisource:|Old Wikisource]]) and it will be imported to here. |
| 103 | + $this->output( "Adding to dblists\n" ); |
107 | 104 | |
108 | | -* If you would like to help translating the interface to this language, please do not translate here, but go to [[betawiki:|Betawiki]], a special wiki for translating the interface. That way everyone can use it on every wiki using the [[mw:|same software]]. |
| 105 | + # Add to dblist |
| 106 | + $file = fopen( "$common/all.dblist", "a" ); |
| 107 | + fwrite( $file, "$dbName\n" ); |
| 108 | + fclose( $file ); |
109 | 109 | |
110 | | -* For information about how to edit and for other general help, see [[m:Help:Contents|Help on Wikimedia's Meta-Wiki]] or [[mw:Help:Contents|Help on MediaWiki.org]]. |
| 110 | + # Update the sublists |
| 111 | + shell_exec("cd $common && ./refresh-dblist"); |
111 | 112 | |
112 | | -== Sister projects == |
113 | | -<span class="plainlinks"> |
114 | | -[http://www.wikipedia.org Wikipedia] | |
115 | | -[http://www.wiktionary.org Wiktonary] | |
116 | | -[http://www.wikibooks.org Wikibooks] | |
117 | | -[http://www.wikinews.org Wikinews] | |
118 | | -[http://www.wikiquote.org Wikiquote] | |
119 | | -[http://www.wikisource.org Wikisource] |
120 | | -[http://www.wikiversity.org Wikiversity] |
121 | | -</span> |
| 113 | + #print "Constructing interwiki SQL\n"; |
| 114 | + # Rebuild interwiki tables |
| 115 | + #passthru( '/home/wikipedia/conf/interwiki/update' ); |
122 | 116 | |
123 | | -See Wikimedia's [[m:|Meta-Wiki]] for the coordination of these projects. |
| 117 | + $this->output( "Script ended. You still have to: |
| 118 | + * Add any required settings in InitialiseSettings.php |
| 119 | + * Run sync-common-all |
| 120 | + * Run /home/wikipedia/conf/interwiki/update |
| 121 | + " ); |
| 122 | + } |
| 123 | + |
| 124 | + private function getFirstArticle( $ucsite, $name ) { |
| 125 | + return <<<EOT |
| 126 | + ==This subdomain is reserved for the creation of a [[wikimedia:Our projects|$ucsite]] in '''[[w:en:{$name}|{$name}]]''' language== |
124 | 127 | |
125 | | -[[aa:]] |
126 | | -[[af:]] |
127 | | -[[als:]] |
128 | | -[[ar:]] |
129 | | -[[de:]] |
130 | | -[[en:]] |
131 | | -[[as:]] |
132 | | -[[ast:]] |
133 | | -[[ay:]] |
134 | | -[[az:]] |
135 | | -[[bcl:]] |
136 | | -[[be:]] |
137 | | -[[bg:]] |
138 | | -[[bn:]] |
139 | | -[[bo:]] |
140 | | -[[bs:]] |
141 | | -[[cs:]] |
142 | | -[[co:]] |
143 | | -[[cs:]] |
144 | | -[[cy:]] |
145 | | -[[da:]] |
146 | | -[[el:]] |
147 | | -[[eo:]] |
148 | | -[[es:]] |
149 | | -[[et:]] |
150 | | -[[eu:]] |
151 | | -[[fa:]] |
152 | | -[[fi:]] |
153 | | -[[fr:]] |
154 | | -[[fy:]] |
155 | | -[[ga:]] |
156 | | -[[gl:]] |
157 | | -[[gn:]] |
158 | | -[[gu:]] |
159 | | -[[he:]] |
160 | | -[[hi:]] |
161 | | -[[hr:]] |
162 | | -[[hsb:]] |
163 | | -[[hy:]] |
164 | | -[[ia:]] |
165 | | -[[id:]] |
166 | | -[[is:]] |
167 | | -[[it:]] |
168 | | -[[ja:]] |
169 | | -[[ka:]] |
170 | | -[[kk:]] |
171 | | -[[km:]] |
172 | | -[[kn:]] |
173 | | -[[ko:]] |
174 | | -[[ks:]] |
175 | | -[[ku:]] |
176 | | -[[ky:]] |
177 | | -[[la:]] |
178 | | -[[ln:]] |
179 | | -[[lo:]] |
180 | | -[[lt:]] |
181 | | -[[lv:]] |
182 | | -[[hu:]] |
183 | | -[[mi:]] |
184 | | -[[mk:]] |
185 | | -[[ml:]] |
186 | | -[[mn:]] |
187 | | -[[mr:]] |
188 | | -[[ms:]] |
189 | | -[[mt:]] |
190 | | -[[my:]] |
191 | | -[[na:]] |
192 | | -[[nah:]] |
193 | | -[[nds:]] |
194 | | -[[ne:]] |
195 | | -[[nl:]] |
196 | | -[[no:]] |
197 | | -[[oc:]] |
198 | | -[[om:]] |
199 | | -[[pa:]] |
200 | | -[[pl:]] |
201 | | -[[ps:]] |
202 | | -[[pt:]] |
203 | | -[[qu:]] |
204 | | -[[ro:]] |
205 | | -[[ru:]] |
206 | | -[[sa:]] |
207 | | -[[si:]] |
208 | | -[[sk:]] |
209 | | -[[sl:]] |
210 | | -[[sq:]] |
211 | | -[[sr:]] |
212 | | -[[sv:]] |
213 | | -[[sw:]] |
214 | | -[[ta:]] |
215 | | -[[te:]] |
216 | | -[[tg:]] |
217 | | -[[th:]] |
218 | | -[[tk:]] |
219 | | -[[tl:]] |
220 | | -[[tr:]] |
221 | | -[[tt:]] |
222 | | -[[ug:]] |
223 | | -[[uk:]] |
224 | | -[[ur:]] |
225 | | -[[uz:]] |
226 | | -[[vi:]] |
227 | | -[[vo:]] |
228 | | -[[xh:]] |
229 | | -[[yo:]] |
230 | | -[[za:]] |
231 | | -[[zh:]] |
232 | | -[[zu:]] |
| 128 | + * Please '''do not start editing''' this new site. This site has a test project on the [[incubator:|Wikimedia Incubator]] (or on the [[betawikiversity:|BetaWikiversity]] or on the [[oldwikisource:|Old Wikisource]]) and it will be imported to here. |
233 | 129 | |
234 | | -EOT |
235 | | -, '', false, false ); |
| 130 | + * If you would like to help translating the interface to this language, please do not translate here, but go to [[betawiki:|Betawiki]], a special wiki for translating the interface. That way everyone can use it on every wiki using the [[mw:|same software]]. |
236 | 131 | |
237 | | - print "Adding to dblists\n"; |
| 132 | + * For information about how to edit and for other general help, see [[m:Help:Contents|Help on Wikimedia's Meta-Wiki]] or [[mw:Help:Contents|Help on MediaWiki.org]]. |
238 | 133 | |
239 | | - # Add to dblist |
240 | | - $file = fopen( "$common/all.dblist", "a" ); |
241 | | - fwrite( $file, "$dbName\n" ); |
242 | | - fclose( $file ); |
| 134 | + == Sister projects == |
| 135 | + <span class="plainlinks"> |
| 136 | + [http://www.wikipedia.org Wikipedia] | |
| 137 | + [http://www.wiktionary.org Wiktonary] | |
| 138 | + [http://www.wikibooks.org Wikibooks] | |
| 139 | + [http://www.wikinews.org Wikinews] | |
| 140 | + [http://www.wikiquote.org Wikiquote] | |
| 141 | + [http://www.wikisource.org Wikisource] |
| 142 | + [http://www.wikiversity.org Wikiversity] |
| 143 | + </span> |
243 | 144 | |
244 | | - # Update the sublists |
245 | | - shell_exec("cd $common && ./refresh-dblist"); |
| 145 | + See Wikimedia's [[m:|Meta-Wiki]] for the coordination of these projects. |
246 | 146 | |
247 | | - #print "Constructing interwiki SQL\n"; |
248 | | - # Rebuild interwiki tables |
249 | | - #passthru( '/home/wikipedia/conf/interwiki/update' ); |
| 147 | + [[aa:]] |
| 148 | + [[af:]] |
| 149 | + [[als:]] |
| 150 | + [[ar:]] |
| 151 | + [[de:]] |
| 152 | + [[en:]] |
| 153 | + [[as:]] |
| 154 | + [[ast:]] |
| 155 | + [[ay:]] |
| 156 | + [[az:]] |
| 157 | + [[bcl:]] |
| 158 | + [[be:]] |
| 159 | + [[bg:]] |
| 160 | + [[bn:]] |
| 161 | + [[bo:]] |
| 162 | + [[bs:]] |
| 163 | + [[cs:]] |
| 164 | + [[co:]] |
| 165 | + [[cs:]] |
| 166 | + [[cy:]] |
| 167 | + [[da:]] |
| 168 | + [[el:]] |
| 169 | + [[eo:]] |
| 170 | + [[es:]] |
| 171 | + [[et:]] |
| 172 | + [[eu:]] |
| 173 | + [[fa:]] |
| 174 | + [[fi:]] |
| 175 | + [[fr:]] |
| 176 | + [[fy:]] |
| 177 | + [[ga:]] |
| 178 | + [[gl:]] |
| 179 | + [[gn:]] |
| 180 | + [[gu:]] |
| 181 | + [[he:]] |
| 182 | + [[hi:]] |
| 183 | + [[hr:]] |
| 184 | + [[hsb:]] |
| 185 | + [[hy:]] |
| 186 | + [[ia:]] |
| 187 | + [[id:]] |
| 188 | + [[is:]] |
| 189 | + [[it:]] |
| 190 | + [[ja:]] |
| 191 | + [[ka:]] |
| 192 | + [[kk:]] |
| 193 | + [[km:]] |
| 194 | + [[kn:]] |
| 195 | + [[ko:]] |
| 196 | + [[ks:]] |
| 197 | + [[ku:]] |
| 198 | + [[ky:]] |
| 199 | + [[la:]] |
| 200 | + [[ln:]] |
| 201 | + [[lo:]] |
| 202 | + [[lt:]] |
| 203 | + [[lv:]] |
| 204 | + [[hu:]] |
| 205 | + [[mi:]] |
| 206 | + [[mk:]] |
| 207 | + [[ml:]] |
| 208 | + [[mn:]] |
| 209 | + [[mr:]] |
| 210 | + [[ms:]] |
| 211 | + [[mt:]] |
| 212 | + [[my:]] |
| 213 | + [[na:]] |
| 214 | + [[nah:]] |
| 215 | + [[nds:]] |
| 216 | + [[ne:]] |
| 217 | + [[nl:]] |
| 218 | + [[no:]] |
| 219 | + [[oc:]] |
| 220 | + [[om:]] |
| 221 | + [[pa:]] |
| 222 | + [[pl:]] |
| 223 | + [[ps:]] |
| 224 | + [[pt:]] |
| 225 | + [[qu:]] |
| 226 | + [[ro:]] |
| 227 | + [[ru:]] |
| 228 | + [[sa:]] |
| 229 | + [[si:]] |
| 230 | + [[sk:]] |
| 231 | + [[sl:]] |
| 232 | + [[sq:]] |
| 233 | + [[sr:]] |
| 234 | + [[sv:]] |
| 235 | + [[sw:]] |
| 236 | + [[ta:]] |
| 237 | + [[te:]] |
| 238 | + [[tg:]] |
| 239 | + [[th:]] |
| 240 | + [[tk:]] |
| 241 | + [[tl:]] |
| 242 | + [[tr:]] |
| 243 | + [[tt:]] |
| 244 | + [[ug:]] |
| 245 | + [[uk:]] |
| 246 | + [[ur:]] |
| 247 | + [[uz:]] |
| 248 | + [[vi:]] |
| 249 | + [[vo:]] |
| 250 | + [[xh:]] |
| 251 | + [[yo:]] |
| 252 | + [[za:]] |
| 253 | + [[zh:]] |
| 254 | + [[zu:]] |
250 | 255 | |
251 | | - print "Script ended. You still have to: |
252 | | -* Add any required settings in InitialiseSettings.php |
253 | | -* Run sync-common-all |
254 | | -* Run /home/wikipedia/conf/interwiki/update |
255 | | -"; |
| 256 | +EOT; |
| 257 | + } |
256 | 258 | } |
257 | 259 | |
| 260 | +$maintClass = "AddWiki"; |
| 261 | +require_once( DO_MAINTENANCE ); |
Index: branches/maintenance-work/maintenance/patchSql.php |
— | — | @@ -20,7 +20,7 @@ |
21 | 21 | foreach( $files as $file ) { |
22 | 22 | if( file_exists( $file ) ) { |
23 | 23 | echo "$file ...\n"; |
24 | | - dbsource( $file ); |
| 24 | + wfGetDB( DB_MASTER )->fileSource( $file ); |
25 | 25 | continue 2; |
26 | 26 | } |
27 | 27 | } |
Index: branches/maintenance-work/maintenance/Maintenance.php |
— | — | @@ -675,6 +675,13 @@ |
676 | 676 | # Done |
677 | 677 | $dbw->commit(); |
678 | 678 | } |
| 679 | + |
| 680 | + /** |
| 681 | + * Get the maintenance directory. |
| 682 | + */ |
| 683 | + protected function getDir() { |
| 684 | + return dirname( __FILE__ ); |
| 685 | + } |
679 | 686 | |
680 | 687 | /** |
681 | 688 | * Get the list of available maintenance scripts. Note |
— | — | @@ -695,6 +702,7 @@ |
696 | 703 | if( !self::$mCoreScripts ) { |
697 | 704 | $d = dirname( __FILE__ ) . DIRECTORY_SEPARATOR; |
698 | 705 | self::$mCoreScripts = array( |
| 706 | + 'AddWiki' => $d . 'addwiki.php', |
699 | 707 | 'AttachLatest' => $d . 'attachLatest.php', |
700 | 708 | 'BenchmarkPurge' => $d . 'benchmarkPurge.php', |
701 | 709 | 'ChangePassword' => $d . 'changePassword.php', |
— | — | @@ -723,6 +731,8 @@ |
724 | 732 | 'EditCLI' => $d . 'edit.php', |
725 | 733 | 'EvalPrompt' => $d . 'eval.php', |
726 | 734 | 'FetchText' => $d . 'fetchText.php', |
| 735 | + 'FixSlaveDesync' => $d . 'fixSlaveDesync.php', |
| 736 | + 'FixTimestamps' => $d . 'fixTimestamps.php', |
727 | 737 | 'FixUserRegistration' => $d . 'fixUserRegistration.php', |
728 | 738 | 'GenerateSitemap' => $d . 'generateSitemap.php', |
729 | 739 | 'GetLagTimes' => $d . 'getLagTimes.php', |
— | — | @@ -752,6 +762,7 @@ |
753 | 763 | 'RefreshLinks' => $d . 'refreshLinks.php', |
754 | 764 | 'RemoveUnusedAccounts' => $d . 'removeUnusedAccounts.php', |
755 | 765 | 'RenameDbPrefix' => $d . 'renameDbPrefix.php', |
| 766 | + 'RenameWiki' => $d . 'renamewiki.php', |
756 | 767 | 'DumpRenderer' => $d . 'renderDump.php', |
757 | 768 | 'RunJobs' => $d . 'runJobs.php', |
758 | 769 | 'ShowJobs' => $d . 'showJobs.php', |
Index: branches/maintenance-work/maintenance/fixTimestamps.php |
— | — | @@ -9,98 +9,99 @@ |
10 | 10 | * @file |
11 | 11 | * @ingroup Maintenance |
12 | 12 | */ |
| 13 | + |
| 14 | +require_once( "Maintenance.php" ); |
13 | 15 | |
14 | | -require_once( 'commandLine.inc' ); |
| 16 | +class FixTimestamps extends Maintenance { |
| 17 | + public function __construct() { |
| 18 | + parent::__construct(); |
| 19 | + $this->mDescription = ""; |
| 20 | + $this->addArgs( array( 'offset', 'start', 'end' ) ); |
| 21 | + } |
15 | 22 | |
16 | | -if ( count( $args ) < 3 ) { |
17 | | - echo "Usage: php fixTimestamps.php <offset in hours> <start time> <end time>\n"; |
18 | | - exit(1); |
19 | | -} |
| 23 | + public function execute() { |
| 24 | + $offset = $this->getArg(0) * 3600; |
| 25 | + $start = $this->getArg(1); |
| 26 | + $end = $this->getArg(2); |
| 27 | + $grace = 60; // maximum normal clock offset |
| 28 | + |
| 29 | + # Find bounding revision IDs |
| 30 | + $dbw = wfGetDB( DB_MASTER ); |
| 31 | + $revisionTable = $dbw->tableName( 'revision' ); |
| 32 | + $res = $dbw->query( "SELECT MIN(rev_id) as minrev, MAX(rev_id) as maxrev FROM $revisionTable " . |
| 33 | + "WHERE rev_timestamp BETWEEN '{$start}' AND '{$end}'", __METHOD__ ); |
| 34 | + $row = $dbw->fetchObject( $res ); |
| 35 | + |
| 36 | + if ( is_null( $row->minrev ) ) { |
| 37 | + $this->error( "No revisions in search period.\n", true ); |
| 38 | + } |
| 39 | + |
| 40 | + $minRev = $row->minrev; |
| 41 | + $maxRev = $row->maxrev; |
| 42 | + |
| 43 | + # Select all timestamps and IDs |
| 44 | + $sql = "SELECT rev_id, rev_timestamp FROM $revisionTable " . |
| 45 | + "WHERE rev_id BETWEEN $minRev AND $maxRev"; |
| 46 | + if ( $offset > 0 ) { |
| 47 | + $sql .= " ORDER BY rev_id DESC"; |
| 48 | + $expectedSign = -1; |
| 49 | + } else { |
| 50 | + $expectedSign = 1; |
| 51 | + } |
| 52 | + |
| 53 | + $res = $dbw->query( $sql, __METHOD__ ); |
| 54 | + |
| 55 | + $lastNormal = 0; |
| 56 | + $badRevs = array(); |
| 57 | + $numGoodRevs = 0; |
| 58 | + |
| 59 | + while ( $row = $dbw->fetchObject( $res ) ) { |
| 60 | + $timestamp = wfTimestamp( TS_UNIX, $row->rev_timestamp ); |
| 61 | + $delta = $timestamp - $lastNormal; |
| 62 | + $sign = $delta == 0 ? 0 : $delta / abs( $delta ); |
| 63 | + if ( $sign == 0 || $sign == $expectedSign ) { |
| 64 | + // Monotonic change |
| 65 | + $lastNormal = $timestamp; |
| 66 | + ++ $numGoodRevs; |
| 67 | + continue; |
| 68 | + } elseif ( abs( $delta ) <= $grace ) { |
| 69 | + // Non-monotonic change within grace interval |
| 70 | + ++ $numGoodRevs; |
| 71 | + continue; |
| 72 | + } else { |
| 73 | + // Non-monotonic change larger than grace interval |
| 74 | + $badRevs[] = $row->rev_id; |
| 75 | + } |
| 76 | + } |
| 77 | + $dbw->freeResult( $res ); |
| 78 | + |
| 79 | + $numBadRevs = count( $badRevs ); |
| 80 | + if ( $numBadRevs > $numGoodRevs ) { |
| 81 | + $this->error( |
| 82 | + "The majority of revisions in the search interval are marked as bad. |
20 | 83 | |
21 | | -$offset = $args[0] * 3600; |
22 | | -$start = $args[1]; |
23 | | -$end = $args[2]; |
24 | | -$fname = 'fixTimestamps.php'; |
25 | | -$grace = 60; // maximum normal clock offset |
| 84 | + Are you sure the offset ($offset) has the right sign? Positive means the clock |
| 85 | + was incorrectly set forward, negative means the clock was incorrectly set back. |
26 | 86 | |
27 | | -# Find bounding revision IDs |
28 | | -$dbw = wfGetDB( DB_MASTER ); |
29 | | -$revisionTable = $dbw->tableName( 'revision' ); |
30 | | -$res = $dbw->query( "SELECT MIN(rev_id) as minrev, MAX(rev_id) as maxrev FROM $revisionTable " . |
31 | | - "WHERE rev_timestamp BETWEEN '{$start}' AND '{$end}'", $fname ); |
32 | | -$row = $dbw->fetchObject( $res ); |
33 | | - |
34 | | -if ( is_null( $row->minrev ) ) { |
35 | | - echo "No revisions in search period.\n"; |
36 | | - exit(0); |
37 | | -} |
38 | | - |
39 | | -$minRev = $row->minrev; |
40 | | -$maxRev = $row->maxrev; |
41 | | - |
42 | | -# Select all timestamps and IDs |
43 | | -$sql = "SELECT rev_id, rev_timestamp FROM $revisionTable " . |
44 | | - "WHERE rev_id BETWEEN $minRev AND $maxRev"; |
45 | | -if ( $offset > 0 ) { |
46 | | - $sql .= " ORDER BY rev_id DESC"; |
47 | | - $expectedSign = -1; |
48 | | -} else { |
49 | | - $expectedSign = 1; |
50 | | -} |
51 | | - |
52 | | -$res = $dbw->query( $sql, $fname ); |
53 | | - |
54 | | -$lastNormal = 0; |
55 | | -$badRevs = array(); |
56 | | -$numGoodRevs = 0; |
57 | | - |
58 | | -while ( $row = $dbw->fetchObject( $res ) ) { |
59 | | - $timestamp = wfTimestamp( TS_UNIX, $row->rev_timestamp ); |
60 | | - $delta = $timestamp - $lastNormal; |
61 | | - $sign = $delta == 0 ? 0 : $delta / abs( $delta ); |
62 | | - if ( $sign == 0 || $sign == $expectedSign ) { |
63 | | - // Monotonic change |
64 | | - $lastNormal = $timestamp; |
65 | | - ++ $numGoodRevs; |
66 | | - continue; |
67 | | - } elseif ( abs( $delta ) <= $grace ) { |
68 | | - // Non-monotonic change within grace interval |
69 | | - ++ $numGoodRevs; |
70 | | - continue; |
71 | | - } else { |
72 | | - // Non-monotonic change larger than grace interval |
73 | | - $badRevs[] = $row->rev_id; |
| 87 | + If the offset is right, then increase the search interval until there are enough |
| 88 | + good revisions to provide a majority reference. |
| 89 | + ", true ); |
| 90 | + } elseif ( $numBadRevs == 0 ) { |
| 91 | + $this->output( "No bad revisions found.\n" ); |
| 92 | + exit(0); |
| 93 | + } |
| 94 | + |
| 95 | + $this->output( sprintf( "Fixing %d revisions (%.2f%% of revisions in search interval)\n", |
| 96 | + $numBadRevs, $numBadRevs / ($numGoodRevs + $numBadRevs) * 100 ) ); |
| 97 | + |
| 98 | + $fixup = -$offset; |
| 99 | + $sql = "UPDATE $revisionTable " . |
| 100 | + "SET rev_timestamp=DATE_FORMAT(DATE_ADD(rev_timestamp, INTERVAL $fixup SECOND), '%Y%m%d%H%i%s') " . |
| 101 | + "WHERE rev_id IN (" . $dbw->makeList( $badRevs ) . ')'; |
| 102 | + $dbw->query( $sql, __METHOD__ ); |
| 103 | + $this->output( "Done\n" ); |
74 | 104 | } |
75 | 105 | } |
76 | | -$dbw->freeResult( $res ); |
77 | 106 | |
78 | | -$numBadRevs = count( $badRevs ); |
79 | | -if ( $numBadRevs > $numGoodRevs ) { |
80 | | - echo |
81 | | -"The majority of revisions in the search interval are marked as bad. |
82 | | - |
83 | | -Are you sure the offset ($offset) has the right sign? Positive means the clock |
84 | | -was incorrectly set forward, negative means the clock was incorrectly set back. |
85 | | - |
86 | | -If the offset is right, then increase the search interval until there are enough |
87 | | -good revisions to provide a majority reference. |
88 | | -"; |
89 | | - |
90 | | - exit(1); |
91 | | -} elseif ( $numBadRevs == 0 ) { |
92 | | - echo "No bad revisions found.\n"; |
93 | | - exit(0); |
94 | | -} |
95 | | - |
96 | | -printf( "Fixing %d revisions (%.2f%% of revisions in search interval)\n", |
97 | | - $numBadRevs, $numBadRevs / ($numGoodRevs + $numBadRevs) * 100 ); |
98 | | - |
99 | | -$fixup = -$offset; |
100 | | -$sql = "UPDATE $revisionTable " . |
101 | | - "SET rev_timestamp=DATE_FORMAT(DATE_ADD(rev_timestamp, INTERVAL $fixup SECOND), '%Y%m%d%H%i%s') " . |
102 | | - "WHERE rev_id IN (" . $dbw->makeList( $badRevs ) . ')'; |
103 | | -//echo "$sql\n"; |
104 | | -$dbw->query( $sql, $fname ); |
105 | | -echo "Done\n"; |
106 | | - |
107 | | - |
| 107 | +$maintClass = "FixTimestamps"; |
| 108 | +require_once( DO_MAINTENANCE ); |
Index: branches/maintenance-work/maintenance/populateLogUsertext.php |
— | — | @@ -9,9 +9,59 @@ |
10 | 10 | * @ingroup Maintenance
|
11 | 11 | */
|
12 | 12 |
|
13 | | -require_once 'commandLine.inc';
|
14 | | -require_once 'populateLogUsertext.inc';
|
15 | | -
|
16 | | -$db =& wfGetDB( DB_MASTER );
|
| 13 | +require_once( "Maintenance.php" );
|
17 | 14 |
|
18 | | -populate_logusertext( $db );
|
| 15 | +class PopulateLogUsertext extends Maintenance {
|
| 16 | + public function __construct() {
|
| 17 | + parent::__construct();
|
| 18 | + $this->mDescription = "Populates the log_user_text";
|
| 19 | + $this->setBatchSize( 100 );
|
| 20 | + }
|
| 21 | +
|
| 22 | + public function execute() {
|
| 23 | + $db = wfGetDB( DB_MASTER );
|
| 24 | + $start = $db->selectField( 'logging', 'MIN(log_id)', false, __METHOD__ );
|
| 25 | + if( !$start ) {
|
| 26 | + $this->output( "Nothing to do.\n" );
|
| 27 | + return true;
|
| 28 | + }
|
| 29 | + $end = $db->selectField( 'logging', 'MAX(log_id)', false, __METHOD__ );
|
| 30 | +
|
| 31 | + # Do remaining chunk
|
| 32 | + $end += $this->mBatchSize - 1;
|
| 33 | + $blockStart = $start;
|
| 34 | + $blockEnd = $start + $this->mBatchSize - 1;
|
| 35 | + while( $blockEnd <= $end ) {
|
| 36 | + $this->output( "...doing log_id from $blockStart to $blockEnd\n" );
|
| 37 | + $cond = "log_id BETWEEN $blockStart AND $blockEnd AND log_user = user_id";
|
| 38 | + $res = $db->select( array('logging','user'),
|
| 39 | + array('log_id','user_name'), $cond, __METHOD__ );
|
| 40 | + $batch = array();
|
| 41 | + $db->begin();
|
| 42 | + while( $row = $db->fetchObject( $res ) ) {
|
| 43 | + $db->update( 'logging', array('log_user_text' => $row->user_name),
|
| 44 | + array('log_id' => $row->log_id), __METHOD__ );
|
| 45 | + }
|
| 46 | + $db->commit();
|
| 47 | + $blockStart += $this->mBatchSize;
|
| 48 | + $blockEnd += $this->mBatchSize;
|
| 49 | + wfWaitForSlaves( 5 );
|
| 50 | + }
|
| 51 | + if( $db->insert(
|
| 52 | + 'updatelog',
|
| 53 | + array( 'ul_key' => 'populate log_usertext' ),
|
| 54 | + __METHOD__,
|
| 55 | + 'IGNORE'
|
| 56 | + )
|
| 57 | + ) {
|
| 58 | + $this->output( "log_usertext population complete.\n" );
|
| 59 | + return true;
|
| 60 | + } else {
|
| 61 | + $this->output( "Could not insert log_usertext population row.\n" );
|
| 62 | + return false;
|
| 63 | + }
|
| 64 | + }
|
| 65 | +}
|
| 66 | +
|
| 67 | +$maintClass = "PopulateLogUsertext";
|
| 68 | +require_once( DO_MAINTENANCE );
|
Index: branches/maintenance-work/maintenance/namespaceDupes.php |
— | — | @@ -22,33 +22,50 @@ |
23 | 23 | * @ingroup Maintenance |
24 | 24 | */ |
25 | 25 | |
26 | | -$options = array( 'fix', 'suffix', 'help' ); |
| 26 | +require_once( "Maintenance.php" ); |
27 | 27 | |
28 | | -/** */ |
29 | | -require_once( 'commandLine.inc' ); |
| 28 | +class NamespaceConflictChecker extends Maintenance { |
| 29 | + public function __construct() { |
| 30 | + parent::__construct(); |
| 31 | + $this->mDescription = ""; |
| 32 | + $this->addOption( 'fix', 'Attempt to automatically fix errors' ); |
| 33 | + $this->addOption( 'suffix', "Dupes will be renamed with correct namespace with\n" . |
| 34 | + "\t\t<text> Appended after the article name", false, true ); |
| 35 | + $this->addOption( 'prefix', "Do an explicit check for the given title prefix\n" . |
| 36 | + "\t\tappended after the article name", false, true ); |
| 37 | + $this->addOption( 'wiki', 'Enter the wiki database to edit', false, true ); |
| 38 | + } |
30 | 39 | |
31 | | -if(isset( $options['help'] ) ) { |
32 | | -print <<<ENDS |
33 | | -usage: namespaceDupes.php [--fix] [--suffix=<text>] [--help] |
34 | | - --help : this help message |
35 | | - --fix : attempt to automatically fix errors |
36 | | - --suffix=<text> : dupes will be renamed with correct namespace with <text> |
37 | | - appended after the article name. |
38 | | - --prefix=<text> : Do an explicit check for the given title prefix |
39 | | - in place of the standard namespace list. |
40 | | - --verbose : Display output for checked namespaces without conflicts |
41 | | - --wiki=<wiki> : enter the wiki database to edit |
42 | | -ENDS; |
43 | | -die; |
44 | | -} |
| 40 | + public function execute() { |
| 41 | + global $wgTitle; |
45 | 42 | |
46 | | -class NamespaceConflictChecker { |
47 | | - function NamespaceConflictChecker( $db, $verbose=false ) { |
48 | | - $this->db = $db; |
49 | | - $this->verbose = $verbose; |
| 43 | + $this->db = wfGetDB( DB_MASTER ); |
| 44 | + $wgTitle = Title::newFromText( 'Namespace title conflict cleanup script' ); |
| 45 | + |
| 46 | + $fix = $this->hasOption( 'fix' ); |
| 47 | + $suffix = $this->getOption( 'suffix', '' ); |
| 48 | + $prefix = $this->getOption( 'prefix', '' ); |
| 49 | + $key = intval( $this->getOption( 'key', 0 ) ); |
| 50 | + |
| 51 | + if( $prefix ) { |
| 52 | + $retval = $this->checkPrefix( $key, $prefix, $fix, $suffix ); |
| 53 | + } else { |
| 54 | + $retval = $this->checkAll( $fix, $suffix ); |
| 55 | + } |
| 56 | + |
| 57 | + if( $retval ) { |
| 58 | + $this->output( "\nLooks good!\n" ); |
| 59 | + } else { |
| 60 | + $this->output( "\nOh noeees\n" ); |
| 61 | + } |
50 | 62 | } |
51 | 63 | |
52 | | - function checkAll( $fix, $suffix = '' ) { |
| 64 | + /** |
| 65 | + * @todo Document |
| 66 | + * @param $fix bool Whether or not to fix broken entries |
| 67 | + * @param $suffix String Suffix to append to renamed articles |
| 68 | + */ |
| 69 | + private function checkAll( $fix, $suffix = '' ) { |
53 | 70 | global $wgContLang, $wgNamespaceAliases, $wgCanonicalNamespaceNames; |
54 | 71 | global $wgCapitalLinks; |
55 | 72 | |
— | — | @@ -112,7 +129,11 @@ |
113 | 130 | } |
114 | 131 | return $ok; |
115 | 132 | } |
116 | | - |
| 133 | + |
| 134 | + /** |
| 135 | + * Get the interwiki list |
| 136 | + * @return array |
| 137 | + */ |
117 | 138 | private function getInterwikiList() { |
118 | 139 | $result = $this->db->select( 'interwiki', array( 'iw_prefix' ) ); |
119 | 140 | $prefixes = array(); |
— | — | @@ -123,7 +144,14 @@ |
124 | 145 | return $prefixes; |
125 | 146 | } |
126 | 147 | |
127 | | - function checkNamespace( $ns, $name, $fix, $suffix = '' ) { |
| 148 | + /** |
| 149 | + * @todo Document |
| 150 | + * @param $ns int A namespace id |
| 151 | + * @param $name String |
| 152 | + * @param $fix bool Whether to fix broken entries |
| 153 | + * @param $suffix String Suffix to append to renamed articles |
| 154 | + */ |
| 155 | + private function checkNamespace( $ns, $name, $fix, $suffix = '' ) { |
128 | 156 | if( $ns == 0 ) { |
129 | 157 | $header = "Checking interwiki prefix: \"$name\"\n"; |
130 | 158 | } else { |
— | — | @@ -133,15 +161,11 @@ |
134 | 162 | $conflicts = $this->getConflicts( $ns, $name ); |
135 | 163 | $count = count( $conflicts ); |
136 | 164 | if( $count == 0 ) { |
137 | | - if( $this->verbose ) { |
138 | | - echo $header; |
139 | | - echo "... no conflicts detected!\n"; |
140 | | - } |
| 165 | + $this->output( $header . "... no conflict detected!\n" ); |
141 | 166 | return true; |
142 | 167 | } |
143 | 168 | |
144 | | - echo $header; |
145 | | - echo "... $count conflicts detected:\n"; |
| 169 | + $this->output( $header . "... $count conflicts detected:\n" ); |
146 | 170 | $ok = true; |
147 | 171 | foreach( $conflicts as $row ) { |
148 | 172 | $resolvable = $this->reportConflict( $row, $suffix ); |
— | — | @@ -156,12 +180,18 @@ |
157 | 181 | /** |
158 | 182 | * @todo: do this for reals |
159 | 183 | */ |
160 | | - function checkPrefix( $key, $prefix, $fix, $suffix = '' ) { |
161 | | - echo "Checking prefix \"$prefix\" vs namespace $key\n"; |
| 184 | + private function checkPrefix( $key, $prefix, $fix, $suffix = '' ) { |
| 185 | + $this->output( "Checking prefix \"$prefix\" vs namespace $key\n" ); |
162 | 186 | return $this->checkNamespace( $key, $prefix, $fix, $suffix ); |
163 | 187 | } |
164 | 188 | |
165 | | - function getConflicts( $ns, $name ) { |
| 189 | + /** |
| 190 | + * Find pages in mainspace that have a prefix of the new namespace |
| 191 | + * so we know titles that will need migrating |
| 192 | + * @param $ns int Namespace id (id for new namespace?) |
| 193 | + * @param $name String Prefix that is being made a namespace |
| 194 | + */ |
| 195 | + private function getConflicts( $ns, $name ) { |
166 | 196 | $page = 'page'; |
167 | 197 | $table = $this->db->tableName( $page ); |
168 | 198 | |
— | — | @@ -194,52 +224,61 @@ |
195 | 225 | return $set; |
196 | 226 | } |
197 | 227 | |
198 | | - function reportConflict( $row, $suffix ) { |
| 228 | + /** |
| 229 | + * Report any conflicts we find |
| 230 | + */ |
| 231 | + private function reportConflict( $row, $suffix ) { |
199 | 232 | $newTitle = Title::makeTitleSafe( $row->namespace, $row->title ); |
200 | 233 | if( is_null($newTitle) || !$newTitle->canExist() ) { |
201 | 234 | // Title is also an illegal title... |
202 | 235 | // For the moment we'll let these slide to cleanupTitles or whoever. |
203 | | - printf( "... %d (0,\"%s\")\n", |
| 236 | + $this->output( sprintf( "... %d (0,\"%s\")\n", |
204 | 237 | $row->id, |
205 | | - $row->oldtitle ); |
206 | | - echo "... *** cannot resolve automatically; illegal title ***\n"; |
| 238 | + $row->oldtitle ) ); |
| 239 | + $this->output( "... *** cannot resolve automatically; illegal title ***\n" ); |
207 | 240 | return false; |
208 | 241 | } |
209 | | - |
210 | | - printf( "... %d (0,\"%s\") -> (%d,\"%s\") [[%s]]\n", |
| 242 | + |
| 243 | + $this->output( sprintf( "... %d (0,\"%s\") -> (%d,\"%s\") [[%s]]\n", |
211 | 244 | $row->id, |
212 | 245 | $row->oldtitle, |
213 | 246 | $newTitle->getNamespace(), |
214 | 247 | $newTitle->getDBkey(), |
215 | | - $newTitle->getPrefixedText() ); |
| 248 | + $newTitle->getPrefixedText() ) ); |
216 | 249 | |
217 | 250 | $id = $newTitle->getArticleId(); |
218 | 251 | if( $id ) { |
219 | | - echo "... *** cannot resolve automatically; page exists with ID $id ***\n"; |
| 252 | + $this->output( "... *** cannot resolve automatically; page exists with ID $id ***\n" ); |
220 | 253 | return false; |
221 | 254 | } else { |
222 | 255 | return true; |
223 | 256 | } |
224 | 257 | } |
225 | 258 | |
226 | | - function resolveConflict( $row, $resolvable, $suffix ) { |
| 259 | + /** |
| 260 | + * Resolve any conflicts |
| 261 | + * @param $row Row from the page table to fix |
| 262 | + * @param $resolveable bool |
| 263 | + * @param $suffix String Suffix to append to the fixed page |
| 264 | + */ |
| 265 | + private function resolveConflict( $row, $resolvable, $suffix ) { |
227 | 266 | if( !$resolvable ) { |
228 | | - echo "... *** old title {$row->title}\n"; |
| 267 | + $this->output( "... *** old title {$row->title}\n" ); |
229 | 268 | while( true ) { |
230 | 269 | $row->title .= $suffix; |
231 | | - echo "... *** new title {$row->title}\n"; |
| 270 | + $this->output( "... *** new title {$row->title}\n" ); |
232 | 271 | $title = Title::makeTitleSafe( $row->namespace, $row->title ); |
233 | 272 | if ( ! $title ) { |
234 | | - echo "... !!! invalid title\n"; |
| 273 | + $this->output( "... !!! invalid title\n" ); |
235 | 274 | return false; |
236 | 275 | } |
237 | 276 | if ( $id = $title->getArticleId() ) { |
238 | | - echo "... *** page exists with ID $id ***\n"; |
| 277 | + $this->output( "... *** page exists with ID $id ***\n" ); |
239 | 278 | } else { |
240 | 279 | break; |
241 | 280 | } |
242 | 281 | } |
243 | | - echo "... *** using suffixed form [[" . $title->getPrefixedText() . "]] ***\n"; |
| 282 | + $this->output( "... *** using suffixed form [[" . $title->getPrefixedText() . "]] ***\n" ); |
244 | 283 | } |
245 | 284 | $tables = array( 'page' ); |
246 | 285 | foreach( $tables as $table ) { |
— | — | @@ -248,8 +287,13 @@ |
249 | 288 | return true; |
250 | 289 | } |
251 | 290 | |
252 | | - function resolveConflictOn( $row, $table ) { |
253 | | - echo "... resolving on $table... "; |
| 291 | + /** |
| 292 | + * Resolve a given conflict |
| 293 | + * @param $row Row from the old broken entry |
| 294 | + * @param $table String Table to update |
| 295 | + */ |
| 296 | + private function resolveConflictOn( $row, $table ) { |
| 297 | + $this->output( "... resolving on $table... " ); |
254 | 298 | $newTitle = Title::makeTitleSafe( $row->namespace, $row->title ); |
255 | 299 | $this->db->update( $table, |
256 | 300 | array( |
— | — | @@ -261,37 +305,10 @@ |
262 | 306 | "{$table}_title" => $row->oldtitle, |
263 | 307 | ), |
264 | 308 | __METHOD__ ); |
265 | | - echo "ok.\n"; |
| 309 | + $this->output( "ok.\n" ); |
266 | 310 | return true; |
267 | 311 | } |
268 | 312 | } |
269 | 313 | |
270 | | - |
271 | | - |
272 | | - |
273 | | -$wgTitle = Title::newFromText( 'Namespace title conflict cleanup script' ); |
274 | | - |
275 | | -$verbose = isset( $options['verbose'] ); |
276 | | -$fix = isset( $options['fix'] ); |
277 | | -$suffix = isset( $options['suffix'] ) ? $options['suffix'] : ''; |
278 | | -$prefix = isset( $options['prefix'] ) ? $options['prefix'] : ''; |
279 | | -$key = isset( $options['key'] ) ? intval( $options['key'] ) : 0; |
280 | | - |
281 | | -$dbw = wfGetDB( DB_MASTER ); |
282 | | -$duper = new NamespaceConflictChecker( $dbw, $verbose ); |
283 | | - |
284 | | -if( $prefix ) { |
285 | | - $retval = $duper->checkPrefix( $key, $prefix, $fix, $suffix ); |
286 | | -} else { |
287 | | - $retval = $duper->checkAll( $fix, $suffix ); |
288 | | -} |
289 | | - |
290 | | -if( $retval ) { |
291 | | - echo "\nLooks good!\n"; |
292 | | - exit( 0 ); |
293 | | -} else { |
294 | | - echo "\nOh noeees\n"; |
295 | | - exit( -1 ); |
296 | | -} |
297 | | - |
298 | | - |
| 314 | +$maintClass = "NamespaceConflictChecker"; |
| 315 | +require_once( DO_MAINTENANCE ); |
Index: branches/maintenance-work/maintenance/fixSlaveDesync.php |
— | — | @@ -4,193 +4,199 @@ |
5 | 5 | * @ingroup Maintenance |
6 | 6 | */ |
7 | 7 | |
8 | | -$wgUseRootUser = true; |
9 | | -require_once( 'commandLine.inc' ); |
| 8 | +require_once( "Maintenance.php" ); |
10 | 9 | |
11 | | -//$wgDebugLogFile = '/dev/stdout'; |
12 | | - |
13 | | -$slaveIndexes = array(); |
14 | | -for ( $i = 1; $i < count( $wgDBservers ); $i++ ) { |
15 | | - if ( wfGetLB()->isNonZeroLoad( $i ) ) { |
16 | | - $slaveIndexes[] = $i; |
| 10 | +class FixSlaveDesync extends Maintenance { |
| 11 | + public function __construct() { |
| 12 | + parent::__construct(); |
| 13 | + $this->mDescription = ""; |
| 14 | + |
17 | 15 | } |
18 | | -} |
19 | | -/* |
20 | | -foreach ( wfGetLB()->mServers as $i => $server ) { |
21 | | - wfGetLB()->mServers[$i]['flags'] |= DBO_DEBUG; |
22 | | -}*/ |
23 | | -$reportingInterval = 1000; |
| 16 | + |
| 17 | + public function execute() { |
| 18 | + global $wgUseRootUser, $wgDBservers; |
| 19 | + $wgUseRootUser = true; |
24 | 20 | |
25 | | -if ( isset( $args[0] ) ) { |
26 | | - desyncFixPage( $args[0] ); |
27 | | -} else { |
28 | | - $dbw = wfGetDB( DB_MASTER ); |
29 | | - $maxPage = $dbw->selectField( 'page', 'MAX(page_id)', false, 'fixDesync.php' ); |
30 | | - $corrupt = findPageLatestCorruption(); |
31 | | - foreach ( $corrupt as $id => $dummy ) { |
32 | | - desyncFixPage( $id ); |
33 | | - } |
34 | | - /* |
35 | | - for ( $i=1; $i <= $maxPage; $i++ ) { |
36 | | - desyncFixPage( $i ); |
37 | | - if ( !($i % $reportingInterval) ) { |
38 | | - print "$i\n"; |
| 21 | + $slaveIndexes = array(); |
| 22 | + for ( $i = 1; $i < count( $wgDBservers ); $i++ ) { |
| 23 | + if ( wfGetLB()->isNonZeroLoad( $i ) ) { |
| 24 | + $slaveIndexes[] = $i; |
| 25 | + } |
39 | 26 | } |
40 | | - }*/ |
41 | | -} |
42 | 27 | |
43 | | -function findPageLatestCorruption() { |
44 | | - $desync = array(); |
45 | | - $n = 0; |
46 | | - $dbw = wfGetDB( DB_MASTER ); |
47 | | - $masterIDs = array(); |
48 | | - $res = $dbw->select( 'page', array( 'page_id', 'page_latest' ), array( 'page_id<6054123' ), __METHOD__ ); |
49 | | - print "Number of pages: " . $dbw->numRows( $res ) . "\n"; |
50 | | - while ( $row = $dbw->fetchObject( $res ) ) { |
51 | | - $masterIDs[$row->page_id] = $row->page_latest; |
52 | | - if ( !( ++$n % 10000 ) ) { |
53 | | - print "$n\r"; |
| 28 | + if ( $this->hasArg() ) { |
| 29 | + $this->desyncFixPage( $this->getArg() ); |
| 30 | + } else { |
| 31 | + $dbw = wfGetDB( DB_MASTER ); |
| 32 | + $maxPage = $dbw->selectField( 'page', 'MAX(page_id)', false, __METHOD__ ); |
| 33 | + $corrupt = $this->findPageLatestCorruption(); |
| 34 | + foreach ( $corrupt as $id => $dummy ) { |
| 35 | + $this->desyncFixPage( $id ); |
| 36 | + } |
54 | 37 | } |
55 | 38 | } |
56 | | - print "\n"; |
57 | | - $dbw->freeResult( $res ); |
58 | | - |
59 | | - global $slaveIndexes; |
60 | | - foreach ( $slaveIndexes as $i ) { |
61 | | - $db = wfGetDB( $i ); |
62 | | - $res = $db->select( 'page', array( 'page_id', 'page_latest' ), array( 'page_id<6054123' ), __METHOD__ ); |
63 | | - while ( $row = $db->fetchObject( $res ) ) { |
64 | | - if ( isset( $masterIDs[$row->page_id] ) && $masterIDs[$row->page_id] != $row->page_latest ) { |
65 | | - $desync[$row->page_id] = true; |
66 | | - print $row->page_id . "\t"; |
| 39 | + |
| 40 | + /** |
| 41 | + * Find all pages that have a corrupted page_latest |
| 42 | + * @return array |
| 43 | + */ |
| 44 | + private function findPageLatestCorruption() { |
| 45 | + $desync = array(); |
| 46 | + $n = 0; |
| 47 | + $dbw = wfGetDB( DB_MASTER ); |
| 48 | + $masterIDs = array(); |
| 49 | + $res = $dbw->select( 'page', array( 'page_id', 'page_latest' ), array( 'page_id<6054123' ), __METHOD__ ); |
| 50 | + $this->output( "Number of pages: " . $dbw->numRows( $res ) . "\n" ); |
| 51 | + while ( $row = $dbw->fetchObject( $res ) ) { |
| 52 | + $masterIDs[$row->page_id] = $row->page_latest; |
| 53 | + if ( !( ++$n % 10000 ) ) { |
| 54 | + $this->output( "$n\r" ); |
67 | 55 | } |
68 | 56 | } |
69 | | - $db->freeResult( $res ); |
| 57 | + $this->output( "\n" ); |
| 58 | + $dbw->freeResult( $res ); |
| 59 | + |
| 60 | + global $slaveIndexes; |
| 61 | + foreach ( $slaveIndexes as $i ) { |
| 62 | + $db = wfGetDB( $i ); |
| 63 | + $res = $db->select( 'page', array( 'page_id', 'page_latest' ), array( 'page_id<6054123' ), __METHOD__ ); |
| 64 | + while ( $row = $db->fetchObject( $res ) ) { |
| 65 | + if ( isset( $masterIDs[$row->page_id] ) && $masterIDs[$row->page_id] != $row->page_latest ) { |
| 66 | + $desync[$row->page_id] = true; |
| 67 | + $this->output( $row->page_id . "\t" ); |
| 68 | + } |
| 69 | + } |
| 70 | + $db->freeResult( $res ); |
| 71 | + } |
| 72 | + $this->output( "\n" ); |
| 73 | + return $desync; |
70 | 74 | } |
71 | | - print "\n"; |
72 | | - return $desync; |
73 | | -} |
74 | 75 | |
75 | | -function desyncFixPage( $pageID ) { |
76 | | - global $slaveIndexes; |
77 | | - $fname = 'desyncFixPage'; |
| 76 | + /** |
| 77 | + * Fix a broken page entry |
| 78 | + * @param $pageID int The page_id to fix |
| 79 | + */ |
| 80 | + private function desyncFixPage( $pageID ) { |
| 81 | + global $slaveIndexes; |
78 | 82 | |
79 | | - # Check for a corrupted page_latest |
80 | | - $dbw = wfGetDB( DB_MASTER ); |
81 | | - $dbw->begin(); |
82 | | - $realLatest = $dbw->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ), |
83 | | - $fname, 'FOR UPDATE' ); |
84 | | - #list( $masterFile, $masterPos ) = $dbw->getMasterPos(); |
85 | | - $found = false; |
86 | | - foreach ( $slaveIndexes as $i ) { |
87 | | - $db = wfGetDB( $i ); |
88 | | - /* |
89 | | - if ( !$db->masterPosWait( $masterFile, $masterPos, 10 ) ) { |
90 | | - echo "Slave is too lagged, aborting\n"; |
91 | | - $dbw->commit(); |
92 | | - sleep(10); |
93 | | - return; |
94 | | - }*/ |
95 | | - $latest = $db->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ), $fname ); |
96 | | - $max = $db->selectField( 'revision', 'MAX(rev_id)', false, $fname ); |
97 | | - if ( $latest != $realLatest && $realLatest < $max ) { |
98 | | - print "page_latest corrupted in page $pageID, server $i\n"; |
99 | | - $found = true; |
100 | | - break; |
| 83 | + # Check for a corrupted page_latest |
| 84 | + $dbw = wfGetDB( DB_MASTER ); |
| 85 | + $dbw->begin(); |
| 86 | + $realLatest = $dbw->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ), |
| 87 | + __METHOD__, 'FOR UPDATE' ); |
| 88 | + #list( $masterFile, $masterPos ) = $dbw->getMasterPos(); |
| 89 | + $found = false; |
| 90 | + foreach ( $slaveIndexes as $i ) { |
| 91 | + $db = wfGetDB( $i ); |
| 92 | + /* |
| 93 | + if ( !$db->masterPosWait( $masterFile, $masterPos, 10 ) ) { |
| 94 | + $this->output( "Slave is too lagged, aborting\n" ); |
| 95 | + $dbw->commit(); |
| 96 | + sleep(10); |
| 97 | + return; |
| 98 | + }*/ |
| 99 | + $latest = $db->selectField( 'page', 'page_latest', array( 'page_id' => $pageID ), __METHOD__ ); |
| 100 | + $max = $db->selectField( 'revision', 'MAX(rev_id)', false, __METHOD__ ); |
| 101 | + if ( $latest != $realLatest && $realLatest < $max ) { |
| 102 | + $this->output( "page_latest corrupted in page $pageID, server $i\n" ); |
| 103 | + $found = true; |
| 104 | + break; |
| 105 | + } |
101 | 106 | } |
102 | | - } |
103 | | - if ( !$found ) { |
104 | | - print "page_id $pageID seems fine\n"; |
105 | | - $dbw->commit(); |
106 | | - return; |
107 | | - } |
| 107 | + if ( !$found ) { |
| 108 | + $this->output( "page_id $pageID seems fine\n" ); |
| 109 | + $dbw->commit(); |
| 110 | + return; |
| 111 | + } |
108 | 112 | |
109 | | - # Find the missing revisions |
110 | | - $res = $dbw->select( 'revision', array( 'rev_id' ), array( 'rev_page' => $pageID ), |
111 | | - $fname, 'FOR UPDATE' ); |
112 | | - $masterIDs = array(); |
113 | | - while ( $row = $dbw->fetchObject( $res ) ) { |
114 | | - $masterIDs[] = $row->rev_id; |
115 | | - } |
116 | | - $dbw->freeResult( $res ); |
| 113 | + # Find the missing revisions |
| 114 | + $res = $dbw->select( 'revision', array( 'rev_id' ), array( 'rev_page' => $pageID ), |
| 115 | + __METHOD__, 'FOR UPDATE' ); |
| 116 | + $masterIDs = array(); |
| 117 | + while ( $row = $dbw->fetchObject( $res ) ) { |
| 118 | + $masterIDs[] = $row->rev_id; |
| 119 | + } |
| 120 | + $dbw->freeResult( $res ); |
117 | 121 | |
118 | | - $res = $db->select( 'revision', array( 'rev_id' ), array( 'rev_page' => $pageID ), $fname ); |
119 | | - $slaveIDs = array(); |
120 | | - while ( $row = $db->fetchObject( $res ) ) { |
121 | | - $slaveIDs[] = $row->rev_id; |
122 | | - } |
123 | | - $db->freeResult( $res ); |
124 | | - if ( count( $masterIDs ) < count( $slaveIDs ) ) { |
125 | | - $missingIDs = array_diff( $slaveIDs, $masterIDs ); |
126 | | - if ( count( $missingIDs ) ) { |
127 | | - print "Found " . count( $missingIDs ) . " lost in master, copying from slave... "; |
128 | | - $dbFrom = $db; |
129 | | - $found = true; |
130 | | - $toMaster = true; |
131 | | - } else { |
132 | | - $found = false; |
| 122 | + $res = $db->select( 'revision', array( 'rev_id' ), array( 'rev_page' => $pageID ), __METHOD__ ); |
| 123 | + $slaveIDs = array(); |
| 124 | + while ( $row = $db->fetchObject( $res ) ) { |
| 125 | + $slaveIDs[] = $row->rev_id; |
133 | 126 | } |
134 | | - } else { |
135 | | - $missingIDs = array_diff( $masterIDs, $slaveIDs ); |
136 | | - if ( count( $missingIDs ) ) { |
137 | | - print "Found " . count( $missingIDs ) . " missing revision(s), copying from master... "; |
138 | | - $dbFrom = $dbw; |
139 | | - $found = true; |
140 | | - $toMaster = false; |
| 127 | + $db->freeResult( $res ); |
| 128 | + if ( count( $masterIDs ) < count( $slaveIDs ) ) { |
| 129 | + $missingIDs = array_diff( $slaveIDs, $masterIDs ); |
| 130 | + if ( count( $missingIDs ) ) { |
| 131 | + $this->output( "Found " . count( $missingIDs ) . " lost in master, copying from slave... " ); |
| 132 | + $dbFrom = $db; |
| 133 | + $found = true; |
| 134 | + $toMaster = true; |
| 135 | + } else { |
| 136 | + $found = false; |
| 137 | + } |
141 | 138 | } else { |
142 | | - $found = false; |
| 139 | + $missingIDs = array_diff( $masterIDs, $slaveIDs ); |
| 140 | + if ( count( $missingIDs ) ) { |
| 141 | + $this->output( "Found " . count( $missingIDs ) . " missing revision(s), copying from master... " ); |
| 142 | + $dbFrom = $dbw; |
| 143 | + $found = true; |
| 144 | + $toMaster = false; |
| 145 | + } else { |
| 146 | + $found = false; |
| 147 | + } |
143 | 148 | } |
144 | | - } |
145 | 149 | |
146 | | - if ( $found ) { |
147 | | - foreach ( $missingIDs as $rid ) { |
148 | | - print "$rid "; |
149 | | - # Revision |
150 | | - $row = $dbFrom->selectRow( 'revision', '*', array( 'rev_id' => $rid ), $fname ); |
151 | | - if ( $toMaster ) { |
152 | | - $id = $dbw->selectField( 'revision', 'rev_id', array( 'rev_id' => $rid ), |
153 | | - $fname, 'FOR UPDATE' ); |
154 | | - if ( $id ) { |
155 | | - echo "Revision already exists\n"; |
156 | | - $found = false; |
157 | | - break; |
| 150 | + if ( $found ) { |
| 151 | + foreach ( $missingIDs as $rid ) { |
| 152 | + $this->output( "$rid " ); |
| 153 | + # Revision |
| 154 | + $row = $dbFrom->selectRow( 'revision', '*', array( 'rev_id' => $rid ), __METHOD__ ); |
| 155 | + if ( $toMaster ) { |
| 156 | + $id = $dbw->selectField( 'revision', 'rev_id', array( 'rev_id' => $rid ), |
| 157 | + __METHOD__, 'FOR UPDATE' ); |
| 158 | + if ( $id ) { |
| 159 | + $this->output( "Revision already exists\n" ); |
| 160 | + $found = false; |
| 161 | + break; |
| 162 | + } else { |
| 163 | + $dbw->insert( 'revision', get_object_vars( $row ), __METHOD__, 'IGNORE' ); |
| 164 | + } |
158 | 165 | } else { |
159 | | - $dbw->insert( 'revision', get_object_vars( $row ), $fname, 'IGNORE' ); |
| 166 | + foreach ( $slaveIndexes as $i ) { |
| 167 | + $db = wfGetDB( $i ); |
| 168 | + $db->insert( 'revision', get_object_vars( $row ), __METHOD__, 'IGNORE' ); |
| 169 | + } |
160 | 170 | } |
161 | | - } else { |
162 | | - foreach ( $slaveIndexes as $i ) { |
163 | | - $db = wfGetDB( $i ); |
164 | | - $db->insert( 'revision', get_object_vars( $row ), $fname, 'IGNORE' ); |
| 171 | + |
| 172 | + # Text |
| 173 | + $row = $dbFrom->selectRow( 'text', '*', array( 'old_id' => $row->rev_text_id ), __METHOD__ ); |
| 174 | + if ( $toMaster ) { |
| 175 | + $dbw->insert( 'text', get_object_vars( $row ), __METHOD__, 'IGNORE' ); |
| 176 | + } else { |
| 177 | + foreach ( $slaveIndexes as $i ) { |
| 178 | + $db = wfGetDB( $i ); |
| 179 | + $db->insert( 'text', get_object_vars( $row ), __METHOD__, 'IGNORE' ); |
| 180 | + } |
165 | 181 | } |
166 | 182 | } |
| 183 | + $this->output( "done\n" ); |
| 184 | + } |
167 | 185 | |
168 | | - # Text |
169 | | - $row = $dbFrom->selectRow( 'text', '*', array( 'old_id' => $row->rev_text_id ), $fname ); |
| 186 | + if ( $found ) { |
| 187 | + $this->output( "Fixing page_latest... " ); |
170 | 188 | if ( $toMaster ) { |
171 | | - $dbw->insert( 'text', get_object_vars( $row ), $fname, 'IGNORE' ); |
| 189 | + #$dbw->update( 'page', array( 'page_latest' => $realLatest ), array( 'page_id' => $pageID ), __METHOD__ ); |
172 | 190 | } else { |
173 | 191 | foreach ( $slaveIndexes as $i ) { |
174 | 192 | $db = wfGetDB( $i ); |
175 | | - $db->insert( 'text', get_object_vars( $row ), $fname, 'IGNORE' ); |
| 193 | + $db->update( 'page', array( 'page_latest' => $realLatest ), array( 'page_id' => $pageID ), __METHOD__ ); |
176 | 194 | } |
177 | 195 | } |
| 196 | + $this->output( "done\n" ); |
178 | 197 | } |
179 | | - print "done\n"; |
| 198 | + $dbw->commit(); |
180 | 199 | } |
181 | | - |
182 | | - if ( $found ) { |
183 | | - print "Fixing page_latest... "; |
184 | | - if ( $toMaster ) { |
185 | | - #$dbw->update( 'page', array( 'page_latest' => $realLatest ), array( 'page_id' => $pageID ), $fname ); |
186 | | - } else { |
187 | | - foreach ( $slaveIndexes as $i ) { |
188 | | - $db = wfGetDB( $i ); |
189 | | - $db->update( 'page', array( 'page_latest' => $realLatest ), array( 'page_id' => $pageID ), $fname ); |
190 | | - } |
191 | | - } |
192 | | - print "done\n"; |
193 | | - } |
194 | | - $dbw->commit(); |
195 | 200 | } |
196 | 201 | |
197 | | - |
| 202 | +$maintClass = "FixSlaveDesync"; |
| 203 | +require_once( DO_MAINTENANCE ); |
Index: branches/maintenance-work/includes/db/DatabaseOracle.php |
— | — | @@ -881,7 +881,7 @@ |
882 | 882 | global $wgVersion, $wgDBmwschema, $wgDBts2schema, $wgDBport, $wgDBuser; |
883 | 883 | |
884 | 884 | echo "<li>Creating DB objects</li>\n"; |
885 | | - $res = dbsource( "../maintenance/ora/tables.sql", $this); |
| 885 | + $res = $this->sourceFile( "../maintenance/ora/tables.sql" ); |
886 | 886 | |
887 | 887 | // Avoid the non-standard "REPLACE INTO" syntax |
888 | 888 | echo "<li>Populating table interwiki</li>\n"; |
Index: branches/maintenance-work/includes/db/DatabasePostgres.php |
— | — | @@ -1232,7 +1232,7 @@ |
1233 | 1233 | } |
1234 | 1234 | $this->doQuery("DROP TABLE $safeschema.$ctest"); |
1235 | 1235 | |
1236 | | - $res = dbsource( "../maintenance/postgres/tables.sql", $this); |
| 1236 | + $res = $this->sourceFile( "../maintenance/postgres/tables.sql" ); |
1237 | 1237 | |
1238 | 1238 | ## Update version information |
1239 | 1239 | $mwv = $this->addQuotes($wgVersion); |
Index: branches/maintenance-work/includes/db/DatabaseIbm_db2.php |
— | — | @@ -707,7 +707,7 @@ |
708 | 708 | $this->applySchema(); |
709 | 709 | $this->begin(); |
710 | 710 | |
711 | | - $res = dbsource( "../maintenance/ibm_db2/tables.sql", $this); |
| 711 | + $res = $this->sourceFile( "../maintenance/ibm_db2/tables.sql" ); |
712 | 712 | $res = null; |
713 | 713 | |
714 | 714 | // TODO: update mediawiki_version table |
Index: branches/maintenance-work/config/index.php |
— | — | @@ -983,7 +983,7 @@ |
984 | 984 | if ($wgDatabase->isOpen()) { |
985 | 985 | $wgDBOracleDefTS = $conf->DBdefTS_ora; |
986 | 986 | $wgDBOracleTempTS = $conf->DBtempTS_ora; |
987 | | - dbsource( "../maintenance/ora/user.sql", $wgDatabase ); |
| 987 | + $wgDatabase->fileSource( "../maintenance/ora/user.sql", ); |
988 | 988 | } else { |
989 | 989 | echo "<li>Invalid database superuser, please supply a valid superuser account.</li>"; |
990 | 990 | echo "<li>ERR: ".print_r(oci_error(), true)."</li>"; |
— | — | @@ -1156,7 +1156,7 @@ |
1157 | 1157 | print " <b class='error'>If the next step fails, see <a href='http://dev.mysql.com/doc/mysql/en/old-client.html'>http://dev.mysql.com/doc/mysql/en/old-client.html</a> for help.</b>"; |
1158 | 1158 | } |
1159 | 1159 | print "</li>\n"; |
1160 | | - dbsource( "../maintenance/users.sql", $wgDatabase ); |
| 1160 | + $wgDatabase->fileSource( "../maintenance/users.sql" ); |
1161 | 1161 | } |
1162 | 1162 | } |
1163 | 1163 | } |
— | — | @@ -1190,8 +1190,8 @@ |
1191 | 1191 | # FIXME: Check for errors |
1192 | 1192 | print "<li>Creating tables..."; |
1193 | 1193 | if ($conf->DBtype == 'mysql') { |
1194 | | - dbsource( "../maintenance/tables.sql", $wgDatabase ); |
1195 | | - dbsource( "../maintenance/interwiki.sql", $wgDatabase ); |
| 1194 | + $wgDatabase->fileSource( "../maintenance/tables.sql" ); |
| 1195 | + $wgDatabase->fileSource( "../maintenance/interwiki.sql" ); |
1196 | 1196 | } elseif (is_callable(array($wgDatabase, 'setup_database'))) { |
1197 | 1197 | $wgDatabase->setup_database(); |
1198 | 1198 | } |
— | — | @@ -1224,7 +1224,7 @@ |
1225 | 1225 | } else { |
1226 | 1226 | # Yes, so run the grants |
1227 | 1227 | echo( "<li>" . htmlspecialchars( "Granting user permissions to $wgDBuser on $wgDBname..." ) ); |
1228 | | - dbsource( "../maintenance/users.sql", $wgDatabase ); |
| 1228 | + $wgDatabase->fileSource( "../maintenance/users.sql" ); |
1229 | 1229 | echo( "success.</li>\n" ); |
1230 | 1230 | } |
1231 | 1231 | } |