00001 <?php
00007 require_once "commandLine.inc";
00008
00009 if( isset( $options['help'] ) ) {
00010 die( "Batch-recalculate user_editcount fields from the revision table.
00011 Options:
00012 --quick Force the update to be done in a single query.
00013 --background Force replication-friendly mode; may be inefficient but
00014 avoids locking tables or lagging slaves with large updates;
00015 calculates counts on a slave if possible.
00016
00017 Background mode will be automatically used if the server is MySQL 4.0
00018 (which does not support subqueries) or if multiple servers are listed
00019 in \$wgDBservers, usually indicating a replication environment.
00020
00021 ");
00022 }
00023 $dbw = wfGetDB( DB_MASTER );
00024 $user = $dbw->tableName( 'user' );
00025 $revision = $dbw->tableName( 'revision' );
00026
00027 $dbver = $dbw->getServerVersion();
00028
00029
00030 $backgroundMode = count( $wgDBservers ) > 1 ||
00031 ($dbw instanceof DatabaseMySql && version_compare( $dbver, '4.1' ) < 0);
00032
00033 if( isset( $options['background'] ) ) {
00034 $backgroundMode = true;
00035 } elseif( isset( $options['quick'] ) ) {
00036 $backgroundMode = false;
00037 }
00038
00039 if( $backgroundMode ) {
00040 echo "Using replication-friendly background mode...\n";
00041
00042 $dbr = wfGetDB( DB_SLAVE );
00043 $chunkSize = 100;
00044 $lastUser = $dbr->selectField( 'user', 'MAX(user_id)', '', __FUNCTION__ );
00045
00046 $start = microtime( true );
00047 $migrated = 0;
00048 for( $min = 0; $min <= $lastUser; $min += $chunkSize ) {
00049 $max = $min + $chunkSize;
00050 $result = $dbr->query(
00051 "SELECT
00052 user_id,
00053 COUNT(rev_user) AS user_editcount
00054 FROM $user
00055 LEFT OUTER JOIN $revision ON user_id=rev_user
00056 WHERE user_id > $min AND user_id <= $max
00057 GROUP BY user_id",
00058 __FUNCTION__ );
00059
00060 while( $row = $dbr->fetchObject( $result ) ) {
00061 $dbw->update( 'user',
00062 array( 'user_editcount' => $row->user_editcount ),
00063 array( 'user_id' => $row->user_id ),
00064 __FUNCTION__ );
00065 ++$migrated;
00066 }
00067 $dbr->freeResult( $result );
00068
00069 $delta = microtime( true ) - $start;
00070 $rate = ($delta == 0.0) ? 0.0 : $migrated / $delta;
00071 printf( "%s %d (%0.1f%%) done in %0.1f secs (%0.3f accounts/sec).\n",
00072 $wgDBname,
00073 $migrated,
00074 min( $max, $lastUser ) / $lastUser * 100.0,
00075 $delta,
00076 $rate );
00077
00078 wfWaitForSlaves( 10 );
00079 }
00080 } else {
00081
00082 echo "Using single-query mode...\n";
00083 $sql = "UPDATE $user SET user_editcount=(SELECT COUNT(*) FROM $revision WHERE rev_user=user_id)";
00084 $dbw->query( $sql );
00085 }
00086
00087 echo "Done!\n";
00088
00089