jenkins-bot has submitted this change and it was merged.

Change subject: Introduce EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK
......................................................................


Introduce EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK

For getting data from slaves but explicitly fallback to master in
case we didn't find data about a given entity.

The new EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK has
almost the same semantics EntityRevisionLookup::LATEST_FROM_SLAVE had.

Please note that this doesn't not change the behavior for any callers,
yet.

Bug: T108929
Change-Id: Ic9ef30431f8ad23f70d84df8fe005d05e4fec9ab
---
M lib/includes/Store/CachingEntityRevisionLookup.php
M lib/includes/Store/EntityRevisionLookup.php
M lib/includes/Store/Sql/PrefetchingWikiPageEntityMetaDataAccessor.php
M lib/includes/Store/Sql/WikiPageEntityMetaDataAccessor.php
M lib/includes/Store/Sql/WikiPageEntityMetaDataLookup.php
M lib/includes/Store/Sql/WikiPageEntityRevisionLookup.php
M lib/tests/phpunit/EntityRevisionLookupTest.php
M lib/tests/phpunit/MockRepository.php
M lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php
M lib/tests/phpunit/Store/PrefetchingWikiPageEntityMetaDataAccessorTest.php
M repo/includes/Api/EntityLoadingHelper.php
M repo/includes/Api/EntitySavingHelper.php
M repo/includes/Api/LinkTitles.php
M repo/includes/EditEntity.php
M repo/includes/Hooks/OutputPageBeforeHTMLHookHandler.php
M repo/includes/Interactors/ItemMergeInteractor.php
M repo/includes/Interactors/RedirectCreationInteractor.php
M repo/includes/LinkedData/EntityDataRequestHandler.php
M repo/includes/Specials/SpecialModifyEntity.php
M repo/includes/UpdateRepo/UpdateRepoJob.php
M repo/tests/phpunit/includes/EditEntityTest.php
M repo/tests/phpunit/includes/Store/Sql/WikiPageEntityMetaDataLookupTest.php
M repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php
23 files changed, 382 insertions(+), 121 deletions(-)

Approvals:
  Daniel Kinzler: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/lib/includes/Store/CachingEntityRevisionLookup.php 
b/lib/includes/Store/CachingEntityRevisionLookup.php
index 5926e1d..26acf4e 100644
--- a/lib/includes/Store/CachingEntityRevisionLookup.php
+++ b/lib/includes/Store/CachingEntityRevisionLookup.php
@@ -6,6 +6,7 @@
 use Wikibase\DataModel\Entity\EntityId;
 use Wikibase\DataModel\Entity\EntityRedirect;
 use Wikibase\EntityRevision;
+use Wikimedia\Assert\Assert;
 
 /**
  * Implementation of EntityLookup that caches the obtained entities.
@@ -96,24 +97,29 @@
         * still the latest. Otherwise, any cached revision will be used if 
$revisionId=0.
         *
         * @param EntityId $entityId
-        * @param int|string $revisionId The desired revision id, or 
LATEST_FROM_SLAVE or LATEST_FROM_MASTER.
+        * @param int $revisionId The desired revision id, or 0 for the latest 
revision.
+        * @param string $mode LATEST_FROM_SLAVE, 
LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *        LATEST_FROM_MASTER.
         *
         * @throws StorageException
         * @return EntityRevision|null
         */
-       public function getEntityRevision( EntityId $entityId, $revisionId = 
self::LATEST_FROM_SLAVE ) {
-               $key = $this->getCacheKey( $entityId );
+       public function getEntityRevision(
+               EntityId $entityId,
+               $revisionId = 0,
+               $mode = self::LATEST_FROM_SLAVE_WITH_FALLBACK
+       ) {
+               Assert::parameterType( 'integer', $revisionId, '$revisionId' );
+               Assert::parameterType( 'string', $mode, '$mode' );
 
-               if ( $revisionId === 0 ) {
-                       $revisionId = self::LATEST_FROM_SLAVE;
-               }
+               $key = $this->getCacheKey( $entityId );
 
                /** @var EntityRevision $entityRevision */
                $entityRevision = $this->cache->get( $key );
 
                if ( $entityRevision !== false ) {
-                       if ( !is_int( $revisionId ) && 
$this->shouldVerifyRevision ) {
-                               $latestRevision = 
$this->lookup->getLatestRevisionId( $entityId, $revisionId );
+                       if ( $revisionId === 0 && $this->shouldVerifyRevision ) 
{
+                               $latestRevision = 
$this->lookup->getLatestRevisionId( $entityId, $mode );
 
                                if ( $latestRevision === false ) {
                                        // entity no longer exists!
@@ -123,13 +129,13 @@
                                }
                        }
 
-                       if ( is_int( $revisionId ) && $entityRevision && 
$entityRevision->getRevisionId() !== $revisionId ) {
+                       if ( $revisionId > 0 && $entityRevision && 
$entityRevision->getRevisionId() !== $revisionId ) {
                                $entityRevision = false;
                        }
                }
 
                if ( $entityRevision === false ) {
-                       $entityRevision = $this->fetchEntityRevision( 
$entityId, $revisionId );
+                       $entityRevision = $this->fetchEntityRevision( 
$entityId, $revisionId, $mode );
                }
 
                return $entityRevision;
@@ -139,16 +145,17 @@
         * Fetches the EntityRevision and updates the cache accordingly.
         *
         * @param EntityId $entityId
-        * @param int|string $revisionId
+        * @param int $revisionId
+        * @param string $mode
         *
         * @throws StorageException
         * @return EntityRevision|null
         */
-       private function fetchEntityRevision( EntityId $entityId, $revisionId ) 
{
+       private function fetchEntityRevision( EntityId $entityId, $revisionId, 
$mode ) {
                $key = $this->getCacheKey( $entityId );
-               $entityRevision = $this->lookup->getEntityRevision( $entityId, 
$revisionId );
+               $entityRevision = $this->lookup->getEntityRevision( $entityId, 
$revisionId, $mode );
 
-               if ( !is_int( $revisionId ) ) {
+               if ( $revisionId === 0 ) {
                        if ( $entityRevision === null ) {
                                $this->cache->delete( $key );
                        } else {
diff --git a/lib/includes/Store/EntityRevisionLookup.php 
b/lib/includes/Store/EntityRevisionLookup.php
index c251e60..4f60668 100644
--- a/lib/includes/Store/EntityRevisionLookup.php
+++ b/lib/includes/Store/EntityRevisionLookup.php
@@ -23,6 +23,13 @@
        const LATEST_FROM_SLAVE = 'slave';
 
        /**
+        * Flag used to indicate that loading slightly lagged data is fine (like
+        * LATEST_FROM_SLAVE), but in case an entity or revision couldn't be 
found,
+        * we try loading it from master.
+        */
+       const LATEST_FROM_SLAVE_WITH_FALLBACK = 'master_fallback';
+
+       /**
         * Flag to use instead of a revision ID to indicate that the latest 
revision is desired,
         * and it is essential to assert that there really is no newer version, 
to avoid data loss
         * or conflicts. This would generally be the case when loading an 
entity for
@@ -41,15 +48,19 @@
         * @since 0.4
         *
         * @param EntityId $entityId
-        * @param int|string $revisionId The desired revision id, or 
LATEST_FROM_SLAVE or LATEST_FROM_MASTER
-        *        to indicate that the latest revision is required. 
LATEST_FROM_MASTER would force the
-        *        revision to be determined from the canonical master database.
+        * @param int $revisionId The desired revision id, or 0 for the latest 
revision.
+        * @param string $mode LATEST_FROM_SLAVE, 
LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *        LATEST_FROM_MASTER.
         *
         * @throws RevisionedUnresolvedRedirectException
         * @throws StorageException
         * @return EntityRevision|null
         */
-       public function getEntityRevision( EntityId $entityId, $revisionId = 
self::LATEST_FROM_SLAVE );
+       public function getEntityRevision(
+               EntityId $entityId,
+               $revisionId = 0,
+               $mode = self::LATEST_FROM_SLAVE_WITH_FALLBACK
+       );
 
        /**
         * Returns the id of the latest revision of the given entity, or false 
if there is no such entity.
diff --git 
a/lib/includes/Store/Sql/PrefetchingWikiPageEntityMetaDataAccessor.php 
b/lib/includes/Store/Sql/PrefetchingWikiPageEntityMetaDataAccessor.php
index 2072c0d..77fd538 100644
--- a/lib/includes/Store/Sql/PrefetchingWikiPageEntityMetaDataAccessor.php
+++ b/lib/includes/Store/Sql/PrefetchingWikiPageEntityMetaDataAccessor.php
@@ -137,7 +137,9 @@
         * @see WikiPageEntityMetaDataAccessor::loadRevisionInformation
         *
         * @param EntityId[] $entityIds
-        * @param string $mode (EntityRevisionLookup::LATEST_FROM_SLAVE or 
EntityRevisionLookup::LATEST_FROM_MASTER)
+        * @param string $mode (EntityRevisionLookup::LATEST_FROM_SLAVE,
+        *     EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *     EntityRevisionLookup::LATEST_FROM_MASTER)
         *
         * @return stdClass[] Array of entity id serialization => object.
         */
@@ -159,7 +161,7 @@
                }
 
                $this->prefetch( $entityIds );
-               $this->doFetch();
+               $this->doFetch( $mode );
 
                $data = array();
                foreach ( $entityIds as $entityId ) {
@@ -174,23 +176,27 @@
         *
         * @param EntityId $entityId
         * @param int $revisionId
+        * @param string $mode (EntityRevisionLookup::LATEST_FROM_SLAVE,
+        *     EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *     EntityRevisionLookup::LATEST_FROM_MASTER)
         *
         * @return stdClass|bool false if no such entity exists
         */
-       public function loadRevisionInformationByRevisionId( EntityId 
$entityId, $revisionId ) {
+       public function loadRevisionInformationByRevisionId(
+               EntityId $entityId,
+               $revisionId,
+               $mode = EntityRevisionLookup::LATEST_FROM_MASTER
+       ) {
                // Caching this would have little or no benefit, but would be 
rather complex.
-               return $this->lookup->loadRevisionInformationByRevisionId( 
$entityId, $revisionId );
+               return $this->lookup->loadRevisionInformationByRevisionId( 
$entityId, $revisionId, $mode );
        }
 
-       private function doFetch() {
+       private function doFetch( $mode ) {
                if ( empty( $this->toFetch ) ) {
                        return;
                }
 
-               $data = $this->lookup->loadRevisionInformation(
-                       $this->toFetch,
-                       EntityRevisionLookup::LATEST_FROM_SLAVE
-               );
+               $data = $this->lookup->loadRevisionInformation( $this->toFetch, 
$mode );
 
                // Store the data, including cache misses
                $this->store( $data );
diff --git a/lib/includes/Store/Sql/WikiPageEntityMetaDataAccessor.php 
b/lib/includes/Store/Sql/WikiPageEntityMetaDataAccessor.php
index 82a36a0..2801478 100644
--- a/lib/includes/Store/Sql/WikiPageEntityMetaDataAccessor.php
+++ b/lib/includes/Store/Sql/WikiPageEntityMetaDataAccessor.php
@@ -4,6 +4,7 @@
 
 use stdClass;
 use Wikibase\DataModel\Entity\EntityId;
+use Wikibase\Lib\Store\EntityRevisionLookup;
 
 /**
  * Interface for services giving access to meta data about one or more 
entities as needed for
@@ -23,7 +24,9 @@
         * 'page_latest', 'old_id', 'old_text' and 'old_flags'.
         *
         * @param EntityId[] $entityIds
-        * @param string $mode (EntityRevisionLookup::LATEST_FROM_SLAVE or 
EntityRevisionLookup::LATEST_FROM_MASTER)
+        * @param string $mode (EntityRevisionLookup::LATEST_FROM_SLAVE,
+        *     EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *     EntityRevisionLookup::LATEST_FROM_MASTER)
         *
         * @return stdClass[] Array of entity id serialization => object.
         */
@@ -34,12 +37,22 @@
         * revision of the entity or to load entity content from a MediaWiki 
revision. Included fields are
         * 'rev_id', 'rev_content_format', 'rev_timestamp', 'page_latest', 
'old_id', 'old_text'
         * and 'old_flags'.
+        * Given that revision are immutable, this function will always try to 
load a revision from
+        * slave first and only use the master (with 
EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK
+        * or EntityRevisionLookup::LATEST_FROM_MASTER) in case the revision 
couldn't be found.
         *
         * @param EntityId $entityId
         * @param int $revisionId Revision id to fetch data about, must be an 
integer greater than 0.
+        * @param string $mode (EntityRevisionLookup::LATEST_FROM_SLAVE,
+        *     EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *     EntityRevisionLookup::LATEST_FROM_MASTER).
         *
         * @return stdClass|bool false if no such entity exists
         */
-       public function loadRevisionInformationByRevisionId( EntityId 
$entityId, $revisionId );
+       public function loadRevisionInformationByRevisionId(
+               EntityId $entityId,
+               $revisionId,
+               $mode = EntityRevisionLookup::LATEST_FROM_MASTER
+       );
 
 }
diff --git a/lib/includes/Store/Sql/WikiPageEntityMetaDataLookup.php 
b/lib/includes/Store/Sql/WikiPageEntityMetaDataLookup.php
index 65ec67d..01669eb 100644
--- a/lib/includes/Store/Sql/WikiPageEntityMetaDataLookup.php
+++ b/lib/includes/Store/Sql/WikiPageEntityMetaDataLookup.php
@@ -8,8 +8,8 @@
 use ResultWrapper;
 use stdClass;
 use Wikibase\DataModel\Entity\EntityId;
-use Wikibase\Lib\Store\EntityRevisionLookup;
 use Wikibase\Lib\Store\EntityNamespaceLookup;
+use Wikibase\Lib\Store\EntityRevisionLookup;
 
 /**
  * Service for looking up meta data about one or more entities as needed for
@@ -43,30 +43,38 @@
 
        /**
         * @param EntityId[] $entityIds
-        * @param string $mode (EntityRevisionLookup::LATEST_FROM_SLAVE or 
EntityRevisionLookup::LATEST_FROM_MASTER)
+        * @param string $mode (EntityRevisionLookup::LATEST_FROM_SLAVE,
+        *     EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *     EntityRevisionLookup::LATEST_FROM_MASTER)
         *
         * @throws DBQueryError
         * @return stdClass[] Array of entity id serialization => object.
         */
-       public function loadRevisionInformation( array $entityIds, $mode ) {
+       public function loadRevisionInformation(
+               array $entityIds,
+               $mode
+       ) {
                $rows = array();
 
                if ( $mode !== EntityRevisionLookup::LATEST_FROM_MASTER ) {
                        $rows = $this->selectRevisionInformationMultiple( 
$entityIds, DB_SLAVE );
                }
 
-               $loadFromMaster = array();
-               foreach ( $entityIds as $entityId ) {
-                       if ( !isset( $rows[$entityId->getSerialization()] ) || 
!$rows[$entityId->getSerialization()] ) {
-                               $loadFromMaster[] = $entityId;
+               if ( $mode !== EntityRevisionLookup::LATEST_FROM_SLAVE ) {
+                       // Attempt to load (missing) rows from master if the 
caller asked for that.
+                       $loadFromMaster = array();
+                       foreach ( $entityIds as $entityId ) {
+                               if ( !isset( 
$rows[$entityId->getSerialization()] ) || !$rows[$entityId->getSerialization()] 
) {
+                                       $loadFromMaster[] = $entityId;
+                               }
                        }
-               }
 
-               if ( $loadFromMaster ) {
-                       $rows = array_merge(
-                               $rows,
-                               $this->selectRevisionInformationMultiple( 
$loadFromMaster, DB_MASTER )
-                       );
+                       if ( $loadFromMaster ) {
+                               $rows = array_merge(
+                                       $rows,
+                                       
$this->selectRevisionInformationMultiple( $loadFromMaster, DB_MASTER )
+                               );
+                       }
                }
 
                return $rows;
@@ -75,15 +83,22 @@
        /**
         * @param EntityId $entityId
         * @param int $revisionId
+        * @param string $mode 
(WikiPageEntityMetaDataAccessor::LATEST_FROM_SLAVE,
+        *     WikiPageEntityMetaDataAccessor::LATEST_FROM_SLAVE_WITH_FALLBACK 
or
+        *     WikiPageEntityMetaDataAccessor::LATEST_FROM_MASTER)
         *
         * @throws DBQueryError
         * @return stdClass|bool
         */
-       public function loadRevisionInformationByRevisionId( EntityId 
$entityId, $revisionId ) {
+       public function loadRevisionInformationByRevisionId(
+               EntityId $entityId,
+               $revisionId,
+               $mode = EntityRevisionLookup::LATEST_FROM_MASTER
+       ) {
                $row = $this->selectRevisionInformationById( $entityId, 
$revisionId, DB_SLAVE );
 
-               if ( !$row ) {
-                       // Try loading from master
+               if ( !$row && $mode !== EntityRevisionLookup::LATEST_FROM_SLAVE 
) {
+                       // Try loading from master, unless the caller only 
wants slave data.
                        wfDebugLog( __CLASS__, __FUNCTION__ . ': try to load ' 
. $entityId
                                . " with $revisionId from DB_MASTER." );
 
diff --git a/lib/includes/Store/Sql/WikiPageEntityRevisionLookup.php 
b/lib/includes/Store/Sql/WikiPageEntityRevisionLookup.php
index 7f529bd..8c19757 100644
--- a/lib/includes/Store/Sql/WikiPageEntityRevisionLookup.php
+++ b/lib/includes/Store/Sql/WikiPageEntityRevisionLookup.php
@@ -10,6 +10,7 @@
 use Wikibase\DataModel\Entity\EntityRedirect;
 use Wikibase\Lib\Store\Sql\WikiPageEntityMetaDataAccessor;
 use Wikibase\EntityRevision;
+use Wikimedia\Assert\Assert;
 
 /**
  * Implements an entity repo based on blobs stored in wiki pages on a locally 
reachable
@@ -55,30 +56,32 @@
         * @see   EntityRevisionLookup::getEntityRevision
         *
         * @param EntityId $entityId
-        * @param int|string $revisionId The desired revision id, or 
LATEST_FROM_SLAVE or LATEST_FROM_MASTER.
+        * @param int $revisionId The desired revision id, or 0 for the latest 
revision.
+        * @param string $mode LATEST_FROM_SLAVE, 
LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *        LATEST_FROM_MASTER.
         *
         * @throws RevisionedUnresolvedRedirectException
         * @throws StorageException
         * @return EntityRevision|null
         */
-       public function getEntityRevision( EntityId $entityId, $revisionId = 
self::LATEST_FROM_SLAVE ) {
+       public function getEntityRevision(
+               EntityId $entityId,
+               $revisionId = 0,
+               $mode = self::LATEST_FROM_SLAVE_WITH_FALLBACK
+       ) {
+               Assert::parameterType( 'integer', $revisionId, '$revisionId' );
+               Assert::parameterType( 'string', $mode, '$mode' );
+
                wfDebugLog( __CLASS__, __FUNCTION__ . ': Looking up entity ' . 
$entityId
                        . " (revision $revisionId)." );
-
-               // default changed from false to 0 and then to LATEST_FROM_SLAVE
-               if ( $revisionId === false || $revisionId === 0 ) {
-                       wfWarn( 'getEntityRevision() called with $revisionId = 
false or 0, ' .
-                               'use EntityRevisionLookup::LATEST_FROM_SLAVE or 
EntityRevisionLookup::LATEST_FROM_MASTER instead.' );
-                       $revisionId = self::LATEST_FROM_SLAVE;
-               }
 
                /** @var EntityRevision $entityRevision */
                $entityRevision = null;
 
-               if ( is_int( $revisionId ) ) {
-                       $row = 
$this->entityMetaDataAccessor->loadRevisionInformationByRevisionId( $entityId, 
$revisionId );
+               if ( $revisionId > 0 ) {
+                       $row = 
$this->entityMetaDataAccessor->loadRevisionInformationByRevisionId( $entityId, 
$revisionId, $mode );
                } else {
-                       $rows = 
$this->entityMetaDataAccessor->loadRevisionInformation( array( $entityId ), 
$revisionId );
+                       $rows = 
$this->entityMetaDataAccessor->loadRevisionInformation( array( $entityId ), 
$mode );
                        $row = $rows[$entityId->getSerialization()];
                }
 
@@ -111,11 +114,11 @@
                        $actualEntityId = 
$entityRevision->getEntity()->getId()->getSerialization();
 
                        // Get the revision id we actually loaded, if none was 
passed explicitly
-                       $revisionId = is_int( $revisionId ) ? $revisionId : 
$entityRevision->getRevisionId();
+                       $revisionId = $revisionId ?: 
$entityRevision->getRevisionId();
                        throw new BadRevisionException( "Revision $revisionId 
belongs to $actualEntityId instead of expected $entityId" );
                }
 
-               if ( is_int( $revisionId ) && $entityRevision === null ) {
+               if ( $revisionId > 0 && $entityRevision === null ) {
                        // If a revision ID was specified, but that revision 
doesn't exist:
                        throw new BadRevisionException( "No such revision found 
for $entityId: $revisionId" );
                }
diff --git a/lib/tests/phpunit/EntityRevisionLookupTest.php 
b/lib/tests/phpunit/EntityRevisionLookupTest.php
index 40e987e..1599b5a 100644
--- a/lib/tests/phpunit/EntityRevisionLookupTest.php
+++ b/lib/tests/phpunit/EntityRevisionLookupTest.php
@@ -84,7 +84,7 @@
        public function provideGetEntityRevision() {
                $cases = array(
                        array( // #0: any revision
-                               new ItemId( 'q42' ), 
EntityRevisionLookup::LATEST_FROM_SLAVE, true,
+                               new ItemId( 'q42' ), 0, true,
                        ),
                        array( // #1: first revision
                                new ItemId( 'q42' ), 11, true,
@@ -96,13 +96,13 @@
                                new ItemId( 'q42' ), 600000, false, 
StorageException::class,
                        ),
                        array( // #4: wrong type
-                               new ItemId( 'q753' ), 
EntityRevisionLookup::LATEST_FROM_SLAVE, false,
+                               new ItemId( 'q753' ), 0, false,
                        ),
                        array( // #5: mismatching revision
                                new PropertyId( 'p753' ), 11, false, 
StorageException::class,
                        ),
                        array( // #6: some revision
-                               new PropertyId( 'p753' ), 
EntityRevisionLookup::LATEST_FROM_SLAVE, true,
+                               new PropertyId( 'p753' ), 0, true,
                        ),
                );
 
@@ -113,7 +113,7 @@
         * @dataProvider provideGetEntityRevision
         *
         * @param EntityId $id    The entity to get
-        * @param int             $revision The revision to get (or 
LATEST_FROM_SLAVE or LATEST_FROM_MASTER)
+        * @param int             $revision The revision to get (or 0 for 
latest)
         * @param bool            $shouldExist
         * @param string|null     $expectException
         */
diff --git a/lib/tests/phpunit/MockRepository.php 
b/lib/tests/phpunit/MockRepository.php
index 102f59a..9f6acee 100644
--- a/lib/tests/phpunit/MockRepository.php
+++ b/lib/tests/phpunit/MockRepository.php
@@ -121,13 +121,19 @@
         * @see EntityRevisionLookup::getEntityRevision
         *
         * @param EntityId $entityId
-        * @param int|string $revisionId The desired revision id, or 
LATEST_FROM_SLAVE or LATEST_FROM_MASTER.
+        * @param int $revisionId The desired revision id, or 0 for the latest 
revision.
+        * @param string $mode LATEST_FROM_SLAVE, 
LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *        LATEST_FROM_MASTER.
         *
         * @throws RevisionedUnresolvedRedirectException
         * @throws StorageException
         * @return EntityRevision|null
         */
-       public function getEntityRevision( EntityId $entityId, $revisionId = 
self::LATEST_FROM_SLAVE ) {
+       public function getEntityRevision(
+               EntityId $entityId,
+               $revisionId = 0,
+               $mode = self::LATEST_FROM_SLAVE_WITH_FALLBACK
+       ) {
                $key = $entityId->getSerialization();
 
                if ( isset( $this->redirects[$key] ) ) {
@@ -144,17 +150,15 @@
                        return null;
                }
 
-               // default changed from false to 0 and then to LATEST_FROM_SLAVE
-               if ( $revisionId === false || $revisionId === 0 ) {
-                       wfWarn( 'getEntityRevision() called with $revisionId = 
false or 0, ' .
-                               'use EntityRevisionLookup::LATEST_FROM_SLAVE or 
EntityRevisionLookup::LATEST_FROM_MASTER instead.' );
-                       $revisionId = self::LATEST_FROM_SLAVE;
+               if ( !is_int( $revisionId ) ) {
+                       wfWarn( 'getEntityRevision() called with $revisionId = 
false or a string, use 0 instead.' );
+                       $revisionId = 0;
                }
 
                /** @var EntityRevision[] $revisions */
                $revisions = $this->entities[$key];
 
-               if ( !is_int( $revisionId ) ) {
+               if ( $revisionId === 0 ) {
                        $revisionIds = array_keys( $revisions );
                        $revisionId = end( $revisionIds );
                } elseif ( !isset( $revisions[$revisionId] ) ) {
@@ -467,7 +471,7 @@
         */
        public function getLatestRevisionId( EntityId $entityId, $mode = 
self::LATEST_FROM_SLAVE ) {
                try {
-                       $revision = $this->getEntityRevision( $entityId, $mode 
);
+                       $revision = $this->getEntityRevision( $entityId, 0, 
$mode );
                } catch ( RevisionedUnresolvedRedirectException $e ) {
                        return false;
                }
diff --git a/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php 
b/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php
index de1aa08..dd91cb2 100644
--- a/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php
+++ b/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php
@@ -9,6 +9,7 @@
 use Wikibase\DataModel\Services\Lookup\EntityLookup;
 use Wikibase\EntityRevision;
 use Wikibase\Lib\Store\CachingEntityRevisionLookup;
+use Wikibase\Lib\Store\EntityRevisionLookup;
 use Wikibase\Lib\Store\RevisionedUnresolvedRedirectException;
 use Wikibase\Lib\Tests\EntityRevisionLookupTest;
 use Wikibase\Lib\Tests\MockRepository;
@@ -47,6 +48,25 @@
                return new CachingEntityRevisionLookup( $mock, new 
HashBagOStuff() );
        }
 
+       public function testGetEntityRevision_byRevisionIdWithMode() {
+               $id = new ItemId( 'Q123' );
+               $item = new Item( $id );
+
+               $mock = $this->getMock( EntityRevisionLookup::class );
+               $mock->expects( $this->once() )
+                       ->method( 'getEntityRevision' )
+                       ->with( $id, 1234, 'load-mode' )
+                       ->will( $this->returnValue( $item ) );
+
+               $lookup = new CachingEntityRevisionLookup( $mock, new 
HashBagOStuff() );
+               $lookup->setVerifyRevision( false );
+
+               $this->assertSame(
+                       $item,
+                       $lookup->getEntityRevision( $id, 1234, 'load-mode' )
+               );
+       }
+
        public function testWithRevisionVerification() {
                $mock = new MockRepository();
 
diff --git 
a/lib/tests/phpunit/Store/PrefetchingWikiPageEntityMetaDataAccessorTest.php 
b/lib/tests/phpunit/Store/PrefetchingWikiPageEntityMetaDataAccessorTest.php
index c2585d6..5f26412 100644
--- a/lib/tests/phpunit/Store/PrefetchingWikiPageEntityMetaDataAccessorTest.php
+++ b/lib/tests/phpunit/Store/PrefetchingWikiPageEntityMetaDataAccessorTest.php
@@ -33,10 +33,14 @@
                $lookup = $this->getMock( WikiPageEntityMetaDataAccessor::class 
);
                $lookup->expects( $this->once() )
                        ->method( 'loadRevisionInformation' )
-                       ->with( array(
-                               $q1->getSerialization() => $q1,
-                               $q3->getSerialization() => $q3,
-                               $q2->getSerialization() => $q2 ) )
+                       ->with(
+                               array(
+                                       $q1->getSerialization() => $q1,
+                                       $q3->getSerialization() => $q3,
+                                       $q2->getSerialization() => $q2
+                               ),
+                               $fromSlave
+                       )
                        ->will( $this->returnValue( array(
                                'Q1' => 'Nyan',
                                'Q2' => 'cat',
@@ -193,6 +197,29 @@
                );
        }
 
+       /**
+        * Make sure we do the actual fetch with the right $mode set.
+        */
+       public function testLoadRevisionInformation_mode() {
+               $q1 = new ItemId( 'Q1' );
+
+               $lookup = $this->getMock( WikiPageEntityMetaDataAccessor::class 
);
+               $lookup->expects( $this->once() )
+                       ->method( 'loadRevisionInformation' )
+                       ->with(
+                               array( $q1->getSerialization() => $q1 ),
+                               'load-mode'
+                       )
+                       ->will( $this->returnValue( array( 'Q1' => 'data' ) ) );
+
+               $accessor = new PrefetchingWikiPageEntityMetaDataAccessor( 
$lookup );
+
+               // This loads Q1 with $mode = 'load-mode'
+               $result = $accessor->loadRevisionInformation( array( $q1 ), 
'load-mode' );
+
+               $this->assertSame( array( 'Q1' => 'data' ), $result );
+       }
+
        public function testLoadRevisionInformationByRevisionId() {
                // This function is a very simple, it's just a wrapper around 
the
                // lookup function.
@@ -201,7 +228,7 @@
                $lookup = $this->getMock( WikiPageEntityMetaDataAccessor::class 
);
                $lookup->expects( $this->once() )
                        ->method( 'loadRevisionInformationByRevisionId' )
-                       ->with( $q1, 123 )
+                       ->with( $q1, 123, 
EntityRevisionLookup::LATEST_FROM_MASTER )
                        ->will( $this->returnValue( 'passthrough' ) );
 
                $accessor = new PrefetchingWikiPageEntityMetaDataAccessor( 
$lookup );
diff --git a/repo/includes/Api/EntityLoadingHelper.php 
b/repo/includes/Api/EntityLoadingHelper.php
index d2e6f3b..082b915 100644
--- a/repo/includes/Api/EntityLoadingHelper.php
+++ b/repo/includes/Api/EntityLoadingHelper.php
@@ -130,9 +130,9 @@
         * cannot be found or cannot be loaded.
         *
         * @param EntityId $entityId EntityId of the page to load the revision 
for
-        * @param int|string|null $revId revision to load, or the retrieval 
mode,
-        *        see the LATEST_XXX constants defined in EntityRevisionLookup.
-        *        If not given, the current revision will be loaded, using the 
default retrieval mode.
+        * @param int $revId The desired revision id, or 0 for the latest 
revision.
+        * @param string|null $mode LATEST_FROM_SLAVE, 
LATEST_FROM_SLAVE_WITH_FALLBACK or
+        *        LATEST_FROM_MASTER (from EntityRevisionLookup). Null for the 
default.
         *
         * @throws UsageException
         * @throws LogicException
@@ -140,14 +140,18 @@
         */
        protected function loadEntityRevision(
                EntityId $entityId,
-               $revId = null
+               $revId = 0,
+               $mode = null
        ) {
                if ( $revId === null ) {
-                       $revId = $this->defaultRetrievalMode;
+                       $revId = 0;
+               }
+               if ( $mode === null ) {
+                       $mode = $this->defaultRetrievalMode;
                }
 
                try {
-                       $revision = 
$this->entityRevisionLookup->getEntityRevision( $entityId, $revId );
+                       $revision = 
$this->entityRevisionLookup->getEntityRevision( $entityId, $revId, $mode );
                        return $revision;
                } catch ( RevisionedUnresolvedRedirectException $ex ) {
                        $this->errorReporter->dieException( $ex, 
'unresolved-redirect' );
diff --git a/repo/includes/Api/EntitySavingHelper.php 
b/repo/includes/Api/EntitySavingHelper.php
index d7ee757..9973005 100644
--- a/repo/includes/Api/EntitySavingHelper.php
+++ b/repo/includes/Api/EntitySavingHelper.php
@@ -153,14 +153,10 @@
                        ? (int)$params['baserevid']
                        : 0;
 
-               if ( $baseRev === 0 ) {
-                       $baseRev = $this->defaultRetrievalMode;
-               }
-
                if ( $entityId ) {
                        $entityRevision = $this->loadEntityRevision( $entityId, 
$baseRev );
                } else {
-                       if ( is_int( $baseRev ) ) {
+                       if ( $baseRev > 0 ) {
                                $this->errorReporter->dieError(
                                        'Cannot load specific revision ' . 
$baseRev . ' if no entity is defined.',
                                        'param-illegal'
@@ -172,7 +168,7 @@
 
                $new = isset( $params['new'] ) ? $params['new'] : null;
                if ( is_null( $entityRevision ) ) {
-                       if ( is_int( $baseRev ) ) {
+                       if ( $baseRev > 0 ) {
                                $this->errorReporter->dieError(
                                        'Could not find revision ' . $baseRev,
                                        'nosuchrevid'
diff --git a/repo/includes/Api/LinkTitles.php b/repo/includes/Api/LinkTitles.php
index ea7f272..97b01e7 100644
--- a/repo/includes/Api/LinkTitles.php
+++ b/repo/includes/Api/LinkTitles.php
@@ -141,7 +141,7 @@
                } elseif ( $fromId === null && $toId !== null ) {
                        // reuse to-site's item
                        /** @var Item $item */
-                       $itemRev = $lookup->getEntityRevision( $toId, 
EntityRevisionLookup::LATEST_FROM_MASTER );
+                       $itemRev = $lookup->getEntityRevision( $toId, 0, 
EntityRevisionLookup::LATEST_FROM_MASTER );
                        $item = $itemRev->getEntity();
                        $fromLink = new SiteLink( $fromSite->getGlobalId(), 
$fromPage );
                        $item->addSiteLink( $fromLink );
@@ -150,7 +150,7 @@
                } elseif ( $fromId !== null && $toId === null ) {
                        // reuse from-site's item
                        /** @var Item $item */
-                       $itemRev = $lookup->getEntityRevision( $fromId, 
EntityRevisionLookup::LATEST_FROM_MASTER );
+                       $itemRev = $lookup->getEntityRevision( $fromId, 0, 
EntityRevisionLookup::LATEST_FROM_MASTER );
                        $item = $itemRev->getEntity();
                        $toLink = new SiteLink( $toSite->getGlobalId(), $toPage 
);
                        $item->addSiteLink( $toLink );
diff --git a/repo/includes/EditEntity.php b/repo/includes/EditEntity.php
index 321d749..6eb21a1 100644
--- a/repo/includes/EditEntity.php
+++ b/repo/includes/EditEntity.php
@@ -278,6 +278,7 @@
                                // $this->getPage(), this should NOT change!
                                $this->latestRev = 
$this->entityRevisionLookup->getEntityRevision(
                                        $id,
+                                       0,
                                        EntityRevisionLookup::LATEST_FROM_MASTER
                                );
                        }
@@ -353,10 +354,6 @@
                        } elseif ( $baseRevId === $this->getLatestRevisionId() 
) {
                                $this->baseRev = $this->getLatestRevision();
                        } else {
-                               if ( $baseRevId === 0 ) {
-                                       $baseRevId = 
EntityRevisionLookup::LATEST_FROM_MASTER;
-                               }
-
                                $id = $this->newEntity->getId();
                                $this->baseRev = 
$this->entityRevisionLookup->getEntityRevision( $id, $baseRevId );
 
diff --git a/repo/includes/Hooks/OutputPageBeforeHTMLHookHandler.php 
b/repo/includes/Hooks/OutputPageBeforeHTMLHookHandler.php
index 2ca9873..7a6cde2 100644
--- a/repo/includes/Hooks/OutputPageBeforeHTMLHookHandler.php
+++ b/repo/includes/Hooks/OutputPageBeforeHTMLHookHandler.php
@@ -188,7 +188,7 @@
 
        /**
         * @param EntityId $entityId
-        * @param string $revisionId
+        * @param int $revisionId
         * @param bool $termsListPrerendered
         *
         * @return EntityDocument|null
diff --git a/repo/includes/Interactors/ItemMergeInteractor.php 
b/repo/includes/Interactors/ItemMergeInteractor.php
index 11f898a..e1e7af5 100644
--- a/repo/includes/Interactors/ItemMergeInteractor.php
+++ b/repo/includes/Interactors/ItemMergeInteractor.php
@@ -225,6 +225,7 @@
                try {
                        $revision = 
$this->entityRevisionLookup->getEntityRevision(
                                $itemId,
+                               0,
                                EntityRevisionLookup::LATEST_FROM_MASTER
                        );
 
diff --git a/repo/includes/Interactors/RedirectCreationInteractor.php 
b/repo/includes/Interactors/RedirectCreationInteractor.php
index c5edb5e..15309e1 100644
--- a/repo/includes/Interactors/RedirectCreationInteractor.php
+++ b/repo/includes/Interactors/RedirectCreationInteractor.php
@@ -171,7 +171,11 @@
         */
        private function checkCanCreateRedirect( EntityId $entityId ) {
                try {
-                       $revision = 
$this->entityRevisionLookup->getEntityRevision( $entityId, 
EntityRevisionLookup::LATEST_FROM_MASTER );
+                       $revision = 
$this->entityRevisionLookup->getEntityRevision(
+                               $entityId,
+                               0,
+                               EntityRevisionLookup::LATEST_FROM_MASTER
+                       );
 
                        if ( !$revision ) {
                                $title = 
$this->entityTitleLookup->getTitleForId( $entityId );
diff --git a/repo/includes/LinkedData/EntityDataRequestHandler.php 
b/repo/includes/LinkedData/EntityDataRequestHandler.php
index 323803d..1aa588d 100644
--- a/repo/includes/LinkedData/EntityDataRequestHandler.php
+++ b/repo/includes/LinkedData/EntityDataRequestHandler.php
@@ -344,11 +344,6 @@
         */
        private function getEntityRevision( EntityId $id, $revision ) {
                $prefixedId = $id->getSerialization();
-
-               if ( $revision === 0 ) {
-                       $revision = EntityRevisionLookup::LATEST_FROM_SLAVE;
-               }
-
                $redirectRevision = null;
 
                try {
@@ -365,7 +360,7 @@
                                $ex->getRevisionId(), 
$ex->getRevisionTimestamp()
                        );
 
-                       if ( is_string( $revision ) ) {
+                       if ( $revision === 0 ) {
                                // If no specific revision is requested, 
resolve the redirect.
                                list( $entityRevision, ) = 
$this->getEntityRevision( $ex->getRedirectTargetId(), $revision );
                        } else {
diff --git a/repo/includes/Specials/SpecialModifyEntity.php 
b/repo/includes/Specials/SpecialModifyEntity.php
index ee00149..dd5ae88 100644
--- a/repo/includes/Specials/SpecialModifyEntity.php
+++ b/repo/includes/Specials/SpecialModifyEntity.php
@@ -186,15 +186,15 @@
         * @since 0.5
         *
         * @param EntityId $id
-        * @param int|string $revisionId
         *
         * @throws MessageException
         * @throws UserInputException
         * @return EntityRevision
         */
-       protected function loadEntity( EntityId $id, $revisionId = 
EntityRevisionLookup::LATEST_FROM_MASTER ) {
+       protected function loadEntity( EntityId $id ) {
                try {
-                       $entity = 
$this->entityRevisionLookup->getEntityRevision( $id, $revisionId );
+                       $entity = $this->entityRevisionLookup
+                               ->getEntityRevision( $id, 0, 
EntityRevisionLookup::LATEST_FROM_MASTER );
 
                        if ( $entity === null ) {
                                throw new UserInputException(
diff --git a/repo/includes/UpdateRepo/UpdateRepoJob.php 
b/repo/includes/UpdateRepo/UpdateRepoJob.php
index 4b1255a..91db8e7 100644
--- a/repo/includes/UpdateRepo/UpdateRepoJob.php
+++ b/repo/includes/UpdateRepo/UpdateRepoJob.php
@@ -120,7 +120,7 @@
                }
 
                try {
-                       $entityRevision = 
$this->entityRevisionLookup->getEntityRevision( $itemId, 
EntityRevisionLookup::LATEST_FROM_MASTER );
+                       $entityRevision = 
$this->entityRevisionLookup->getEntityRevision( $itemId, 0, 
EntityRevisionLookup::LATEST_FROM_MASTER );
                } catch ( StorageException $ex ) {
                        wfDebugLog(
                                'UpdateRepo',
diff --git a/repo/tests/phpunit/includes/EditEntityTest.php 
b/repo/tests/phpunit/includes/EditEntityTest.php
index 9f3879b..1f3f1f9 100644
--- a/repo/tests/phpunit/includes/EditEntityTest.php
+++ b/repo/tests/phpunit/includes/EditEntityTest.php
@@ -216,7 +216,7 @@
                return array(
                        array( // #0: case I: no base rev given.
                                null,  // input data
-                               EntityRevisionLookup::LATEST_FROM_MASTER,  // 
base rev
+                               0,  // base rev
                                false, // expected conflict
                                false, // expected fix
                        ),
diff --git 
a/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityMetaDataLookupTest.php 
b/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityMetaDataLookupTest.php
index b237d53..e7d7fd0 100644
--- a/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityMetaDataLookupTest.php
+++ b/repo/tests/phpunit/includes/Store/Sql/WikiPageEntityMetaDataLookupTest.php
@@ -2,11 +2,15 @@
 
 namespace Wikibase\Repo\Tests\Store\Sql;
 
+use DatabaseBase;
+use FakeResultWrapper;
 use MediaWikiTestCase;
 use Wikibase\DataModel\Entity\Item;
 use Wikibase\DataModel\Entity\ItemId;
 use Wikibase\EntityRevision;
 use Wikibase\Lib\Store\EntityNamespaceLookup;
+use Wikibase\Lib\Store\EntityRevisionLookup;
+use Wikibase\Lib\Store\Sql\WikiPageEntityMetaDataAccessor;
 use Wikibase\Lib\Store\Sql\WikiPageEntityMetaDataLookup;
 use Wikibase\Repo\WikibaseRepo;
 
@@ -64,6 +68,72 @@
                return new WikiPageEntityMetaDataLookup( 
$this->getEntityNamespaceLookup() );
        }
 
+       /**
+        * This mock uses the real code except for DBAccessBase::getConnection
+        *
+        * @param int $selectCount Number of mocked/lagged 
DBAccessBase::getConnection::select calls
+        * @param int $selectRowCount Number of mocked/lagged 
DBAccessBase::getConnection::selectRow calls
+        * @param int $getConnectionCount Number of 
WikiPageEntityMetaDataLookup::getConnection calls
+        *
+        * @return WikiPageEntityMetaDataLookup
+        */
+       private function getLookupWithLaggedConnection( $selectCount, 
$selectRowCount, $getConnectionCount ) {
+               $lookup = $this->getMockBuilder( 
WikiPageEntityMetaDataLookup::class )
+                       ->setConstructorArgs( array( 
$this->getEntityNamespaceLookup() ) )
+                       ->setMethods( array( 'getConnection' ) )
+                       ->getMock();
+
+               $lookup->expects( $this->exactly( $getConnectionCount ) )
+                       ->method( 'getConnection' )
+                       ->will( $this->returnCallback( function( $id ) use ( 
$selectCount, $selectRowCount ) {
+                               $db = $realDB = wfGetDB( DB_MASTER );
+
+                               if ( $id === DB_SLAVE ) {
+                                       // This is a (fake) lagged database 
connection.
+                                       $db = $this->getLaggedDatabase( 
$realDB, $selectCount, $selectRowCount );
+                               }
+
+                               return $db;
+                       } ) );
+
+               return $lookup;
+       }
+
+       /**
+        * Gets a "lagged" database connection: We always leave out the first 
row on select.
+        */
+       private function getLaggedDatabase( DatabaseBase $realDB, $selectCount, 
$selectRowCount ) {
+               $db = $this->getMockBuilder( DatabaseBase::class )
+                       ->disableOriginalConstructor()
+                       ->setMethods( array( 'select', 'selectRow' ) )
+                       ->setProxyTarget( $realDB )
+                       ->getMockForAbstractClass();
+
+               $db->expects( $this->exactly( $selectCount ) )
+                       ->method( 'select' )
+                       ->will( $this->returnCallback( function() use ( $realDB 
) {
+                               // Get the actual result
+                               $res = call_user_func_array(
+                                       array( $realDB, 'select' ),
+                                       func_get_args()
+                               );
+
+                               // Return the real result minus the first row
+                               $data = array();
+                               foreach ( $res as $row ) {
+                                       $data[] = $row;
+                               }
+
+                               return new FakeResultWrapper( array_slice( 
$data, 1 ) );
+                       } ) );
+
+               $db->expects( $this->exactly( $selectRowCount ) )
+                       ->method( 'selectRow' )
+                       ->will( $this->returnValue( false ) );
+
+               return $db;
+       }
+
        public function testLoadRevisionInformationById_latest() {
                $entityRevision = $this->data[0];
 
@@ -72,6 +142,39 @@
 
                $this->assertEquals( $entityRevision->getRevisionId(), 
$result->rev_id );
                $this->assertEquals( $entityRevision->getRevisionId(), 
$result->page_latest );
+       }
+
+       public function testLoadRevisionInformationById_masterFallback() {
+               $entityRevision = $this->data[0];
+
+               // Make sure we have two calls to getConnection: One that asks 
for a
+               // slave and one that asks for the master.
+               $lookup = $this->getLookupWithLaggedConnection( 0, 1, 2 );
+
+               $result = $lookup->loadRevisionInformationByRevisionId(
+                       $entityRevision->getEntity()->getId(),
+                       $entityRevision ->getRevisionId(),
+                       EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK
+               );
+
+               $this->assertEquals( $entityRevision->getRevisionId(), 
$result->rev_id );
+               $this->assertEquals( $entityRevision->getRevisionId(), 
$result->page_latest );
+       }
+
+       public function testLoadRevisionInformationById_noFallback() {
+               $entityRevision = $this->data[0];
+
+               // Should do only one getConnection call.
+               $lookup = $this->getLookupWithLaggedConnection( 0, 1, 1 );
+
+               $result = $lookup->loadRevisionInformationByRevisionId(
+                       $entityRevision->getEntity()->getId(),
+                       $entityRevision ->getRevisionId(),
+                       EntityRevisionLookup::LATEST_FROM_SLAVE
+               );
+
+               // No fallback: Lagged data is omitted.
+               $this->assertFalse( $result );
        }
 
        public function testLoadRevisionInformationById_old() {
@@ -110,17 +213,7 @@
                $this->assertFalse( $result );
        }
 
-       public function testLoadRevisionInformation() {
-               $entityIds = array(
-                       $this->data[0]->getEntity()->getId(),
-                       $this->data[1]->getEntity()->getId(),
-                       new ItemId( 'Q823487354' ), // Doesn't exist
-                       $this->data[2]->getEntity()->getId()
-               );
-
-               $result = $this->getWikiPageEntityMetaDataLookup()
-                       ->loadRevisionInformation( $entityIds, DB_SLAVE );
-
+       private function assertRevisionInformation( $entityIds, $result ) {
                $serializedEntityIds = array();
                foreach ( $entityIds as $entityId ) {
                        $serializedEntityIds[] = $entityId->getSerialization();
@@ -140,8 +233,45 @@
                        $result[$serializedEntityIds[3]]->rev_id, 
$this->data[2]->getRevisionId()
                );
 
-               // Verify that Q823487354 (doesn't exist) is not part of the 
result
-               $this->assertFalse( $result['Q823487354'] );
+               // Verify that no further entities are part of the result
+               $this->assertCount( count( $entityIds ), $result );
+       }
+
+       public function testLoadRevisionInformation() {
+               $entityIds = array(
+                       $this->data[0]->getEntity()->getId(),
+                       $this->data[1]->getEntity()->getId(),
+                       new ItemId( 'Q823487354' ), // Doesn't exist
+                       $this->data[2]->getEntity()->getId()
+               );
+
+               $result = $this->getWikiPageEntityMetaDataLookup()
+                       ->loadRevisionInformation(
+                               $entityIds,
+                               EntityRevisionLookup::LATEST_FROM_SLAVE
+                       );
+
+               $this->assertRevisionInformation( $entityIds, $result );
+       }
+
+       public function testLoadRevisionInformation_masterFallback() {
+               $entityIds = array(
+                       $this->data[0]->getEntity()->getId(),
+                       $this->data[1]->getEntity()->getId(),
+                       new ItemId( 'Q823487354' ), // Doesn't exist
+                       $this->data[2]->getEntity()->getId()
+               );
+
+               // Make sure we have two calls to getConnection: One that asks 
for a
+               // slave and one that asks for the master.
+               $lookup = $this->getLookupWithLaggedConnection( 1, 0, 2 );
+
+               $result = $lookup->loadRevisionInformation(
+                       $entityIds,
+                       EntityRevisionLookup::LATEST_FROM_SLAVE_WITH_FALLBACK
+               );
+
+               $this->assertRevisionInformation( $entityIds, $result );
        }
 
 }
diff --git 
a/repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php 
b/repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php
index 4ed2916..506c5fa 100644
--- a/repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php
+++ b/repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php
@@ -126,4 +126,32 @@
                $lookup->getEntityRevision( new ItemId( 'Q42' ) );
        }
 
+       public function testGetEntityRevision_byRevisionIdWithMode() {
+               $testEntityRevision = reset( self::$testEntities );
+               $entityId = $testEntityRevision->getEntity()->getId();
+               $revisionId = $testEntityRevision->getRevisionId();
+
+               $realMetaDataLookup = new WikiPageEntityMetaDataLookup( 
$this->getEntityNamespaceLookup() );
+               $metaDataLookup = $this->getMockBuilder( 
WikiPageEntityMetaDataLookup::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $metaDataLookup->expects( $this->once() )
+                       ->method( 'loadRevisionInformationByRevisionId' )
+                       ->with( $entityId, $revisionId, 'load-mode' )
+                       ->will( $this->returnValue(
+                               
$realMetaDataLookup->loadRevisionInformationByRevisionId( $entityId, 
$revisionId )
+                       ) );
+
+               $lookup = new WikiPageEntityRevisionLookup(
+                       
WikibaseRepo::getDefaultInstance()->getEntityContentDataCodec(),
+                       $metaDataLookup,
+                       false
+               );
+
+               $entityRevision = $lookup->getEntityRevision( $entityId, 
$revisionId, 'load-mode' );
+
+               $this->assertSame( $revisionId, 
$entityRevision->getRevisionId() );
+       }
+
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/302199
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ic9ef30431f8ad23f70d84df8fe005d05e4fec9ab
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Hoo man <h...@online.de>
Gerrit-Reviewer: Aaron Schulz <asch...@wikimedia.org>
Gerrit-Reviewer: Aude <aude.w...@gmail.com>
Gerrit-Reviewer: Daniel Kinzler <daniel.kinz...@wikimedia.de>
Gerrit-Reviewer: Hoo man <h...@online.de>
Gerrit-Reviewer: Smalyshev <smalys...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to