Skip to content

Commit 7515350

Browse files
jakobwjenkins-bot
authored andcommitted
GQL: Determine GraphQL value type by data type
This changes the way the specific value type was determined in the Value union type. The type was previously resolved by inspecting the type of value, whereas now it gets the property data type from the Statement or PropertyValuePair model. This means that no further changes have to be made to the Value union type. Additional types of values will be supported as soon as they have a corresponding entry in the data type definitions. Bug: T404838 Change-Id: I01f81d3dbcbd70799ad56e912b224549321167c8
1 parent a33fbba commit 7515350

File tree

9 files changed

+78
-43
lines changed

9 files changed

+78
-43
lines changed

lib/includes/DataTypeDefinitions.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,13 @@ public function getNormalizerFactoryCallbacks(): array {
410410

411411
/**
412412
* Get the GraphQL type to be used for values of different data types and value types
413-
* @return callable[] List of callbacks, with keys having "VT:" and "PT:" prefixes.
413+
* @return callable[] List of callbacks by data type, without "PT:" prefixes.
414414
*/
415415
public function getGraphqlValueTypes(): array {
416-
return $this->getMapForDefinitionField( 'graphql-value-type' );
416+
return $this->resolveValueTypeFallback(
417+
$this->getMapForDefinitionField( 'graphql-value-type' ),
418+
allowMissing: true, // TODO remove or set to false once T404692 is done since it should no longer be needed
419+
);
417420
}
418421

419422
}

repo/WikibaseRepo.datatypes.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@
4848
use Wikibase\Lib\Formatters\SnakFormatter;
4949
use Wikibase\Lib\Store\FieldPropertyInfoProvider;
5050
use Wikibase\Lib\Store\PropertyInfoStore;
51-
use Wikibase\Repo\Domains\Reuse\Domain\Model\Value;
51+
use Wikibase\Repo\Domains\Reuse\Domain\Model\PropertyValuePair;
52+
use Wikibase\Repo\Domains\Reuse\Domain\Model\Statement;
5253
use Wikibase\Repo\Domains\Reuse\WbReuse;
5354
use Wikibase\Repo\Parsers\EntityIdValueParser;
5455
use Wikibase\Repo\Parsers\MediaWikiNumberUnlocalizer;
@@ -306,15 +307,7 @@
306307
return WikibaseRepo::getStringValueNormalizer();
307308
},
308309
'graphql-value-type' => static function () {
309-
return new ObjectType( [
310-
'name' => 'StringValue',
311-
'fields' => [
312-
'content' => [
313-
'type' => Type::nonNull( Type::string() ),
314-
'resolve' => fn( Value $v ) => $v->content->getValue(),
315-
],
316-
],
317-
] );
310+
return WbReuse::getStringValueType();
318311
},
319312
],
320313
'VT:time' => [
@@ -499,7 +492,7 @@
499492
],
500493
],
501494
] ) ),
502-
'resolve' => fn( Value $v ) => $v->content,
495+
'resolve' => fn( Statement|PropertyValuePair $valueProvider ) => $valueProvider->value->content,
503496
],
504497
],
505498
] );

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@ public function __construct(
1616
ValueType $valueType,
1717
ValueTypeType $valueTypeType
1818
) {
19-
$config = [
19+
parent::__construct( [
2020
'fields' => [
2121
'property' => [
2222
'type' => Type::nonNull( $predicateType ),
2323
'resolve' => fn( PropertyValuePair $rootValue ) => $rootValue->property,
2424
],
2525
'value' => [
2626
'type' => $valueType,
27-
'resolve' => fn( PropertyValuePair $rootValue ) => $rootValue->value,
27+
// The whole PropertyValuePair is passed down here so that the Value type has access to the property data type.
28+
'resolve' => fn( PropertyValuePair $rootValue ) => $rootValue->value ? $rootValue : null,
2829
],
2930
'valueType' => [
3031
'type' => Type::nonNull( $valueTypeType ),
3132
'resolve' => fn( PropertyValuePair $rootValue ) => $rootValue->valueType,
3233
],
3334
],
34-
];
35-
parent::__construct( $config );
35+
] );
3636
}
3737

3838
}

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,11 @@ private function statementType(): ObjectType {
132132
'type' => Type::nonNull( $this->predicatePropertyType ),
133133
'resolve' => fn( Statement $statement ) => $statement->property,
134134
],
135-
'value' => $this->valueType,
135+
'value' => [
136+
'type' => $this->valueType,
137+
// The whole Statement is passed down here so that the Value type has access to the property data type.
138+
'resolve' => fn( Statement $statement ) => $statement->value ? $statement : null,
139+
],
136140
'valueType' => [
137141
'type' => Type::nonNull( $this->valueTypeType ),
138142
'resolve' => fn( Statement $statement ) => $statement->valueType,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare( strict_types=1 );
2+
3+
namespace Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema;
4+
5+
use GraphQL\Type\Definition\ObjectType;
6+
use GraphQL\Type\Definition\Type;
7+
use Wikibase\Repo\Domains\Reuse\Domain\Model\PropertyValuePair;
8+
use Wikibase\Repo\Domains\Reuse\Domain\Model\Statement;
9+
10+
/**
11+
* @license GPL-2.0-or-later
12+
*/
13+
class StringValueType extends ObjectType {
14+
public function __construct() {
15+
parent::__construct( [
16+
'name' => 'StringValue',
17+
'fields' => [
18+
'content' => [
19+
'type' => Type::nonNull( Type::string() ),
20+
'resolve' => fn( Statement|PropertyValuePair $valueProvider ) => $valueProvider->value->content->getValue(),
21+
],
22+
],
23+
] );
24+
}
25+
}

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

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,22 @@
22

33
namespace Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema;
44

5-
use DataValues\StringValue;
65
use GraphQL\Type\Definition\UnionType;
7-
use Wikibase\Repo\Domains\Reuse\Domain\Model\Value;
8-
use Wikibase\Repo\WikibaseRepo;
6+
use Wikibase\Repo\Domains\Reuse\Domain\Model\PropertyValuePair;
7+
use Wikibase\Repo\Domains\Reuse\Domain\Model\Statement;
98

109
/**
1110
* @license GPL-2.0-or-later
1211
*/
1312
class ValueType extends UnionType {
1413

15-
public function __construct() {
16-
$valueTypes = array_map(
17-
fn( $c ) => $c(),
18-
WikibaseRepo::getDataTypeDefinitions()->getGraphqlValueTypes()
19-
);
20-
$config = [
21-
'types' => array_values( $valueTypes ),
22-
'resolveType' => fn( Value $v ) => $v->content instanceof StringValue
23-
? $valueTypes[ 'VT:string' ]
24-
: $valueTypes[ 'PT:wikibase-item' ],
25-
];
26-
parent::__construct( $config );
14+
public function __construct( array $valueTypeCallbacks ) {
15+
$valueTypes = array_map( fn( $c ) => $c(), $valueTypeCallbacks );
16+
17+
parent::__construct( [
18+
'types' => array_values( array_unique( $valueTypes ) ),
19+
'resolveType' => fn( Statement|PropertyValuePair $valueProvider ) => $valueTypes[$valueProvider->property->dataType],
20+
] );
2721
}
2822

2923
}

repo/domains/reuse/src/WbReuse.ServiceWiring.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema\PropertyValuePairType;
1818
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema\Schema;
1919
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema\SiteIdType;
20+
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema\StringValueType;
2021
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema\ValueType;
2122
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema\ValueTypeType;
2223
use Wikibase\Repo\Domains\Reuse\WbReuse;
@@ -34,7 +35,7 @@
3435
),
3536
$languageCodeType,
3637
);
37-
$valueType = new ValueType();
38+
$valueType = new ValueType( WikibaseRepo::getDataTypeDefinitions( $services )->getGraphqlValueTypes() );
3839
$valueTypeType = new ValueTypeType();
3940

4041
return new Schema(
@@ -76,4 +77,7 @@
7677
'WbReuse.LanguageCodeType' => function( MediaWikiServices $services ): LanguageCodeType {
7778
return new LanguageCodeType( WikibaseRepo::getTermsLanguages( $services )->getLanguages() );
7879
},
80+
'WbReuse.StringValueType' => function( MediaWikiServices $services ): StringValueType {
81+
return new StringValueType();
82+
},
7983
];

repo/domains/reuse/src/WbReuse.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Resolvers\ItemLabelsResolver;
99
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema\LanguageCodeType;
1010
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema\Schema;
11+
use Wikibase\Repo\Domains\Reuse\Infrastructure\GraphQL\Schema\StringValueType;
1112

1213
/**
1314
* @license GPL-2.0-or-later
@@ -32,4 +33,9 @@ public static function getLanguageCodeType( ?ContainerInterface $services = null
3233
return ( $services ?: MediaWikiServices::getInstance() )
3334
->get( 'WbReuse.LanguageCodeType' );
3435
}
36+
37+
public static function getStringValueType( ?ContainerInterface $services = null ): StringValueType {
38+
return ( $services ?: MediaWikiServices::getInstance() )
39+
->get( 'WbReuse.StringValueType' );
40+
}
3541
}

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Wikibase\DataModel\Entity\NumericPropertyId;
1717
use Wikibase\DataModel\Entity\Property;
1818
use Wikibase\DataModel\Services\Lookup\EntityLookup;
19+
use Wikibase\DataModel\Services\Lookup\InMemoryDataTypeLookup;
1920
use Wikibase\DataModel\Services\Lookup\InMemoryEntityLookup;
2021
use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
2122
use Wikibase\DataModel\Term\Fingerprint;
@@ -40,7 +41,8 @@ class GraphQLServiceTest extends MediaWikiIntegrationTestCase {
4041
private static Item $item2;
4142
private static Item $statementValueItem;
4243
private static Item $qualifierValueItem;
43-
private static Property $statementProperty;
44+
private static Property $stringTypeProperty;
45+
private static Property $itemTypeProperty;
4446
private static Property $qualifierProperty;
4547
private static MediaWikiSite $sitelinkSite;
4648
private const ALLOWED_SITELINK_SITES = [ 'examplewiki', 'otherwiki' ];
@@ -64,19 +66,25 @@ public function testQuery( string $query, array $expectedResult ): void {
6466

6567
$termLookup = new InMemoryPrefetchingTermLookup();
6668
$termLookup->setData( [
67-
self::$statementProperty,
69+
self::$stringTypeProperty,
6870
self::$qualifierProperty,
6971
self::$statementValueItem,
7072
self::$qualifierValueItem,
7173
] );
7274

75+
$dataTypeLookup = new InMemoryDataTypeLookup();
76+
$dataTypeLookup->setDataTypeForProperty( self::$stringTypeProperty->getId(), 'string' );
77+
$dataTypeLookup->setDataTypeForProperty( self::$qualifierProperty->getId(), 'string' );
78+
$dataTypeLookup->setDataTypeForProperty( self::$itemTypeProperty->getId(), 'wikibase-item' );
79+
7380
$this->assertEquals(
7481
$expectedResult,
7582
$this->newGraphQLService(
7683
$entityLookup,
7784
new HashSiteStore( [ self::$sitelinkSite ] ),
7885
$siteIdProvider,
7986
$termLookup,
87+
$dataTypeLookup,
8088
)->query( $query )
8189
);
8290
}
@@ -134,11 +142,12 @@ public function queryProvider(): Generator {
134142
$expectedSitelinkUrl = "https://wiki.example/wiki/$sitelinkTitle";
135143
self::$sitelinkSite->setGlobalId( $sitelinkSiteId );
136144

137-
self::$statementProperty = new Property(
145+
self::$stringTypeProperty = new Property(
138146
new NumericPropertyId( $statementWithStringValuePropertyId ),
139147
new Fingerprint( new TermList( [ new Term( 'en', 'statement prop' ) ] ) ),
140148
'string',
141149
);
150+
self::$itemTypeProperty = new Property( new NumericPropertyId( $statementWithItemValuePropertyId ), null, 'wikibase-item' );
142151
self::$qualifierProperty = new Property(
143152
new NumericPropertyId( $qualifierPropertyId ),
144153
new Fingerprint( new TermList( [ new Term( 'en', 'qualifier prop' ) ] ) ),
@@ -344,7 +353,7 @@ public function queryProvider(): Generator {
344353
'item' => [
345354
'statements' => [
346355
[
347-
'property' => [ 'label' => self::$statementProperty->getLabels()->getByLanguage( 'en' )->getText() ],
356+
'property' => [ 'label' => self::$stringTypeProperty->getLabels()->getByLanguage( 'en' )->getText() ],
348357
'qualifiers' => [
349358
[
350359
'property' => [
@@ -463,14 +472,11 @@ private function newGraphQLService(
463472
?SiteLookup $siteLookup = null,
464473
?SiteLinkGlobalIdentifiersProvider $siteLinkGlobalIdentifiersProvider = null,
465474
?PrefetchingTermLookup $termLookup = null,
475+
?PropertyDataTypeLookup $dataTypeLookup = null,
466476
): GraphQLService {
467477
$this->setService( 'WikibaseRepo.EntityLookup', $entityLookup );
468478
$this->setService( 'SiteLookup', $siteLookup ?? new HashSiteStore() );
469-
470-
$dataTypeLookup = $this->createMock( PropertyDataTypeLookup::class );
471-
$dataTypeLookup->method( 'getDataTypeIdForProperty' )
472-
->willReturn( 'string' );
473-
$this->setService( 'WikibaseRepo.PropertyDataTypeLookup', $dataTypeLookup );
479+
$this->setService( 'WikibaseRepo.PropertyDataTypeLookup', $dataTypeLookup ?? new InMemoryDataTypeLookup() );
474480

475481
$this->setService(
476482
'WikibaseRepo.SiteLinkGlobalIdentifiersProvider',

0 commit comments

Comments
 (0)