This class is not stable to extend, nor does codesearch reveal any classes extending it outside of core, so we can just evaluate if $wgUser needs to be set for this class and subclasses in core. TableCleanup is not set up to be run directly, it requires that it be subclassed and the subclass run as a maintenance script. Within TableCleanup itself, nothing depends on $wgUser. Looking at the subclasses in core: * CleanupCaps overrides the execute method, so the code to set $wgUser in TableCleanup::execute() is not being run * CleanupImages, TitleCleanup, and ClenupWatchlist do not appear to have any code that relies on anything related to the current user or context Since nothing is using the user in any form, simply remove the write to $wgUser, no need to replace it with setting the context user Bug: T243708 Change-Id: I1a22f2ebab028822e663ab1fdcbd6c7b02331fef
176 lines
4.8 KiB
PHP
176 lines
4.8 KiB
PHP
<?php
|
|
/**
|
|
* Generic class to cleanup a database table.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
* @file
|
|
* @ingroup Maintenance
|
|
*/
|
|
|
|
require_once __DIR__ . '/Maintenance.php';
|
|
|
|
/**
|
|
* Generic class to cleanup a database table. Already subclasses Maintenance.
|
|
*
|
|
* @ingroup Maintenance
|
|
*/
|
|
class TableCleanup extends Maintenance {
|
|
protected $defaultParams = [
|
|
'table' => 'page',
|
|
'conds' => [],
|
|
'index' => 'page_id',
|
|
'callback' => 'processRow',
|
|
];
|
|
|
|
protected $dryrun = false;
|
|
protected $reportInterval = 100;
|
|
|
|
protected $processed, $updated, $count, $startTime, $table;
|
|
|
|
public function __construct() {
|
|
parent::__construct();
|
|
$this->addOption( 'dry-run', 'Perform a dry run' );
|
|
$this->addOption( 'reporting-interval', 'How often to print status line' );
|
|
$this->setBatchSize( 100 );
|
|
}
|
|
|
|
public function execute() {
|
|
$this->reportInterval = $this->getOption( 'reporting-interval', $this->reportInterval );
|
|
|
|
$this->dryrun = $this->hasOption( 'dry-run' );
|
|
|
|
if ( $this->dryrun ) {
|
|
$this->output( "Checking for bad titles...\n" );
|
|
} else {
|
|
$this->output( "Checking and fixing bad titles...\n" );
|
|
}
|
|
|
|
$this->runTable( $this->defaultParams );
|
|
}
|
|
|
|
protected function init( $count, $table ) {
|
|
$this->processed = 0;
|
|
$this->updated = 0;
|
|
$this->count = $count;
|
|
$this->startTime = microtime( true );
|
|
$this->table = $table;
|
|
}
|
|
|
|
/**
|
|
* @param int $updated
|
|
*/
|
|
protected function progress( $updated ) {
|
|
$this->updated += $updated;
|
|
$this->processed++;
|
|
if ( $this->processed % $this->reportInterval != 0 ) {
|
|
return;
|
|
}
|
|
$portion = $this->processed / $this->count;
|
|
$updateRate = $this->updated / $this->processed;
|
|
|
|
$now = microtime( true );
|
|
$delta = $now - $this->startTime;
|
|
$estimatedTotalTime = $delta / $portion;
|
|
$eta = $this->startTime + $estimatedTotalTime;
|
|
|
|
$this->output(
|
|
sprintf( "%s %s: %6.2f%% done on %s; ETA %s [%d/%d] %.2f/sec <%.2f%% updated>\n",
|
|
WikiMap::getCurrentWikiDbDomain()->getId(),
|
|
wfTimestamp( TS_DB, intval( $now ) ),
|
|
$portion * 100.0,
|
|
$this->table,
|
|
wfTimestamp( TS_DB, intval( $eta ) ),
|
|
$this->processed,
|
|
$this->count,
|
|
$this->processed / $delta,
|
|
$updateRate * 100.0
|
|
)
|
|
);
|
|
flush();
|
|
}
|
|
|
|
/**
|
|
* @param array $params
|
|
* @throws MWException
|
|
*/
|
|
public function runTable( $params ) {
|
|
$dbr = $this->getDB( DB_REPLICA );
|
|
|
|
if ( array_diff( array_keys( $params ),
|
|
[ 'table', 'conds', 'index', 'callback' ] )
|
|
) {
|
|
throw new MWException( __METHOD__ . ': Missing parameter ' . implode( ', ', $params ) );
|
|
}
|
|
|
|
$table = $params['table'];
|
|
// count(*) would melt the DB for huge tables, we can estimate here
|
|
$count = $dbr->estimateRowCount( $table, '*', '', __METHOD__ );
|
|
$this->init( $count, $table );
|
|
$this->output( "Processing $table...\n" );
|
|
|
|
$index = (array)$params['index'];
|
|
$indexConds = [];
|
|
$options = [
|
|
'ORDER BY' => implode( ',', $index ),
|
|
'LIMIT' => $this->getBatchSize()
|
|
];
|
|
$callback = [ $this, $params['callback'] ];
|
|
|
|
while ( true ) {
|
|
$conds = array_merge( $params['conds'], $indexConds );
|
|
$res = $dbr->select( $table, '*', $conds, __METHOD__, $options );
|
|
if ( !$res->numRows() ) {
|
|
// Done
|
|
break;
|
|
}
|
|
|
|
foreach ( $res as $row ) {
|
|
call_user_func( $callback, $row );
|
|
}
|
|
|
|
if ( $res->numRows() < $this->getBatchSize() ) {
|
|
// Done
|
|
break;
|
|
}
|
|
|
|
// Update the conditions to select the next batch.
|
|
// Construct a condition string by starting with the least significant part
|
|
// of the index, and adding more significant parts progressively to the left
|
|
// of the string.
|
|
$nextCond = '';
|
|
foreach ( array_reverse( $index ) as $field ) {
|
|
$encValue = $dbr->addQuotes( $row->$field );
|
|
if ( $nextCond === '' ) {
|
|
$nextCond = "$field > $encValue";
|
|
} else {
|
|
$nextCond = "$field > $encValue OR ($field = $encValue AND ($nextCond))";
|
|
}
|
|
}
|
|
$indexConds = [ $nextCond ];
|
|
}
|
|
|
|
$this->output( "Finished $table... $this->updated of $this->processed rows updated\n" );
|
|
}
|
|
|
|
/**
|
|
* @param string[] $matches
|
|
* @return string
|
|
*/
|
|
protected function hexChar( $matches ) {
|
|
return sprintf( "\\x%02x", ord( $matches[1] ) );
|
|
}
|
|
}
|