Rewrite reassignEdits script to be more efficient; support optional updates to recent changes table; add reporting and silent modes

This commit is contained in:
Rob Church 2006-04-29 18:44:00 +00:00
parent cfa7981e34
commit c29846f281
4 changed files with 173 additions and 96 deletions

View file

@ -142,7 +142,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
* (bug 4737) MediaWiki:Viewcount supports {{PLURAL}} now
* Fix bug in wfMsgExt under PHP 5.1.2
* (bug 5761) Project talk namespace broken in Xal, Os, Udm and Cv
* Rewrite reassignEdits script to be more efficient; support optional updates to
recent changes table
== Compatibility ==

View file

@ -1,83 +0,0 @@
<?php
/**
* Support functions for the reassignEdits script
*
* @package MediaWiki
* @subpackage Maintenance
* @author Rob Church <robchur@gmail.com>
*/
function ReassignEdits( $from, $to ) {
# This stuff needs to come off the master, wrapped in a transaction
$dbw =& wfGetDB( DB_MASTER );
$dbw->begin();
$tbl_arc = $dbw->tableName( 'archive' );
$tbl_rev = $dbw->tableName( 'revision' );
$from_txt = $from['text'];
$to_id = $to['id'];
$to_txt = $to['text'];
echo( "Searching for current revisions..." );
$res = $dbw->query( "SELECT rev_id FROM $tbl_rev WHERE rev_user_text = \"$from_txt\"" );
while( $row = $dbw->fetchObject( $res ) ) {
$cur[] = $row->rev_id;
}
$ccount = count( $cur );
echo( "found $ccount.\n" );
echo( "Searching for deleted revisions..." );
$res = $dbw->query( "SELECT ar_rev_id FROM $tbl_arc WHERE ar_user_text = \"$from_txt\"" );
while( $row = $dbw->fetchObject( $res ) ){
$old[] = $row->ar_rev_id;
}
$ocount = count( $old );
echo( "found $ocount.\n" );
if( $ccount > 0 || $ocount > 0 ) {
echo( "Reassigning edits to $to_txt..." );
}
if( $ccount > 0 ) {
$set = implode( ', ', $cur );
$res = $dbw->query( "UPDATE $tbl_rev SET rev_user = $to_id, rev_user_text = \"$to_txt\" WHERE rev_id IN ( $set )" );
}
if( $ocount > 0 ) {
$set = implode( ', ', $old );
$res = $dbw->query( "UPDATE $tbl_arc SET ar_user = $to_id, ar_user_text = \"$to_txt\" WHERE ar_rev_id IN ( $set )" );
}
if( $ccount > 0 || $ocount > 0 ) {
echo( "done.\n" );
}
$dbw->commit();
return( true );
}
function GetUserDetails( $spec ) {
# IP addresses are quick to handle
if( User::isIP( $spec ) ) {
return( array( 'id' => 0, 'text' => $spec, 'valid' => true ) );
}
# Need to check the user exists and get ID and canonical username
$user = User::newFromName( $spec );
if( $user->getID() ) {
# We have them
return( array( 'id' => $user->getID(), 'text' => $user->getName(), 'valid' => true ) );
} else {
# No such user
return( array( 'id' => 0, 'text' => $spec, 'valid' => false ) );
}
}
?>

View file

@ -0,0 +1,144 @@
<?php
/**
* Support functions for the reassignEdits script
*
* @package MediaWiki
* @subpackage Maintenance
* @author Rob Church <robchur@gmail.com>
* @licence GNU General Public Licence 2.0 or later
*/
/**
* Reassign edits from one user to another
*
* @param $from User to take edits from
* @param $to User to assign edits to
* @param $rc Update the recent changes table
* @param $report Don't change things; just echo numbers
* @return integer Number of entries changed, or that would be changed
*/
function reassignEdits( &$from, &$to, $rc = false, $report = false ) {
$dbw =& wfGetDB( DB_MASTER );
$dbw->immediateBegin();
$fname = 'reassignEdits';
# Count things
out( "Checking current edits..." );
$res = $dbw->select( 'revision', 'COUNT(*) AS count', userConditions( $from, 'rev_user', 'rev_user_text' ), $fname );
$row = $dbw->fetchObject( $res );
$cur = $row->count;
out( "found {$cur}.\n" );
out( "Checking deleted edits..." );
$res = $dbw->select( 'archive', 'COUNT(*) AS count', userConditions( $from, 'ar_user', 'ar_user_text' ), $fname );
$row = $dbw->fetchObject( $res );
$del = $row->count;
out( "found {$del}.\n" );
# Don't count recent changes if we're not supposed to
if( $rc ) {
out( "Checking recent changes..." );
$res = $dbw->select( 'recentchanges', 'COUNT(*) AS count', userConditions( $from, 'rc_user', 'rc_user_text' ), $fname );
$row = $dbw->fetchObject( $res );
$rec = $row->count;
out( "found {$rec}.\n" );
} else {
$rec = 0;
}
$total = $cur + $del + $rec;
out( "\nTotal entries to change: {$total}\n" );
if( !$report ) {
if( $total ) {
# Reassign edits
out( "\nReassigning current edits..." );
$res = $dbw->update( 'revision', userSpecification( $to, 'rev_user', 'rev_user_text' ), userConditions( $from, 'rev_user', 'rev_user_text' ), $fname );
out( "done.\nReassigning deleted edits..." );
$res = $dbw->update( 'archive', userSpecification( $to, 'ar_user', 'ar_user_text' ), userConditions( $from, 'ar_user', 'ar_user_text' ), $fname );
out( "done.\n" );
# Update recent changes if required
if( $rc ) {
out( "Updating recent changes..." );
$res = $dbw->update( 'recentchanges', userSpecification( $to, 'rc_user', 'rc_user_text' ), userConditions( $from, 'rc_user', 'rc_user_text' ), $fname );
out( "done.\n" );
}
}
}
$dbw->immediateCommit();
return (int)$total;
}
/**
* Return the most efficient set of user conditions
* i.e. a user => id mapping, or a user_text => text mapping
*
* @param $user User for the condition
* @param $idfield Field name containing the identifier
* @param $utfield Field name containing the user text
* @return array
*/
function userConditions( &$user, $idfield, $utfield ) {
return $user->getId() ? array( $idfield => $user->getID() ) : array( $utfield => $user->getName() );
}
/**
* Return user specifications
* i.e. user => id, user_text => text
*
* @param $user User for the spec
* @param $idfield Field name containing the identifier
* @param $utfield Field name containing the user text
* @return array
*/
function userSpecification( &$user, $idfield, $utfield ) {
return array( $idfield => $user->getId(), $utfield => $user->getName() );
}
/**
* Echo output if $wgSilent is off
*
* @param $output Output to echo
* @return bool True if the output was echoed
*/
function out( $output ) {
global $wgSilent;
if( !$wgSilent ) {
echo( $output );
return true;
} else {
return false;
}
}
/**
* Mutator for $wgSilent
*
* @param $silent Switch on $wgSilent
*/
function silent( $silent = true ) {
global $wgSilent;
$wgSilent = $silent;
}
/**
* Initialise the user object
*
* @param $username Username or IP address
* @return User
*/
function initialiseUser( $username ) {
if( User::isIP( $username ) ) {
$user = new User();
$user->setId( 0 );
$user->setName( $username );
} else {
$user = User::newFromName( $username );
}
$user->loadFromDatabase();
return $user;
}
?>

View file

@ -6,26 +6,38 @@
* @package MediaWiki
* @subpackage Maintenance
* @author Rob Church <robchur@gmail.com>
* @licence GNU General Public Licence 2.0 or later
*/
$options = array( 'force' );
$options = array( 'force', 'norc', 'quiet', 'report' );
require_once( 'commandLine.inc' );
require_once( 'reassignEdits.inc' );
require_once( 'reassignEdits.inc.php' );
echo( "Reassign Edits\n\n" );
# Set silent mode; --report overrides --quiet
if( !@$options['report'] && @$options['quiet'] )
setSilent();
out( "Reassign Edits\n\n" );
if( @$args[0] && @$args[1] ) {
$from = GetUserDetails( $args[0] );
$to = GetUserDetails( $args[1] );
$tor = $args[1];
# Set up the users involved
$from =& initialiseUser( $args[0] );
$to =& initialiseUser( $args[1] );
if( $to['valid'] || @$options['force'] ) {
ReassignEdits( $from, $to );
# If the target doesn't exist, and --force is not set, stop here
if( $to->getId() || @$options['force'] ) {
# Reassign the edits
$report = @$options['report'];
$count = reassignEdits( $from, $to, !@$options['norc'], $report );
# If reporting, and there were items, advise the user to run without --report
if( $report )
out( "Run the script again without --report to update.\n" );
} else {
echo( "User \"$tor\" not found.\n" );
$ton = $to->getName();
echo( "User '{$ton}' not found.\n" );
}
} else {
ShowUsage();
}
@ -33,10 +45,13 @@ if( @$args[0] && @$args[1] ) {
/** Show script usage information */
function ShowUsage() {
echo( "Reassign edits from one user to another.\n\n" );
echo( "Usage: php reassignEdits.php <from> <to> [--force]\n\n" );
echo( "Usage: php reassignEdits.php [--force|--quiet|--norc|--report] <from> <to>\n\n" );
echo( " <from> : Name of the user to assign edits from\n" );
echo( " <to> : Name of the user to assign edits to\n" );
echo( " --force : Reassign even if the target user doesn't exist\n\n" );
echo( " --force : Reassign even if the target user doesn't exist\n" );
echo( " --quiet : Don't print status information (except for errors)\n" );
echo( " --norc : Don't update the recent changes table\n" );
echo( " --report : Print out details of what would be changed, but don't update it\n\n" );
}
?>