Index: branches/maintenance-work/maintenance/nextJobDB.php |
— | — | @@ -6,55 +6,71 @@ |
7 | 7 | * @ingroup Maintenance |
8 | 8 | */ |
9 | 9 | |
10 | | -$options = array( 'type' ); |
| 10 | +require_once( "Maintenance.php" ); |
11 | 11 | |
12 | | -require_once( 'commandLine.inc' ); |
13 | | - |
14 | | -$type = isset($options['type']) |
15 | | - ? $options['type'] |
16 | | - : false; |
17 | | - |
18 | | -$mckey = $type === false |
19 | | - ? "jobqueue:dbs" |
20 | | - : "jobqueue:dbs:$type"; |
21 | | - |
22 | | -$pendingDBs = $wgMemc->get( $mckey ); |
23 | | -if ( !$pendingDBs ) { |
24 | | - $pendingDBs = array(); |
25 | | - # Cross-reference DBs by master DB server |
26 | | - $dbsByMaster = array(); |
27 | | - foreach ( $wgLocalDatabases as $db ) { |
28 | | - $lb = wfGetLB( $db ); |
29 | | - $dbsByMaster[$lb->getServerName(0)][] = $db; |
| 12 | +class nextJobDB extends Maintenance { |
| 13 | + public function __construct() { |
| 14 | + parent::__construct(); |
| 15 | + $this->mDescription = "Pick a database that has pending jobs"; |
| 16 | + $this->addParam( 'type', "The type of job to search for", false, true ); |
30 | 17 | } |
31 | | - |
32 | | - foreach ( $dbsByMaster as $master => $dbs ) { |
33 | | - $dbConn = wfGetDB( DB_MASTER, array(), $dbs[0] ); |
34 | | - $stype = $dbConn->addQuotes($type); |
35 | | - |
36 | | - # Padding row for MySQL bug |
37 | | - $sql = "(SELECT '-------------------------------------------')"; |
38 | | - foreach ( $dbs as $dbName ) { |
39 | | - if ( $sql != '' ) { |
40 | | - $sql .= ' UNION '; |
41 | | - } |
42 | | - if ($type === false) |
43 | | - $sql .= "(SELECT '$dbName' FROM `$dbName`.job LIMIT 1)"; |
44 | | - else |
45 | | - $sql .= "(SELECT '$dbName' FROM `$dbName`.job WHERE job_cmd=$stype LIMIT 1)"; |
| 18 | + public function execute() { |
| 19 | + global $wgMemc; |
| 20 | + $type = $this->getParam( 'type', false ); |
| 21 | + $mckey = $type === false |
| 22 | + ? "jobqueue:dbs" |
| 23 | + : "jobqueue:dbs:$type"; |
| 24 | + $pendingDBs = $wgMemcKey->get( $mckey ); |
| 25 | + |
| 26 | + # If we didn't get it from the cache |
| 27 | + if( !$pendingDBs ) { |
| 28 | + $pendingDBs = $this->getPendingDbs( $type ); |
| 29 | + $wgMemc->get( $mckey, $pendingDBs, 300 ) |
46 | 30 | } |
47 | | - $res = $dbConn->query( $sql, 'nextJobDB.php' ); |
48 | | - $row = $dbConn->fetchRow( $res ); // discard padding row |
49 | | - while ( $row = $dbConn->fetchRow( $res ) ) { |
50 | | - $pendingDBs[] = $row[0]; |
| 31 | + # If we've got a pending job in a db, display it. |
| 32 | + if ( $pendingDBs ) { |
| 33 | + $this->output( $pendingDBs[mt_rand(0, count( $pendingDBs ) - 1)] ); |
51 | 34 | } |
52 | 35 | } |
53 | | - |
54 | | - $wgMemc->set( $mckey, $pendingDBs, 300 ); |
| 36 | + |
| 37 | + /** |
| 38 | + * Get all databases that have a pending job |
| 39 | + * @param $type String Job type |
| 40 | + * @return array |
| 41 | + */ |
| 42 | + private function getPendingDbs( $type ) { |
| 43 | + $pendingDBs = array(); |
| 44 | + # Cross-reference DBs by master DB server |
| 45 | + $dbsByMaster = array(); |
| 46 | + foreach ( $wgLocalDatabases as $db ) { |
| 47 | + $lb = wfGetLB( $db ); |
| 48 | + $dbsByMaster[$lb->getServerName(0)][] = $db; |
| 49 | + } |
| 50 | + |
| 51 | + foreach ( $dbsByMaster as $master => $dbs ) { |
| 52 | + $dbConn = wfGetDB( DB_MASTER, array(), $dbs[0] ); |
| 53 | + $stype = $dbConn->addQuotes($type); |
| 54 | + $jobTable = $dbConn->getTable( 'job' ); |
| 55 | + |
| 56 | + # Padding row for MySQL bug |
| 57 | + $sql = "(SELECT '-------------------------------------------')"; |
| 58 | + foreach ( $dbs as $dbName ) { |
| 59 | + if ( $sql != '' ) { |
| 60 | + $sql .= ' UNION '; |
| 61 | + } |
| 62 | + if ($type === false) |
| 63 | + $sql .= "(SELECT '$dbName' FROM `$dbName`.$jobTable LIMIT 1)"; |
| 64 | + else |
| 65 | + $sql .= "(SELECT '$dbName' FROM `$dbName`.$jobTable WHERE job_cmd=$stype LIMIT 1)"; |
| 66 | + } |
| 67 | + $res = $dbConn->query( $sql, __METHOD__ ); |
| 68 | + $row = $dbConn->fetchRow( $res ); // discard padding row |
| 69 | + while ( $row = $dbConn->fetchRow( $res ) ) { |
| 70 | + $pendingDBs[] = $row[0]; |
| 71 | + } |
| 72 | + } |
| 73 | + } |
55 | 74 | } |
56 | 75 | |
57 | | -if ( $pendingDBs ) { |
58 | | - echo $pendingDBs[mt_rand(0, count( $pendingDBs ) - 1)]; |
59 | | -} |
60 | | - |
61 | | - |
| 76 | +$maintClass = "nextJobDb"; |
| 77 | +require_once( DO_MAINTENANCE ); |
Index: branches/maintenance-work/maintenance/Maintenance.php |
— | — | @@ -78,7 +78,13 @@ |
79 | 79 | * @return mixed |
80 | 80 | */ |
81 | 81 | protected function getOption( $name, $default = null ) { |
82 | | - return $this->hasOption($name) ? $this->mOptions[$name] : $default; |
| 82 | + if( $this->hasOption($name) ) { |
| 83 | + return $this->mOptions[$name]; |
| 84 | + } else { |
| 85 | + // Set it so we don't have to provide the default again |
| 86 | + $this->mOptions[$name] = $default; |
| 87 | + return $this->mOptions[$name]; |
| 88 | + } |
83 | 89 | } |
84 | 90 | |
85 | 91 | /** |
Index: branches/maintenance-work/maintenance/renameDbPrefix.php |
— | — | @@ -6,62 +6,59 @@ |
7 | 7 | * @file |
8 | 8 | * @ingroup Maintenance |
9 | 9 | */ |
10 | | -$optionsWithArgs = array( 'old', 'new', 'help' ); |
| 10 | + |
| 11 | +require_once( "Maintenance.php" ); |
11 | 12 | |
12 | | -require_once( 'commandLine.inc' ); |
13 | | - |
14 | | -if( @$options['help'] || !isset( $options['old'] ) || !isset( $options['new'] ) ) { |
15 | | - print "usage: renameDbPrefix.php [--help] [--old x] [new y]\n"; |
16 | | - print " --help : this help message\n"; |
17 | | - print " --old x : old db prefix x\n"; |
18 | | - print " --old 0 : EMPTY old db prefix x\n"; |
19 | | - print " --new y : new db prefix y\n"; |
20 | | - print " --new 0 : EMPTY new db prefix\n"; |
21 | | - wfDie(); |
22 | | -} |
23 | | - |
24 | | -// Allow for no old prefix |
25 | | -if( $options['old'] === '0' ) { |
26 | | - $old = ''; |
27 | | -} else { |
28 | | - // Use nice safe, sane, prefixes |
29 | | - preg_match( '/^[a-zA-Z]+_$/', $options['old'], $m ); |
30 | | - $old = isset( $m[0] ) ? $m[0] : false; |
31 | | -} |
32 | | -// Allow for no new prefix |
33 | | -if( $options['new'] === '0' ) { |
34 | | - $new = ''; |
35 | | -} else { |
36 | | - // Use nice safe, sane, prefixes |
37 | | - preg_match( '/^[a-zA-Z]+_$/', $options['new'], $m ); |
38 | | - $new = isset( $m[0] ) ? $m[0] : false; |
39 | | -} |
40 | | - |
41 | | -if( $old === false || $new === false ) { |
42 | | - print "Invalid prefix!\n"; |
43 | | - wfDie(); |
44 | | -} |
45 | | -if( $old === $new ) { |
46 | | - print "Same prefix. Nothing to rename!\n"; |
47 | | - wfDie(); |
48 | | -} |
49 | | - |
50 | | -print "Renaming DB prefix for tables of $wgDBname from '$old' to '$new'\n"; |
51 | | -$count = 0; |
52 | | - |
53 | | -$dbw = wfGetDB( DB_MASTER ); |
54 | | -$res = $dbw->query( "SHOW TABLES LIKE '".$dbw->escapeLike( $old )."%'" ); |
55 | | -foreach( $res as $row ) { |
56 | | - // XXX: odd syntax. MySQL outputs an oddly cased "Tables of X" |
57 | | - // sort of message. Best not to try $row->x stuff... |
58 | | - $fields = get_object_vars( $row ); |
59 | | - // Silly for loop over one field... |
60 | | - foreach( $fields as $resName => $table ) { |
61 | | - // $old should be regexp safe ([a-zA-Z_]) |
62 | | - $newTable = preg_replace( '/^'.$old.'/', $new, $table ); |
63 | | - print "Renaming table $table to $newTable\n"; |
64 | | - $dbw->query( "RENAME TABLE $table TO $newTable" ); |
| 13 | +class RenameDbPrefix extends Maintenance { |
| 14 | + public function __construct() { |
| 15 | + parent::__construct(); |
| 16 | + $this->addParam( "old", "Old db prefix [0 for none]", true, true ); |
| 17 | + $this->addParam( "new", "New db prefix [0 for none]", true, true ); |
65 | 18 | } |
66 | | - $count++; |
| 19 | + |
| 20 | + public function execute() { |
| 21 | + // Allow for no old prefix |
| 22 | + if( $this->getOption( 'old', 0 ) === '0' ) { |
| 23 | + $old = ''; |
| 24 | + } else { |
| 25 | + // Use nice safe, sane, prefixes |
| 26 | + preg_match( '/^[a-zA-Z]+_$/', $this->getOption('old'), $m ); |
| 27 | + $old = isset( $m[0] ) ? $m[0] : false; |
| 28 | + } |
| 29 | + // Allow for no new prefix |
| 30 | + if( $this->getOption( 'new', 0 ) === '0' ) { |
| 31 | + $new = ''; |
| 32 | + } else { |
| 33 | + // Use nice safe, sane, prefixes |
| 34 | + preg_match( '/^[a-zA-Z]+_$/', $this->getOption('new'), $m ); |
| 35 | + $new = isset( $m[0] ) ? $m[0] : false; |
| 36 | + } |
| 37 | + |
| 38 | + if( $old === false || $new === false ) { |
| 39 | + $this->error( "Invalid prefix!\n", true ); |
| 40 | + } |
| 41 | + if( $old === $new ) { |
| 42 | + $this->( "Same prefix. Nothing to rename!\n", true ); |
| 43 | + } |
| 44 | + |
| 45 | + $this->output( "Renaming DB prefix for tables of $wgDBname from '$old' to '$new'\n" ); |
| 46 | + $count = 0; |
| 47 | + |
| 48 | + $dbw = wfGetDB( DB_MASTER ); |
| 49 | + $res = $dbw->query( "SHOW TABLES LIKE '".$dbw->escapeLike( $old )."%'" ); |
| 50 | + foreach( $res as $row ) { |
| 51 | + // XXX: odd syntax. MySQL outputs an oddly cased "Tables of X" |
| 52 | + // sort of message. Best not to try $row->x stuff... |
| 53 | + $fields = get_object_vars( $row ); |
| 54 | + // Silly for loop over one field... |
| 55 | + foreach( $fields as $resName => $table ) { |
| 56 | + // $old should be regexp safe ([a-zA-Z_]) |
| 57 | + $newTable = preg_replace( '/^'.$old.'/', $new, $table ); |
| 58 | + $this->output( "Renaming table $table to $newTable\n" ); |
| 59 | + $dbw->query( "RENAME TABLE $table TO $newTable" ); |
| 60 | + } |
| 61 | + $count++; |
| 62 | + } |
| 63 | + $this->output( "Done! [$count tables]\n" ); |
| 64 | + } |
67 | 65 | } |
68 | | -print "Done! [$count tables]\n"; |
\ No newline at end of file |