protected $page;
/** @var integer */
protected $pageId;
+ /** @var string */
+ protected $timestamp;
/**
* @param WikiPage $page Page we are updating
* @param integer|null $pageId ID of the page we are updating [optional]
+ * @param string|null $timestamp TS_MW timestamp of deletion
* @throws MWException
*/
- function __construct( WikiPage $page, $pageId = null ) {
+ function __construct( WikiPage $page, $pageId = null, $timestamp = null ) {
parent::__construct( false ); // no implicit transaction
$this->page = $page;
- if ( $page->exists() ) {
+ if ( $pageId ) {
+ $this->pageId = $pageId; // page ID at time of deletion
+ } elseif ( $page->exists() ) {
$this->pageId = $page->getId();
- } elseif ( $pageId ) {
- $this->pageId = $pageId;
} else {
throw new InvalidArgumentException( "Page ID not known. Page doesn't exist?" );
}
+
+ $this->timestamp = $timestamp ?: wfTimestampNow();
}
public function doUpdate() {
// This handles the case when updates have to batched into several COMMITs.
$scopedLock = LinksUpdate::acquirePageLock( $this->mDb, $id );
+ $title = $this->page->getTitle();
+
// Delete restrictions for it
$this->mDb->delete( 'page_restrictions', [ 'pr_page' => $id ], __METHOD__ );
);
$catBatches = array_chunk( $cats, $batchSize );
foreach ( $catBatches as $catBatch ) {
- $this->page->updateCategoryCounts( [], $catBatch );
+ $this->page->updateCategoryCounts( [], $catBatch, $id );
if ( count( $catBatches ) > 1 ) {
$this->mDb->commit( __METHOD__, 'flush' );
wfGetLBFactory()->waitForReplication( [ 'wiki' => $this->mDb->getWikiID() ] );
}
}
+ // Refresh the category table entry if it seems to have no pages. Check
+ // master for the most up-to-date cat_pages count.
+ if ( $title->getNamespace() === NS_CATEGORY ) {
+ $row = $this->mDb->selectRow(
+ 'category',
+ [ 'cat_id', 'cat_title', 'cat_pages', 'cat_subcats', 'cat_files' ],
+ [ 'cat_title' => $title->getDBkey(), 'cat_pages <= 0' ],
+ __METHOD__
+ );
+ if ( $row ) {
+ $cat = Category::newFromRow( $row, $title )->refreshCounts();
+ }
+ }
+
// If using cascading deletes, we can skip some explicit deletes
if ( !$this->mDb->cascadingDeletes() ) {
// Delete outgoing links
);
$this->batchDeleteByPK(
'langlinks',
- [ 'il_from' => $id ],
- [ 'il_from', 'll_lang' ],
+ [ 'll_from' => $id ],
+ [ 'll_from', 'll_lang' ],
$batchSize
);
$this->batchDeleteByPK(
'iwlinks',
- [ 'il_from' => $id ],
+ [ 'iwl_from' => $id ],
[ 'iwl_from', 'iwl_prefix', 'iwl_title' ],
$batchSize
);
// If using cleanup triggers, we can skip some manual deletes
if ( !$this->mDb->cleanupTriggers() ) {
- $title = $this->page->getTitle();
// Find recentchanges entries to clean up...
$rcIdsForTitle = $this->mDb->selectFieldValues(
'recentchanges',
[
'rc_type != ' . RC_LOG,
'rc_namespace' => $title->getNamespace(),
- 'rc_title' => $title->getDBkey()
+ 'rc_title' => $title->getDBkey(),
+ 'rc_timestamp < ' .
+ $this->mDb->addQuotes( $this->mDb->timestamp( $this->timestamp ) )
],
__METHOD__
);
}
}
- $this->mDb->onTransactionIdle( function() use ( &$scopedLock ) {
- // Release the lock *after* the final COMMIT for correctness
- ScopedCallback::consume( $scopedLock );
- } );
+ // Commit and release the lock
+ ScopedCallback::consume( $scopedLock );
}
private function batchDeleteByPK( $table, array $conds, array $pk, $bSize ) {
'wiki' => $this->mDb->getWikiID(),
'job' => new JobSpecification(
'deleteLinks',
- [ 'pageId' => $this->pageId ],
+ [ 'pageId' => $this->pageId, 'timestamp' => $this->timestamp ],
[ 'removeDuplicates' => true ],
$this->page->getTitle()
)