jenkins-bot has submitted this change and it was merged.
Change subject: (bug 49742) introducing PropertyInfoTable.
......................................................................
(bug 49742) introducing PropertyInfoTable.
This is the first over several changes that introduce a system for
fast access to property meta-info.
Change-Id: I197360a45f8ce1aefe29460c19142f2dfbee1525
---
M lib/WikibaseLib.classes.php
A lib/includes/store/PropertyInfoStore.php
A lib/includes/store/sql/PropertyInfoTable.php
A lib/includes/store/sql/wb_property_info.sql
A lib/includes/store/sql/wb_property_info.sqlite.sql
A lib/tests/phpunit/store/PropertyInfoStoreTestHelper.php
A lib/tests/phpunit/store/PropertyInfoTableTest.php
M repo/Wikibase.classes.php
M repo/includes/content/PropertyContent.php
M repo/includes/store/Store.php
M repo/includes/store/sql/SqlStore.php
A repo/includes/updates/PropertyInfoDeletion.php
A repo/includes/updates/PropertyInfoUpdate.php
13 files changed, 827 insertions(+), 25 deletions(-)
Approvals:
Aude: Looks good to me, approved
jenkins-bot: Verified
diff --git a/lib/WikibaseLib.classes.php b/lib/WikibaseLib.classes.php
index cd1d7f0..7098d8a 100644
--- a/lib/WikibaseLib.classes.php
+++ b/lib/WikibaseLib.classes.php
@@ -133,12 +133,15 @@
'Wikibase\TermCombinationMatchFinder' =>
'includes/store/TermCombinationMatchFinder.php',
'Wikibase\TermMatchScoreCalculator' =>
'includes/store/TermMatchScoreCalculator.php',
'Wikibase\TermPropertyLabelResolver' =>
'includes/store/TermPropertyLabelResolver.php',
- 'Wikibase\TermSqlIndex' =>
'includes/store/sql/TermSqlIndex.php',
+
+ 'Wikibase\PropertyInfoStore' =>
'includes/store/PropertyInfoStore.php',
// includes/store/sql
'Wikibase\CachingEntityLoader' =>
'includes/store/sql/CachingEntityLoader.php',
'Wikibase\SiteLinkTable' =>
'includes/store/sql/SiteLinkTable.php',
'Wikibase\WikiPageEntityLookup' =>
'includes/store/sql/WikiPageEntityLookup.php',
+ 'Wikibase\TermSqlIndex' =>
'includes/store/sql/TermSqlIndex.php',
+ 'Wikibase\PropertyInfoTable' =>
'includes/store/sql/PropertyInfoTable.php',
// includes/util
'Wikibase\HttpAcceptNegotiator' =>
'includes/util/HttpAcceptNegotiator.php',
@@ -175,6 +178,8 @@
'Wikibase\Test\EntityLookupTest' =>
'tests/phpunit/EntityLookupTest.php',
'Wikibase\Test\MockChunkAccess' =>
'tests/phpunit/store/MockChunkAccess.php',
'Wikibase\Test\TermIndexTest' =>
'tests/phpunit/store/TermIndexTest.php',
+
+ 'Wikibase\Test\PropertyInfoStoreTestHelper' =>
'tests/phpunit/store/PropertyInfoStoreTestHelper.php',
);
return $classes;
diff --git a/lib/includes/store/PropertyInfoStore.php
b/lib/includes/store/PropertyInfoStore.php
new file mode 100644
index 0000000..04f27ed
--- /dev/null
+++ b/lib/includes/store/PropertyInfoStore.php
@@ -0,0 +1,95 @@
+<?php
+ /**
+ *
+ * Copyright © 26.06.13 by the authors listed below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @license GPL 2+
+ * @file
+ * @ingroup WikibaseLib
+ *
+ * @author Daniel Kinzler
+ */
+
+
+namespace Wikibase;
+
+
+use DBError;
+
+interface PropertyInfoStore {
+
+ /**
+ * Key to use in the info array for the property's data type ID.
+ */
+ const KEY_DATA_TYPE = 'type';
+
+ /**
+ * Returns the property info for the given property ID.
+ *
+ * @note: Even if the property is known to exist, this method may not
return
+ * an info array, or the info array may not contain all well
known fields.
+ *
+ * @param EntityId $propertyId
+ *
+ * @return array|null
+ *
+ * @throws StorageException
+ * @throws DBError
+ */
+ public function getPropertyInfo( EntityId $propertyId );
+
+ /**
+ * Returns the property info for all properties.
+ * The caller is responsible for avoiding calling this if there are too
many properties.
+ *
+ * @note: There is no guarantee that an info array is returned for all
existing properties.
+ * Also, it is not guaranteed that the ionfo arrays will contain
all well known fields.
+ *
+ * @return array[] An associative array mapping property IDs to info
arrays.
+ *
+ * @throws StorageException
+ * @throws \DBError
+ */
+ public function getAllPropertyInfo();
+
+ /**
+ * Update the info for the given property.
+ *
+ * @note: All well known fields MUST be set in $info.
+ *
+ * @param EntityId $propertyId
+ * @param array $info
+ *
+ * @throws StorageException
+ * @throws DBError
+ */
+ public function setPropertyInfo( EntityId $propertyId, array $info );
+
+ /**
+ * Remove the info entry for the given property.
+ *
+ * @param EntityId $propertyId
+ *
+ * @return bool true iff something was deleted
+ *
+ * @throws StorageException
+ * @throws DBError
+ */
+ public function removePropertyInfo( EntityId $propertyId );
+
+}
\ No newline at end of file
diff --git a/lib/includes/store/sql/PropertyInfoTable.php
b/lib/includes/store/sql/PropertyInfoTable.php
new file mode 100644
index 0000000..8c1c3e0
--- /dev/null
+++ b/lib/includes/store/sql/PropertyInfoTable.php
@@ -0,0 +1,270 @@
+<?php
+ /**
+ *
+ * Copyright © 26.06.13 by the authors listed below.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @license GPL 2+
+ * @file
+ * @ingroup WikibaseLib
+ *
+ * @author Daniel Kinzler
+ */
+
+
+namespace Wikibase;
+
+
+use DBError;
+
+/**
+ * Class PropertyInfoTable implemnents PropertyInfoStore on top of an SQL
table.
+ *
+ * @since 0.4
+ *
+ * @package Wikibase
+ */
+class PropertyInfoTable extends \DBAccessBase implements PropertyInfoStore {
+
+ /**
+ * @var string
+ */
+ protected $table;
+
+ /**
+ * @var bool
+ */
+ protected $readonly;
+
+ /**
+ * @param string $table The table to use
+ * @param bool $readonly Whether the table can be modified.
+ * @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.
+ */
+ public function __construct( $readonly, $wiki = false ) {
+ assert( is_bool( $readonly ) );
+ assert( is_string( $wiki ) || $wiki === false );
+
+ $this->table = 'wb_property_info';
+ $this->readonly = $readonly;
+ $this->wiki = $wiki;
+ }
+
+ /**
+ * Register the updates needed for creating the appropriate table(s).
+ *
+ * @param \DatabaseUpdater $updater
+ */
+ public static function registerDatabaseUpdates( \DatabaseUpdater
$updater ) {
+ $table = 'wb_property_info';
+
+ if ( !$updater->tableExists( $table ) ) {
+ $type = $updater->getDB()->getType();
+ $fileBase = __DIR__ . '/' . $table;
+
+ $file = $fileBase . '.' . $type . '.sql';
+ if ( !file_exists( $file ) ) {
+ $file = $fileBase . '.sql';
+ }
+
+ $updater->addExtensionTable( $table, $file );
+ }
+ }
+
+ /**
+ * @see PropertyInfoStore::getPropertyInfo
+ *
+ * @param EntityId $propertyId
+ *
+ * @return array|null
+ *
+ * @throws \InvalidArgumentException
+ * @throws \DBError
+ */
+ public function getPropertyInfo( EntityId $propertyId ) {
+ if ( $propertyId->getEntityType() !== Property::ENTITY_TYPE ) {
+ throw new \InvalidArgumentException( 'Property ID
expected! ' . $propertyId );
+ }
+
+ wfProfileIn( __METHOD__ );
+
+ $dbw = $this->getConnection( DB_SLAVE );
+
+ $res = $dbw->selectField(
+ $this->table,
+ 'pi_info',
+ array( 'pi_property_id' => $propertyId->getNumericId()
),
+ __METHOD__
+ );
+
+ $this->releaseConnection( $dbw );
+
+ if ( $res === false ) {
+ $info = null;
+ } else {
+ $info = json_decode( $res, true );
+
+ if ( $info === null ) {
+ wfLogWarning( "failed to decode property info
blob for " . $propertyId . ": " . $res );
+ }
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $info;
+ }
+
+ /**
+ * @see PropertyInfoStore::getAllPropertyInfo
+ *
+ * @return array[]
+ *
+ * @throws \DBError
+ */
+ public function getAllPropertyInfo() {
+ wfProfileIn( __METHOD__ );
+ $dbw = $this->getConnection( DB_SLAVE );
+
+ $res = $dbw->select(
+ $this->table,
+ array( 'pi_property_id', 'pi_info' ),
+ array(),
+ __METHOD__
+ );
+
+ $infos = array();
+
+ while ( $row = $res->fetchObject() ) {
+ $info = json_decode( $row->pi_info );
+
+ if ( $info === null ) {
+ wfLogWarning( "failed to decode property info
blob for property "
+ . $row->pi_property_id . ": " .
$row->pi_info );
+ continue;
+ }
+
+ $infos[$row->pi_property_id] = $info;
+ }
+
+ $this->releaseConnection( $dbw );
+
+ wfProfileOut( __METHOD__ );
+ return $infos;
+ }
+
+ /**
+ * @see PropertyInfoStore::setPropertyInfo
+ *
+ * @param EntityId $propertyId
+ * @param array $info
+ *
+ * @throws \DBError
+ * @throws \InvalidArgumentException
+ */
+ public function setPropertyInfo( EntityId $propertyId, array $info ) {
+ if ( $propertyId->getEntityType() !== Property::ENTITY_TYPE ) {
+ throw new \InvalidArgumentException( 'Property ID
expected! ' . $propertyId );
+ }
+
+ if ( $this->readonly ) {
+ throw new DBError( 'Cannot write when in readonly mode'
);
+ }
+
+ if ( !isset( $info[ PropertyInfoStore::KEY_DATA_TYPE ]) ) {
+ throw new \InvalidArgumentException( 'Missing required
info field: ' . PropertyInfoStore::KEY_DATA_TYPE );
+ }
+
+ wfProfileIn( __METHOD__ );
+
+ $type = $info[ PropertyInfoStore::KEY_DATA_TYPE ];
+ $json = json_encode( $info );
+
+ $dbw = $this->getConnection( DB_MASTER );
+
+ $dbw->replace(
+ $this->table,
+ array( 'pi_property_id' ),
+ array(
+ 'pi_property_id' => $propertyId->getNumericId(),
+ 'pi_info' => $json,
+ 'pi_type' => $type,
+ ),
+ __METHOD__
+ );
+
+ $this->releaseConnection( $dbw );
+
+ wfProfileOut( __METHOD__ );
+ }
+
+ /**
+ * @see PropertyInfoStore::removePropertyInfo
+ *
+ * @param EntityId $propertyId
+ *
+ * @throws DBError
+ * @throws \InvalidArgumentException
+ * @return bool
+ */
+ public function removePropertyInfo( EntityId $propertyId ) {
+ if ( $propertyId->getEntityType() !== Property::ENTITY_TYPE ) {
+ throw new \InvalidArgumentException( 'Property ID
expected! ' . $propertyId );
+ }
+
+ if ( $this->readonly ) {
+ throw new DBError( 'Cannot write when in readonly mode'
);
+ }
+
+ wfProfileIn( __METHOD__ );
+ $dbw = $this->getConnection( DB_MASTER );
+
+ $dbw->delete(
+ $this->table,
+ array( 'pi_property_id' => $propertyId->getNumericId()
),
+ __METHOD__
+ );
+
+ $c = $dbw->affectedRows();
+ $this->releaseConnection( $dbw );
+
+ wfProfileOut( __METHOD__ );
+ return $c > 0 ? true : false;
+ }
+
+ /**
+ * Returns a database connection suitable for writing to the database
that
+ * contains the property info table.
+ *
+ * This is for use for closely related classes that want to operate
directly
+ * on the database table.
+ */
+ public function getWriteConnection() {
+ return $this->getConnection( DB_MASTER );
+ }
+
+ /**
+ * Returns the (logical) name of the database table that contains the
property info.
+ *
+ * This is for use for closely related classes that want to operate
directly
+ * on the database table.
+ *
+ * @return string
+ */
+ public function getTableName() {
+ return $this->table;
+ }
+}
\ No newline at end of file
diff --git a/lib/includes/store/sql/wb_property_info.sql
b/lib/includes/store/sql/wb_property_info.sql
new file mode 100644
index 0000000..82a1dc6
--- /dev/null
+++ b/lib/includes/store/sql/wb_property_info.sql
@@ -0,0 +1,10 @@
+-- property info table --
+
+CREATE TABLE IF NOT EXISTS /*_*/wb_property_info (
+ pi_property_id INT unsigned NOT NULL,
+ pi_type VARBINARY(32) NOT NULL,
+ pi_info BLOB NOT NULL,
+ PRIMARY KEY ( pi_property_id ),
+ INDEX pi_type ( pi_type )
+) /*$wgDBTableOptions*/;
+
diff --git a/lib/includes/store/sql/wb_property_info.sqlite.sql
b/lib/includes/store/sql/wb_property_info.sqlite.sql
new file mode 100644
index 0000000..5905930
--- /dev/null
+++ b/lib/includes/store/sql/wb_property_info.sqlite.sql
@@ -0,0 +1,10 @@
+-- property info table --
+
+CREATE TABLE IF NOT EXISTS /*_*/wb_property_info (
+ pi_property_id INT unsigned NOT NULL,
+ pi_type VARBINARY(32) NOT NULL,
+ pi_info BLOB NOT NULL
+) /*$wgDBTableOptions*/;
+
+CREATE INDEX IF NOT EXISTS /*i*/pi_info ON /*_*/wb_property_info (pi_info);
+
diff --git a/lib/tests/phpunit/store/PropertyInfoStoreTestHelper.php
b/lib/tests/phpunit/store/PropertyInfoStoreTestHelper.php
new file mode 100644
index 0000000..757ae34
--- /dev/null
+++ b/lib/tests/phpunit/store/PropertyInfoStoreTestHelper.php
@@ -0,0 +1,150 @@
+<?php
+
+namespace Wikibase\Test;
+
+use Wikibase\EntityId;
+use Wikibase\Property;
+use Wikibase\PropertyInfoStore;
+
+use Wikibase\SiteLinkTable;
+use Wikibase\Item;
+
+/**
+ * Helper for testing PropertyInfoStore implementations
+ *
+ * @file
+ * @since 0.4
+ *
+ * @ingroup WikibaseLib
+ * @ingroup Test
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class PropertyInfoStoreTestHelper {
+
+ /**
+ * @var \PHPUnit_Framework_TestCase
+ */
+ protected $test;
+
+ public function __construct( \PHPUnit_Framework_TestCase $testCase,
$storeBuilder ) {
+ $this->test = $testCase;
+ $this->storeBuilder = $storeBuilder;
+ }
+
+ protected function newPropertyInfoStore() {
+ return call_user_func( $this->storeBuilder );
+ }
+
+ public static function provideSetPropertyInfo() {
+ return array(
+ array( // #0: ok
+ new EntityId( Property::ENTITY_TYPE, 23 ),
+ array( PropertyInfoStore::KEY_DATA_TYPE =>
'string' ),
+ null
+ ),
+ array( // #1: not a property
+ new EntityId( Item::ENTITY_TYPE, 23 ),
+ array( PropertyInfoStore::KEY_DATA_TYPE =>
'string' ),
+ 'InvalidArgumentException'
+ ),
+ array( // #2: missing required field
+ new EntityId( Property::ENTITY_TYPE, 23 ),
+ array(),
+ 'InvalidArgumentException'
+ ),
+ array( // #3: extra data
+ new EntityId( Property::ENTITY_TYPE, 23 ),
+ array( PropertyInfoStore::KEY_DATA_TYPE =>
'string', 'foo' => 'bar' ),
+ null
+ ),
+ );
+ }
+
+ public function testSetPropertyInfo( EntityId $id, array $info,
$expectedException ) {
+ if ( $expectedException !== null ) {
+ $this->test->setExpectedException( $expectedException );
+ }
+
+ $table = $this->newPropertyInfoStore();
+
+ $table->setPropertyInfo( $id, $info );
+ $res = $table->getPropertyInfo( $id );
+
+ $this->test->assertEquals( $info, $res );
+ }
+
+ public function testGetPropertyInfo() {
+ $table = $this->newPropertyInfoStore();
+ $p23 = new EntityId( Property::ENTITY_TYPE, 23 );
+ $q23 = new EntityId( Item::ENTITY_TYPE, 23 );
+ $p42 = new EntityId( Property::ENTITY_TYPE, 42 );
+ $info23 = array( PropertyInfoStore::KEY_DATA_TYPE => 'string' );
+ $info42 = array( PropertyInfoStore::KEY_DATA_TYPE => 'string',
'foo' => 'bar' );
+
+ $this->test->assertNull( $table->getPropertyInfo( $p23 ), "not
set yet, should be null" );
+
+ $table->setPropertyInfo( $p23, $info23 );
+
+ $this->test->assertNull( $table->getPropertyInfo( $p42 ), "not
set yet, should be null" );
+ $this->test->assertEquals( $info23, $table->getPropertyInfo(
$p23 ), "should return what was set" );
+
+ $table->setPropertyInfo( $p42, $info42 );
+
+ $this->test->assertEquals( $info42, $table->getPropertyInfo(
$p42 ), "should return what was set" );
+ $this->test->assertEquals( $info23, $table->getPropertyInfo(
$p23 ), "should return what was set" );
+
+ $this->test->setExpectedException( 'InvalidArgumentException' );
+ $table->getPropertyInfo( $q23 );
+ }
+
+ public function testGetAllPropertyInfo() {
+ $table = $this->newPropertyInfoStore();
+ $p23 = new EntityId( Property::ENTITY_TYPE, 23 );
+ $p42 = new EntityId( Property::ENTITY_TYPE, 42 );
+ $info23 = array( PropertyInfoStore::KEY_DATA_TYPE => 'string' );
+ $info42 = array( PropertyInfoStore::KEY_DATA_TYPE => 'string',
'foo' => 'bar' );
+
+ $this->test->assertCount( 0, $table->getAllPropertyInfo(),
"should initially be empty" );
+
+ $table->setPropertyInfo( $p23, $info23 );
+ $this->test->assertCount( 1, $table->getAllPropertyInfo(),
"after adding one property" );
+
+ $table->setPropertyInfo( $p42, $info42 );
+ $this->test->assertCount( 2, $table->getAllPropertyInfo(),
"after adding the second property" );
+
+ $table->removePropertyInfo( $p23 );
+ $this->test->assertCount( 1, $table->getAllPropertyInfo(),
"after removing one property" );
+ }
+
+ public function testRemovePropertyInfo() {
+ $table = $this->newPropertyInfoStore();
+ $p23 = new EntityId( Property::ENTITY_TYPE, 23 );
+ $q23 = new EntityId( Item::ENTITY_TYPE, 23 );
+ $p42 = new EntityId( Property::ENTITY_TYPE, 42 );
+ $info23 = array( PropertyInfoStore::KEY_DATA_TYPE => 'string' );
+
+ $table->setPropertyInfo( $p23, $info23 );
+
+ $this->test->assertFalse( $table->removePropertyInfo( $p42 ),
"deleted unknown" );
+ $this->test->assertTrue( $table->removePropertyInfo( $p23 ),
"deleted something" );
+ $this->test->assertFalse( $table->removePropertyInfo( $p23 ),
"deleted nothing" );
+
+ $this->test->setExpectedException( 'InvalidArgumentException' );
+ $table->removePropertyInfo( $q23 );
+
+ }
+
+ public function testPropertyInfoPersistance() {
+ $p23 = new EntityId( Property::ENTITY_TYPE, 23 );
+ $info23 = array( PropertyInfoStore::KEY_DATA_TYPE => 'string' );
+
+ $table1 = $this->newPropertyInfoStore();
+ $table1->setPropertyInfo( $p23, $info23 );
+
+ $table2 = $this->newPropertyInfoStore();
+ $this->test->assertEquals( $info23, $table2->getPropertyInfo(
$p23 ), "should return persisted info" );
+ }
+
+}
diff --git a/lib/tests/phpunit/store/PropertyInfoTableTest.php
b/lib/tests/phpunit/store/PropertyInfoTableTest.php
new file mode 100644
index 0000000..a8856a9
--- /dev/null
+++ b/lib/tests/phpunit/store/PropertyInfoTableTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Wikibase\Test;
+
+use Wikibase\EntityId;
+use Wikibase\Property;
+use Wikibase\PropertyInfoTable;
+use Wikibase\Settings;
+use Wikibase\Item;
+
+/**
+ * @covers Wikibase\PropertyInfoTable
+ *
+ * @file
+ * @since 0.4
+ *
+ * @ingroup WikibaseLib
+ * @ingroup Test
+ *
+ * @group Wikibase
+ * @group WikibaseLib
+ * @group WikibaseStore
+ * @group WikibasePropertyInfo
+ * @group Database
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class PropertyInfoTableTest extends \MediaWikiTestCase {
+
+ /**
+ * @var PropertyInfoStoreTestHelper
+ */
+ public $helper;
+
+ public function __construct( $name = null, $data = array(), $dataName =
'' ) {
+ parent::__construct( $name, $data, $dataName );
+
+ $this->helper = new PropertyInfoStoreTestHelper( $this, array(
$this, 'newPropertyInfoTable' ) );
+ }
+
+ public function setUp() {
+ parent::setUp();
+
+ if ( !defined( 'WB_VERSION' ) ) {
+ $this->markTestSkipped( "Skipping because
WikibaseClient doesn't have a local wb_property_info table." );
+ }
+
+ //FIXME: usePropertyInfoTable is defined in a follow-up
+ //if ( !Settings::get( 'usePropertyInfoTable' ) ) {
+ // $this->markTestSkipped( "Skipping because
wb_property_info isn't configured." );
+ //}
+
+ $this->tablesUsed[] = 'wb_property_info';
+ }
+
+ public function newPropertyInfoTable() {
+ return new PropertyInfoTable( false );
+ }
+
+ public function provideSetPropertyInfo() {
+ return $this->helper->provideSetPropertyInfo();
+ }
+
+ /**
+ * @dataProvider provideSetPropertyInfo
+ */
+ public function testSetPropertyInfo( EntityId $id, array $info,
$expectedException ) {
+ $this->helper->testSetPropertyInfo( $id, $info,
$expectedException );
+ }
+
+ public function testGetPropertyInfo() {
+ $this->helper->testGetPropertyInfo();
+ }
+
+ public function testGetAllPropertyInfo() {
+ $this->helper->testGetAllPropertyInfo();
+ }
+
+ public function testRemovePropertyInfo() {
+ $this->helper->testRemovePropertyInfo();
+ }
+
+ public function testPropertyInfoPersistance() {
+ $this->helper->testPropertyInfoPersistance();
+ }
+
+}
diff --git a/repo/Wikibase.classes.php b/repo/Wikibase.classes.php
index adfa41e..63f62e1 100644
--- a/repo/Wikibase.classes.php
+++ b/repo/Wikibase.classes.php
@@ -149,6 +149,8 @@
'Wikibase\EntityModificationUpdate' =>
'includes/updates/EntityModificationUpdate.php',
'Wikibase\ItemDeletionUpdate' =>
'includes/updates/ItemDeletionUpdate.php',
'Wikibase\ItemModificationUpdate' =>
'includes/updates/ItemModificationUpdate.php',
+ 'Wikibase\PropertyInfoUpdate' =>
'includes/updates/PropertyInfoUpdate.php',
+ 'Wikibase\PropertyInfoDeletion' =>
'includes/updates/PropertyInfoDeletion.php',
// includes/Validators
'Wikibase\Validators\SnakValidator' =>
'includes/Validators/SnakValidator.php',
diff --git a/repo/includes/content/PropertyContent.php
b/repo/includes/content/PropertyContent.php
index 7113dee..48f495c 100644
--- a/repo/includes/content/PropertyContent.php
+++ b/repo/includes/content/PropertyContent.php
@@ -3,6 +3,7 @@
namespace Wikibase;
use Title, Content, ParserOptions, ParserOutput, WikiPage, User, Status,
DataUpdate;
use \ValueFormatters\ValueFormatterFactory;
+use Wikibase\Repo\WikibaseRepo;
/**
* Content object for articles representing Wikibase properties.
@@ -159,9 +160,43 @@
* @return DataUpdate[]
*/
public function getDeletionUpdates( \WikiPage $page, \ParserOutput
$parserOutput = null ) {
+ //XXX: access to services should be done via the ContentHandler.
+ $infoStore =
WikibaseRepo::getDefaultInstance()->getStore()->getPropertyInfoStore();
+
return array_merge(
parent::getDeletionUpdates( $page, $parserOutput ),
- array( new EntityDeletionUpdate( $this ) )
+ array(
+ new EntityDeletionUpdate( $this ),
+ new PropertyInfoDeletion(
$this->getProperty()->getId(), $infoStore ),
+ )
+ );
+ }
+
+ /**
+ * @see ContentHandler::getSecondaryDataUpdates
+ *
+ * @since 0.1
+ *
+ * @param Title $title
+ * @param Content|null $old
+ * @param boolean $recursive
+ *
+ * @param null|ParserOutput $parserOutput
+ *
+ * @return DataUpdate[]
+ */
+ public function getSecondaryDataUpdates( Title $title, Content $old =
null,
+ $recursive = false, ParserOutput $parserOutput = null ) {
+
+ //XXX: access to services should be done via the ContentHandler.
+ $infoStore =
WikibaseRepo::getDefaultInstance()->getStore()->getPropertyInfoStore();
+
+ return array_merge(
+ parent::getSecondaryDataUpdates( $title, $old,
$recursive, $parserOutput ),
+ array(
+ new EntityModificationUpdate( $this ),
+ new PropertyInfoUpdate( $this->getProperty(),
$infoStore ),
+ )
);
}
@@ -182,28 +217,6 @@
$propertyView = new PropertyView( $valueFormatters );
return $propertyView->getParserOutput( $this, $options,
$generateHtml );
- }
-
- /**
- * @see ContentHandler::getSecondaryDataUpdates
- *
- * @since 0.1
- *
- * @param Title $title
- * @param Content|null $old
- * @param boolean $recursive
- *
- * @param null|ParserOutput $parserOutput
- *
- * @return DataUpdate[]
- */
- public function getSecondaryDataUpdates( Title $title, Content $old =
null,
- $recursive = false, ParserOutput $parserOutput = null ) {
-
- return array_merge(
- parent::getSecondaryDataUpdates( $title, $old,
$recursive, $parserOutput ),
- array( new EntityModificationUpdate( $this ) )
- );
}
}
diff --git a/repo/includes/store/Store.php b/repo/includes/store/Store.php
index b61037a..1f3bf61 100644
--- a/repo/includes/store/Store.php
+++ b/repo/includes/store/Store.php
@@ -95,4 +95,13 @@
*/
public function getEntityLookup();
+ /**
+ * Returns an PropertyInfoStore
+ *
+ * @since 0.4
+ *
+ * @return PropertyInfoStore
+ */
+ public function getPropertyInfoStore();
+
}
diff --git a/repo/includes/store/sql/SqlStore.php
b/repo/includes/store/sql/SqlStore.php
index 8869547..7f1c49e 100644
--- a/repo/includes/store/sql/SqlStore.php
+++ b/repo/includes/store/sql/SqlStore.php
@@ -37,6 +37,11 @@
private $entityLookup = null;
/**
+ * @var PropertyInfoTable
+ */
+ private $propertyInfoTable = null;
+
+ /**
* @var TermIndex
*/
private $termIndex = null;
@@ -178,8 +183,10 @@
}
}
else {
- wfWarn( "Database type '$type' is not supported by
Wikibase Client." );
+ wfWarn( "Database type '$type' is not supported by
Wikibase." );
}
+
+ PropertyInfoTable::registerDatabaseUpdates( $updater );
}
/**
@@ -243,4 +250,31 @@
return new CachingEntityLoader( $lookup );
}
+ /**
+ * @see Store::getPropertyInfoStore
+ *
+ * @since 0.4
+ *
+ * @return PropertyInfoStore
+ */
+ public function getPropertyInfoStore() {
+ if ( !$this->propertyInfoTable ) {
+ $this->propertyInfoTable =
$this->newPropertyInfoTable();
+ }
+
+ return $this->propertyInfoTable;
+ }
+
+ /**
+ * Creates a new PropertyInfoTable
+ *
+ * @return PropertyInfoTable
+ */
+ protected function newPropertyInfoTable() {
+ //FIXME: use usePropertyInfoTable defined in follow-up
+ //FIXME: use CachingPropertyInfoStore defined in follow-up
+ $table = new PropertyInfoTable( false );
+ return $table;
+ }
+
}
diff --git a/repo/includes/updates/PropertyInfoDeletion.php
b/repo/includes/updates/PropertyInfoDeletion.php
new file mode 100644
index 0000000..63e98cb
--- /dev/null
+++ b/repo/includes/updates/PropertyInfoDeletion.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace Wikibase;
+
+/**
+ * Removes a property info entry.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.4
+ *
+ * @file
+ * @ingroup WikibaseRepo
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class PropertyInfoDeletion extends \DataUpdate {
+
+ /**
+ * Constructor.
+ *
+ * @param EntityId $id
+ * @param PropertyInfoStore $store
+ */
+ public function __construct( EntityId $id, PropertyInfoStore $store ) {
+ $this->propertyId = $id;
+ $this->store = $store;
+ }
+
+ /**
+ * Perform the actual work
+ */
+ function doUpdate() {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ': deleting property info
for ' . $this->propertyId );
+ $this->store->removePropertyInfo( $this->propertyId );
+ }
+}
diff --git a/repo/includes/updates/PropertyInfoUpdate.php
b/repo/includes/updates/PropertyInfoUpdate.php
new file mode 100644
index 0000000..5d456c8
--- /dev/null
+++ b/repo/includes/updates/PropertyInfoUpdate.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace Wikibase;
+
+/**
+ * Updates property info entries.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.4
+ *
+ * @file
+ * @ingroup WikibaseRepo
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class PropertyInfoUpdate extends \DataUpdate {
+
+ /**
+ * Constructor.
+ *
+ * @param Property $property
+ * @param PropertyInfoStore $store
+ */
+ public function __construct( Property $property, PropertyInfoStore
$store ) {
+ $this->property = $property;
+ $this->store = $store;
+ }
+
+ /**
+ * Perform the actual work
+ */
+ function doUpdate() {
+ //XXX: Where to encode the knowledge about how to extract an
info array from a Property object?
+ // Should we have a PropertyInfo class? Or can we put this
into the Property class?
+
+ $info = array(
+ PropertyInfoStore::KEY_DATA_TYPE =>
$this->property->getDataTypeId()
+ );
+
+ $id = $this->property->getId();
+ $oldInfo = $this->store->getPropertyInfo( $id );
+
+ if ( $oldInfo !== $info ) {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ': property info
for ' . $id . ' changed, updating' );
+ $this->store->setPropertyInfo( $id, $info );
+ } else {
+ wfDebugLog( __CLASS__, __FUNCTION__ . ': property info
for ' . $id . ' didn\'t change, skipping update' );
+ }
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/71333
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I197360a45f8ce1aefe29460c19142f2dfbee1525
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Aude <[email protected]>
Gerrit-Reviewer: Daniel Werner <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits