Skip to content

Commit 1e5c364

Browse files
dima koushhajenkins-bot
authored andcommitted
GQL: Enable fetching statements with references
Bug: T404834 Change-Id: Id7c460946f6c1fd156b2eaec9a36ab963e8e1284
1 parent aa35dfc commit 1e5c364

File tree

8 files changed

+166
-1
lines changed

8 files changed

+166
-1
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php declare( strict_types = 1 );
2+
3+
namespace Wikibase\Repo\Domains\Reuse\Domain\Model;
4+
5+
/**
6+
* @license GPL-2.0-or-later
7+
*/
8+
class Reference {
9+
/**
10+
* @param PropertyValuePair[] $parts
11+
*/
12+
public function __construct( public readonly array $parts ) {
13+
}
14+
}

repo/domains/reuse/src/Domain/Model/Statement.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,20 @@
99
*/
1010
class Statement {
1111

12+
/**
13+
* @param StatementGuid $id
14+
* @param Rank $rank
15+
* @param Qualifiers $qualifiers
16+
* @param Reference[] $references
17+
* @param PredicateProperty $property
18+
* @param Value|null $value
19+
* @param ValueType $valueType
20+
*/
1221
public function __construct(
1322
public readonly StatementGuid $id,
1423
public readonly Rank $rank,
1524
public readonly Qualifiers $qualifiers,
25+
public readonly array $references,
1626
public readonly PredicateProperty $property,
1727
public readonly ?Value $value,
1828
public readonly ValueType $valueType

repo/domains/reuse/src/Domain/Services/StatementReadModelConverter.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Wikibase\Repo\Domains\Reuse\Domain\Services;
44

55
use InvalidArgumentException;
6+
use Wikibase\DataModel\Reference as DataModelReference;
7+
use Wikibase\DataModel\ReferenceList;
68
use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
79
use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookupException;
810
use Wikibase\DataModel\Services\Statement\StatementGuidParser;
@@ -14,6 +16,7 @@
1416
use Wikibase\Repo\Domains\Reuse\Domain\Model\PropertyValuePair;
1517
use Wikibase\Repo\Domains\Reuse\Domain\Model\Qualifiers;
1618
use Wikibase\Repo\Domains\Reuse\Domain\Model\Rank;
19+
use Wikibase\Repo\Domains\Reuse\Domain\Model\Reference;
1720
use Wikibase\Repo\Domains\Reuse\Domain\Model\Statement;
1821
use Wikibase\Repo\Domains\Reuse\Domain\Model\Value;
1922
use Wikibase\Repo\Domains\Reuse\Domain\Model\ValueType;
@@ -41,6 +44,7 @@ public function convert( DataModelStatement $inputStatement ): Statement {
4144
$this->statementIdParser->parse( $guid ),
4245
new Rank( $inputStatement->getRank() ),
4346
$this->convertQualifiers( $inputStatement->getQualifiers() ),
47+
$this->convertReferences( $inputStatement->getReferences() ),
4448
$mainPropertyValuePair->property,
4549
$mainPropertyValuePair->value,
4650
ValueType::fromString( $inputStatement->getMainSnak()->getType() ),
@@ -56,6 +60,23 @@ private function convertQualifiers( SnakList $qualifiers ): Qualifiers {
5660
);
5761
}
5862

63+
/**
64+
* @param ReferenceList $references
65+
*
66+
* @return Reference[]
67+
*/
68+
private function convertReferences( ReferenceList $references ): array {
69+
return array_map(
70+
fn( DataModelReference $ref ) => new Reference(
71+
array_map(
72+
$this->convertSnakToPropertyValuePair( ... ),
73+
iterator_to_array( $ref->getSnaks() )
74+
)
75+
),
76+
iterator_to_array( $references )
77+
);
78+
}
79+
5980
private function convertSnakToPropertyValuePair( Snak $snak ): PropertyValuePair {
6081
try {
6182
$dataType = $this->dataTypeLookup->getDataTypeIdForProperty( $snak->getPropertyId() );

repo/domains/reuse/src/Infrastructure/GraphQL/Schema/Schema.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Wikibase\DataModel\Entity\NumericPropertyId;
1010
use Wikibase\DataModel\Statement\Statement as StatementWriteModel;
1111
use Wikibase\Repo\Domains\Reuse\Domain\Model\Item;
12+
use Wikibase\Repo\Domains\Reuse\Domain\Model\Reference;
1213
use Wikibase\Repo\Domains\Reuse\Domain\Model\Statement;
1314
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Resolvers\ItemResolver;
1415

@@ -128,6 +129,11 @@ private function statementType(): ObjectType {
128129
'resolve' => fn( Statement $statement, $args ) => $statement->qualifiers
129130
->getQualifiersByPropertyId( new NumericPropertyId( $args[ 'propertyId' ] ) ),
130131
],
132+
'references' => [
133+
// @phan-suppress-next-line PhanUndeclaredInvokeInCallable
134+
'type' => Type::nonNull( Type::listOf( $this->referenceType() ) ),
135+
'resolve' => fn( Statement $statement ) => $statement->references,
136+
],
131137
'property' => [
132138
'type' => Type::nonNull( $this->predicatePropertyType ),
133139
'resolve' => fn( Statement $statement ) => $statement->property,
@@ -162,4 +168,17 @@ private function rankType(): EnumType {
162168
] );
163169
}
164170

171+
private function referenceType(): ObjectType {
172+
return new ObjectType( [
173+
'name' => 'Reference',
174+
'fields' => [
175+
'parts' => [
176+
// @phan-suppress-next-line PhanUndeclaredInvokeInCallable
177+
'type' => Type::nonNull( Type::listOf( $this->propertyValuePairType ) ),
178+
'resolve' => fn( Reference $reference ) => $reference->parts,
179+
],
180+
],
181+
] );
182+
}
183+
165184
}

repo/domains/reuse/src/Infrastructure/GraphQL/Schema/ValueTypeType.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ class ValueTypeType extends EnumType {
1212

1313
public function __construct() {
1414
$config = [
15-
'name' => 'ValueType',
1615
'values' => [
1716
'novalue' => [
1817
'value' => ValueType::TYPE_NO_VALUE,

repo/domains/reuse/src/Infrastructure/GraphQL/schema.graphql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type Statement {
2626
id: String!
2727
rank: Rank!
2828
qualifiers(propertyId: String!): [PropertyValuePair]!
29+
references: [Reference]!
2930
property: PredicateProperty!
3031
value: Value
3132
valueType: ValueType!
@@ -69,3 +70,7 @@ enum ValueType {
6970
somevalue
7071
value
7172
}
73+
74+
type Reference {
75+
parts: [PropertyValuePair]!
76+
}

repo/domains/reuse/tests/phpunit/Infrastructure/DataAccess/EntityLookupItemsBatchRetrieverTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
use PHPUnit\Framework\TestCase;
1010
use Wikibase\DataModel\Entity\ItemId;
1111
use Wikibase\DataModel\Entity\NumericPropertyId;
12+
use Wikibase\DataModel\Reference;
1213
use Wikibase\DataModel\Services\Lookup\EntityLookup;
1314
use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup;
1415
use Wikibase\DataModel\Services\Lookup\InMemoryEntityLookup;
16+
use Wikibase\DataModel\Snak\PropertySomeValueSnak;
1517
use Wikibase\DataModel\Tests\NewItem;
1618
use Wikibase\DataModel\Tests\NewStatement;
1719
use Wikibase\Repo\Domains\Reuse\Domain\Model\Sitelink;
@@ -176,6 +178,53 @@ public function testGetItemsWithStatements(): void {
176178
$this->assertNull( $batch->getItem( $this->deletedItem ) );
177179
}
178180

181+
public function testGetItemsWithStatementsWithReferences(): void {
182+
$item1StatementGuid = "$this->item1Id\$bed933b7-4207-d679-7571-3630cfb49d7f";
183+
$item1StatementPropertyId = 'P1';
184+
$item1StatementReferencePropertyId = new NumericPropertyId( 'P42' );
185+
$item1Statement = NewStatement::noValueFor( $item1StatementPropertyId )
186+
->withGuid( $item1StatementGuid )
187+
->withReference( new Reference( [ new PropertySomeValueSnak( $item1StatementReferencePropertyId ) ] ) )
188+
->build();
189+
190+
$dataTypeLookup = new InMemoryDataTypeLookup();
191+
$dataTypeLookup->setDataTypeForProperty( new NumericPropertyId( $item1StatementPropertyId ), 'string' );
192+
193+
$entityLookup = new InMemoryEntityLookup();
194+
$entityLookup->addEntity(
195+
NewItem::withId( $this->item1Id )
196+
->andStatement( $item1Statement )
197+
->build()
198+
);
199+
200+
$batch = $this->newRetriever( $entityLookup, new HashSiteStore( [] ), $dataTypeLookup )
201+
->getItems( $this->item1Id, $this->item2Id );
202+
203+
$this->assertEquals( $this->item1Id, $batch->getItem( $this->item1Id )->id );
204+
205+
$statements = $batch->getItem( $this->item1Id )
206+
->statements->getStatementsByPropertyId( new NumericPropertyId( $item1StatementPropertyId ) );
207+
$this->assertCount( 1, $statements );
208+
209+
$references = $statements[0]->references;
210+
$this->assertCount( 1, $references );
211+
212+
$this->assertSame(
213+
$item1StatementReferencePropertyId,
214+
$references[0]->parts[0]->property->id
215+
);
216+
217+
$this->assertSame(
218+
null,
219+
$references[0]->parts[0]->value
220+
);
221+
222+
$this->assertSame(
223+
'somevalue',
224+
$references[0]->parts[0]->valueType->value
225+
);
226+
}
227+
179228
public function testGetItemWithStatementsWithValue(): void {
180229
$item1StatementGuid = "$this->item1Id\$bed933b7-4207-d679-7571-3630cfb49d7f";
181230
$item1Statement2Guid = "$this->item1Id\$bed933b7-4207-d679-7571-3630cfb49d8f";

repo/domains/reuse/tests/phpunit/Infrastructure/GraphQL/GraphQLServiceTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
use Wikibase\DataModel\Entity\ItemId;
1616
use Wikibase\DataModel\Entity\NumericPropertyId;
1717
use Wikibase\DataModel\Entity\Property;
18+
use Wikibase\DataModel\Reference;
1819
use Wikibase\DataModel\Services\Lookup\EntityLookup;
1920
use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup;
2021
use Wikibase\DataModel\Services\Lookup\InMemoryEntityLookup;
2122
use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
23+
use Wikibase\DataModel\Snak\PropertySomeValueSnak;
2224
use Wikibase\DataModel\Term\Fingerprint;
2325
use Wikibase\DataModel\Term\Term;
2426
use Wikibase\DataModel\Term\TermList;
@@ -113,17 +115,21 @@ public function queryProvider(): Generator {
113115
$qualifierPropertyId = 'P2';
114116
$statementWithItemValuePropertyId = 'P3';
115117
$statementWithNoValuePropertyId = 'P4';
118+
$statementWithNoReferencesPropertyId = $statementWithNoValuePropertyId;
116119
$statementWithSomeValuePropertyId = 'P5';
117120
$statementWithItemValueQualifierPropertyId = $statementWithItemValuePropertyId; // also type wikibase-item so we can just reuse it.
121+
$statementReferencePropertyId = 'P6';
118122
$unusedPropertyId = 'P9999';
119123
$qualifierStringValue = 'qualifierStringValue';
120124
$statementStringValue = 'statementStringValue';
121125
$statementWithStringValue = NewStatement::forProperty( ( $statementWithStringValuePropertyId ) )
122126
->withGuid( "$itemId\$bed933b7-4207-d679-7571-3630cfb49d7f" )
123127
->withRank( 1 )
124128
->withQualifier( new NumericPropertyId( $qualifierPropertyId ), new StringValue( $qualifierStringValue ) )
129+
->withReference( new Reference( [ new PropertySomeValueSnak( new NumericPropertyId( $statementReferencePropertyId ) ) ] ) )
125130
->withValue( $statementStringValue )
126131
->build();
132+
127133
$statementWithItemValue = NewStatement::forProperty( ( $statementWithItemValuePropertyId ) )
128134
->withGuid( "$itemId\$bed933b7-4207-d679-7571-3630cfb49d8f" )
129135
->withValue( new ItemId( $itemValueItemId ) )
@@ -236,6 +242,48 @@ public function queryProvider(): Generator {
236242
],
237243
],
238244
];
245+
yield 'statement with references' => [
246+
"{ item(id: \"$itemId\") {
247+
$statementWithStringValuePropertyId: statements(propertyId: \"$statementWithStringValuePropertyId\") {
248+
references{
249+
parts{
250+
property { id dataType }
251+
value { ...on StringValue { content } }
252+
valueType
253+
}
254+
}
255+
}
256+
$statementWithNoReferencesPropertyId: statements(propertyId: \"$statementWithNoReferencesPropertyId\") {
257+
references { parts { valueType }
258+
}
259+
}
260+
} }",
261+
[
262+
'data' => [
263+
'item' => [
264+
$statementWithStringValuePropertyId => [
265+
[
266+
'references' => [
267+
[
268+
'parts' => [
269+
[
270+
'property' => [
271+
'id' => $statementReferencePropertyId,
272+
'dataType' => null,
273+
],
274+
'value' => null,
275+
'valueType' => 'somevalue',
276+
],
277+
],
278+
],
279+
],
280+
],
281+
],
282+
$statementWithNoReferencesPropertyId => [ [ 'references' => [] ] ],
283+
],
284+
],
285+
],
286+
];
239287
yield 'statement with qualifier' => [
240288
"{ item(id: \"$itemId\") {
241289
statements(propertyId: \"$statementWithStringValuePropertyId\") {

0 commit comments

Comments
 (0)