WikidataBuilder has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/386794 )
Change subject: New Wikidata Build - 2017-10-27T10:00:01+0000 ...................................................................... New Wikidata Build - 2017-10-27T10:00:01+0000 Change-Id: I1e1e9e0a198a82b4753527140d5e68c5a2cd05e1 --- M composer.lock M extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php M extensions/Constraints/tests/phpunit/DelegatingConstraintCheckerTest.php M extensions/MediaInfo/src/Content/MediaInfoHandler.php M extensions/Wikibase/client/includes/Changes/InjectRCRecordsJob.php M extensions/Wikibase/client/includes/Store/Sql/DirectSqlStore.php M extensions/Wikibase/client/includes/Usage/Sql/EntityUsageTable.php M extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/LuaWikibaseLibraryTests.lua M extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibraryTest.php M extensions/Wikibase/lib/includes/Changes/EntityChange.php A extensions/Wikibase/lib/includes/Store/CacheRetrievingEntityRevisionLookup.php M extensions/Wikibase/lib/includes/Store/CachingEntityRevisionLookup.php A extensions/Wikibase/lib/includes/Store/EntityRevisionCache.php A extensions/Wikibase/lib/tests/phpunit/Store/CacheRetrievingEntityRevisionLookupTest.php M extensions/Wikibase/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php A extensions/Wikibase/lib/tests/phpunit/Store/EntityRevisionCacheTest.php M extensions/Wikibase/repo/i18n/tr.json M extensions/Wikibase/repo/includes/Search/Elastic/EntitySearchElastic.php M extensions/Wikibase/repo/includes/Store/Sql/DatabaseSchemaUpdater.php M extensions/Wikibase/repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php M extensions/Wikibase/repo/includes/Store/Sql/SqlStore.php M extensions/Wikibase/repo/includes/Store/Store.php M extensions/Wikibase/repo/includes/WikibaseRepo.php M extensions/Wikibase/repo/maintenance/dumpJson.php M extensions/Wikibase/repo/maintenance/dumpRdf.php M extensions/Wikibase/repo/maintenance/rebuildItemsPerSite.php M extensions/Wikibase/repo/maintenance/rebuildTermSqlIndex.php M extensions/Wikibase/repo/tests/phpunit/includes/Store/Sql/SqlStoreTest.php M extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php M vendor/composer/autoload_classmap.php M vendor/composer/autoload_static.php M vendor/composer/installed.json M vendor/wikibase/internal-serialization/README.md M vendor/wikibase/internal-serialization/src/DeserializerFactory.php 34 files changed, 889 insertions(+), 232 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikidata refs/changes/94/386794/1 diff --git a/composer.lock b/composer.lock index c03e2d9..348900d 100644 --- a/composer.lock +++ b/composer.lock @@ -971,7 +971,7 @@ "source": { "type": "git", "url": "https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQualityConstraints", - "reference": "598671433d7c5d8cef818c6eff957a5eb00e0040" + "reference": "b0e8881e094cea6e89963cdfeac5fa8c932a2d05" }, "require": { "php": ">=5.5.9", @@ -1031,7 +1031,7 @@ "support": { "issues": "https://phabricator.wikimedia.org/project/profile/1202/" }, - "time": "2017-10-25 21:08:09" + "time": "2017-10-26 13:19:54" }, { "name": "wikibase/data-model", @@ -1264,21 +1264,21 @@ }, { "name": "wikibase/internal-serialization", - "version": "2.6.0", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/wmde/WikibaseInternalSerialization.git", - "reference": "b1ac697ede618d70108d5d6e0e623e9fcbb90976" + "reference": "a1a9257221a81b1de3226be6b13178203cf680b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wmde/WikibaseInternalSerialization/zipball/b1ac697ede618d70108d5d6e0e623e9fcbb90976", - "reference": "b1ac697ede618d70108d5d6e0e623e9fcbb90976", + "url": "https://api.github.com/repos/wmde/WikibaseInternalSerialization/zipball/a1a9257221a81b1de3226be6b13178203cf680b1", + "reference": "a1a9257221a81b1de3226be6b13178203cf680b1", "shasum": "" }, "require": { "php": ">=5.5.9", - "serialization/serialization": "~3.2", + "serialization/serialization": "~4.0|~3.2", "wikibase/data-model": "~7.0|~6.0|~5.0|~4.2", "wikibase/data-model-serialization": "~2.0" }, @@ -1289,12 +1289,12 @@ "data-values/time": ">=0.1 <0.9", "phpmd/phpmd": "~2.3", "phpunit/phpunit": "~4.8", - "wikibase/wikibase-codesniffer": "^0.1.0" + "wikibase/wikibase-codesniffer": "^0.2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6.x-dev" + "dev-master": "2.7.x-dev" } }, "autoload": { @@ -1323,7 +1323,7 @@ "wikibase", "wikidata" ], - "time": "2017-09-18 08:42:51" + "time": "2017-10-26 12:45:36" }, { "name": "wikibase/javascript-api", @@ -1376,7 +1376,7 @@ "source": { "type": "git", "url": "https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseMediaInfo", - "reference": "2e477617530539bc4ba3e2196d5533bde3f72455" + "reference": "81a601a7f844da6c83133c2464c4ac81715a4f6d" }, "require": { "php": ">=5.5.9", @@ -1423,7 +1423,7 @@ "issues": "https://phabricator.wikimedia.org/", "irc": "irc://irc.freenode.net/wikidata" }, - "time": "2017-10-17 21:06:57" + "time": "2017-10-26 10:42:44" }, { "name": "wikibase/quality", @@ -1542,12 +1542,12 @@ "source": { "type": "git", "url": "https://github.com/wikimedia/mediawiki-extensions-Wikibase.git", - "reference": "84f5795908c00f3c37072b02aa025c782083bda3" + "reference": "b789faeb3a3898e03ec31ce4b628611642b141dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/84f5795908c00f3c37072b02aa025c782083bda3", - "reference": "84f5795908c00f3c37072b02aa025c782083bda3", + "url": "https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/b789faeb3a3898e03ec31ce4b628611642b141dc", + "reference": "b789faeb3a3898e03ec31ce4b628611642b141dc", "shasum": "" }, "require": { @@ -1626,7 +1626,7 @@ "wikibaserepo", "wikidata" ], - "time": "2017-10-26 07:53:28" + "time": "2017-10-26 21:39:21" }, { "name": "wikibase/wikimedia-badges", diff --git a/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php b/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php index 198fef6..869381f 100644 --- a/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php +++ b/extensions/Constraints/includes/ConstraintCheck/DelegatingConstraintChecker.php @@ -19,6 +19,7 @@ use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\LoggingHelper; use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\SparqlHelperException; use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResult; +use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\NullResult; use WikibaseQuality\ConstraintReport\ConstraintLookup; use WikibaseQuality\ConstraintReport\Constraint; use Wikibase\DataModel\Entity\EntityId; @@ -573,6 +574,13 @@ $hashB = $b->getContext()->getSnak()->getHash(); if ( $hashA === $hashB ) { + if ( $a instanceof NullResult ) { + return $b instanceof NullResult ? 0 : -1; + } + if ( $b instanceof NullResult ) { + return $a instanceof NullResult ? 0 : 1; + } + $typeA = $a->getConstraint()->getConstraintTypeItemId(); $typeB = $b->getConstraint()->getConstraintTypeItemId(); diff --git a/extensions/Constraints/tests/phpunit/DelegatingConstraintCheckerTest.php b/extensions/Constraints/tests/phpunit/DelegatingConstraintCheckerTest.php index eafa1c8..72b9a60 100644 --- a/extensions/Constraints/tests/phpunit/DelegatingConstraintCheckerTest.php +++ b/extensions/Constraints/tests/phpunit/DelegatingConstraintCheckerTest.php @@ -14,6 +14,7 @@ use Wikibase\Repo\Tests\NewStatement; use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterException; use WikibaseQuality\ConstraintReport\ConstraintCheck\DelegatingConstraintChecker; +use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\NullResult; use WikibaseQuality\ConstraintReport\ConstraintReportFactory; use WikibaseQuality\ConstraintReport\Tests\ConstraintParameters; use WikibaseQuality\ConstraintReport\Tests\ResultAssertions; @@ -364,6 +365,26 @@ $this->assertEmpty( $result ); } + public function testCheckOnEntityIdNullResult() { + $statement = NewStatement::forProperty( 'P2' ) + ->withValue( 'foo' ); + $entity = NewItem::withId( 'Q2' ) + ->andStatement( $statement ) + ->andStatement( $statement ) + ->build(); + $this->lookup->addEntity( $entity ); + + $result = $this->constraintChecker->checkAgainstConstraintsOnEntityId( + $entity->getId(), + null, + function( $context ) { + return [ new NullResult( $context ) ]; + } + ); + + $this->assertCount( 2, $result ); + } + public function testCheckOnEntityIdUnknownConstraint() { $entity = NewItem::withId( 'Q3' ) ->andStatement( diff --git a/extensions/MediaInfo/src/Content/MediaInfoHandler.php b/extensions/MediaInfo/src/Content/MediaInfoHandler.php index cf0beb4..b149ba3 100644 --- a/extensions/MediaInfo/src/Content/MediaInfoHandler.php +++ b/extensions/MediaInfo/src/Content/MediaInfoHandler.php @@ -15,9 +15,9 @@ use Wikibase\MediaInfo\Actions\ViewMediaInfoAction; use Wikibase\MediaInfo\DataModel\MediaInfo; use Wikibase\MediaInfo\DataModel\MediaInfoId; -use Wikibase\MediaInfo\Search\MediaInfoFieldDefinitions; use Wikibase\MediaInfo\Services\FilePageLookup; use Wikibase\Repo\Content\EntityHandler; +use Wikibase\Repo\Search\Elastic\Fields\FieldDefinitions; use Wikibase\Repo\Validators\EntityConstraintProvider; use Wikibase\Repo\Validators\ValidatorErrorLocalizer; use Wikibase\Store\EntityIdLookup; @@ -60,7 +60,7 @@ * @param LanguageFallbackLabelDescriptionLookupFactory $labelLookupFactory * @param MissingMediaInfoHandler $missingMediaInfoHandler * @param FilePageLookup $filePageLookup - * @param MediaInfoFieldDefinitions $fieldDefinitions + * @param FieldDefinitions $mediaInfoFieldDefinitions * @param callable|null $legacyExportFormatDetector */ public function __construct( @@ -73,7 +73,7 @@ LanguageFallbackLabelDescriptionLookupFactory $labelLookupFactory, MissingMediaInfoHandler $missingMediaInfoHandler, FilePageLookup $filePageLookup, - MediaInfoFieldDefinitions $fieldDefinitions, + FieldDefinitions $mediaInfoFieldDefinitions, $legacyExportFormatDetector = null ) { parent::__construct( @@ -83,7 +83,7 @@ $constraintProvider, $errorLocalizer, $entityIdParser, - $fieldDefinitions, + $mediaInfoFieldDefinitions, $legacyExportFormatDetector ); $this->entityIdLookup = $entityIdLookup; diff --git a/extensions/Wikibase/client/includes/Changes/InjectRCRecordsJob.php b/extensions/Wikibase/client/includes/Changes/InjectRCRecordsJob.php index dc5ec94..545fdd2 100644 --- a/extensions/Wikibase/client/includes/Changes/InjectRCRecordsJob.php +++ b/extensions/Wikibase/client/includes/Changes/InjectRCRecordsJob.php @@ -274,6 +274,8 @@ } } + // Wait for all database replicas to be updated, but only for the affected client wiki. The + // "domain" argument is documented at ILBFactory::waitForReplication. $this->lbFactory->commitAndWaitForReplication( __METHOD__, $trxToken, [ 'domain' => wfWikiID() ] ); $this->incrementStats( 'InjectRCRecords.run.titles', count( $titles ) ); diff --git a/extensions/Wikibase/client/includes/Store/Sql/DirectSqlStore.php b/extensions/Wikibase/client/includes/Store/Sql/DirectSqlStore.php index 5118911..e5d0404 100644 --- a/extensions/Wikibase/client/includes/Store/Sql/DirectSqlStore.php +++ b/extensions/Wikibase/client/includes/Store/Sql/DirectSqlStore.php @@ -29,6 +29,7 @@ use Wikibase\Lib\EntityIdComposer; use Wikibase\Lib\Store\CachingEntityRevisionLookup; use Wikibase\Lib\Store\CachingSiteLinkLookup; +use Wikibase\Lib\Store\EntityRevisionCache; use Wikibase\Lib\Store\Sql\EntityChangeLookup; use Wikibase\Lib\Store\EntityNamespaceLookup; use Wikibase\Lib\Store\EntityRevisionLookup; @@ -346,18 +347,20 @@ // Lower caching layer using persistent cache (e.g. memcached). $persistentCachingLookup = new CachingEntityRevisionLookup( - $dispatchingLookup, - wfGetCache( $this->cacheType ), - $this->cacheDuration, - $cacheKeyPrefix + new EntityRevisionCache( + wfGetCache( $this->cacheType ), + $this->cacheDuration, + $cacheKeyPrefix + ), + $dispatchingLookup ); // We need to verify the revision ID against the database to avoid stale data. $persistentCachingLookup->setVerifyRevision( true ); // Top caching layer using an in-process hash. $hashCachingLookup = new CachingEntityRevisionLookup( - $persistentCachingLookup, - new HashBagOStuff( [ 'maxKeys' => 1000 ] ) + new EntityRevisionCache( new HashBagOStuff( [ 'maxKeys' => 1000 ] ) ), + $persistentCachingLookup ); // No need to verify the revision ID, we'll ignore updates that happen during the request. $hashCachingLookup->setVerifyRevision( false ); diff --git a/extensions/Wikibase/client/includes/Usage/Sql/EntityUsageTable.php b/extensions/Wikibase/client/includes/Usage/Sql/EntityUsageTable.php index c555d8e..59a80df 100644 --- a/extensions/Wikibase/client/includes/Usage/Sql/EntityUsageTable.php +++ b/extensions/Wikibase/client/includes/Usage/Sql/EntityUsageTable.php @@ -13,6 +13,7 @@ use Wikibase\DataModel\Entity\EntityIdParser; use Wikimedia\Rdbms\Database; use Wikimedia\Rdbms\DBUnexpectedError; +use Wikimedia\Rdbms\LBFactory; /** * Helper class for updating the wbc_entity_usage table. @@ -26,6 +27,13 @@ class EntityUsageTable { const DEFAULT_TABLE_NAME = 'wbc_entity_usage'; + + /** + * INSERTs are supposed to be done in much larger batches than SELECTs or DELETEs, per the DBA. + * About 1000 was suggested. Given the default batch size is 100, a factor of 5 seems to be a + * good compromise. + */ + const INSERT_BATCH_SIZE_FACTOR = 5; /** * @var EntityIdParser @@ -43,9 +51,9 @@ private $readConnection; /** - * @var string + * @var LBFactory */ - private $tableName; + private $loadBalancerFactory; /** * @var int @@ -53,9 +61,15 @@ private $batchSize; /** + * @var string + */ + private $tableName; + + /** * @param EntityIdParser $idParser * @param Database $writeConnection - * @param int $batchSize defaults to 100 + * @param int $batchSize Batch size for database queries on the entity usage table, including + * INSERTs, SELECTs, and DELETEs. Defaults to 100. * @param string|null $tableName defaults to wbc_entity_usage * * @throws InvalidArgumentException @@ -80,8 +94,8 @@ $this->tableName = $tableName ?: self::DEFAULT_TABLE_NAME; //TODO: Inject - $this->readConnection = MediaWikiServices::getInstance()->getDBLoadBalancer() - ->getConnection( DB_REPLICA ); + $this->loadBalancerFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory(); + $this->readConnection = $this->loadBalancerFactory->getMainLB()->getConnection( DB_REPLICA ); } /** @@ -160,7 +174,7 @@ $batches = array_chunk( $this->makeUsageRows( $pageId, $usages ), - $this->batchSize + $this->batchSize * self::INSERT_BATCH_SIZE_FACTOR ); $c = 0; @@ -174,6 +188,10 @@ $this->writeConnection->endAtomic( __METHOD__ ); + // Wait for all database replicas to be updated, but only for the affected client wiki. The + // "domain" argument is documented at ILBFactory::waitForReplication. + $this->loadBalancerFactory->waitForReplication( [ 'domain' => wfWikiID() ] ); + return $c; } diff --git a/extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/LuaWikibaseLibraryTests.lua b/extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/LuaWikibaseLibraryTests.lua index 73de15f..80292f8 100644 --- a/extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/LuaWikibaseLibraryTests.lua +++ b/extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/LuaWikibaseLibraryTests.lua @@ -87,6 +87,12 @@ return mw.wikibase.formatValues( snaks ) end +local function testGetEntityUrl( expectedItemId, itemId ) + local url = mw.wikibase.getEntityUrl( itemId ) + + return url:match( '//.*/' .. expectedItemId ) ~= nil +end + local tests = { -- Integration tests @@ -118,7 +124,7 @@ args = { 0, 'P12' }, expect = "bad argument #1 to 'getBestStatements' (string expected, got number)" }, - { name = 'mw.wikibase.getBestStatements (entityId must be string)', func = mw.wikibase.getBestStatements, type='ToString', + { name = 'mw.wikibase.getBestStatements (propertyId must be string)', func = mw.wikibase.getBestStatements, type='ToString', args = { 'Q2', 12 }, expect = "bad argument #2 to 'getBestStatements' (string expected, got number)" }, @@ -132,7 +138,7 @@ args = { 0, 'P12' }, expect = "bad argument #1 to 'getAllStatements' (string expected, got number)" }, - { name = 'mw.wikibase.getAllStatements (entityId must be string)', func = mw.wikibase.getAllStatements, type='ToString', + { name = 'mw.wikibase.getAllStatements (propertyId must be string)', func = mw.wikibase.getAllStatements, type='ToString', args = { 'Q2', 12 }, expect = "bad argument #2 to 'getAllStatements' (string expected, got number)" }, @@ -311,6 +317,33 @@ args = { 'foo' }, expect = { nil } }, + { name = 'mw.wikibase.getEntityUrl (by entity id)', func = testGetEntityUrl, + args = { 'Q42', 'Q42' }, + expect = { true } + }, + { name = 'mw.wikibase.getEntityUrl (connected page)', func = testGetEntityUrl, + args = { 'Q32487', nil }, + expect = { true } + }, + { name = 'mw.wikibase.getEntityUrl (must be string or nil)', func = mw.wikibase.getEntityUrl, + args = { -1 }, + expect = "bad argument #1 to 'getEntityUrl' (string or nil expected, got number)" + }, + { name = 'mw.wikibase.getEntityUrl (invalid entity id)', func = mw.wikibase.getEntityUrl, + args = { "BlahBlah" }, + expect = { nil } + }, + { name = 'mw.wikibase.getPropertyOrder', func = mw.wikibase.getPropertyOrder, + expect = { { ['P1'] = 0, ['P22'] = 1, ['P11'] = 2 } } + }, + { name = 'mw.wikibase.orderProperties', func = mw.wikibase.orderProperties, + args = { { 'P22', 'P1', 'P44', 'Llama' } }, + expect = { { 'P1', 'P22', 'P44', 'Llama' } } + }, + { name = 'mw.wikibase.orderProperties (must be table)', func = mw.wikibase.orderProperties, + args = { function() end }, + expect = "bad argument #1 to 'orderProperties' (table expected, got function)" + }, } return testframework.getTestProvider( tests ) diff --git a/extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibraryTest.php b/extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibraryTest.php index 423268d..16c70a2 100644 --- a/extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibraryTest.php +++ b/extensions/Wikibase/client/tests/phpunit/includes/DataAccess/Scribunto/Scribunto_LuaWikibaseLibraryTest.php @@ -20,6 +20,7 @@ * @group WikibaseIntegration * @group WikibaseClient * @group Wikibase + * @group Database * * @license GPL-2.0+ * @author Katie Filbert < aude.w...@gmail.com > @@ -55,6 +56,11 @@ $settings = WikibaseClient::getDefaultInstance()->getSettings(); $this->oldAllowDataAccessInUserLanguage = $settings->getSetting( 'allowDataAccessInUserLanguage' ); $this->setAllowDataAccessInUserLanguage( false ); + + $this->insertPage( + 'MediaWiki:Wikibase-SortedProperties', + "* P1\n* P22\n* P11" + ); } protected function tearDown() { diff --git a/extensions/Wikibase/lib/includes/Changes/EntityChange.php b/extensions/Wikibase/lib/includes/Changes/EntityChange.php index 7a4e818..9c62ac9 100644 --- a/extensions/Wikibase/lib/includes/Changes/EntityChange.php +++ b/extensions/Wikibase/lib/includes/Changes/EntityChange.php @@ -355,7 +355,7 @@ $info = parent::unserializeInfo( $serialization ); - if ( isset( $info['diff'] ) && is_array( $info['diff'] ) ) { + if ( isset( $info['diff'] ) && is_array( $info['diff'] ) && $info['diff'] ) { if ( $factory === null ) { $factory = $this->newDiffOpFactory(); } diff --git a/extensions/Wikibase/lib/includes/Store/CacheRetrievingEntityRevisionLookup.php b/extensions/Wikibase/lib/includes/Store/CacheRetrievingEntityRevisionLookup.php new file mode 100644 index 0000000..2913e1d --- /dev/null +++ b/extensions/Wikibase/lib/includes/Store/CacheRetrievingEntityRevisionLookup.php @@ -0,0 +1,157 @@ +<?php + +namespace Wikibase\Lib\Store; + +use Wikibase\DataModel\Entity\EntityId; +use Wikimedia\Assert\Assert; + +/** + * EntityRevisionLookup implementation that checks an EntityRevisionCache for cached revisions (but + * doesn't cache on its own). Falls back to a given EntityRevisionLookup. + * + * @license GPL-2.0+ + * @author Daniel Kinzler + * @author Marius Hoch + */ +class CacheRetrievingEntityRevisionLookup implements EntityRevisionLookup { + + /** + * @var EntityRevisionCache + */ + private $cache; + + /** + * @var EntityRevisionLookup + */ + private $lookup; + + /** + * @var bool + */ + private $shouldVerifyRevision = false; + + /** + * @param EntityRevisionCache $cache + * @param EntityRevisionLookup $lookup + */ + public function __construct( EntityRevisionCache $cache, EntityRevisionLookup $lookup ) { + $this->cache = $cache; + $this->lookup = $lookup; + } + + /** + * Determine whether the revision of the cached entity should be verified against the + * current revision in the underlying lookup. + * + * @param bool $shouldVerifyRevision + */ + public function setVerifyRevision( $shouldVerifyRevision ) { + $this->shouldVerifyRevision = $shouldVerifyRevision; + } + + /** + * Get an EntityRevision from cache or (otherwise) from the underlying EntityRevisionLookup. + * + * @see EntityRevisionLookup::getEntityRevision + * + * @note: If this lookup is configured to verify revisions, getLatestRevisionId() + * will be called on the underlying lookup to check whether the cached revision is + * still the latest. Otherwise, any cached revision will be used if $revisionId=0. + * + * @param EntityId $entityId + * @param int $revisionId The desired revision id, or 0 for the latest revision. + * @param string $mode One of the EntityRevisionLookup::LATEST_* constants. + * + * @throws StorageException + * @return EntityRevision|null + */ + public function getEntityRevision( + EntityId $entityId, + $revisionId = 0, + $mode = self::LATEST_FROM_REPLICA + ) { + Assert::parameterType( 'integer', $revisionId, '$revisionId' ); + Assert::parameterType( 'string', $mode, '$mode' ); + + $entityRevision = $this->getEntityRevisionFromCache( $entityId, $revisionId, $mode ); + + if ( $entityRevision === null ) { + $entityRevision = $this->lookup->getEntityRevision( $entityId, $revisionId, $mode ); + } + + return $entityRevision; + } + + /** + * Try to get an EntityRevision from cache. + * + * @note: If this lookup is configured to verify revisions, getLatestRevisionId() + * will be called on the underlying lookup to check whether the cached revision is + * still the latest. Otherwise, any cached revision will be used if $revisionId=0. + * + * @param EntityId $entityId + * @param int $revisionId The desired revision id, or 0 for the latest revision. + * @param string $mode LATEST_FROM_REPLICA, LATEST_FROM_REPLICA_WITH_FALLBACK or + * LATEST_FROM_MASTER. + * + * @throws StorageException + * @return EntityRevision|null Null if the EntityRevision in question is not cached. + */ + public function getEntityRevisionFromCache( + EntityId $entityId, + $revisionId = 0, + $mode = self::LATEST_FROM_REPLICA + ) { + Assert::parameterType( 'integer', $revisionId, '$revisionId' ); + Assert::parameterType( 'string', $mode, '$mode' ); + + $entityRevision = $this->cache->get( $entityId ); + + if ( $entityRevision !== null ) { + if ( $revisionId === 0 && $this->shouldVerifyRevision ) { + $latestRevision = $this->lookup->getLatestRevisionId( $entityId, $mode ); + + if ( $latestRevision === false ) { + // entity no longer exists! + return null; + } else { + $revisionId = $latestRevision; + } + } + + if ( $revisionId > 0 && $entityRevision && $entityRevision->getRevisionId() !== $revisionId ) { + $entityRevision = null; + } + } + + return $entityRevision; + } + + /** + * @see EntityRevisionLookup::getLatestRevisionId + * + * @note: If this lookup is configured to verify revisions, this just delegates + * to the underlying lookup. Otherwise, it may return the ID of a cached + * revision. + * + * @param EntityId $entityId + * @param string $mode + * + * @return int|false + */ + public function getLatestRevisionId( EntityId $entityId, $mode = self::LATEST_FROM_REPLICA ) { + // If we do not need to verify the revision, and the revision isn't + // needed for an update, we can get the revision from the cached object. + // XXX: whether this is actually quicker depends on the cache. + if ( ! ( $this->shouldVerifyRevision || $mode === self::LATEST_FROM_MASTER ) ) { + $entityRevision = $this->cache->get( $entityId ); + + if ( $entityRevision ) { + return $entityRevision->getRevisionId(); + } + } + + return $this->lookup->getLatestRevisionId( $entityId, $mode ); + } + +} diff --git a/extensions/Wikibase/lib/includes/Store/CachingEntityRevisionLookup.php b/extensions/Wikibase/lib/includes/Store/CachingEntityRevisionLookup.php index dc24a9c..3c50bbc 100644 --- a/extensions/Wikibase/lib/includes/Store/CachingEntityRevisionLookup.php +++ b/extensions/Wikibase/lib/includes/Store/CachingEntityRevisionLookup.php @@ -2,7 +2,6 @@ namespace Wikibase\Lib\Store; -use BagOStuff; use Wikibase\DataModel\Entity\EntityId; use Wikibase\DataModel\Entity\EntityRedirect; use Wikimedia\Assert\Assert; @@ -16,28 +15,19 @@ class CachingEntityRevisionLookup implements EntityRevisionLookup, EntityStoreWatcher { /** + * @var EntityRevisionCache + */ + private $entityRevisionCache; + + /** * @var EntityRevisionLookup */ private $lookup; /** - * The cache to use for caching entities. - * - * @var BagOStuff + * @var CacheRetrievingEntityRevisionLookup */ - private $cache; - - /** - * @var int - */ - private $cacheTimeout; - - /** - * The key prefix to use when caching entities in memory. - * - * @var string - */ - private $cacheKeyPrefix; + private $cacheRetrievingLookup; /** * @var bool @@ -45,22 +35,20 @@ private $shouldVerifyRevision = false; /** - * @param EntityRevisionLookup $entityRevisionLookup The lookup to use - * @param BagOStuff $cache The cache to use - * @param int $cacheDuration Cache duration in seconds. Defaults to 3600 (1 hour). - * @param string $cacheKeyPrefix The key prefix to use for constructing cache keys. - * Defaults to "wbentity". There should be no reason to change this. + * @param EntityRevisionCache $entityRevisionCache + * @param EntityRevisionLookup $entityRevisionLookup */ public function __construct( - EntityRevisionLookup $entityRevisionLookup, - BagOStuff $cache, - $cacheDuration = 3600, - $cacheKeyPrefix = 'wbentity' + EntityRevisionCache $entityRevisionCache, + EntityRevisionLookup $entityRevisionLookup ) { + $this->entityRevisionCache = $entityRevisionCache; $this->lookup = $entityRevisionLookup; - $this->cache = $cache; - $this->cacheTimeout = $cacheDuration; - $this->cacheKeyPrefix = $cacheKeyPrefix; + + $this->cacheRetrievingLookup = new CacheRetrievingEntityRevisionLookup( + $entityRevisionCache, + $entityRevisionLookup + ); } /** @@ -71,23 +59,11 @@ */ public function setVerifyRevision( $shouldVerifyRevision ) { $this->shouldVerifyRevision = $shouldVerifyRevision; + $this->cacheRetrievingLookup->setVerifyRevision( $shouldVerifyRevision ); } /** - * Returns a cache key suitable for the given entity - * - * @param EntityId $entityId - * - * @return string - */ - private function getCacheKey( EntityId $entityId ) { - $cacheKey = $this->cacheKeyPrefix . ':' . $entityId->getSerialization(); - - return $cacheKey; - } - - /** - * @see EntityLookup::getEntity + * @see EntityRevisionLookup::getEntityRevision * * @note: If this lookup is configured to verify revisions, getLatestRevisionId() * will be called on the underlying lookup to check whether the cached revision is @@ -109,29 +85,9 @@ Assert::parameterType( 'integer', $revisionId, '$revisionId' ); Assert::parameterType( 'string', $mode, '$mode' ); - $key = $this->getCacheKey( $entityId ); + $entityRevision = $this->cacheRetrievingLookup->getEntityRevisionFromCache( $entityId, $revisionId, $mode ); - /** @var EntityRevision $entityRevision */ - $entityRevision = $this->cache->get( $key ); - - if ( $entityRevision !== false ) { - if ( $revisionId === 0 && $this->shouldVerifyRevision ) { - $latestRevision = $this->lookup->getLatestRevisionId( $entityId, $mode ); - - if ( $latestRevision === false ) { - // entity no longer exists! - $entityRevision = null; - } else { - $revisionId = $latestRevision; - } - } - - if ( $revisionId > 0 && $entityRevision && $entityRevision->getRevisionId() !== $revisionId ) { - $entityRevision = false; - } - } - - if ( $entityRevision === false ) { + if ( $entityRevision === null ) { $entityRevision = $this->fetchEntityRevision( $entityId, $revisionId, $mode ); } @@ -149,14 +105,13 @@ * @return EntityRevision|null */ private function fetchEntityRevision( EntityId $entityId, $revisionId, $mode ) { - $key = $this->getCacheKey( $entityId ); $entityRevision = $this->lookup->getEntityRevision( $entityId, $revisionId, $mode ); if ( $revisionId === 0 ) { if ( $entityRevision === null ) { - $this->cache->delete( $key ); + $this->entityRevisionCache->delete( $entityId ); } else { - $this->cache->set( $key, $entityRevision, $this->cacheTimeout ); + $this->entityRevisionCache->set( $entityRevision ); } } @@ -166,30 +121,13 @@ /** * @see EntityRevisionLookup::getLatestRevisionId * - * @note: If this lookup is configured to verify revisions, this just delegates - * to the underlying lookup. Otherwise, it may return the ID of a cached - * revision. - * * @param EntityId $entityId * @param string $mode * * @return int|false */ public function getLatestRevisionId( EntityId $entityId, $mode = self::LATEST_FROM_REPLICA ) { - // If we do not need to verify the revision, and the revision isn't - // needed for an update, we can get the revision from the cached object. - // XXX: whether this is actually quicker depends on the cache. - if ( ! ( $this->shouldVerifyRevision || $mode === self::LATEST_FROM_MASTER ) ) { - $key = $this->getCacheKey( $entityId ); - /** @var EntityRevision $entityRevision */ - $entityRevision = $this->cache->get( $key ); - - if ( $entityRevision ) { - return $entityRevision->getRevisionId(); - } - } - - return $this->lookup->getLatestRevisionId( $entityId, $mode ); + return $this->cacheRetrievingLookup->getLatestRevisionId( $entityId, $mode ); } /** @@ -198,8 +136,7 @@ * @param EntityRevision $entityRevision */ public function entityUpdated( EntityRevision $entityRevision ) { - $key = $this->getCacheKey( $entityRevision->getEntity()->getId() ); - $this->cache->set( $key, $entityRevision, $this->cacheTimeout ); + $this->entityRevisionCache->set( $entityRevision ); } /** @@ -210,8 +147,7 @@ */ public function redirectUpdated( EntityRedirect $entityRedirect, $revisionId ) { //TODO: cache redirects - $key = $this->getCacheKey( $entityRedirect->getEntityId() ); - $this->cache->delete( $key ); + $this->entityRevisionCache->delete( $entityRedirect->getEntityId() ); } /** @@ -220,8 +156,7 @@ * @param EntityId $entityId */ public function entityDeleted( EntityId $entityId ) { - $key = $this->getCacheKey( $entityId ); - $this->cache->delete( $key ); + $this->entityRevisionCache->delete( $entityId ); // XXX: if $this->lookup supports purging, purge? } diff --git a/extensions/Wikibase/lib/includes/Store/EntityRevisionCache.php b/extensions/Wikibase/lib/includes/Store/EntityRevisionCache.php new file mode 100644 index 0000000..7242dcc --- /dev/null +++ b/extensions/Wikibase/lib/includes/Store/EntityRevisionCache.php @@ -0,0 +1,103 @@ +<?php + +namespace Wikibase\Lib\Store; + +use BagOStuff; +use Wikibase\DataModel\Entity\EntityId; + +/** + * Service for caching the latest EntityRevision of an Entity. + * + * @license GPL-2.0+ + * @author Marius Hoch + */ +class EntityRevisionCache { + + /** + * The cache to use for caching entities. + * + * @var BagOStuff + */ + private $cache; + + /** + * @var int + */ + private $cacheTimeout; + + /** + * The key prefix to use when caching entities in memory. + * + * @var string + */ + private $cacheKeyPrefix; + + /** + * @param BagOStuff $cache The cache to use + * @param int $cacheDuration Cache duration in seconds. Defaults to 3600 (1 hour). + * @param string $cacheKeyPrefix The key prefix to use for constructing cache keys. + * Defaults to "wbentity". There should be no reason to change this. + */ + public function __construct( + BagOStuff $cache, + $cacheDuration = 3600, + $cacheKeyPrefix = 'wbentity' + ) { + $this->cache = $cache; + $this->cacheTimeout = $cacheDuration; + $this->cacheKeyPrefix = $cacheKeyPrefix; + } + + /** + * Returns a cache key suitable for the given entity + * + * @param EntityId $entityId + * + * @return string + */ + private function getCacheKey( EntityId $entityId ) { + $cacheKey = $this->cacheKeyPrefix . ':' . $entityId->getSerialization(); + + return $cacheKey; + } + + /** + * Get the latest EntityRevision from cache. + * Note: This might return stale data! + * + * @param EntityId $entityId + * + * @return EntityRevision|null Null if the EntityRevision is not cached. + */ + public function get( EntityId $entityId ) { + $key = $this->getCacheKey( $entityId ); + $entityRevision = $this->cache->get( $key ); + + if ( $entityRevision instanceof EntityRevision ) { + return $entityRevision; + } + + return null; + } + + /** + * Place the latest EntityRevision in the cache. + * + * @param EntityRevision $entityRevision + */ + public function set( EntityRevision $entityRevision ) { + $key = $this->getCacheKey( $entityRevision->getEntity()->getId() ); + $this->cache->set( $key, $entityRevision, $this->cacheTimeout ); + } + + /** + * Removes an Entity's EntityRevision from the cache. + * + * @param EntityId $entityId + */ + public function delete( EntityId $entityId ) { + $key = $this->getCacheKey( $entityId ); + $this->cache->delete( $key ); + } + +} diff --git a/extensions/Wikibase/lib/tests/phpunit/Store/CacheRetrievingEntityRevisionLookupTest.php b/extensions/Wikibase/lib/tests/phpunit/Store/CacheRetrievingEntityRevisionLookupTest.php new file mode 100644 index 0000000..90fb6ad --- /dev/null +++ b/extensions/Wikibase/lib/tests/phpunit/Store/CacheRetrievingEntityRevisionLookupTest.php @@ -0,0 +1,152 @@ +<?php + +namespace Wikibase\Lib\Tests\Store; + +use HashBagOStuff; +use Wikibase\DataModel\Entity\EntityRedirect; +use Wikibase\DataModel\Entity\Item; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\DataModel\Services\Lookup\EntityLookup; +use Wikibase\Lib\Store\EntityRevision; +use Wikibase\Lib\Store\CacheRetrievingEntityRevisionLookup; +use Wikibase\Lib\Store\EntityRevisionCache; +use Wikibase\Lib\Store\EntityRevisionLookup; +use Wikibase\Lib\Tests\EntityRevisionLookupTest; +use Wikibase\Lib\Tests\MockRepository; + +/** + * @covers Wikibase\Lib\Store\CacheRetrievingEntityRevisionLookup + * + * @group WikibaseEntityLookup + * @group Wikibase + * + * @license GPL-2.0+ + * @author Daniel Kinzler + * @author Marius Hoch + */ +class CacheRetrievingEntityRevisionLookupTest extends EntityRevisionLookupTest { + + /** + * @see EntityRevisionLookupTest::newEntityRevisionLookup + * + * @param EntityRevision[] $entityRevisions + * @param EntityRedirect[] $entityRedirects + * + * @return EntityLookup + */ + protected function newEntityRevisionLookup( array $entityRevisions, array $entityRedirects ) { + $mock = new MockRepository(); + + foreach ( $entityRevisions as $entityRev ) { + $mock->putEntity( $entityRev->getEntity(), $entityRev->getRevisionId() ); + } + + foreach ( $entityRedirects as $entityRedir ) { + $mock->putRedirect( $entityRedir ); + } + + return new CacheRetrievingEntityRevisionLookup( new EntityRevisionCache( new HashBagOStuff() ), $mock ); + } + + 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 CacheRetrievingEntityRevisionLookup( new EntityRevisionCache( new HashBagOStuff() ), $mock ); + $lookup->setVerifyRevision( false ); + + $this->assertSame( + $item, + $lookup->getEntityRevision( $id, 1234, 'load-mode' ) + ); + } + + public function testRetrievingDoesNotWriteToTheCache() { + $mock = new MockRepository(); + + $id = new ItemId( 'Q123' ); + $item = new Item( $id ); + + $mock->putEntity( $item, 11 ); + + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + $lookup = new CacheRetrievingEntityRevisionLookup( $entityRevisionCache, $mock ); + + $this->assertEquals( $item, $lookup->getEntityRevision( $id )->getEntity(), 'Retrieve' ); + + $this->assertNull( $entityRevisionCache->get( $id ), 'Should still not be cached' ); + } + + public function testWithRevisionVerification() { + $mock = new MockRepository(); + + $id = new ItemId( 'Q123' ); + $item = new Item( $id ); + + $mock->putEntity( $item, 11 ); + + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + $lookup = new CacheRetrievingEntityRevisionLookup( $entityRevisionCache, $mock ); + $lookup->setVerifyRevision( true ); + + // Cache the initial version + $entityRevisionCache->set( new EntityRevision( $item, 11 ) ); + + // create new revision + $mock->putEntity( $item, 12 ); + + // make sure we get the new revision automatically + $revId = $lookup->getLatestRevisionId( $id ); + $this->assertEquals( 12, $revId, 'new revision should be detected if verification is enabled' ); + + $rev = $lookup->getEntityRevision( $id ); + $this->assertEquals( 12, $rev->getRevisionId(), 'new revision should be detected if verification is enabled' ); + + $mock->removeEntity( $id ); + + // try to fetch it again + $revId = $lookup->getLatestRevisionId( $id ); + $this->assertFalse( $revId, 'deletion should be detected if verification is enabled' ); + + $rev = $lookup->getEntityRevision( $id ); + $this->assertNull( $rev, 'deletion should be detected if verification is enabled' ); + } + + public function testWithoutRevisionVerification() { + $mock = new MockRepository(); + + $id = new ItemId( 'Q123' ); + $item = new Item( $id ); + + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + $lookup = new CacheRetrievingEntityRevisionLookup( $entityRevisionCache, $mock ); + $lookup->setVerifyRevision( false ); + + // Create and cache new revision + $mock->putEntity( $item, 12 ); + $entityRevisionCache->set( new EntityRevision( $item, 11 ) ); + + // check that we are still getting the old revision + $revId = $lookup->getLatestRevisionId( $id ); + $this->assertEquals( 11, $revId, 'new revision should be ignored if verification is disabled' ); + + $rev = $lookup->getEntityRevision( $id ); + $this->assertEquals( 11, $rev->getRevisionId(), 'new revision should be ignored if verification is disabled' ); + + $mock->removeEntity( $id ); + + // try to fetch it again - should still be cached + $revId = $lookup->getLatestRevisionId( $id ); + $this->assertEquals( 11, $revId, 'deletion should be ignored if verification is disabled' ); + + $rev = $lookup->getEntityRevision( $id ); + $this->assertEquals( 11, $rev->getRevisionId(), 'deletion should be ignored if verification is disabled' ); + } + +} diff --git a/extensions/Wikibase/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php b/extensions/Wikibase/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php index 93dd33f..7bbc348 100644 --- a/extensions/Wikibase/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php +++ b/extensions/Wikibase/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php @@ -9,6 +9,7 @@ use Wikibase\DataModel\Services\Lookup\EntityLookup; use Wikibase\Lib\Store\EntityRevision; use Wikibase\Lib\Store\CachingEntityRevisionLookup; +use Wikibase\Lib\Store\EntityRevisionCache; use Wikibase\Lib\Store\EntityRevisionLookup; use Wikibase\Lib\Store\RevisionedUnresolvedRedirectException; use Wikibase\Lib\Tests\EntityRevisionLookupTest; @@ -26,7 +27,7 @@ class CachingEntityRevisionLookupTest extends EntityRevisionLookupTest { /** - * @see EntityLookupTest::newEntityLoader(newEntityLookup + * @see EntityRevisionLookupTest::newEntityRevisionLookup * * @param EntityRevision[] $entityRevisions * @param EntityRedirect[] $entityRedirects @@ -44,7 +45,9 @@ $mock->putRedirect( $entityRedir ); } - return new CachingEntityRevisionLookup( $mock, new HashBagOStuff() ); + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + + return new CachingEntityRevisionLookup( $entityRevisionCache, $mock ); } public function testGetEntityRevision_byRevisionIdWithMode() { @@ -57,7 +60,9 @@ ->with( $id, 1234, 'load-mode' ) ->will( $this->returnValue( $item ) ); - $lookup = new CachingEntityRevisionLookup( $mock, new HashBagOStuff() ); + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + + $lookup = new CachingEntityRevisionLookup( $entityRevisionCache, $mock ); $lookup->setVerifyRevision( false ); $this->assertSame( @@ -74,7 +79,9 @@ $mock->putEntity( $item, 11 ); - $lookup = new CachingEntityRevisionLookup( $mock, new HashBagOStuff() ); + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + $lookup = new CachingEntityRevisionLookup( $entityRevisionCache, $mock ); + $lookup->setVerifyRevision( true ); // fetch first revision, so it gets cached @@ -109,7 +116,9 @@ $mock->putEntity( $item, 11 ); - $lookup = new CachingEntityRevisionLookup( $mock, new HashBagOStuff() ); + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + $lookup = new CachingEntityRevisionLookup( $entityRevisionCache, $mock ); + $lookup->setVerifyRevision( false ); // fetch first revision, so it gets cached @@ -144,7 +153,9 @@ $mock->putEntity( $item, 11 ); - $lookup = new CachingEntityRevisionLookup( $mock, new HashBagOStuff() ); + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + $lookup = new CachingEntityRevisionLookup( $entityRevisionCache, $mock ); + $lookup->setVerifyRevision( false ); // fetch first revision, so it gets cached @@ -172,7 +183,9 @@ $mock->putEntity( $item, 11 ); - $lookup = new CachingEntityRevisionLookup( $mock, new HashBagOStuff() ); + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + $lookup = new CachingEntityRevisionLookup( $entityRevisionCache, $mock ); + $lookup->setVerifyRevision( false ); // fetch first revision, so it gets cached @@ -203,7 +216,9 @@ $mock->putEntity( $item, 11 ); - $lookup = new CachingEntityRevisionLookup( $mock, new HashBagOStuff() ); + $entityRevisionCache = new EntityRevisionCache( new HashBagOStuff() ); + $lookup = new CachingEntityRevisionLookup( $entityRevisionCache, $mock ); + $lookup->setVerifyRevision( false ); // fetch first revision, so it gets cached diff --git a/extensions/Wikibase/lib/tests/phpunit/Store/EntityRevisionCacheTest.php b/extensions/Wikibase/lib/tests/phpunit/Store/EntityRevisionCacheTest.php new file mode 100644 index 0000000..304e7b2 --- /dev/null +++ b/extensions/Wikibase/lib/tests/phpunit/Store/EntityRevisionCacheTest.php @@ -0,0 +1,73 @@ +<?php + +namespace Wikibase\Lib\Tests\Store; + +use HashBagOStuff; +use PHPUnit_Framework_TestCase; +use Wikibase\DataModel\Entity\Item; +use Wikibase\DataModel\Entity\ItemId; +use Wikibase\Lib\Store\EntityRevision; +use Wikibase\Lib\Store\EntityRevisionCache; + +/** + * @covers Wikibase\Lib\Store\EntityRevisionCache + * + * @group WikibaseEntityLookup + * @group Wikibase + * + * @license GPL-2.0+ + * @author Marius Hoch + */ +class EntityRevisionCacheTest extends PHPUnit_Framework_TestCase { + + public function testGet() { + $q5 = new ItemId( 'Q5' ); + $q2 = new ItemId( 'Q2' ); + + $entityRevision = new EntityRevision( new Item( $q5 ) ); + + $bagOStuff = new HashBagOStuff(); + $bagOStuff->set( 'blah:Q5', $entityRevision ); + + $cache = new EntityRevisionCache( $bagOStuff, 3600, 'blah' ); + + $this->assertNull( $cache->get( $q2 ), 'Cache miss' ); + $this->assertSame( $entityRevision, $cache->get( $q5 ), 'Cache hit' ); + } + + public function testSet() { + $q5 = new ItemId( 'Q5' ); + + $entityRevision = new EntityRevision( new Item( $q5 ) ); + + $bagOStuff = new HashBagOStuff(); + + $cache = new EntityRevisionCache( $bagOStuff, 3600, 'cache-key' ); + + $this->assertNull( $cache->get( $q5 ), 'Cache miss' ); + + $cache->set( $entityRevision ); + + $this->assertSame( $entityRevision, $bagOStuff->get( 'cache-key:Q5' ) ); + $this->assertSame( $entityRevision, $cache->get( $q5 ) ); + } + + public function testDelete() { + $q5 = new ItemId( 'Q5' ); + + $entityRevision = new EntityRevision( new Item( $q5 ) ); + + $bagOStuff = new HashBagOStuff(); + + $cache = new EntityRevisionCache( $bagOStuff, 3600, 'cache-key' ); + $cache->set( $entityRevision ); + + $this->assertSame( $entityRevision, $cache->get( $q5 ), 'Cache hit' ); + + $cache->delete( $q5 ); + + $this->assertFalse( $bagOStuff->get( 'cache-key:Q5' ), 'No longer cached' ); + $this->assertNull( $cache->get( $q5 ), 'No longer cached' ); + } + +} diff --git a/extensions/Wikibase/repo/i18n/tr.json b/extensions/Wikibase/repo/i18n/tr.json index 0abdfe5..2851f1d 100644 --- a/extensions/Wikibase/repo/i18n/tr.json +++ b/extensions/Wikibase/repo/i18n/tr.json @@ -30,7 +30,7 @@ "wikibase-entity-query": "sorgu", "wikibase-edit": "düzenle", "wikibase-save": "kaydet", - "wikibase-cancel": "iptal", + "wikibase-cancel": "vazgeç", "wikibase-add": "ekle", "wikibase-addqualifier": "niteleyici еkle", "wikibase-addreference": "kaynak ekle", @@ -38,55 +38,76 @@ "wikibase-remove-inprogress": "Kaldırılıyor...", "wikibase-statementlistview-add": "değer ekle", "wikibase-statementlistview-add-tooltip": "Yeni bir değer ekle", - "wikibase-statementgrouplistview-add": "görüş ekle", + "wikibase-statementgrouplistview-add": "ifade ekle", "wikibase-statementgrouplistview-add-tooltip": "Yeni bir ifade ekle", "wikibase-entitytermsview-entitytermsforlanguagelistview-toggler": "Daha fazla dilde", "wikibase-entitytermsview-entitytermsforlanguagelistview-configure-link-label": "Yapılandır", "wikibase-setting-entitytermsview-showEntitytermslistview": "Sayfa yüklenirken tüm dillerimdeki açıklamaları ve etiketlerin takma adlarını göster", - "wikibase-entitytermsforlanguagelistview-aliases": "Şu şekilde de bilinir:", + "wikibase-setting-entitytermsview-showEntitytermslistview-help": "Kullanıcı arayüzü diline ek olarak kullanılan diller [[mw:Extension:Babel|Babel uzantısı]] sözdizimi kullanılarak kullanıcı sayfasında gösterilebilir.", + "wikibase-entitytermsforlanguagelistview-aliases": "Olarak da bilinir", "wikibase-entitytermsforlanguagelistview-description": "Tanım", "wikibase-entitytermsforlanguagelistview-label": "Etiket", "wikibase-entitytermsforlanguagelistview-language": "Dil", - "wikibase-entitytermsforlanguagelistview-more": "Girilen tüm diller", + "wikibase-entitytermsforlanguagelistview-more": "Eklenmiş tüm diller", "wikibase-entitytermsforlanguagelistview-less": "Daha az dil", - "wikibase-label-empty": "Hiçbir etiket tanımlanmadı", - "wikibase-label-edit-placeholder": "etiket girin", + "wikibase-label-empty": "Hiçbir etiket tanımlanmamış", + "wikibase-label-edit-placeholder": "bir etiket girin", "wikibase-label-edit-placeholder-language-aware": "$1 etiketini girin", - "wikibase-description-empty": "Açıklama bulunamadı", - "wikibase-description-edit-placeholder": "bir açıklama girin", - "wikibase-description-edit-placeholder-language-aware": "$1 açıklamasını girin", - "wikibase-aliases-edit-placeholder": "bir takma ad girin", - "wikibase-aliases-edit-placeholder-language-aware": "$1 takma adını girin", + "wikibase-description-empty": "Tanım bulunamadı", + "wikibase-description-edit-placeholder": "bir tanım girin", + "wikibase-description-edit-placeholder-language-aware": "$1 tanımını girin", + "wikibase-aliases-edit-placeholder": "diğer adını girin", + "wikibase-aliases-edit-placeholder-language-aware": "$1 diğer adını girin", + "wikibase-aliases-edit-label": "Ayrılan diğer adlar:", + "wikibase-content-language-edit-label": "Dil:", + "wikibase-content-language-edit-not-recognized-language": "Belirtilen dil kodu tanımlanamadı.", "wikibase-diffview-reference": "kaynak", - "wikibase-diffview-rank": "rütbe", - "wikibase-diffview-rank-preferred": "Öncelikli düzey", - "wikibase-diffview-rank-normal": "Normal düzey", - "wikibase-diffview-rank-deprecated": "Kullanılmayan düzey", + "wikibase-diffview-rank": "sıralama", + "wikibase-diffview-rank-preferred": "Öncelikli sıralama", + "wikibase-diffview-rank-normal": "Normal sıralama", + "wikibase-diffview-rank-deprecated": "Kullanılmayan sıralama", "wikibase-diffview-qualifier": "niteleyici", "wikibase-diffview-label": "etiket", - "wikibase-diffview-alias": "eşdeşler", - "wikibase-diffview-description": "açıklama", + "wikibase-diffview-alias": "diğer adı", + "wikibase-diffview-description": "tanım", "wikibase-diffview-link": "bağlantılar", + "wikibase-diffview-link-name": "başlık", + "wikibase-diffview-link-badges": "rozetler", "wikibase-sitelink-site-edit-placeholder": "viki", "wikibase-sitelink-page-edit-placeholder": "sayfa", - "wikibase-alias-edit-placeholder": "başka bir ad girin", + "wikibase-alias-edit-placeholder": "diğer adını girin", "wikibase-label-input-help-message": "Bu varlığın etiketini $1 dilinde girin.", - "wikibase-entitytermsview-input-help-message": "Bu varlığa dilin başına eklenecek kısa bir açıklama ve etiket girin.", + "wikibase-entitytermsview-input-help-message": "Bu varlığa dilin başına eklenecek kısa bir tanım ve etiket girin.", "wikibase-statementsection-statements": "İfadeler", - "wikibase-sitelinks": "Site bağlantıları", - "wikibase-sitelinkgroupview-input-help-message": "Bir siteyi veya o sitedeki bir sayfayı belirterek bağlantı ekleyin, var olan site bağlantılarını düzenleyin veya kaldırın.", - "wikibase-sitelinks-counter": "$1 girdi", + "wikibase-sitelinks": "Sitebağlantıları", + "wikibase-sitelinkgroupview-input-help-message": "Bir site ve bu sitenin sayfasını belirterek site bağlantısı ekleyin, mevcut site bağlantılarını düzenleyin ya da kaldırın.", + "wikibase-sitelinks-counter": "$1 {{PLURAL:$1|girdi|girdi}}", "wikibase-sitelinks-empty": "Hiçbir sayfa bu ögeye bağlı değil.", "wikibase-sitelinks-special": "Diğer siteler", - "wikibase-badgeselector-badge-placeholder-title": "Bir kimlik kartı atamak için tıklayın.", + "wikibase-badgeselector-badge-placeholder-title": "Bir rozet atamak için tıklayın.", "wikibase-remove": "kaldır", "wikibase-move-up": "yukarı taşı", "wikibase-move-down": "aşağı taşı", - "wikibase-undo-title": "\"$1\" üzerindeki değişiklik geri alınıyor", - "wikibase-restore-title": "\"$1\" eski revizyonu geri yükleniyor", + "wikibase-undo-title": "\"$1\" değişikliği geri alınıyor", + "wikibase-restore-title": "\"$1\" eski sürüme yükleniyor", "wikibase-partial-undo": "Düzenleme kısmen geri alınabilir.", + "wikibase-omitted-undo-ops": "$1 {{PLURAL:$1|değişikliği|değişikliği}} {{PLURAL:$1|değiştirildiğinden|değiştirildiğinden}} dolayı geri alınamıyor.", + "wikibase-empty-undo": "Burada geri alınabilecek bir şey bulunmuyor.", + "wikibase-undo-revision-error": "Geri alınamadı", + "wikibase-undo-samerev": "Bu düzenlemeyi geriye almak için iki farklı sürüm belirtilmelidir.", + "wikibase-undo-badpage": "Bozuk sürüm: $2 sürümü [[$1]] ait değil.", + "wikibase-undo-firstrev": "Sayfaların oluşturulması geri alınamaz", + "wikibase-undo-nocontent": "$1 sayfasındaki $2 sürüm içeriği yüklenemiyor", + "wikibase-summary-generated": "Özet (otomatik olarak oluşturulan özete eklenir):", + "wikibase-disambiguation-title": "\"$1\" için anlam ayrımı", + "wb-special-newitem-new-item-notification": "$1 yeni öge oluşturuldu ve sayfaya yönlendirildi. $2 geri dön.", + "wikibase-aliases-input-help-message": "Bu varlığın bulunmasını kolaylaştırmak için alternatif isimler ekleyebilirsiniz.", "wikibase-propertypage-datatype": "Veri türü", - "wikibase-statementview-rank-normal": "Normal oran", + "wikibase-propertypage-bad-datatype": "Bilinmeyen veri türü: $1", + "wikibase-claimview-snak-tooltip": "\"$1\" isimli özelliğin yerini tutabilecek bir değer ekleyin. Eğer özelliğin değeri belirlenmemiş veya gerçek değeri bilinmiyorsa, kutucuktaki simgeye tıklayarak alternatif bir değer türü seçebilirsiniz.", + "wikibase-statementview-rank-preferred": "Öncelikli sıralama", + "wikibase-statementview-rank-normal": "Normal sıralama", + "wikibase-statementview-rank-deprecated": "Kullanılmayan sıralama", "wikibase-statementview-references-counter": "$1{{PLURAL:$2|0=|$3+$2$4}} {{PLURAL:$1|kaynak|kaynak}}", "wikibase-snakview-property-input-placeholder": "özellik", "wikibase-snakview-unsupportedsnaktype": "\"$1\" türü Snak. Bu tür Snak ile ilgili işlemler henüz desteklenmiyor.", @@ -102,12 +123,18 @@ "wikibase-entityselector-notfound": "Eşleşme bulunamadı", "wikibase-anonymouseditwarning": "Uyarı: Giriş yapmadınız.\nIP adresiniz bu varlığın düzenleme geçmişine kaydedilecektir.", "wikibase-validator-sitelink-conflict": "$1 bağlantısı halihazırda $2 tarafından kullanılmaktadır. Eğer bu bağlantı oraya ait değilse $2 sayfasından bağlantıyı kaldırabilir veya aynı konu hakkındaysa her iki sayfayı birleştirebilirsiniz.", + "wikibase-validator-no-such-sitelink": "Rozetlerin düzenlenmesi esnasında \"$1\" için bir site bağlantısı bulunamadı.", + "wikibase-validator-page-not-exists": "\"$1\" sayfası mevcut değil.", "wikibase-validator-not-a-language": "\"$1\" bilinen bir dil kodu değil.", + "wikibase-item-reference-edit-placeholder": "Öge ID girin örn. Q10", + "wikibase-item-reference-edit-invalid-format": "Girilen öge ID geçersiz biçime sahip", + "wikibase-item-reference-edit-nonexistent-item": "Bu ID ile öge bulunmuyor", "wikibase-wikibaserepopage-not-itemid": "\"$1\" geçerli bir ID değil.", "wikibase-wikibaserepopage-invalid-langcode": "\"$1\" dil kodu bilinmiyor. Lütfen \"tr\" gibi bilinen bir dil kodu kullanın.", - "wikibase-wikibaserepopage-invalid-id": "\"$1\" ID bilinmeyen bir sisteme ait. Lütfen geçerli bir ID değeri kullanın.", - "wikibase-wikibaserepopage-unresolved-redirect": "$1 bir yönlendirme", + "wikibase-wikibaserepopage-invalid-id": "\"$1\" ID bilinmeyen bir sisteme ait. Lütfen geçerli bir varlık ID kullanın.", + "wikibase-wikibaserepopage-unresolved-redirect": "$1 bir yönlendirmedir", "wikibase-wikibaserepopage-storage-exception": "$1 yüklenirken bir hata oluştu: $2.", + "special-availablebadges": "Kullanılabilir rozetler", "special-itembytitle": "Başlığına göre öge", "wikibase-itembytitle-lookup-site": "Site:", "wikibase-itembytitle-lookup-page": "Sayfa:", @@ -135,30 +162,35 @@ "wikibase-newitem-page": "İlk bağlanan sayfanın adı", "wikibase-newentity-language": "Dil:", "wikibase-newentity-label": "Etiket:", - "wikibase-newentity-description": "Açıklama:", + "wikibase-newentity-description": "Tanım:", "wikibase-newentity-submit": "Oluştur", "special-setlabel": "Bir etiket ayarla", "wikibase-setlabel-label": "Etiket:", "wikibase-setlabel-submit": "Etiket ayarla", - "special-setdescription": "Bir açıklama ayarla", + "special-setdescription": "Bir tanım ayarla", "wikibase-setdescription-label": "Tanım:", - "wikibase-setdescription-submit": "Açıklama ayarla", + "wikibase-setdescription-submit": "Tanım ayarla", "special-setaliases": "Diğer adları ayarla", "wikibase-setaliases-label": "Eşdeşler:", + "wikibase-setaliases-submit": "Diğer adları ayarla", + "special-setlabeldescriptionaliases": "Etiket, tanım ve diğer adı ayarla", "wikibase-setlabeldescriptionaliases-label-label": "Etiket:", - "wikibase-setlabeldescriptionaliases-description-label": "Açıklama:", - "wikibase-setlabeldescriptionaliases-aliases-label": "Eşdeğeri:", - "wikibase-setsitelink-site": "Site kimliği:", - "wikibase-setsitelink-label": "Site bağlantısı:", - "wikibase-setsitelink-badges": "Ödüller:", + "wikibase-setlabeldescriptionaliases-description-label": "Tanım:", + "wikibase-setlabeldescriptionaliases-aliases-label": "Diğer adları:", + "wikibase-setlabeldescriptionaliases-submit": "Etiketi, tanımı ve diğer adı ayarla", + "wikibase-setsitelink-intro-badges": "Ayrıca, bu site bağlantısı için aşağıda listelenen rozetleri ayarlayabilirsiniz.", + "wikibase-setsitelink-site": "Site ID:", + "wikibase-setsitelink-label": "Sitebağlantısı:", + "wikibase-setsitelink-badges": "Rozetler:", "wikibase-setsitelink-submit": "Site bağlantısını oluştur", + "wikibase-setsitelink-not-badge": "$1 ögesi bir rozet değil.", "wikibase-modifyentity-id": "Kimlik:", "wikibase-modifyterm-language": "Dil kodu:", "special-mergeitems": "İki ögeyi birleştir", "wikibase-mergeitems-submit": "Ögeleri birleştir", "wikibase-itemmerge-permissiondenied": "İzin verilmedi.", "wikibase-dispatchstats-change-id": "Kimlik", - "wikibase-dispatchstats-change-timestamp": "Zaman damgası", + "wikibase-dispatchstats-change-timestamp": "Zamandamgası", "wikibase-dispatchstats-newest-change": "En yeniler", "wikibase-dispatchstats-site-id": "Site", "wikibase-dispatchstats-pos": "Konum", @@ -167,6 +199,7 @@ "wikibase-dispatchstats-touched": "Son dokunulan zaman", "wikibase-dispatchstats-large-lag": "(çok büyük)", "wikibase-dispatchstats-freshest": "En tazeler", + "wikibase-dispatchstats-median": "Orta değer", "wikibase-dispatchstats-average": "Ortalama", "special-listdatatypes": "Kullanılabilen tüm veri türleri listesi", "special-listproperties": "Özellikler listesi", @@ -174,24 +207,37 @@ "wikibase-listproperties-submit": "Bul", "wikibase-entitieswithoutlabel-label-language": "Dil kodu:", "wikibase-entitieswithoutlabel-label-type": "Tür:", + "special-entitydata": "Varlık verisi", "wikibase-entitydata-not-found": "$1 kimliğiyle hiçbir varlık bulunamadı.", "wikibase-entitydata-not-acceptable": "Eşleşen hiçbir biçim bulunamadı. Desteklenen MIME türleri: $1", "wikibase-entitydata-bad-id": "Geçersiz kimlik: $1.", "wikibase-entitydata-unsupported-format": "Veri biçimi $1, bu arayüz tarafından desteklenmiyor.", "wikibase-entitydata-storage-error": "$1 varlığı yüklenemedi.", "wikibase-entitydata-title": "Varlık Verisi", + "wikibase-entitypage-title": "Varlık Sayfası", "special-redirectentity": "Varlık yönlendir", "wikibase-redirectentity-fromid": "Yönlendirilecek kimlik", "wikibase-redirectentity-toid": "Üzerine yönlendirilecek kimlik", "wikibase-redirectentity-submit": "Yönlendirme", - "special-mylanguagefallbackchain": "Dil geri dönüş zincirim", + "special-mylanguagefallbackchain": "Dil zincirlerim", + "wikibase-api-no-such-sitelink": "Rozetlerin düzenlenmesi esnasında \"$1\" için bir site bağlantısı bulunamadı.", + "wikibase-api-not-recognized-datatype": "Bir veri türü bekleniyor ancak eksik ya da tanınmıyor.", + "wikibase-api-target-not-empty": "Yönlendirme sadece boş veya silinmiş varlığın üstünde oluşturulabilir.", "wikibase-api-target-is-redirect": "Yönlendirmenin hedefi başka bir yönlendirme olmamalıdır.", + "wikibase-api-target-is-incompatible": "Farklı türde bir varlığa yönlendirme denemesi.", + "wikibase-api-cant-redirect": "Yönlendirme oluşturulamıyor (muhtemelen bu türde varlıklar arasındaki yönlendirme desteklenmiyor).", + "wikibase-self-conflict-patched": "Yaptığınız düzenleme son sürüme eklendi ve bu varsa bazı ara düzenlemelerinizi geçersiz kılacaktır.", + "wikibase-conflict-patched": "Yaptığınız düzenleme en son sürüme eklendi.", + "wikibase-restoreold": "geri yükle", + "wikibase-entity-summary-restore": "[[Special:Contributions/$4|{{GENDER:$4|$4}}]] düzenlemeleri $3 sürümüne döndürüldü", "wikibase-no-direct-editing": "$1 ad alanında doğrudan düzenleme devre dışı bırakıldı.", "wikibase-special-mergeitems-error-prefix": "Ögeler birleştirilemedi. Aşağıdaki hata oluştu:", "wikibase-listdatatypes-wikibase-item-head": "Öge", "wikibase-listdatatypes-wikibase-property-head": "Özellik", - "wikibase-listdatatypes-commonsmedia-head": "Commons medya", - "wikibase-listdatatypes-quantity-head": "Miktar", + "wikibase-listdatatypes-commonsmedia-head": "Commons dosyası", + "wikibase-listdatatypes-globe-coordinate-head": "Küresel koordinat", + "wikibase-listdatatypes-tabular-data-head": "Tablo veri", + "wikibase-listdatatypes-quantity-head": "Birim", "wikibase-listdatatypes-monolingualtext-head": "Tek dilli metin", "wikibase-listdatatypes-multilingualtext-head": "Çok dilli metin", "wikibase-listdatatypes-string-head": "Dize", @@ -199,6 +245,7 @@ "wikibase-listdatatypes-url-head": "URL", "wikibase-listdatatypes-external-id-head": "Dış tanımlayıcı", "datatypes-type-url": "URL", + "content-model-wikibase-item": "Wikibase ögesi", "content-model-wikibase-property": "Wikibase özelliği", "content-model-wikibase-query": "Wikibase sorgu", "right-item-term": "Öğe terimlerini değiştirme (etiketler, açıklamalar, eşdeşler)", @@ -208,14 +255,16 @@ "wikibase-entity-not-viewable-title": "İçerik türü uyuşmazlığı: İçerik gösterilemiyor", "action-item-merge": "öğeleri birleştirme", "action-property-create": "özellik oluşturma", + "wikibase-search-bad-entity-type": "Bozuk varlık türü: $1", "apihelp-wbavailablebadges-description": "Müsait rozet öğelerini sorgular.", "apihelp-wbavailablebadges-example-1": "Tüm müsait rozet öğelerini sorgular", - "apihelp-wbcreateclaim-description": "Wikibase iddiaları oluşturur.", + "apihelp-wbcreateclaim-description": "Wikibase taleplerini oluşturur.", "apihelp-wbcreateclaim-param-property": "Snaks özelliği kimliği", "apihelp-wbcreateclaim-param-value": "Değeri olan bir Snak ile iddia yaratırken Snak'in değeri", "apihelp-wbcreateclaim-param-snaktype": "Snak'in türü", "apihelp-wbcreateclaim-example-1": "P9001 özellikli Q42 öğesi için değersiz Snak ile bir iddia oluşturur.", "apihelp-wbcreateclaim-example-2": "P9002 özelliğinin Q42 öğesi için \"itsastring\" değeri ile iddia oluşturur.", + "apihelp-wbcreateredirect-description": "Varlık yönlendirmesi oluştur.", "apihelp-wbcreateredirect-example-1": "Q!! Q12 üzerine yönlendirmeye dönüşsün", "apihelp-wbeditentity-description": "Tek bir yeni Wikibase varlığı oluşturur ve dizilenmiş bilgi ile onu modifiye eder.", "apihelp-wbeditentity-param-id": "Varlık için tanımlayıcı, prefiks ile beraber.\n<var>id</var> veya <var>site</var> ile <var>title</var>ı beraber kullan.", @@ -224,9 +273,10 @@ "apihelp-wbeditentity-param-baserevid": "Modifikasyon için baz alınacak sürümün sayısal tanımlayıcısı\nKaydederken karşılaşılacak çatışmalarda kullanılmak üzere...", "apihelp-wbeditentity-example-11": "Eğer zaten varsa, üzerine yazmadan etiket ekler", "apihelp-wbeditentity-example-12": "Etiket kaldırır", + "apihelp-wbgetclaims-description": "Wikibase taleplerini alır.", "apihelp-wbremoveclaims-param-claim": "Kaldırılacak iddiaları ayıklayan bir GUID ya da birkaç (boruyla ayrılmış) GUID.\nTüm iddialar aynı varlığa ait olmalı.", "apihelp-wbremoveclaims-example-1": "\"$D8404CDA Q42-25E4-4334-AF13-A3290BCD9C0N\" GUID ile iddiayı kaldır", - "apihelp-wbremovequalifiers-description": "Bir iddiadan bir niteleyiciyi kaldırır.", + "apihelp-wbremovequalifiers-description": "Bir talepteki niteleyiciyi kaldırır.", "apihelp-wbsearchentities-description": "Varlık arar.", "apihelp-wbsearchentities-param-search": "Bu metni ara.", "apihelp-wbsearchentities-param-language": "Bu dilde arama.", diff --git a/extensions/Wikibase/repo/includes/Search/Elastic/EntitySearchElastic.php b/extensions/Wikibase/repo/includes/Search/Elastic/EntitySearchElastic.php index 9dd9755..7452a2f 100644 --- a/extensions/Wikibase/repo/includes/Search/Elastic/EntitySearchElastic.php +++ b/extensions/Wikibase/repo/includes/Search/Elastic/EntitySearchElastic.php @@ -191,7 +191,7 @@ $labelsQuery->addFilter( $labelsFilter ); $labelsQuery->addMust( $dismax ); // TODO: this is a bit hacky, better way would be to make the field case-insensitive - // or add new subfiled which is case-insensitive + // or add new subfield which is case-insensitive $titleMatch = new Term( [ 'title.keyword' => strtoupper( $text ) ] ); // Match either labels or exact match to title diff --git a/extensions/Wikibase/repo/includes/Store/Sql/DatabaseSchemaUpdater.php b/extensions/Wikibase/repo/includes/Store/Sql/DatabaseSchemaUpdater.php index 19e7227..7bacb4f 100644 --- a/extensions/Wikibase/repo/includes/Store/Sql/DatabaseSchemaUpdater.php +++ b/extensions/Wikibase/repo/includes/Store/Sql/DatabaseSchemaUpdater.php @@ -7,6 +7,7 @@ use MWException; use Wikibase\Lib\Reporting\ObservableMessageReporter; use Wikibase\Lib\Store\CachingEntityRevisionLookup; +use Wikibase\Lib\Store\EntityRevisionCache; use Wikibase\Lib\Store\RevisionBasedEntityLookup; use Wikibase\Lib\Store\Sql\PropertyInfoTable; use Wikibase\Lib\Store\Sql\WikiPageEntityMetaDataLookup; @@ -189,7 +190,10 @@ false ); - $cachingEntityLookup = new CachingEntityRevisionLookup( $wikiPageEntityLookup, new HashBagOStuff() ); + $cachingEntityLookup = new CachingEntityRevisionLookup( + new EntityRevisionCache( new HashBagOStuff() ), + $wikiPageEntityLookup + ); $entityLookup = new RevisionBasedEntityLookup( $cachingEntityLookup ); $builder = new PropertyInfoTableBuilder( diff --git a/extensions/Wikibase/repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php b/extensions/Wikibase/repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php index 713b8c3..8497b3d 100644 --- a/extensions/Wikibase/repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php +++ b/extensions/Wikibase/repo/includes/Store/Sql/SqlChangeDispatchCoordinator.php @@ -527,7 +527,8 @@ } $db->commit( __METHOD__ ); - # wait for replication to finish + // Wait for all database replicas to be updated, but only for the affected client wiki. The + // "domain" argument is documented at ILBFactory::waitForReplication. $this->LBFactory->waitForReplication( [ 'domain' => $this->repoDB ] ); $this->releaseRepoDb( $db ); diff --git a/extensions/Wikibase/repo/includes/Store/Sql/SqlStore.php b/extensions/Wikibase/repo/includes/Store/Sql/SqlStore.php index d3943ee..5bb643d 100644 --- a/extensions/Wikibase/repo/includes/Store/Sql/SqlStore.php +++ b/extensions/Wikibase/repo/includes/Store/Sql/SqlStore.php @@ -15,11 +15,13 @@ use Wikibase\DataModel\Services\Lookup\RedirectResolvingEntityLookup; use Wikibase\Lib\Changes\EntityChangeFactory; use Wikibase\Lib\EntityIdComposer; +use Wikibase\Lib\Store\CacheRetrievingEntityRevisionLookup; use Wikibase\Lib\Store\CachingEntityRevisionLookup; use Wikibase\Lib\Store\CacheAwarePropertyInfoStore; use Wikibase\Lib\Store\CachingPropertyInfoLookup; use Wikibase\Lib\Store\Sql\EntityChangeLookup; use Wikibase\Lib\Store\EntityInfoBuilderFactory; +use Wikibase\Lib\Store\EntityRevisionCache; use Wikibase\Lib\Store\EntityRevisionLookup; use Wikibase\Lib\Store\EntityNamespaceLookup; use Wikibase\Lib\Store\EntityStore; @@ -82,6 +84,11 @@ * @var EntityRevisionLookup|null */ private $rawEntityRevisionLookup = null; + + /** + * @var CacheRetrievingEntityRevisionLookup|null + */ + private $cacheRetrievingEntityRevisionLookup = null; /** * @var EntityStore|null @@ -359,12 +366,13 @@ * * The EntityLookup returned by this method will resolve redirects. * - * @param string $uncached Flag string, set to 'uncached' to get an uncached direct lookup service. + * @param string $cache Flag string: Can be set to 'uncached' to get an uncached direct lookup or to 'retrieve-only' to get a + * lookup which reads from the cache, but doesn't store retrieved entities there. Defaults to a caching lookup. * * @return EntityLookup */ - public function getEntityLookup( $uncached = '' ) { - $revisionLookup = $this->getEntityRevisionLookup( $uncached ); + public function getEntityLookup( $cache = '' ) { + $revisionLookup = $this->getEntityRevisionLookup( $cache ); $revisionBasedLookup = new RevisionBasedEntityLookup( $revisionLookup ); $resolvingLookup = new RedirectResolvingEntityLookup( $revisionBasedLookup ); return $resolvingLookup; @@ -411,20 +419,31 @@ /** * @see Store::getEntityRevisionLookup * - * @param string $uncached Flag string, set to 'uncached' to get an uncached direct lookup service. + * @param string $cache Flag string: Can be set to 'uncached' to get an uncached direct lookup or to 'retrieve-only' to get a + * lookup which reads from the cache, but doesn't store retrieved entities there. Defaults to a caching lookup. * * @return EntityRevisionLookup */ - public function getEntityRevisionLookup( $uncached = '' ) { + public function getEntityRevisionLookup( $cache = '' ) { if ( !$this->entityRevisionLookup ) { list( $this->rawEntityRevisionLookup, $this->entityRevisionLookup ) = $this->newEntityRevisionLookup(); } - if ( $uncached === 'uncached' ) { + if ( $cache === 'uncached' ) { return $this->rawEntityRevisionLookup; + } elseif ( $cache === 'retrieve-only' ) { + return $this->getCacheRetrievingEntityRevisionLookup(); } else { return $this->entityRevisionLookup; } + } + + /** + * @return string + */ + private function getEntityRevisionLookupCacheKey() { + // NOTE: Keep cache key in sync with DirectSqlStore::newEntityRevisionLookup in WikibaseClient + return $this->cacheKeyPrefix . ':WikiPageEntityRevisionLookup'; } /** @@ -435,9 +454,6 @@ * EntityRevisionLookup. */ private function newEntityRevisionLookup() { - // NOTE: Keep cache key in sync with DirectSqlStore::newEntityRevisionLookup in WikibaseClient - $cacheKeyPrefix = $this->cacheKeyPrefix . ':WikiPageEntityRevisionLookup'; - // Maintain a list of watchers to be notified of changes to any entities, // in order to update caches. /** @var WikiPageEntityStore $dispatcher */ @@ -448,10 +464,12 @@ // Lower caching layer using persistent cache (e.g. memcached). $persistentCachingLookup = new CachingEntityRevisionLookup( - $nonCachingLookup, - wfGetCache( $this->cacheType ), - $this->cacheDuration, - $cacheKeyPrefix + new EntityRevisionCache( + wfGetCache( $this->cacheType ), + $this->cacheDuration, + $this->getEntityRevisionLookupCacheKey() + ), + $nonCachingLookup ); // We need to verify the revision ID against the database to avoid stale data. $persistentCachingLookup->setVerifyRevision( true ); @@ -459,8 +477,8 @@ // Top caching layer using an in-process hash. $hashCachingLookup = new CachingEntityRevisionLookup( - $persistentCachingLookup, - new HashBagOStuff( [ 'maxKeys' => 1000 ] ) + new EntityRevisionCache( new HashBagOStuff( [ 'maxKeys' => 1000 ] ) ), + $persistentCachingLookup ); // No need to verify the revision ID, we'll ignore updates that happen during the request. $hashCachingLookup->setVerifyRevision( false ); @@ -470,6 +488,28 @@ } /** + * @return CacheRetrievingEntityRevisionLookup + */ + private function getCacheRetrievingEntityRevisionLookup() { + if ( !$this->cacheRetrievingEntityRevisionLookup ) { + $cacheRetrievingEntityRevisionLookup = new CacheRetrievingEntityRevisionLookup( + new EntityRevisionCache( + wfGetCache( $this->cacheType ), + $this->cacheDuration, + $this->getEntityRevisionLookupCacheKey() + ), + $this->getEntityRevisionLookup( 'uncached' ) + ); + + $cacheRetrievingEntityRevisionLookup->setVerifyRevision( true ); + + $this->cacheRetrievingEntityRevisionLookup = $cacheRetrievingEntityRevisionLookup; + } + + return $this->cacheRetrievingEntityRevisionLookup; + } + + /** * @see Store::getEntityInfoBuilderFactory * * @return EntityInfoBuilderFactory diff --git a/extensions/Wikibase/repo/includes/Store/Store.php b/extensions/Wikibase/repo/includes/Store/Store.php index 2c4c702..4070d6f 100644 --- a/extensions/Wikibase/repo/includes/Store/Store.php +++ b/extensions/Wikibase/repo/includes/Store/Store.php @@ -77,18 +77,20 @@ public function getEntityRedirectLookup(); /** - * @param string $uncached Flag string, set to 'uncached' to get an uncached direct lookup service. + * @param string $cache Flag string: Can be set to 'uncached' to get an uncached direct lookup or to 'retrieve-only' to get a + * lookup which reads from the cache, but doesn't store retrieved entities there. Defaults to a caching lookup. * * @return EntityLookup */ - public function getEntityLookup( $uncached = '' ); + public function getEntityLookup( $cache = '' ); /** - * @param string $uncached Flag string, set to 'uncached' to get an uncached direct lookup service. + * @param string $cache Flag string: Can be set to 'uncached' to get an uncached direct lookup or to 'retrieve-only' to get a + * lookup which reads from the cache, but doesn't store retrieved entities there. Defaults to a caching lookup. * * @return EntityRevisionLookup */ - public function getEntityRevisionLookup( $uncached = '' ); + public function getEntityRevisionLookup( $cache = '' ); /** * @return EntityStore diff --git a/extensions/Wikibase/repo/includes/WikibaseRepo.php b/extensions/Wikibase/repo/includes/WikibaseRepo.php index 2b3b881..1ede3de 100644 --- a/extensions/Wikibase/repo/includes/WikibaseRepo.php +++ b/extensions/Wikibase/repo/includes/WikibaseRepo.php @@ -664,12 +664,15 @@ } /** - * @param string $uncached Flag string, set to 'uncached' to get an uncached direct lookup service. + * @see Store::getEntityRevisionLookup + * + * @param string $cache Flag string: Can be set to 'uncached' to get an uncached direct lookup or to 'retrieve-only' to get a + * lookup which reads from the cache, but doesn't store retrieved entities there. Defaults to a caching lookup. * * @return EntityRevisionLookup */ - public function getEntityRevisionLookup( $uncached = '' ) { - return $this->getStore()->getEntityRevisionLookup( $uncached ); + public function getEntityRevisionLookup( $cache = '' ) { + return $this->getStore()->getEntityRevisionLookup( $cache ); } /** @@ -747,12 +750,15 @@ } /** - * @param string $uncached Flag string, set to 'uncached' to get an uncached direct lookup service. + * @see Store::getEntityLookup + * + * @param string $cache Flag string: Can be set to 'uncached' to get an uncached direct lookup or to 'retrieve-only' to get a + * lookup which reads from the cache, but doesn't store retrieved entities there. Defaults to a caching lookup. * * @return EntityLookup */ - public function getEntityLookup( $uncached = '' ) { - return $this->getStore()->getEntityLookup( $uncached ); + public function getEntityLookup( $cache = '' ) { + return $this->getStore()->getEntityLookup( $cache ); } /** diff --git a/extensions/Wikibase/repo/maintenance/dumpJson.php b/extensions/Wikibase/repo/maintenance/dumpJson.php index e3bce27..ef93de1 100644 --- a/extensions/Wikibase/repo/maintenance/dumpJson.php +++ b/extensions/Wikibase/repo/maintenance/dumpJson.php @@ -80,7 +80,7 @@ $wikibaseRepo->getEntityNamespaceLookup(), $wikibaseRepo->getEntityIdParser() ); - $revisionLookup = $wikibaseRepo->getEntityRevisionLookup( 'uncached' ); + $revisionLookup = $wikibaseRepo->getEntityRevisionLookup( 'retrieve-only' ); $this->setServices( $sqlEntityIdPagerFactory, diff --git a/extensions/Wikibase/repo/maintenance/dumpRdf.php b/extensions/Wikibase/repo/maintenance/dumpRdf.php index 274bc92..f1e6b1b 100644 --- a/extensions/Wikibase/repo/maintenance/dumpRdf.php +++ b/extensions/Wikibase/repo/maintenance/dumpRdf.php @@ -120,7 +120,7 @@ $wikibaseRepo->getPropertyDataTypeLookup(), $wikibaseRepo->getValueSnakRdfBuilderFactory(), $wikibaseRepo->getEntityRdfBuilderFactory(), - $wikibaseRepo->getEntityRevisionLookup( 'uncached' ), + $wikibaseRepo->getEntityRevisionLookup( 'retrieve-only' ), $wikibaseRepo->getRdfVocabulary(), $wikibaseRepo->getEntityContentFactory() ); diff --git a/extensions/Wikibase/repo/maintenance/rebuildItemsPerSite.php b/extensions/Wikibase/repo/maintenance/rebuildItemsPerSite.php index b0933db..b73bf19 100644 --- a/extensions/Wikibase/repo/maintenance/rebuildItemsPerSite.php +++ b/extensions/Wikibase/repo/maintenance/rebuildItemsPerSite.php @@ -49,7 +49,7 @@ $siteLinkTable = new SiteLinkTable( 'wb_items_per_site', false ); $wikibaseRepo = WikibaseRepo::getDefaultInstance(); // Use an uncached EntityLookup here to avoid memory leaks - $entityLookup = $wikibaseRepo->getEntityLookup( 'uncached' ); + $entityLookup = $wikibaseRepo->getEntityLookup( 'retrieve-only' ); $store = $wikibaseRepo->getStore(); $builder = new ItemsPerSiteBuilder( $siteLinkTable, diff --git a/extensions/Wikibase/repo/maintenance/rebuildTermSqlIndex.php b/extensions/Wikibase/repo/maintenance/rebuildTermSqlIndex.php index 7e98be0..9748ecd 100644 --- a/extensions/Wikibase/repo/maintenance/rebuildTermSqlIndex.php +++ b/extensions/Wikibase/repo/maintenance/rebuildTermSqlIndex.php @@ -88,7 +88,7 @@ MediaWikiServices::getInstance()->getDBLoadBalancerFactory(), $termIndex, $sqlEntityIdPagerFactory, - $wikibaseRepo->getEntityRevisionLookup( 'uncached' ), + $wikibaseRepo->getEntityRevisionLookup( 'retrieve-only' ), $this->getEntityTypes(), $this->getOption( 'sleep', 10 ) ); diff --git a/extensions/Wikibase/repo/tests/phpunit/includes/Store/Sql/SqlStoreTest.php b/extensions/Wikibase/repo/tests/phpunit/includes/Store/Sql/SqlStoreTest.php index 12b505a..61a49c3 100644 --- a/extensions/Wikibase/repo/tests/phpunit/includes/Store/Sql/SqlStoreTest.php +++ b/extensions/Wikibase/repo/tests/phpunit/includes/Store/Sql/SqlStoreTest.php @@ -102,8 +102,20 @@ $this->assertInstanceOf( EntityRedirectLookup::class, $service ); } - public function testGetEntityLookup() { - $service = $this->newInstance()->getEntityLookup(); + public function entityLoookupCacheProvider() { + return [ + [ '' ], + [ 'uncached' ], + [ 'retrieve-only' ], + ]; + } + + /** + * @dataProvider entityLoookupCacheProvider + */ + public function testGetEntityLookup( $type ) { + $service = $this->newInstance()->getEntityLookup( $type ); + $this->assertInstanceOf( EntityLookup::class, $service ); } @@ -117,8 +129,12 @@ $this->assertInstanceOf( EntityStore::class, $service ); } - public function testGetEntityRevisionLookup() { - $service = $this->newInstance()->getEntityRevisionLookup(); + /** + * @dataProvider entityLoookupCacheProvider + */ + public function testGetEntityRevisionLookup( $type ) { + $service = $this->newInstance()->getEntityRevisionLookup( $type ); + $this->assertInstanceOf( EntityRevisionLookup::class, $service ); } diff --git a/extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php b/extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php index f8c6783..897f565 100644 --- a/extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php +++ b/extensions/Wikibase/repo/tests/phpunit/includes/Store/WikiPageEntityRevisionLookupTest.php @@ -53,7 +53,7 @@ } /** - * @see EntityLookupTest::newEntityLoader(newEntityLookup + * @see EntityRevisionLookupTest::newEntityRevisionLookup * * @param EntityRevision[] $entityRevisions * @param EntityRedirect[] $entityRedirects diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 4005f63..c0aa0a0 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -837,6 +837,7 @@ 'Wikibase\\Lib\\StaticContentLanguages' => $baseDir . '/extensions/Wikibase/lib/includes/StaticContentLanguages.php', 'Wikibase\\Lib\\Store\\BadRevisionException' => $baseDir . '/extensions/Wikibase/lib/includes/Store/BadRevisionException.php', 'Wikibase\\Lib\\Store\\CacheAwarePropertyInfoStore' => $baseDir . '/extensions/Wikibase/lib/includes/Store/CacheAwarePropertyInfoStore.php', + 'Wikibase\\Lib\\Store\\CacheRetrievingEntityRevisionLookup' => $baseDir . '/extensions/Wikibase/lib/includes/Store/CacheRetrievingEntityRevisionLookup.php', 'Wikibase\\Lib\\Store\\CachingEntityRevisionLookup' => $baseDir . '/extensions/Wikibase/lib/includes/Store/CachingEntityRevisionLookup.php', 'Wikibase\\Lib\\Store\\CachingPropertyInfoLookup' => $baseDir . '/extensions/Wikibase/lib/includes/Store/CachingPropertyInfoLookup.php', 'Wikibase\\Lib\\Store\\CachingPropertyOrderProvider' => $baseDir . '/extensions/Wikibase/lib/includes/Store/CachingPropertyOrderProvider.php', @@ -856,6 +857,7 @@ 'Wikibase\\Lib\\Store\\EntityInfoTermLookup' => $baseDir . '/extensions/Wikibase/lib/includes/Store/EntityInfoTermLookup.php', 'Wikibase\\Lib\\Store\\EntityNamespaceLookup' => $baseDir . '/extensions/Wikibase/lib/includes/Store/EntityNamespaceLookup.php', 'Wikibase\\Lib\\Store\\EntityRevision' => $baseDir . '/extensions/Wikibase/lib/includes/Store/EntityRevision.php', + 'Wikibase\\Lib\\Store\\EntityRevisionCache' => $baseDir . '/extensions/Wikibase/lib/includes/Store/EntityRevisionCache.php', 'Wikibase\\Lib\\Store\\EntityRevisionLookup' => $baseDir . '/extensions/Wikibase/lib/includes/Store/EntityRevisionLookup.php', 'Wikibase\\Lib\\Store\\EntityStore' => $baseDir . '/extensions/Wikibase/lib/includes/Store/EntityStore.php', 'Wikibase\\Lib\\Store\\EntityStoreWatcher' => $baseDir . '/extensions/Wikibase/lib/includes/Store/EntityStoreWatcher.php', @@ -980,6 +982,7 @@ 'Wikibase\\Lib\\Tests\\StaticContentLanguagesTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/StaticContentLanguagesTest.php', 'Wikibase\\Lib\\Tests\\Store\\BufferingTermLookupTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/BufferingTermLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\CacheAwarePropertyInfoStoreTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/CacheAwarePropertyInfoStoreTest.php', + 'Wikibase\\Lib\\Tests\\Store\\CacheRetrievingEntityRevisionLookupTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/CacheRetrievingEntityRevisionLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\CachingEntityRevisionLookupTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\CachingPropertyInfoLookupTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/CachingPropertyInfoLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\CachingPropertyOrderProviderTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/CachingPropertyOrderProviderTest.php', @@ -996,6 +999,7 @@ 'Wikibase\\Lib\\Tests\\Store\\EntityInfoTermLookupTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityInfoTermLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\EntityInfoTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityInfoTest.php', 'Wikibase\\Lib\\Tests\\Store\\EntityNamespaceLookupTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityNamespaceLookupTest.php', + 'Wikibase\\Lib\\Tests\\Store\\EntityRevisionCacheTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityRevisionCacheTest.php', 'Wikibase\\Lib\\Tests\\Store\\EntityRevisionTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityRevisionTest.php', 'Wikibase\\Lib\\Tests\\Store\\EntityTermLookupTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityTermLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\FallbackPropertyOrderProviderTest' => $baseDir . '/extensions/Wikibase/lib/tests/phpunit/Store/FallbackPropertyOrderProviderTest.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index fb0c032..cd9eb20 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -1141,6 +1141,7 @@ 'Wikibase\\Lib\\StaticContentLanguages' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/StaticContentLanguages.php', 'Wikibase\\Lib\\Store\\BadRevisionException' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/BadRevisionException.php', 'Wikibase\\Lib\\Store\\CacheAwarePropertyInfoStore' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/CacheAwarePropertyInfoStore.php', + 'Wikibase\\Lib\\Store\\CacheRetrievingEntityRevisionLookup' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/CacheRetrievingEntityRevisionLookup.php', 'Wikibase\\Lib\\Store\\CachingEntityRevisionLookup' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/CachingEntityRevisionLookup.php', 'Wikibase\\Lib\\Store\\CachingPropertyInfoLookup' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/CachingPropertyInfoLookup.php', 'Wikibase\\Lib\\Store\\CachingPropertyOrderProvider' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/CachingPropertyOrderProvider.php', @@ -1160,6 +1161,7 @@ 'Wikibase\\Lib\\Store\\EntityInfoTermLookup' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/EntityInfoTermLookup.php', 'Wikibase\\Lib\\Store\\EntityNamespaceLookup' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/EntityNamespaceLookup.php', 'Wikibase\\Lib\\Store\\EntityRevision' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/EntityRevision.php', + 'Wikibase\\Lib\\Store\\EntityRevisionCache' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/EntityRevisionCache.php', 'Wikibase\\Lib\\Store\\EntityRevisionLookup' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/EntityRevisionLookup.php', 'Wikibase\\Lib\\Store\\EntityStore' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/EntityStore.php', 'Wikibase\\Lib\\Store\\EntityStoreWatcher' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/includes/Store/EntityStoreWatcher.php', @@ -1284,6 +1286,7 @@ 'Wikibase\\Lib\\Tests\\StaticContentLanguagesTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/StaticContentLanguagesTest.php', 'Wikibase\\Lib\\Tests\\Store\\BufferingTermLookupTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/BufferingTermLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\CacheAwarePropertyInfoStoreTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/CacheAwarePropertyInfoStoreTest.php', + 'Wikibase\\Lib\\Tests\\Store\\CacheRetrievingEntityRevisionLookupTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/CacheRetrievingEntityRevisionLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\CachingEntityRevisionLookupTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/CachingEntityRevisionLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\CachingPropertyInfoLookupTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/CachingPropertyInfoLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\CachingPropertyOrderProviderTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/CachingPropertyOrderProviderTest.php', @@ -1300,6 +1303,7 @@ 'Wikibase\\Lib\\Tests\\Store\\EntityInfoTermLookupTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityInfoTermLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\EntityInfoTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityInfoTest.php', 'Wikibase\\Lib\\Tests\\Store\\EntityNamespaceLookupTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityNamespaceLookupTest.php', + 'Wikibase\\Lib\\Tests\\Store\\EntityRevisionCacheTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityRevisionCacheTest.php', 'Wikibase\\Lib\\Tests\\Store\\EntityRevisionTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityRevisionTest.php', 'Wikibase\\Lib\\Tests\\Store\\EntityTermLookupTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/EntityTermLookupTest.php', 'Wikibase\\Lib\\Tests\\Store\\FallbackPropertyOrderProviderTest' => __DIR__ . '/../..' . '/extensions/Wikibase/lib/tests/phpunit/Store/FallbackPropertyOrderProviderTest.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index f4ee55d..46cd70a 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -776,22 +776,22 @@ }, { "name": "wikibase/internal-serialization", - "version": "2.6.0", - "version_normalized": "2.6.0.0", + "version": "2.7.0", + "version_normalized": "2.7.0.0", "source": { "type": "git", "url": "https://github.com/wmde/WikibaseInternalSerialization.git", - "reference": "b1ac697ede618d70108d5d6e0e623e9fcbb90976" + "reference": "a1a9257221a81b1de3226be6b13178203cf680b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wmde/WikibaseInternalSerialization/zipball/b1ac697ede618d70108d5d6e0e623e9fcbb90976", - "reference": "b1ac697ede618d70108d5d6e0e623e9fcbb90976", + "url": "https://api.github.com/repos/wmde/WikibaseInternalSerialization/zipball/a1a9257221a81b1de3226be6b13178203cf680b1", + "reference": "a1a9257221a81b1de3226be6b13178203cf680b1", "shasum": "" }, "require": { "php": ">=5.5.9", - "serialization/serialization": "~3.2", + "serialization/serialization": "~4.0|~3.2", "wikibase/data-model": "~7.0|~6.0|~5.0|~4.2", "wikibase/data-model-serialization": "~2.0" }, @@ -802,13 +802,13 @@ "data-values/time": ">=0.1 <0.9", "phpmd/phpmd": "~2.3", "phpunit/phpunit": "~4.8", - "wikibase/wikibase-codesniffer": "^0.1.0" + "wikibase/wikibase-codesniffer": "^0.2.0" }, - "time": "2017-09-18 08:42:51", + "time": "2017-10-26 12:45:36", "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6.x-dev" + "dev-master": "2.7.x-dev" } }, "installation-source": "dist", @@ -1389,12 +1389,12 @@ "source": { "type": "git", "url": "https://github.com/wikimedia/mediawiki-extensions-Wikibase.git", - "reference": "84f5795908c00f3c37072b02aa025c782083bda3" + "reference": "b789faeb3a3898e03ec31ce4b628611642b141dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/84f5795908c00f3c37072b02aa025c782083bda3", - "reference": "84f5795908c00f3c37072b02aa025c782083bda3", + "url": "https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/b789faeb3a3898e03ec31ce4b628611642b141dc", + "reference": "b789faeb3a3898e03ec31ce4b628611642b141dc", "shasum": "" }, "require": { @@ -1429,7 +1429,7 @@ "mediawiki/minus-x": "0.1.0", "wikibase/wikibase-codesniffer": "^0.2.0" }, - "time": "2017-10-26 07:53:28", + "time": "2017-10-26 21:39:21", "type": "mediawiki-extension", "installation-source": "dist", "autoload": { @@ -1594,7 +1594,7 @@ "source": { "type": "git", "url": "https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseMediaInfo", - "reference": "2e477617530539bc4ba3e2196d5533bde3f72455" + "reference": "81a601a7f844da6c83133c2464c4ac81715a4f6d" }, "require": { "php": ">=5.5.9", @@ -1609,7 +1609,7 @@ "phpunit/phpunit": "~4.8", "wikibase/wikibase-codesniffer": "^0.2.0" }, - "time": "2017-10-17 21:06:57", + "time": "2017-10-26 10:42:44", "type": "mediawiki-extension", "installation-source": "source", "autoload": { @@ -1775,7 +1775,7 @@ "source": { "type": "git", "url": "https://gerrit.wikimedia.org/r/mediawiki/extensions/WikibaseQualityConstraints", - "reference": "598671433d7c5d8cef818c6eff957a5eb00e0040" + "reference": "b0e8881e094cea6e89963cdfeac5fa8c932a2d05" }, "require": { "php": ">=5.5.9", @@ -1791,7 +1791,7 @@ "satooshi/php-coveralls": "master-dev", "wikibase/wikibase-codesniffer": "^0.2.0" }, - "time": "2017-10-25 21:08:09", + "time": "2017-10-26 09:54:31", "type": "mediawiki-extension", "installation-source": "source", "autoload": { diff --git a/vendor/wikibase/internal-serialization/README.md b/vendor/wikibase/internal-serialization/README.md index 0a9e15c..54ec12f 100644 --- a/vendor/wikibase/internal-serialization/README.md +++ b/vendor/wikibase/internal-serialization/README.md @@ -106,6 +106,10 @@ ## Release notes +### 2.7.0 (2017-10-26) + +* Added compatibility with Serialization 4.x + ### 2.6.0 (2017-09-18) * Added compatibility with DataValues Common 0.4, Number 0.9, and Time 0.8 diff --git a/vendor/wikibase/internal-serialization/src/DeserializerFactory.php b/vendor/wikibase/internal-serialization/src/DeserializerFactory.php index 77cbe9f..f773f53 100644 --- a/vendor/wikibase/internal-serialization/src/DeserializerFactory.php +++ b/vendor/wikibase/internal-serialization/src/DeserializerFactory.php @@ -37,7 +37,7 @@ private $currentFactory; /** - * @var DispatchableDeserializer|null $currentEntityDeserializer + * @var DispatchableDeserializer|null */ private $currentEntityDeserializer; -- To view, visit https://gerrit.wikimedia.org/r/386794 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1e1e9e0a198a82b4753527140d5e68c5a2cd05e1 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Wikidata Gerrit-Branch: master Gerrit-Owner: WikidataBuilder <wikidata-servi...@wikimedia.de> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits