+
+ /**
+ * Load a revision based on a known page ID and current revision ID from the DB
+ *
+ * This method allows for the use of caching, though accessing anything that normally
+ * requires permission checks (aside from the text) will trigger a small DB lookup.
+ * The title will also be lazy loaded, though setTitle() can be used to preload it.
+ *
+ * @param IDatabase $db
+ * @param int $pageId Page ID
+ * @param int $revId Known current revision of this page
+ * @return Revision|bool Returns false if missing
+ * @since 1.28
+ */
+ public static function newKnownCurrent( IDatabase $db, $pageId, $revId ) {
+ $cache = ObjectCache::getMainWANInstance();
+ return $cache->getWithSetCallback(
+ // Page/rev IDs passed in from DB to reflect history merges
+ $cache->makeGlobalKey( 'revision', $db->getWikiID(), $pageId, $revId ),
+ $cache::TTL_WEEK,
+ function ( $curValue, &$ttl, array &$setOpts ) use ( $db, $pageId, $revId ) {
+ $setOpts += Database::getCacheSetOptions( $db );
+
+ $rev = Revision::loadFromPageId( $db, $pageId, $revId );
+ // Reflect revision deletion and user renames
+ if ( $rev ) {
+ $rev->mTitle = null; // mutable; lazy-load
+ $rev->mRefreshMutableFields = true;
+ }
+
+ return $rev ?: false; // don't cache negatives
+ }
+ );
+ }
+
+ /**
+ * For cached revisions, make sure the user name and rev_deleted is up-to-date
+ */
+ private function loadMutableFields() {
+ if ( !$this->mRefreshMutableFields ) {
+ return; // not needed
+ }
+
+ $this->mRefreshMutableFields = false;
+ $dbr = wfGetLB( $this->mWiki )->getConnectionRef( DB_REPLICA, [], $this->mWiki );
+ $row = $dbr->selectRow(
+ [ 'revision', 'user' ],
+ [ 'rev_deleted', 'user_name' ],
+ [ 'rev_id' => $this->mId, 'user_id = rev_user' ],
+ __METHOD__
+ );
+ if ( $row ) { // update values
+ $this->mDeleted = (int)$row->rev_deleted;
+ $this->mUserText = $row->user_name;
+ }
+ }