Bene has uploaded a new change for review.
https://gerrit.wikimedia.org/r/234960
Change subject: Use a BadgeStore in SiteLinkTable to update badges
......................................................................
Use a BadgeStore in SiteLinkTable to update badges
This patch injects a BadgeStore into SiteLinkTable and reflects
all updates made on sitelinks also to the badges table.
Bug: T72229
Change-Id: I48eae6239671dbbc0111cf4695a48163705580a4
---
M client/includes/store/sql/DirectSqlStore.php
M lib/includes/store/sql/BadgeTable.php
M lib/includes/store/sql/SiteLinkTable.php
M lib/tests/phpunit/store/Sql/SiteLinkTableTest.php
M repo/includes/store/Store.php
M repo/includes/store/sql/ItemsPerSiteBuilder.php
M repo/includes/store/sql/SqlStore.php
M repo/maintenance/dispatchChanges.php
M repo/maintenance/rebuildItemsPerSite.php
M repo/tests/phpunit/includes/store/StoreTest.php
10 files changed, 171 insertions(+), 50 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase
refs/changes/60/234960/1
diff --git a/client/includes/store/sql/DirectSqlStore.php
b/client/includes/store/sql/DirectSqlStore.php
index fdbdb71..4a8d18a 100644
--- a/client/includes/store/sql/DirectSqlStore.php
+++ b/client/includes/store/sql/DirectSqlStore.php
@@ -19,6 +19,7 @@
use Wikibase\Client\WikibaseClient;
use Wikibase\DataModel\Services\EntityId\EntityIdParser;
use Wikibase\DataModel\Services\Lookup\EntityLookup;
+use Wikibase\Lib\Store\BadgeTable;
use Wikibase\Lib\Store\CachingEntityRevisionLookup;
use Wikibase\Lib\Store\CachingSiteLinkLookup;
use Wikibase\Lib\Store\EntityContentDataCodec;
@@ -278,8 +279,9 @@
*/
public function getSiteLinkLookup() {
if ( $this->siteLinkLookup === null ) {
+ $badgeTable = new BadgeTable( 'wb_badges_per_sitelink',
true );
$this->siteLinkLookup = new CachingSiteLinkLookup(
- new SiteLinkTable( 'wb_items_per_site', true,
$this->repoWiki ),
+ new SiteLinkTable( 'wb_items_per_site', true,
$badgeTable, $this->repoWiki ),
new HashBagOStuff()
);
}
diff --git a/lib/includes/store/sql/BadgeTable.php
b/lib/includes/store/sql/BadgeTable.php
index e4255f6..e4195c3 100644
--- a/lib/includes/store/sql/BadgeTable.php
+++ b/lib/includes/store/sql/BadgeTable.php
@@ -20,18 +20,14 @@
class BadgeTable extends DBAccessBase implements BadgeStore {
/**
- * @since 0.5
- *
* @var string
*/
- protected $table;
+ private $table;
/**
- * @since 0.5
- *
* @var bool
*/
- protected $readonly;
+ private $readonly;
/**
* @param string $table The table to use for the badges
diff --git a/lib/includes/store/sql/SiteLinkTable.php
b/lib/includes/store/sql/SiteLinkTable.php
index 8c1785e..49b1f8e 100644
--- a/lib/includes/store/sql/SiteLinkTable.php
+++ b/lib/includes/store/sql/SiteLinkTable.php
@@ -22,30 +22,32 @@
class SiteLinkTable extends DBAccessBase implements SiteLinkStore,
SiteLinkConflictLookup {
/**
- * @since 0.1
- *
* @var string
*/
- protected $table;
+ private $table;
/**
- * @since 0.3
- *
* @var bool
*/
- protected $readonly;
+ private $readonly;
+
+ /**
+ * @var BadgeStore
+ */
+ private $badgeStore;
/**
* @since 0.1
*
* @param string $table The table to use for the sitelinks
* @param bool $readonly Whether the table can be modified.
+ * @param BadgeStore $badgeStore A badge store to access badges
* @param string|bool $wiki The wiki's database to connect to.
* Must be a value LBFactory understands. Defaults to false,
which is the local wiki.
*
* @throws MWException
*/
- public function __construct( $table, $readonly, $wiki = false ) {
+ public function __construct( $table, $readonly, BadgeStore $badgeStore,
$wiki = false ) {
if ( !is_string( $table ) ) {
throw new MWException( '$table must be a string.' );
}
@@ -58,6 +60,7 @@
$this->table = $table;
$this->readonly = $readonly;
+ $this->badgeStore = $badgeStore;
$this->wiki = $wiki;
}
@@ -151,14 +154,30 @@
);
}
- $success = $dbw->insert(
+ $ok = $dbw->insert(
$this->table,
$insert,
__METHOD__,
array( 'IGNORE' )
);
- return $success && $dbw->affectedRows();
+ $ok = $ok && $dbw->affectedRows();
+
+ if ( !$ok ) {
+ return $ok;
+ }
+
+ return $this->saveBadges( $links );
+ }
+
+ private function saveBadges( array $links ) {
+ foreach ( $links as $siteLink ) {
+ if ( !$this->badgeStore->saveBadgesOfSiteLink(
$siteLink ) ) {
+ return false;
+ }
+ }
+
+ return true;
}
/**
@@ -183,7 +202,7 @@
$siteIds[] = $siteLink->getSiteId();
}
- $success = $dbw->delete(
+ $ok = $dbw->delete(
$this->table,
array(
'ips_item_id' => $item->getId()->getNumericId(),
@@ -192,7 +211,21 @@
__METHOD__
);
- return $success;
+ if ( !$ok ) {
+ return $ok;
+ }
+
+ return $this->deleteBadges( $links );
+ }
+
+ private function deleteBadges( array $links ) {
+ foreach ( $links as $siteLink ) {
+ if ( !$this->badgeStore->deleteBadgesOfSiteLink(
$siteLink ) ) {
+ return false;
+ }
+ }
+
+ return true;
}
/**
@@ -210,6 +243,8 @@
throw new MWException( 'Cannot write when in readonly
mode' );
}
+ $links = $this->getSiteLinksForItem( $itemId );
+
$dbw = $this->getConnection( DB_MASTER );
$ok = $dbw->delete(
@@ -220,7 +255,11 @@
$this->releaseConnection( $dbw );
- return $ok;
+ if ( !$ok ) {
+ return $ok;
+ }
+
+ return $this->deleteBadges( $links );
}
/**
@@ -351,7 +390,8 @@
$ok = $dbw->delete( $this->table, '*', __METHOD__ );
$this->releaseConnection( $dbw );
- return $ok;
+
+ return $this->badgeStore->clear();
}
/**
diff --git a/lib/tests/phpunit/store/Sql/SiteLinkTableTest.php
b/lib/tests/phpunit/store/Sql/SiteLinkTableTest.php
index 7113d55..318e1b9 100644
--- a/lib/tests/phpunit/store/Sql/SiteLinkTableTest.php
+++ b/lib/tests/phpunit/store/Sql/SiteLinkTableTest.php
@@ -4,6 +4,8 @@
use Wikibase\DataModel\Entity\Item;
use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\DataModel\SiteLink;
+use Wikibase\Lib\Store\BadgeStore;
use Wikibase\Lib\Store\SiteLinkTable;
/**
@@ -21,19 +23,49 @@
*/
class SiteLinkTableTest extends \MediaWikiTestCase {
- /**
- * @var SiteLinkTable
- */
- private $siteLinkTable;
-
protected function setUp() {
parent::setUp();
if ( !defined( 'WB_VERSION' ) ) {
$this->markTestSkipped( "Skipping because
WikibaseClient doesn't have a local site link table." );
}
+ }
- $this->siteLinkTable = new SiteLinkTable( 'wb_items_per_site',
false );
+ /**
+ * @param SiteLink[] $updatedLinks
+ * @param SiteLink[] $removedLinks
+ * @param bool $clear
+ * @return BadgeStore
+ */
+ private function newBadgeStore( array $updatedLinks, array
$removedLinks, $clear ) {
+ $badgeStore = $this->getMock( 'Wikibase\Lib\Store\BadgeStore' );
+
+ $i = 0;
+ foreach ( $removedLinks as $siteLink ) {
+ $badgeStore->expects( $this->at( $i++ ) )
+ ->method( 'deleteBadgesOfSiteLink' )
+ ->with( $siteLink )
+ ->will( $this->returnValue( true ) );
+ }
+
+ foreach ( $updatedLinks as $siteLink ) {
+ $badgeStore->expects( $this->at( $i++ ) )
+ ->method( 'saveBadgesOfSiteLink' )
+ ->with( $siteLink )
+ ->will( $this->returnValue( true ) );
+ }
+
+ if ( $clear ) {
+ $badgeStore->expects( $this->once() )
+ ->method( 'clear' )
+ ->will( $this->returnValue( true ) );
+ }
+
+ return $badgeStore;
+ }
+
+ private function newSiteLinkTable( array $updatedLinks = array(), array
$removedLinks = array(), $clear = false ) {
+ return new SiteLinkTable( 'wb_items_per_site', false,
$this->newBadgeStore( $updatedLinks, $removedLinks, $clear ) );
}
public function itemProvider() {
@@ -61,7 +93,8 @@
* @dataProvider itemProvider
*/
public function testSaveLinksOfItem( Item $item ) {
- $res = $this->siteLinkTable->saveLinksOfItem( $item );
+ $siteLinkTable = $this->newSiteLinkTable(
$item->getSiteLinkList()->toArray() );
+ $res = $siteLinkTable->saveLinksOfItem( $item );
$this->assertTrue( $res );
}
@@ -69,10 +102,11 @@
* @depends testSaveLinksOfItem
*/
public function testSaveLinksOfItem_duplicate() {
+ $siteLinkTable = $this->newSiteLinkTable();
$item = new Item( new ItemId( 'Q2' ) );
$item->getSiteLinkList()->addNewSiteLink( 'enwiki', 'Beer' );
- $res = $this->siteLinkTable->saveLinksOfItem( $item );
+ $res = $siteLinkTable->saveLinksOfItem( $item );
$this->assertFalse( $res );
}
@@ -83,22 +117,31 @@
$item->getSiteLinkList()->addNewSiteLink( 'dewiki', 'Bar' );
$item->getSiteLinkList()->addNewSiteLink( 'svwiki', 'Börk' );
- $this->siteLinkTable->saveLinksOfItem( $item );
+ $siteLinkTable = $this->newSiteLinkTable(
$item->getSiteLinkList()->toArray() );
+ $siteLinkTable->saveLinksOfItem( $item );
// modify links, and save again
- $item->getSiteLinkList()->removeLinkWithSiteId( 'enwiki' );
- $item->getSiteLinkList()->addNewSiteLink( 'enwiki', 'FooK' );
+ $item->getSiteLinkList()->setNewSiteLink( 'enwiki', 'FooK' );
$item->getSiteLinkList()->removeLinkWithSiteId( 'dewiki' );
$item->getSiteLinkList()->addNewSiteLink( 'nlwiki', 'GrooK' );
- $this->siteLinkTable->saveLinksOfItem( $item );
+ $updated = array(
+ new SiteLink( 'enwiki', 'FooK' ),
+ new SiteLink( 'nlwiki', 'GrooK' )
+ );
+ $removed = array(
+ new SiteLink( 'enwiki', 'FooK' ),
+ new SiteLink( 'dewiki', 'Bar' )
+ );
+ $siteLinkTable = $this->newSiteLinkTable( $updated, $removed );
+ $siteLinkTable->saveLinksOfItem( $item );
// check that the update worked correctly
- $actualLinks = $this->siteLinkTable->getSiteLinksForItem(
$item->getId() );
+ $actualLinks = $siteLinkTable->getSiteLinksForItem(
$item->getId() );
$expectedLinks = $item->getSiteLinkList()->toArray();
- $missingLinks = array_udiff( $expectedLinks, $actualLinks,
array( $this->siteLinkTable, 'compareSiteLinks' ) );
- $extraLinks = array_udiff( $actualLinks, $expectedLinks, array(
$this->siteLinkTable, 'compareSiteLinks' ) );
+ $missingLinks = array_udiff( $expectedLinks, $actualLinks,
array( $siteLinkTable, 'compareSiteLinks' ) );
+ $extraLinks = array_udiff( $actualLinks, $expectedLinks, array(
$siteLinkTable, 'compareSiteLinks' ) );
$this->assertEmpty( $missingLinks, 'Missing links' );
$this->assertEmpty( $extraLinks, 'Extra links' );
@@ -109,7 +152,8 @@
* @dataProvider itemProvider
*/
public function testGetSiteLinksOfItem( Item $item ) {
- $siteLinks = $this->siteLinkTable->getSiteLinksForItem(
$item->getId() );
+ $siteLinkTable = $this->newSiteLinkTable();
+ $siteLinks = $siteLinkTable->getSiteLinksForItem(
$item->getId() );
$this->assertArrayEquals(
$item->getSiteLinkList()->toArray(),
@@ -122,10 +166,12 @@
* @dataProvider itemProvider
*/
public function testGetItemIdForSiteLink( Item $item ) {
+ $siteLinkTable = $this->newSiteLinkTable();
+
foreach ( $item->getSiteLinkList()->toArray() as $siteLink ) {
$this->assertEquals(
$item->getId(),
- $this->siteLinkTable->getItemIdForSiteLink(
$siteLink )
+ $siteLinkTable->getItemIdForSiteLink( $siteLink
)
);
}
}
@@ -135,10 +181,12 @@
* @dataProvider itemProvider
*/
public function testGetItemIdForLink( Item $item ) {
+ $siteLinkTable = $this->newSiteLinkTable();
+
foreach ( $item->getSiteLinkList()->toArray() as $siteLink ) {
$this->assertEquals(
$item->getId(),
- $this->siteLinkTable->getItemIdForLink(
$siteLink->getSiteId(), $siteLink->getPageName() )
+ $siteLinkTable->getItemIdForLink(
$siteLink->getSiteId(), $siteLink->getPageName() )
);
}
}
@@ -148,12 +196,14 @@
* @dataProvider itemProvider
*/
public function testDeleteLinksOfItem( Item $item ) {
+ $siteLinkTable = $this->newSiteLinkTable( array(),
$item->getSiteLinkList()->toArray() );
+
$this->assertTrue(
- $this->siteLinkTable->deleteLinksOfItem( $item->getId()
) !== false
+ $siteLinkTable->deleteLinksOfItem( $item->getId() ) !==
false
);
$this->assertEmpty(
- $this->siteLinkTable->getSiteLinksForItem(
$item->getId() )
+ $siteLinkTable->getSiteLinksForItem( $item->getId() )
);
}
@@ -162,12 +212,14 @@
* @dataProvider itemProvider
*/
public function testClear( Item $item ) {
+ $siteLinkTable = $this->newSiteLinkTable( array(), array(),
true );
+
$this->assertTrue(
- $this->siteLinkTable->clear()
+ $siteLinkTable->clear()
);
$this->assertEmpty(
- $this->siteLinkTable->getSiteLinksForItem(
$item->getId() )
+ $siteLinkTable->getSiteLinksForItem( $item->getId() )
);
}
diff --git a/repo/includes/store/Store.php b/repo/includes/store/Store.php
index 33f68a3..2face60 100644
--- a/repo/includes/store/Store.php
+++ b/repo/includes/store/Store.php
@@ -5,6 +5,7 @@
use Wikibase\DataModel\Services\Entity\EntityPrefetcher;
use Wikibase\DataModel\Services\Lookup\EntityLookup;
use Wikibase\DataModel\Services\Lookup\EntityRedirectLookup;
+use Wikibase\Lib\Store\BadgeStore;
use Wikibase\Lib\Store\EntityInfoBuilderFactory;
use Wikibase\Lib\Store\EntityRevisionLookup;
use Wikibase\Lib\Store\EntityStore;
@@ -157,4 +158,11 @@
*/
public function getEntityPrefetcher();
+ /**
+ * @since 0.5
+ *
+ * @return BadgeStore
+ */
+ public function newBadgeStore();
+
}
diff --git a/repo/includes/store/sql/ItemsPerSiteBuilder.php
b/repo/includes/store/sql/ItemsPerSiteBuilder.php
index 9979864..d1ce859 100644
--- a/repo/includes/store/sql/ItemsPerSiteBuilder.php
+++ b/repo/includes/store/sql/ItemsPerSiteBuilder.php
@@ -10,7 +10,7 @@
use Wikibase\Repo\Store\EntityIdPager;
/**
- * Utility class for rebuilding the wb_items_per_site table.
+ * Utility class for rebuilding the wb_items_per_site and
wb_badges_per_sitelink table.
*
* @since 0.5
*
diff --git a/repo/includes/store/sql/SqlStore.php
b/repo/includes/store/sql/SqlStore.php
index 4998429..6af941e 100644
--- a/repo/includes/store/sql/SqlStore.php
+++ b/repo/includes/store/sql/SqlStore.php
@@ -13,6 +13,8 @@
use Wikibase\DataModel\Services\Lookup\EntityLookup;
use Wikibase\DataModel\Services\Lookup\EntityRedirectLookup;
use Wikibase\Lib\Reporting\ObservableMessageReporter;
+use Wikibase\Lib\Store\BadgeStore;
+use Wikibase\Lib\Store\BadgeTable;
use Wikibase\Lib\Store\CachingEntityRevisionLookup;
use Wikibase\Lib\Store\EntityContentDataCodec;
use Wikibase\Lib\Store\EntityInfoBuilderFactory;
@@ -315,7 +317,9 @@
$this->getUpdateScriptPath(
'AddBadgesPerSiteLink', $db->getType() )
);
- // TODO populate table
+ $updater->addPostDatabaseUpdateMaintenance(
+ 'Wikibase\Repo\Maintenance\RebuildItemsPerSite'
+ );
}
}
@@ -536,7 +540,7 @@
* @return SiteLinkStore
*/
public function newSiteLinkStore() {
- return new SiteLinkTable( 'wb_items_per_site', false );
+ return new SiteLinkTable( 'wb_items_per_site', false,
$this->newBadgeStore() );
}
/**
@@ -771,7 +775,7 @@
* @return SiteLinkConflictLookup
*/
public function getSiteLinkConflictLookup() {
- return new SiteLinkTable( 'wb_items_per_site', false );
+ return new SiteLinkTable( 'wb_items_per_site', false,
$this->newBadgeStore() );
}
/**
@@ -787,4 +791,11 @@
return $this->entityPrefetcher;
}
+ /**
+ * @return BadgeStore
+ */
+ public function newBadgeStore() {
+ return new BadgeTable( 'wb_badges_per_sitelink', false );
+ }
+
}
diff --git a/repo/maintenance/dispatchChanges.php
b/repo/maintenance/dispatchChanges.php
index 71b1316..300e6e0 100644
--- a/repo/maintenance/dispatchChanges.php
+++ b/repo/maintenance/dispatchChanges.php
@@ -7,6 +7,7 @@
use MWException;
use Wikibase\Lib\Reporting\ObservableMessageReporter;
use Wikibase\Lib\Reporting\ReportingExceptionHandler;
+use Wikibase\Lib\Store\BadgeTable;
use Wikibase\Lib\Store\SiteLinkTable;
use Wikibase\Repo\ChangeDispatcher;
use Wikibase\Repo\Notifications\JobQueueChangeNotificationSender;
@@ -229,7 +230,8 @@
|| $subscriptionLookupMode === 'subscriptions+sitelinks'
) {
$this->log( "Using sitelinks to target notifications."
);
- $siteLinkTable = new SiteLinkTable(
'wb_items_per_site', true, $repoDB );
+ $badgeTable = new BadgeTable( 'wb_badges_per_sitelink',
true );
+ $siteLinkTable = new SiteLinkTable(
'wb_items_per_site', true, $badgeTable, $repoDB );
$lookup = $siteLinkSubscriptionLookup = new
SiteLinkSubscriptionLookup( $siteLinkTable );
}
diff --git a/repo/maintenance/rebuildItemsPerSite.php
b/repo/maintenance/rebuildItemsPerSite.php
index 8773c71..0b244f1 100644
--- a/repo/maintenance/rebuildItemsPerSite.php
+++ b/repo/maintenance/rebuildItemsPerSite.php
@@ -4,6 +4,7 @@
use Maintenance;
use Wikibase\Lib\Reporting\ObservableMessageReporter;
+use Wikibase\Lib\Store\BadgeTable;
use Wikibase\Lib\Store\SiteLinkTable;
use Wikibase\Repo\Store\SQL\EntityPerPageIdPager;
use Wikibase\Repo\Store\SQL\ItemsPerSiteBuilder;
@@ -14,7 +15,7 @@
require_once $basePath . '/maintenance/Maintenance.php';
/**
- * Maintenance script for rebuilding the items_per_site table.
+ * Maintenance script for rebuilding the items_per_site and
badges_per_sitelink tables.
*
* @since 0.5
*
@@ -26,7 +27,7 @@
public function __construct() {
parent::__construct();
- $this->mDescription = 'Rebuild the items_per_site table';
+ $this->mDescription = 'Rebuild the items_per_site and
badges_per_sitelink tables';
$this->addOption( 'batch-size', "Number of rows to update per
batch (100 by default)", false, true );
}
@@ -47,7 +48,8 @@
array( $this, 'report' )
);
- $siteLinkTable = new SiteLinkTable( 'wb_items_per_site', false
);
+ $badgeTable = new BadgeTable( 'wb_badges_per_sitelink', false );
+ $siteLinkTable = new SiteLinkTable( 'wb_items_per_site', false,
$badgeTable );
// Use an uncached EntityLookup here to avoid memory leaks
$entityLookup =
WikibaseRepo::getDefaultInstance()->getEntityLookup( 'uncached' );
$entityPrefetcher =
WikibaseRepo::getDefaultInstance()->getStore()->getEntityPrefetcher();
diff --git a/repo/tests/phpunit/includes/store/StoreTest.php
b/repo/tests/phpunit/includes/store/StoreTest.php
index e46074c..001ade2 100644
--- a/repo/tests/phpunit/includes/store/StoreTest.php
+++ b/repo/tests/phpunit/includes/store/StoreTest.php
@@ -77,4 +77,12 @@
$this->assertInstanceOf( '\Wikibase\IdGenerator',
$store->newIdGenerator() );
}
+ /**
+ * @dataProvider instanceProvider
+ * @param Store $store
+ */
+ public function testNewBadgeStore( Store $store ) {
+ $this->assertInstanceOf( '\Wikibase\Lib\Store\BadgeStore',
$store->newBadgeStore() );
+ }
+
}
--
To view, visit https://gerrit.wikimedia.org/r/234960
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I48eae6239671dbbc0111cf4695a48163705580a4
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Bene <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits