buildQueryForDescription()   B
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 15
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 6

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 15
ccs 12
cts 12
cp 1
rs 8.8571
cc 6
eloc 13
nc 6
nop 2
crap 6
1
<?php
2
3
namespace Wikibase\EntityStore\Api;
4
5
use Ask\Language\Description\AnyValue;
6
use Ask\Language\Description\Conjunction;
7
use Ask\Language\Description\Description;
8
use Ask\Language\Description\Disjunction;
9
use Ask\Language\Description\SomeProperty;
10
use Ask\Language\Description\ValueDescription;
11
use Ask\Language\Option\QueryOptions;
12
use DataValues\StringValue;
13
use DataValues\TimeValue;
14
use Wikibase\DataModel\Entity\EntityIdValue;
15
use Wikibase\DataModel\Entity\ItemId;
16
use Wikibase\DataModel\Entity\PropertyId;
17
use Wikibase\EntityStore\FeatureNotSupportedException;
18
use Wikibase\EntityStore\ItemIdForQueryLookup;
19
use WikidataQueryApi\Query\AndQuery;
20
use WikidataQueryApi\Query\BetweenQuery;
21
use WikidataQueryApi\Query\ClaimQuery;
22
use WikidataQueryApi\Query\OrQuery;
23
use WikidataQueryApi\Query\StringQuery;
24
use WikidataQueryApi\Services\SimpleQueryService;
25
26
/**
27
 * Internal class
28
 *
29
 * @licence GPLv2+
30
 * @author Thomas Pellissier Tanon
31
 */
32
class WikidataQueryItemIdForQueryLookup implements ItemIdForQueryLookup {
33
34
	/**
35
	 * @var SimpleQueryService
36
	 */
37
	private $queryService;
38
39
	/**
40
	 * @param SimpleQueryService $queryService
41
	 */
42 15
	public function __construct( SimpleQueryService $queryService ) {
43 15
		$this->queryService = $queryService;
44 15
	}
45
46
	/**
47
	 * @see ItemIdForQueryLookup::getItemIdsForQuery
48
	 */
49 15
	public function getItemIdsForQuery( Description $queryDescription, QueryOptions $queryOptions = null ) {
50 15
		return $this->queryService->doQuery( $this->buildQueryForDescription( $queryDescription ) );
51
	}
52
53 15
	private function buildQueryForDescription( Description $description, PropertyId $propertyId = null ) {
54 15
		if( $description instanceof AnyValue ) {
55 3
			return $this->buildQueryForAnyValue( $propertyId );
56 14
		} elseif( $description instanceof Conjunction ) {
57 2
			return $this->buildQueryForConjunction( $description, $propertyId );
58 14
		} elseif( $description instanceof Disjunction ) {
59 2
			return $this->buildQueryForDisjunction( $description, $propertyId );
60 14
		} elseif( $description instanceof SomeProperty ) {
61 12
			return $this->buildQueryForSomeProperty( $description );
62 11
		} elseif( $description instanceof ValueDescription ) {
63 10
			return $this->buildQueryForValueDescription( $description, $propertyId );
64
		} else {
65 1
			throw new FeatureNotSupportedException( 'Unknown description type: ' . $description->getType() );
66
		}
67
	}
68
69 3
	private function buildQueryForAnyValue( PropertyId $propertyId = null ) {
70 3
		if( $propertyId === null ) {
71 1
			throw new FeatureNotSupportedException( 'Search for all items is not supported' );
72
		}
73
74 2
		return new ClaimQuery( $propertyId );
75
	}
76
77 2
	private function buildQueryForConjunction( Conjunction $conjunction, PropertyId $propertyId = null ) {
78 2
		$parameters = [];
79 2
		foreach( $conjunction->getDescriptions() as $description ) {
80 2
			$parameters[] = $this->buildQueryForDescription( $description, $propertyId );
81 2
		}
82 2
		return new AndQuery( $parameters );
83
	}
84
85 2
	private function buildQueryForDisjunction( Disjunction $disjunction, PropertyId $propertyId = null ) {
86 2
		$parameters = [];
87 2
		foreach( $disjunction->getDescriptions() as $description ) {
88 2
			$parameters[] = $this->buildQueryForDescription( $description, $propertyId );
89 2
		}
90 2
		return new OrQuery( $parameters );
91
	}
92
93 12
	private function buildQueryForSomeProperty( SomeProperty $someProperty ) {
94 12
		$propertyIdValue = $someProperty->getPropertyId();
95 12
		if( !( $propertyIdValue instanceof EntityIdValue ) ) {
96 1
			throw new FeatureNotSupportedException( 'PropertyId should be an EntityIdValue' );
97
		}
98 11
		$propertyId = $propertyIdValue->getEntityId();
99 11
		if( !( $propertyId instanceof PropertyId ) ) {
100
			throw new FeatureNotSupportedException( 'PropertyId should contain a PropertyId' );
101
		}
102
103 11
		if( $someProperty->isSubProperty() ) {
104 1
			throw new FeatureNotSupportedException( 'Sub-properties are not supported yet' );
105
		} else {
106 11
			return $this->buildQueryForDescription( $someProperty->getSubDescription(), $propertyId );
107
		}
108
	}
109
110 10
	private function buildQueryForValueDescription( ValueDescription $valueDescription, PropertyId $propertyId = null ) {
111 10
		if( $propertyId === null ) {
112 1
			throw new FeatureNotSupportedException( 'Search of value on any properties is not supported' );
113
		}
114
115 9
		if( !in_array(
116 9
			$valueDescription->getComparator(),
117 9
			[ ValueDescription::COMP_EQUAL, ValueDescription::COMP_LIKE ]
118 9
		) ) {
119 1
			throw new FeatureNotSupportedException( 'Unsupported ValueDescription comparator' );
120
		}
121
122 8
		$dataValue = $valueDescription->getValue();
123 8
		if( $dataValue instanceof EntityIdValue ) {
124 5
			return $this->buildEntityIdValueForSearch( $dataValue, $propertyId );
125 6
		} elseif( $dataValue instanceof StringValue ) {
126 4
			return new StringQuery( $propertyId, $dataValue );
127 2
		} elseif( $dataValue instanceof TimeValue ) {
128 1
			return new BetweenQuery( $propertyId, $dataValue, $dataValue );
129
		} else {
130 1
			throw new FeatureNotSupportedException( 'Not supported DataValue type: ' . $dataValue->getType() );
131
		}
132
	}
133
134 5
	private function buildEntityIdValueForSearch( EntityIdValue $entityIdValue, PropertyId $propertyId ) {
135 5
		$entityId = $entityIdValue->getEntityId();
136
137 5
		if( !( $entityId instanceof ItemId ) ) {
138 1
			throw new FeatureNotSupportedException( 'Not supported entity type: ' . $entityId->getEntityType() );
139
		}
140
141 4
		return new ClaimQuery( $propertyId, $entityId );
142
	}
143
}
144