Denny Vrandecic has submitted this change and it was merged. Change subject: Work on DescriptionMatchFinder ......................................................................
Work on DescriptionMatchFinder Change-Id: I0925c4e0df35481fc6e17546536453c32cd1388b --- M QueryEngine/dependencies.txt A QueryEngine/includes/QueryEngineException.php A QueryEngine/includes/QueryNotSupportedException.php M QueryEngine/includes/SQLStore/Engine/DescriptionMatchFinder.php M QueryEngine/includes/SQLStore/Engine/Engine.php M QueryEngine/tests/bootstrap.php A QueryEngine/tests/phpunit/SQLStore/Engine/DescriptionMatchFinderTest.php 7 files changed, 350 insertions(+), 24 deletions(-) Approvals: Denny Vrandecic: Looks good to me, approved jenkins-bot: Verified diff --git a/QueryEngine/dependencies.txt b/QueryEngine/dependencies.txt index dea446b..1676559 100644 --- a/QueryEngine/dependencies.txt +++ b/QueryEngine/dependencies.txt @@ -1,8 +1,10 @@ The Wikibase QueryEngine component is dependent on: -* Wikibase DataModel -* WikibaseLib * DataValues * Ask +* Wikibase DataModel +* Wikibase Database -And nothing else. \ No newline at end of file +And nothing else. + +An always up to date list can be found at tests/bootstrap.php. \ No newline at end of file diff --git a/QueryEngine/includes/QueryEngineException.php b/QueryEngine/includes/QueryEngineException.php new file mode 100644 index 0000000..0bd1e6f --- /dev/null +++ b/QueryEngine/includes/QueryEngineException.php @@ -0,0 +1,33 @@ +<?php + +namespace Wikibase\QueryEngine; + +/** + * Exception originating from the Wikibase QueryEngine component. + * + * 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.1 + * + * @file + * @ingroup WikibaseQueryStore + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + */ +class QueryEngineException extends \Exception { + +} \ No newline at end of file diff --git a/QueryEngine/includes/QueryNotSupportedException.php b/QueryEngine/includes/QueryNotSupportedException.php new file mode 100644 index 0000000..3ff2953 --- /dev/null +++ b/QueryEngine/includes/QueryNotSupportedException.php @@ -0,0 +1,48 @@ +<?php + +namespace Wikibase\QueryEngine; + +use Ask\Language\Description\Description; + +/** + * 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.1 + * + * @file + * @ingroup WikibaseQueryStore + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + */ +class QueryNotSupportedException extends QueryEngineException { + + protected $queryDescription; + + public function __construct( Description $queryDescription, $message = '', \Exception $previous = null ) { + $this->queryDescription = $queryDescription; + + parent::__construct( $message, 0, $previous ); + } + + /** + * @return Description + */ + public function getQueryDescription() { + return $this->queryDescription; + } + +} diff --git a/QueryEngine/includes/SQLStore/Engine/DescriptionMatchFinder.php b/QueryEngine/includes/SQLStore/Engine/DescriptionMatchFinder.php index 0f0783e..33dd821 100644 --- a/QueryEngine/includes/SQLStore/Engine/DescriptionMatchFinder.php +++ b/QueryEngine/includes/SQLStore/Engine/DescriptionMatchFinder.php @@ -1,8 +1,141 @@ <?php + +namespace Wikibase\QueryEngine\SQLStore\Engine; + +use Ask\Language\Description\Description; +use Ask\Language\Description\SomeProperty; +use Ask\Language\Description\ValueDescription; +use Ask\Language\Option\QueryOptions; +use Wikibase\Database\QueryInterface; +use Wikibase\EntityId; +use Wikibase\Lib\EntityIdParser; +use Wikibase\QueryEngine\QueryNotSupportedException; +use Wikibase\QueryEngine\SQLStore\DataValueHandler; +use Wikibase\QueryEngine\SQLStore\InternalEntityIdFinder; +use Wikibase\QueryEngine\SQLStore\PropertyDataValueTypeLookup; +use Wikibase\QueryEngine\SQLStore\Schema; +use Wikibase\SnakRole; + /** - * Created by JetBrains PhpStorm. - * User: j - * Date: 10/05/13 - * Time: 19:38 - * To change this template use File | Settings | File Templates. - */ \ No newline at end of file + * Simple query engine that works on top of the SQLStore. + * + * 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.1 + * + * @file + * @ingroup WikibaseSQLStore + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + */ +class DescriptionMatchFinder { + + protected $queryInterface; + protected $schema; + protected $propertyDataValueTypeLookup; + protected $idFinder; + + public function __construct( QueryInterface $queryInterface, + Schema $schema, + PropertyDataValueTypeLookup $propertyDataValueTypeLookup, + InternalEntityIdFinder $idFinder ) { + $this->queryInterface = $queryInterface; + $this->schema = $schema; + $this->propertyDataValueTypeLookup = $propertyDataValueTypeLookup; + $this->idFinder = $idFinder; + } + + /** + * Finds all entities that match the selection criteria. + * The matching entities are returned as an array of internal entity ids. + * + * @since 0.1 + * + * @param Description $description + * @param QueryOptions $options + * + * @return int[] + */ + public function findMatchingEntities( Description $description, QueryOptions $options ) { + if ( $description instanceof SomeProperty ) { + return $this->findMatchingSomeProperty( $description, $options ); + } + + throw new QueryNotSupportedException( $description ); + + // SomeProperty[AnyValue]: SELECT entity_id FROM $table WHERE property_id = $id + + // SomeProperty[ValueDescription]: + // SELECT SELECT entity_id FROM $table WHERE property_id = $property_id AND + } + + protected function findMatchingSomeProperty( SomeProperty $description, QueryOptions $options ) { + $propertyId = $description->getPropertyId(); + + if ( !( $propertyId instanceof EntityId ) ) { + // TODO: Throw + } + + $dvHandler = $this->schema->getDataValueHandler( + $this->propertyDataValueTypeLookup->getDataValueTypeForProperty( $propertyId ), + SnakRole::MAIN_SNAK + ); + + $conditions = $this->getExtraConditions( $description, $dvHandler ); + + $conditions['property_id'] = $this->getInternalId( $propertyId ); + + $selectionResult = $this->queryInterface->select( + $dvHandler->getDataValueTable()->getTableDefinition()->getName(), + array( + 'subject_id', + ), + $conditions + ); + + $entityIds = array(); + + foreach ( $selectionResult as $resultRow ) { + $entityIds[] = (int)$resultRow->subject_id; + } + + return $entityIds; + } + + protected function getInternalId( EntityId $id ) { + return $this->idFinder->getInternalIdForEntity( + $id->getEntityType(), + $id->getNumericId() + ); + } + + protected function getExtraConditions( SomeProperty $description, DataValueHandler $dvHandler ) { + $subDescription = $description->getSubDescription(); + + if ( $subDescription instanceof ValueDescription ) { + if ( $subDescription->getComparator() !== ValueDescription::COMP_EQUAL ) { + throw new QueryNotSupportedException( $description ); + } + + return $dvHandler->getWhereConditions( $subDescription->getValue() ); + } + + return array(); + } + +} + diff --git a/QueryEngine/includes/SQLStore/Engine/Engine.php b/QueryEngine/includes/SQLStore/Engine/Engine.php index 12bdece..058c584 100644 --- a/QueryEngine/includes/SQLStore/Engine/Engine.php +++ b/QueryEngine/includes/SQLStore/Engine/Engine.php @@ -73,26 +73,12 @@ * @return QueryEngineResult */ public function runQuery( Query $query ) { + // TODO $internalEntityIds = $this->findQueryMatches( $query->getDescription(), $query->getOptions() ); $result = $this->selectRequestedFields( $internalEntityIds, $query->getSelectionRequests() ); return $result; - } - - /** - * Finds all entities that match the selection criteria. - * The matching entities are returned as an array of internal entity ids. - * - * @since 0.1 - * - * @param Description $description - * @param QueryOptions $options - * - * @return int[] - */ - private function findQueryMatches( Description $description, QueryOptions $options ) { - // TODO } /** diff --git a/QueryEngine/tests/bootstrap.php b/QueryEngine/tests/bootstrap.php index 0c9795b..5cae02a 100644 --- a/QueryEngine/tests/bootstrap.php +++ b/QueryEngine/tests/bootstrap.php @@ -14,6 +14,8 @@ require_once( __DIR__ . '/../../../DataValues/DataValues/DataValues.php' ); +require_once( __DIR__ . '/../../../Ask/Ask.php' ); + require_once( __DIR__ . '/../../DataModel/DataModel.php' ); require_once( __DIR__ . '/../../Database/Database.php' ); @@ -21,3 +23,5 @@ require_once( __DIR__ . '/../QueryEngine.php' ); require_once( __DIR__ . '/testLoader.php' ); + +// If something needs to change here, a reflecting change needs to be added to ../dependencies.txt. \ No newline at end of file diff --git a/QueryEngine/tests/phpunit/SQLStore/Engine/DescriptionMatchFinderTest.php b/QueryEngine/tests/phpunit/SQLStore/Engine/DescriptionMatchFinderTest.php new file mode 100644 index 0000000..a91fb7b --- /dev/null +++ b/QueryEngine/tests/phpunit/SQLStore/Engine/DescriptionMatchFinderTest.php @@ -0,0 +1,120 @@ +<?php + +namespace Wikibase\QueryEngine\Tests\SQLStore; + +use Ask\Language\Description\AnyValue; +use Ask\Language\Description\SomeProperty; +use Ask\Language\Option\QueryOptions; +use DataValues\PropertyValue; +use Wikibase\Database\FieldDefinition; +use Wikibase\Database\TableDefinition; +use Wikibase\EntityId; +use Wikibase\QueryEngine\SQLStore\DataValueTable; +use Wikibase\QueryEngine\SQLStore\Engine\DescriptionMatchFinder; +use Wikibase\QueryEngine\SQLStore\EntityIdTransformer; + +/** + * @covers Wikibase\QueryEngine\SQLStore\Engine\DescriptionMatchFinder + * + * 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 + * + * @file + * @since 0.1 + * + * @ingroup WikibaseQueryEngineTest + * + * @group Wikibase + * @group WikibaseQueryEngine + * + * @licence GNU GPL v2+ + * @author Jeroen De Dauw < jeroended...@gmail.com > + */ +class DescriptionMatchFinderTest extends \PHPUnit_Framework_TestCase { + + public function testCanConstruct() { + $this->newInstanceWithMocks(); + $this->assertTrue( true ); + } + + protected function newInstanceWithMocks() { + return new DescriptionMatchFinder( + $this->getMock( 'Wikibase\Database\QueryInterface' ), + $this->getMockBuilder( 'Wikibase\QueryEngine\SQLStore\Schema' ) + ->disableOriginalConstructor()->getMock(), + $this->getMock( 'Wikibase\QueryEngine\SQLStore\PropertyDataValueTypeLookup' ), + $this->getMock( 'Wikibase\QueryEngine\SQLStore\InternalEntityIdFinder' ) + ); + } + + public function testFindMatchingEntitiesWithSomePropertyAnyValue() { + $description = new SomeProperty( new EntityId( 'item', 42 ), new AnyValue() ); + $queryOptions = new QueryOptions( 100, 0 ); + + $queryEngine = $this->getMock( 'Wikibase\Database\QueryInterface' ); + + $queryEngine->expects( $this->once() ) + ->method( 'select' ) + ->with( + $this->equalTo( 'tablename' ), + $this->equalTo( array( 'entity_id' ) ) + ) + ->will( $this->returnValue( array( + (object)array( 'entity_id' => 10 ) + ) ) ); + + $schema = $this->getMockBuilder( 'Wikibase\QueryEngine\SQLStore\Schema' ) + ->disableOriginalConstructor()->getMock(); + + $dvHandler = $this->getMockBuilder( 'Wikibase\QueryEngine\SQLStore\DataValueHandler' ) + ->disableOriginalConstructor()->getMock(); + + $dvHandler->expects( $this->any() ) + ->method( 'getWhereConditions' ) + ->will( $this->returnValue( array() ) ); + + $dvTable = new DataValueTable( + new TableDefinition( 'tablename', array( new FieldDefinition( 'dsfdfdsfds', FieldDefinition::TYPE_BOOLEAN ) ) ), + 'foo', + 'bar' + ); + + $dvHandler->expects( $this->any() ) + ->method( 'getDataValueTable' ) + ->will( $this->returnValue( $dvTable ) ); + + $schema->expects( $this->once() ) + ->method( 'getDataValueHandler' ) + ->will( $this->returnValue( $dvHandler ) ); + + $dvTypeLookup = $this->getMock( 'Wikibase\QueryEngine\SQLStore\PropertyDataValueTypeLookup' ); + + $idTransformer = $this->getMock( 'Wikibase\QueryEngine\SQLStore\InternalEntityIdFinder' ); + + $matchFinder = new DescriptionMatchFinder( + $queryEngine, + $schema, + $dvTypeLookup, + $idTransformer + ); + + $matchingInternalIds = $matchFinder->findMatchingEntities( $description, $queryOptions ); + + $this->assertInternalType( 'array', $matchingInternalIds ); + $this->assertContainsOnly( 'int', $matchingInternalIds ); + $this->assertEquals( array( 10 ), $matchingInternalIds ); + } + +} -- To view, visit https://gerrit.wikimedia.org/r/64050 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I0925c4e0df35481fc6e17546536453c32cd1388b Gerrit-PatchSet: 15 Gerrit-Project: mediawiki/extensions/Wikibase Gerrit-Branch: master Gerrit-Owner: Jeroen De Dauw <jeroended...@gmail.com> Gerrit-Reviewer: Denny Vrandecic <denny.vrande...@wikimedia.de> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits