mTitle = $titleTo;
$this->mTable = $table;
$this->mRowsPerJob = $wgUpdateRowsPerJob;
$this->mRowsPerQuery = $wgUpdateRowsPerQuery;
}
function doUpdate() {
# Fetch the IDs
$cond = $this->getToCondition();
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( $this->mTable, $this->getFromField(), $cond, __METHOD__ );
if ( $dbr->numRows( $res ) != 0 ) {
if ( $dbr->numRows( $res ) > $this->mRowsPerJob ) {
$this->insertJobs( $res );
} else {
$this->invalidateIDs( $res );
}
}
}
function insertJobs( ResultWrapper $res ) {
$numRows = $res->numRows();
$numBatches = ceil( $numRows / $this->mRowsPerJob );
$realBatchSize = $numRows / $numBatches;
$start = false;
$jobs = array();
do {
for ( $i = 0; $i < $realBatchSize - 1; $i++ ) {
$row = $res->fetchRow();
if ( $row ) {
$id = $row[0];
} else {
$id = false;
break;
}
}
$params = array(
'table' => $this->mTable,
'start' => $start,
'end' => ( $id !== false ? $id - 1 : false ),
);
$jobs[] = new HTMLCacheUpdateJob( $this->mTitle, $params );
$start = $id;
} while ( $start );
Job::batchInsert( $jobs );
}
function getPrefix() {
static $prefixes = array(
'pagelinks' => 'pl',
'imagelinks' => 'il',
'categorylinks' => 'cl',
'templatelinks' => 'tl',
'redirect' => 'rd',
# Not needed
# 'externallinks' => 'el',
# 'langlinks' => 'll'
);
if ( is_null( $this->mPrefix ) ) {
$this->mPrefix = $prefixes[$this->mTable];
if ( is_null( $this->mPrefix ) ) {
throw new MWException( "Invalid table type \"{$this->mTable}\" in " . __CLASS__ );
}
}
return $this->mPrefix;
}
function getFromField() {
return $this->getPrefix() . '_from';
}
function getToCondition() {
$prefix = $this->getPrefix();
switch ( $this->mTable ) {
case 'pagelinks':
case 'templatelinks':
case 'redirect':
return array(
"{$prefix}_namespace" => $this->mTitle->getNamespace(),
"{$prefix}_title" => $this->mTitle->getDBkey()
);
case 'imagelinks':
return array( 'il_to' => $this->mTitle->getDBkey() );
case 'categorylinks':
return array( 'cl_to' => $this->mTitle->getDBkey() );
}
throw new MWException( 'Invalid table type in ' . __CLASS__ );
}
/**
* Invalidate a set of IDs, right now
*/
function invalidateIDs( ResultWrapper $res ) {
global $wgUseFileCache, $wgUseSquid;
if ( $res->numRows() == 0 ) {
return;
}
$dbw = wfGetDB( DB_MASTER );
$timestamp = $dbw->timestamp();
$done = false;
while ( !$done ) {
# Get all IDs in this query into an array
$ids = array();
for ( $i = 0; $i < $this->mRowsPerQuery; $i++ ) {
$row = $res->fetchRow();
if ( $row ) {
$ids[] = $row[0];
} else {
$done = true;
break;
}
}
if ( !count( $ids ) ) {
break;
}
# Update page_touched
$dbw->update( 'page',
array( 'page_touched' => $timestamp ),
array( 'page_id IN (' . $dbw->makeList( $ids ) . ')' ),
__METHOD__
);
# Update squid
if ( $wgUseSquid || $wgUseFileCache ) {
$titles = Title::newFromIDs( $ids );
if ( $wgUseSquid ) {
$u = SquidUpdate::newFromTitles( $titles );
$u->doUpdate();
}
# Update file cache
if ( $wgUseFileCache ) {
foreach ( $titles as $title ) {
$cm = new HTMLFileCache($title);
@unlink($cm->fileCacheName());
}
}
}
}
}
}
/**
* @todo document (e.g. one-sentence top-level class description).
* @ingroup JobQueue
*/
class HTMLCacheUpdateJob extends Job {
var $table, $start, $end;
/**
* Construct a job
* @param Title $title The title linked to
* @param array $params Job parameters (table, start and end page_ids)
* @param integer $id job_id
*/
function __construct( $title, $params, $id = 0 ) {
parent::__construct( 'htmlCacheUpdate', $title, $params, $id );
$this->table = $params['table'];
$this->start = $params['start'];
$this->end = $params['end'];
}
function run() {
$update = new HTMLCacheUpdate( $this->title, $this->table );
$fromField = $update->getFromField();
$conds = $update->getToCondition();
if ( $this->start ) {
$conds[] = "$fromField >= {$this->start}";
}
if ( $this->end ) {
$conds[] = "$fromField <= {$this->end}";
}
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( $this->table, $fromField, $conds, __METHOD__ );
$update->invalidateIDs( $res );
return true;
}
}