From: jenkins-bot Date: Thu, 9 Nov 2017 22:33:48 +0000 (+0000) Subject: Merge "Add action/user tracking to html cache purge jobs" X-Git-Tag: 1.31.0-rc.0~1560 X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=b5370206ff602728c08403f14756d4339bf0a708;hp=-c Merge "Add action/user tracking to html cache purge jobs" --- b5370206ff602728c08403f14756d4339bf0a708 diff --combined includes/Title.php index d043b442ac,90ae57d9f3..829be448b2 --- a/includes/Title.php +++ b/includes/Title.php @@@ -3628,20 -3628,19 +3628,20 @@@ class Title implements LinkTarget $blNamespace = "{$prefix}_namespace"; $blTitle = "{$prefix}_title"; + $pageQuery = WikiPage::getQueryInfo(); $res = $db->select( - [ $table, 'page' ], + [ $table, 'nestpage' => $pageQuery['tables'] ], array_merge( [ $blNamespace, $blTitle ], - WikiPage::selectFields() + $pageQuery['fields'] ), [ "{$prefix}_from" => $id ], __METHOD__, $options, - [ 'page' => [ + [ 'nestpage' => [ 'LEFT JOIN', [ "page_namespace=$blNamespace", "page_title=$blTitle" ] - ] ] + ] ] + $pageQuery['joins'] ); $retVal = []; @@@ -4194,15 -4193,13 +4194,15 @@@ $pageId = $this->getArticleID( $flags ); if ( $pageId ) { $db = ( $flags & self::GAID_FOR_UPDATE ) ? wfGetDB( DB_MASTER ) : wfGetDB( DB_REPLICA ); - $row = $db->selectRow( 'revision', Revision::selectFields(), + $revQuery = Revision::getQueryInfo(); + $row = $db->selectRow( $revQuery['tables'], $revQuery['fields'], [ 'rev_page' => $pageId ], __METHOD__, [ 'ORDER BY' => 'rev_timestamp ASC, rev_id ASC', - 'IGNORE INDEX' => 'rev_timestamp', // See T159319 - ] + 'IGNORE INDEX' => [ 'revision' => 'rev_timestamp' ], // See T159319 + ], + $revQuery['joins'] ); if ( $row ) { return new Revision( $row ); @@@ -4622,9 -4619,11 +4622,11 @@@ * on the number of links. Typically called on create and delete. */ public function touchLinks() { - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this, 'pagelinks' ) ); + DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this, 'pagelinks', 'page-touch' ) ); if ( $this->getNamespace() == NS_CATEGORY ) { - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this, 'categorylinks' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $this, 'categorylinks', 'category-touch' ) + ); } } diff --combined includes/filerepo/file/LocalFile.php index 44c90af347,455d6ae4ea..bb12515056 --- a/includes/filerepo/file/LocalFile.php +++ b/includes/filerepo/file/LocalFile.php @@@ -183,10 -183,7 +183,10 @@@ class LocalFile extends File $conds['img_timestamp'] = $dbr->timestamp( $timestamp ); } - $row = $dbr->selectRow( 'image', self::selectFields(), $conds, __METHOD__ ); + $fileQuery = self::getQueryInfo(); + $row = $dbr->selectRow( + $fileQuery['tables'], $fileQuery['fields'], $conds, __METHOD__, [], $fileQuery['joins'] + ); if ( $row ) { return self::newFromRow( $row, $repo ); } else { @@@ -196,11 -193,11 +196,11 @@@ /** * Fields in the image table - * @todo Deprecate this in favor of a method that returns tables and joins - * as well, and use CommentStore::getJoin(). + * @deprecated since 1.31, use self::getQueryInfo() instead. * @return array */ static function selectFields() { + wfDeprecated( __METHOD__, '1.31' ); return [ 'img_name', 'img_size', @@@ -218,51 -215,6 +218,51 @@@ ] + CommentStore::newKey( 'img_description' )->getFields(); } + /** + * Return the tables, fields, and join conditions to be selected to create + * a new localfile object. + * @since 1.31 + * @param string[] $options + * - omit-lazy: Omit fields that are lazily cached. + * @return array With three keys: + * - tables: (string[]) to include in the `$table` to `IDatabase->select()` + * - fields: (string[]) to include in the `$vars` to `IDatabase->select()` + * - joins: (array) to include in the `$join_conds` to `IDatabase->select()` + */ + public static function getQueryInfo( array $options = [] ) { + $commentQuery = CommentStore::newKey( 'img_description' )->getJoin(); + $ret = [ + 'tables' => [ 'image' ] + $commentQuery['tables'], + 'fields' => [ + 'img_name', + 'img_size', + 'img_width', + 'img_height', + 'img_metadata', + 'img_bits', + 'img_media_type', + 'img_major_mime', + 'img_minor_mime', + 'img_user', + 'img_user_text', + 'img_timestamp', + 'img_sha1', + ] + $commentQuery['fields'], + 'joins' => $commentQuery['joins'], + ]; + + if ( in_array( 'omit-nonlazy', $options, true ) ) { + // Internal use only for getting only the lazy fields + $ret['fields'] = []; + } + if ( !in_array( 'omit-lazy', $options, true ) ) { + // Note: Keep this in sync with self::getLazyCacheFields() + $ret['fields'][] = 'img_metadata'; + } + + return $ret; + } + /** * Do not call this except from inside a repo class. * @param Title $title @@@ -389,43 -341,51 +389,43 @@@ } /** - * @param string $prefix + * Returns the list of object properties that are included as-is in the cache. + * @param string $prefix Must be the empty string * @return array + * @since 1.31 No longer accepts a non-empty $prefix */ - function getCacheFields( $prefix = 'img_' ) { - static $fields = [ 'size', 'width', 'height', 'bits', 'media_type', - 'major_mime', 'minor_mime', 'metadata', 'timestamp', 'sha1', 'user', - 'user_text' ]; - static $results = []; - - if ( $prefix == '' ) { - return array_merge( $fields, [ 'description' ] ); - } - if ( !isset( $results[$prefix] ) ) { - $prefixedFields = []; - foreach ( $fields as $field ) { - $prefixedFields[] = $prefix . $field; - } - $prefixedFields += CommentStore::newKey( "{$prefix}description" )->getFields(); - $results[$prefix] = $prefixedFields; + protected function getCacheFields( $prefix = 'img_' ) { + if ( $prefix !== '' ) { + throw new InvalidArgumentException( + __METHOD__ . ' with a non-empty prefix is no longer supported.' + ); } - return $results[$prefix]; + // See self::getQueryInfo() for the fetching of the data from the DB, + // self::loadFromRow() for the loading of the object from the DB row, + // and self::loadFromCache() for the caching, and self::setProps() for + // populating the object from an array of data. + return [ 'size', 'width', 'height', 'bits', 'media_type', + 'major_mime', 'minor_mime', 'metadata', 'timestamp', 'sha1', 'user', + 'user_text', 'description' ]; } /** - * @param string $prefix + * Returns the list of object properties that are included as-is in the + * cache, only when they're not too big, and are lazily loaded by self::loadExtraFromDB(). + * @param string $prefix Must be the empty string * @return array + * @since 1.31 No longer accepts a non-empty $prefix */ - function getLazyCacheFields( $prefix = 'img_' ) { - static $fields = [ 'metadata' ]; - static $results = []; - - if ( $prefix == '' ) { - return $fields; - } - - if ( !isset( $results[$prefix] ) ) { - $prefixedFields = []; - foreach ( $fields as $field ) { - $prefixedFields[] = $prefix . $field; - } - $results[$prefix] = $prefixedFields; + protected function getLazyCacheFields( $prefix = 'img_' ) { + if ( $prefix !== '' ) { + throw new InvalidArgumentException( + __METHOD__ . ' with a non-empty prefix is no longer supported.' + ); } - return $results[$prefix]; + // Keep this in sync with the omit-lazy option in self::getQueryInfo(). + return [ 'metadata' ]; } /** @@@ -443,15 -403,8 +443,15 @@@ ? $this->repo->getMasterDB() : $this->repo->getReplicaDB(); - $row = $dbr->selectRow( 'image', $this->getCacheFields( 'img_' ), - [ 'img_name' => $this->getName() ], $fname ); + $fileQuery = static::getQueryInfo(); + $row = $dbr->selectRow( + $fileQuery['tables'], + $fileQuery['fields'], + [ 'img_name' => $this->getName() ], + $fname, + [], + $fileQuery['joins'] + ); if ( $row ) { $this->loadFromRow( $row ); @@@ -470,9 -423,9 +470,9 @@@ # Unconditionally set loaded=true, we don't want the accessors constantly rechecking $this->extraDataLoaded = true; - $fieldMap = $this->loadFieldsWithTimestamp( $this->repo->getReplicaDB(), $fname ); + $fieldMap = $this->loadExtraFieldsWithTimestamp( $this->repo->getReplicaDB(), $fname ); if ( !$fieldMap ) { - $fieldMap = $this->loadFieldsWithTimestamp( $this->repo->getMasterDB(), $fname ); + $fieldMap = $this->loadExtraFieldsWithTimestamp( $this->repo->getMasterDB(), $fname ); } if ( $fieldMap ) { @@@ -489,46 -442,26 +489,46 @@@ * @param string $fname * @return array|bool */ - private function loadFieldsWithTimestamp( $dbr, $fname ) { + private function loadExtraFieldsWithTimestamp( $dbr, $fname ) { $fieldMap = false; - $row = $dbr->selectRow( 'image', $this->getLazyCacheFields( 'img_' ), [ + $fileQuery = self::getQueryInfo( [ 'omit-nonlazy' ] ); + $row = $dbr->selectRow( + $fileQuery['tables'], + $fileQuery['fields'], + [ 'img_name' => $this->getName(), - 'img_timestamp' => $dbr->timestamp( $this->getTimestamp() ) - ], $fname ); + 'img_timestamp' => $dbr->timestamp( $this->getTimestamp() ), + ], + $fname, + [], + $fileQuery['joins'] + ); if ( $row ) { $fieldMap = $this->unprefixRow( $row, 'img_' ); } else { # File may have been uploaded over in the meantime; check the old versions - $row = $dbr->selectRow( 'oldimage', $this->getLazyCacheFields( 'oi_' ), [ + $fileQuery = OldLocalFile::getQueryInfo( [ 'omit-nonlazy' ] ); + $row = $dbr->selectRow( + $fileQuery['tables'], + $fileQuery['fields'], + [ 'oi_name' => $this->getName(), - 'oi_timestamp' => $dbr->timestamp( $this->getTimestamp() ) - ], $fname ); + 'oi_timestamp' => $dbr->timestamp( $this->getTimestamp() ), + ], + $fname, + [], + $fileQuery['joins'] + ); if ( $row ) { $fieldMap = $this->unprefixRow( $row, 'oi_' ); } } + if ( isset( $fieldMap['metadata'] ) ) { + $fieldMap['metadata'] = $this->repo->getReplicaDB()->decodeBlob( $fieldMap['metadata'] ); + } + return $fieldMap; } @@@ -566,9 -499,6 +566,9 @@@ function decodeRow( $row, $prefix = 'img_' ) { $decoded = $this->unprefixRow( $row, $prefix ); + $decoded['description'] = CommentStore::newKey( 'description' ) + ->getComment( (object)$decoded )->text; + $decoded['timestamp'] = wfTimestamp( TS_MW, $decoded['timestamp'] ); $decoded['metadata'] = $this->repo->getReplicaDB()->decodeBlob( $decoded['metadata'] ); @@@ -606,6 -536,10 +606,6 @@@ $this->dataLoaded = true; $this->extraDataLoaded = true; - $this->description = CommentStore::newKey( "{$prefix}description" ) - // $row is probably using getFields() from self::getCacheFields() - ->getCommentLegacy( wfGetDB( DB_REPLICA ), $row )->text; - $array = $this->decodeRow( $row, $prefix ); foreach ( $array as $name => $value ) { @@@ -1135,12 -1069,9 +1135,12 @@@ */ function getHistory( $limit = null, $start = null, $end = null, $inc = true ) { $dbr = $this->repo->getReplicaDB(); - $tables = [ 'oldimage' ]; - $fields = OldLocalFile::selectFields(); - $conds = $opts = $join_conds = []; + $oldFileQuery = OldLocalFile::getQueryInfo(); + + $tables = $oldFileQuery['tables']; + $fields = $oldFileQuery['fields']; + $join_conds = $oldFileQuery['joins']; + $conds = $opts = []; $eq = $inc ? '=' : ''; $conds[] = "oi_name = " . $dbr->addQuotes( $this->title->getDBkey() ); @@@ -1196,16 -1127,13 +1196,16 @@@ $dbr = $this->repo->getReplicaDB(); if ( $this->historyLine == 0 ) { // called for the first time, return line from cur - $this->historyRes = $dbr->select( 'image', - self::selectFields() + [ + $fileQuery = self::getQueryInfo(); + $this->historyRes = $dbr->select( $fileQuery['tables'], + $fileQuery['fields'] + [ 'oi_archive_name' => $dbr->addQuotes( '' ), 'oi_deleted' => 0, ], [ 'img_name' => $this->title->getDBkey() ], - $fname + $fname, + [], + $fileQuery['joins'] ); if ( 0 == $dbr->numRows( $this->historyRes ) ) { @@@ -1214,14 -1142,12 +1214,14 @@@ return false; } } elseif ( $this->historyLine == 1 ) { + $fileQuery = OldLocalFile::getQueryInfo(); $this->historyRes = $dbr->select( - 'oldimage', - OldLocalFile::selectFields(), + $fileQuery['tables'], + $fileQuery['fields'], [ 'oi_name' => $this->title->getDBkey() ], $fname, - [ 'ORDER BY' => 'oi_timestamp DESC' ] + [ 'ORDER BY' => 'oi_timestamp DESC' ], + $fileQuery['joins'] ); } $this->historyLine++; @@@ -1740,7 -1666,9 +1740,9 @@@ } # Invalidate cache for all pages using this file - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->getTitle(), 'imagelinks' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $this->getTitle(), 'imagelinks', 'file-upload' ) + ); return Status::newGood(); } @@@ -2492,23 -2420,22 +2494,23 @@@ class LocalFileDeleteBatch } if ( count( $oldRels ) ) { + $fileQuery = OldLocalFile::getQueryInfo(); $res = $dbw->select( - 'oldimage', - OldLocalFile::selectFields(), + $fileQuery['tables'], + $fileQuery['fields'], [ 'oi_name' => $this->file->getName(), 'oi_archive_name' => array_keys( $oldRels ) ], __METHOD__, - [ 'FOR UPDATE' ] + [ 'FOR UPDATE' ], + $fileQuery['joins'] ); $rowsInsert = []; if ( $res->numRows() ) { $reason = $commentStoreFaReason->createComment( $dbw, $this->reason ); foreach ( $res as $row ) { - // Legacy from OldLocalFile::selectFields() just above - $comment = $commentStoreOiDesc->getCommentLegacy( $dbw, $row ); + $comment = $commentStoreOiDesc->getComment( $row ); $rowsInsert[] = [ // Deletion-specific fields 'fa_storage_group' => 'deleted', @@@ -2755,14 -2682,12 +2757,14 @@@ class LocalFileRestoreBatch $conditions['fa_id'] = $this->ids; } + $arFileQuery = ArchivedFile::getQueryInfo(); $result = $dbw->select( - 'filearchive', - ArchivedFile::selectFields(), + $arFileQuery['tables'], + $arFileQuery['fields'], $conditions, __METHOD__, - [ 'ORDER BY' => 'fa_timestamp DESC' ] + [ 'ORDER BY' => 'fa_timestamp DESC' ], + $arFileQuery['joins'] ); $idsPresent = []; @@@ -2822,7 -2747,8 +2824,7 @@@ ]; } - // Legacy from ArchivedFile::selectFields() just above - $comment = $commentStoreFaDesc->getCommentLegacy( $dbw, $row ); + $comment = $commentStoreFaDesc->getComment( $row ); if ( $first && !$exists ) { // This revision will be published as the new current version $destRel = $this->file->getRel(); diff --combined includes/page/PageArchive.php index 209551b296,c134b9da00..c03d6b21d6 --- a/includes/page/PageArchive.php +++ b/includes/page/PageArchive.php @@@ -231,14 -231,12 +231,14 @@@ class PageArchive } $dbr = wfGetDB( DB_REPLICA ); + $fileQuery = ArchivedFile::getQueryInfo(); return $dbr->select( - 'filearchive', - ArchivedFile::selectFields(), + $fileQuery['tables'], + $fileQuery['fields'], [ 'fa_name' => $this->title->getDBkey() ], __METHOD__, - [ 'ORDER BY' => 'fa_timestamp DESC' ] + [ 'ORDER BY' => 'fa_timestamp DESC' ], + $fileQuery['joins'] ); } @@@ -251,11 -249,34 +251,11 @@@ */ public function getRevision( $timestamp ) { $dbr = wfGetDB( DB_REPLICA ); - $commentQuery = CommentStore::newKey( 'ar_comment' )->getJoin(); - - $tables = [ 'archive' ] + $commentQuery['tables']; - - $fields = [ - 'ar_rev_id', - 'ar_text', - 'ar_user', - 'ar_user_text', - 'ar_timestamp', - 'ar_minor_edit', - 'ar_flags', - 'ar_text_id', - 'ar_deleted', - 'ar_len', - 'ar_sha1', - ] + $commentQuery['fields']; - - if ( $this->config->get( 'ContentHandlerUseDB' ) ) { - $fields[] = 'ar_content_format'; - $fields[] = 'ar_content_model'; - } - - $join_conds = [] + $commentQuery['joins']; + $arQuery = Revision::getArchiveQueryInfo(); $row = $dbr->selectRow( - $tables, - $fields, + $arQuery['tables'], + $arQuery['fields'], [ 'ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), @@@ -263,7 -284,7 +263,7 @@@ ], __METHOD__, [], - $join_conds + $arQuery['joins'] ); if ( $row ) { @@@ -764,7 -785,9 +764,9 @@@ Hooks::run( 'ArticleUndelete', [ &$this->title, $created, $comment, $oldPageId, $restoredPages ] ); if ( $this->title->getNamespace() == NS_FILE ) { - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $this->title, 'imagelinks' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $this->title, 'imagelinks', 'file-restore' ) + ); } } diff --combined includes/page/WikiPage.php index 95b7be265e,2428fc74b4..8b349288fe --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@@ -158,11 -158,8 +158,11 @@@ class WikiPage implements Page, IDBAcce $from = self::convertSelectType( $from ); $db = wfGetDB( $from === self::READ_LATEST ? DB_MASTER : DB_REPLICA ); + $pageQuery = self::getQueryInfo(); $row = $db->selectRow( - 'page', self::selectFields(), [ 'page_id' => $id ], __METHOD__ ); + $pageQuery['tables'], $pageQuery['fields'], [ 'page_id' => $id ], __METHOD__, + [], $pageQuery['joins'] + ); if ( !$row ) { return null; } @@@ -280,14 -277,11 +280,14 @@@ * Return the list of revision fields that should be selected to create * a new page. * + * @deprecated since 1.31, use self::getQueryInfo() instead. * @return array */ public static function selectFields() { global $wgContentHandlerUseDB, $wgPageLanguageUseDB; + wfDeprecated( __METHOD__, '1.31' ); + $fields = [ 'page_id', 'page_namespace', @@@ -313,47 -307,6 +313,47 @@@ return $fields; } + /** + * Return the tables, fields, and join conditions to be selected to create + * a new page object. + * @since 1.31 + * @return array With three keys: + * - tables: (string[]) to include in the `$table` to `IDatabase->select()` + * - fields: (string[]) to include in the `$vars` to `IDatabase->select()` + * - joins: (array) to include in the `$join_conds` to `IDatabase->select()` + */ + public static function getQueryInfo() { + global $wgContentHandlerUseDB, $wgPageLanguageUseDB; + + $ret = [ + 'tables' => [ 'page' ], + 'fields' => [ + 'page_id', + 'page_namespace', + 'page_title', + 'page_restrictions', + 'page_is_redirect', + 'page_is_new', + 'page_random', + 'page_touched', + 'page_links_updated', + 'page_latest', + 'page_len', + ], + 'joins' => [], + ]; + + if ( $wgContentHandlerUseDB ) { + $ret['fields'][] = 'page_content_model'; + } + + if ( $wgPageLanguageUseDB ) { + $ret['fields'][] = 'page_lang'; + } + + return $ret; + } + /** * Fetch a page record with the given conditions * @param IDatabase $dbr @@@ -362,23 -315,14 +362,23 @@@ * @return object|bool Database result resource, or false on failure */ protected function pageData( $dbr, $conditions, $options = [] ) { - $fields = self::selectFields(); + $pageQuery = self::getQueryInfo(); // Avoid PHP 7.1 warning of passing $this by reference $wikiPage = $this; - Hooks::run( 'ArticlePageDataBefore', [ &$wikiPage, &$fields ] ); + Hooks::run( 'ArticlePageDataBefore', [ + &$wikiPage, &$pageQuery['fields'], &$pageQuery['tables'], &$pageQuery['joins'] + ] ); - $row = $dbr->selectRow( 'page', $fields, $conditions, __METHOD__, $options ); + $row = $dbr->selectRow( + $pageQuery['tables'], + $pageQuery['fields'], + $conditions, + __METHOD__, + $options, + $pageQuery['joins'] + ); Hooks::run( 'ArticlePageDataAfter', [ &$wikiPage, &$row ] ); @@@ -1705,27 -1649,27 +1705,27 @@@ throw new MWException( "Could not find text for current revision {$oldid}." ); } - // @TODO: pass content object?! - $revision = new Revision( [ - 'page' => $this->getId(), - 'title' => $this->mTitle, // for determining the default content model - 'comment' => $summary, - 'minor_edit' => $meta['minor'], - 'text' => $meta['serialized'], - 'len' => $newsize, - 'parent_id' => $oldid, - 'user' => $user->getId(), - 'user_text' => $user->getName(), - 'timestamp' => $now, - 'content_model' => $content->getModel(), - 'content_format' => $meta['serialFormat'], - ] ); - $changed = !$content->equals( $oldContent ); $dbw = wfGetDB( DB_MASTER ); if ( $changed ) { + // @TODO: pass content object?! + $revision = new Revision( [ + 'page' => $this->getId(), + 'title' => $this->mTitle, // for determining the default content model + 'comment' => $summary, + 'minor_edit' => $meta['minor'], + 'text' => $meta['serialized'], + 'len' => $newsize, + 'parent_id' => $oldid, + 'user' => $user->getId(), + 'user_text' => $user->getName(), + 'timestamp' => $now, + 'content_model' => $content->getModel(), + 'content_format' => $meta['serialFormat'], + ] ); + $prepStatus = $content->prepareSave( $this, $flags, $oldid, $user ); $status->merge( $prepStatus ); if ( !$status->isOK() ) { @@@ -1791,9 -1735,11 +1791,9 @@@ } else { // T34948: revision ID must be set to page {{REVISIONID}} and // related variables correctly. Likewise for {{REVISIONUSER}} (T135261). - $revision->setId( $this->getLatest() ); - $revision->setUserIdAndName( - $this->getUser( Revision::RAW ), - $this->getUserText( Revision::RAW ) - ); + // Since we don't insert a new revision into the database, the least + // error-prone way is to reuse given old revision. + $revision = $meta['oldRevision']; } if ( $changed ) { @@@ -2842,13 -2788,13 +2842,13 @@@ $revCommentStore = new CommentStore( 'rev_comment' ); $arCommentStore = new CommentStore( 'ar_comment' ); - $fields = Revision::selectFields(); + $revQuery = Revision::getQueryInfo(); $bitfield = false; // Bitfields to further suppress the content if ( $suppress ) { $bitfield = Revision::SUPPRESSED_ALL; - $fields = array_diff( $fields, [ 'rev_deleted' ] ); + $revQuery['fields'] = array_diff( $revQuery['fields'], [ 'rev_deleted' ] ); } // For now, shunt the revision data into the archive table. @@@ -2859,13 -2805,14 +2859,13 @@@ // the rev_deleted field, which is reserved for this purpose. // Get all of the page revisions - $commentQuery = $revCommentStore->getJoin(); $res = $dbw->select( - [ 'revision' ] + $commentQuery['tables'], - $fields + $commentQuery['fields'], + $revQuery['tables'], + $revQuery['fields'], [ 'rev_page' => $id ], __METHOD__, 'FOR UPDATE', - $commentQuery['joins'] + $revQuery['joins'] ); // Build their equivalent archive rows @@@ -3317,7 -3264,9 +3317,9 @@@ MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle( $title ); // Invalidate caches of articles which include this page - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'templatelinks' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $title, 'templatelinks', 'page-create' ) + ); if ( $title->getNamespace() == NS_CATEGORY ) { // Load the Category object, which will schedule a job to create @@@ -3355,7 -3304,9 +3357,9 @@@ // Images if ( $title->getNamespace() == NS_FILE ) { - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'imagelinks' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $title, 'imagelinks', 'page-delete' ) + ); } // User talk pages @@@ -3378,10 -3329,14 +3382,14 @@@ */ public static function onArticleEdit( Title $title, Revision $revision = null ) { // Invalidate caches of articles which include this page - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'templatelinks' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $title, 'templatelinks', 'page-edit' ) + ); // Invalidate the caches of all pages which redirect here - DeferredUpdates::addUpdate( new HTMLCacheUpdate( $title, 'redirect' ) ); + DeferredUpdates::addUpdate( + new HTMLCacheUpdate( $title, 'redirect', 'page-edit' ) + ); MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle( $title );