ValueSnakStore::getInsertValues()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 2
1
<?php
2
3
namespace Wikibase\QueryEngine\SQLStore\SnakStore;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\DBALException;
7
use InvalidArgumentException;
8
use OutOfBoundsException;
9
use Wikibase\DataModel\Entity\EntityId;
10
use Wikibase\QueryEngine\QueryEngineException;
11
use Wikibase\QueryEngine\SQLStore\DataValueHandler;
12
13
/**
14
 * @licence GNU GPL v2+
15
 * @author Jeroen De Dauw < [email protected] >
16
 */
17
class ValueSnakStore extends SnakStore {
18
19
	private $connection;
20
	private $dataValueHandlers;
21
	private $snakRole;
22
23
	/**
24
	 * The array of DataValueHandlers must have DataValue types as array keys pointing to
25
	 * the corresponding DataValueHandler.
26
	 *
27
	 * @param Connection $connection
28
	 * @param DataValueHandler[] $dataValueHandlers
29
	 * @param int $supportedSnakRole
30
	 */
31
	public function __construct( Connection $connection, array $dataValueHandlers, $supportedSnakRole ) {
32
		$this->connection = $connection;
33
		$this->dataValueHandlers = $dataValueHandlers;
34
		$this->snakRole = $supportedSnakRole;
35
	}
36
37
	public function canStore( SnakRow $snakRow ) {
38
		return ( $snakRow instanceof ValueSnakRow )
39
			&& $this->snakRole === $snakRow->getSnakRole();
40
	}
41
42
	/**
43
	 * @param string $dataValueType
44
	 *
45
	 * @return DataValueHandler
46
	 * @throws OutOfBoundsException
47
	 */
48
	private function getDataValueHandler( $dataValueType ) {
49
		if ( !array_key_exists( $dataValueType, $this->dataValueHandlers ) ) {
50
			throw new OutOfBoundsException( "There is no DataValueHandler set for '$dataValueType'" );
51
		}
52
53
		return $this->dataValueHandlers[$dataValueType];
54
	}
55
56
	public function storeSnakRow( SnakRow $snakRow ) {
57
		if ( !$this->canStore( $snakRow ) ) {
58
			throw new InvalidArgumentException( 'Can only store ValueSnakRow of the right snak type in ValueSnakStore' );
59
		}
60
61
		/**
62
		 * @var ValueSnakRow $snakRow
63
		 */
64
		if ( !array_key_exists( $snakRow->getValue()->getType(), $this->dataValueHandlers ) ) {
65
			return;
66
		}
67
68
		$dataValueHandler = $this->getDataValueHandler( $snakRow->getValue()->getType() );
69
70
		$tableName = $dataValueHandler->getTableName();
71
72
		$this->doInsert(
73
			$tableName,
74
			$this->getInsertValues( $snakRow, $dataValueHandler )
75
		);
76
	}
77
78
	private function doInsert( $tableName, array $values ) {
79
		try {
80
			$this->connection->insert( $tableName, $values );
81
		}
82
		catch ( DBALException $ex ) {
83
			throw new QueryEngineException( $ex->getMessage(), 0, $ex );
84
		}
85
	}
86
87
	private function getInsertValues( ValueSnakRow $snakRow, DataValueHandler $dataValueHandler ) {
88
		return array_merge(
89
			array(
90
				'subject_id' => $snakRow->getSubjectId()->getSerialization(),
91
				'subject_type' => $snakRow->getSubjectId()->getEntityType(),
92
				'property_id' => $snakRow->getPropertyId(),
93
				'statement_rank' => $snakRow->getStatementRank(),
94
			),
95
			$dataValueHandler->getInsertValues( $snakRow->getValue() )
96
		);
97
	}
98
99
	public function removeSnaksOfSubject( EntityId $subjectId ) {
100
		foreach ( $this->dataValueHandlers as $dvHandler ) {
101
			$this->doDelete( $dvHandler->getTableName(), $subjectId->getSerialization() );
102
		}
103
	}
104
105
	private function doDelete( $tableName, $subjectIdSerialization ) {
106
		try {
107
			$this->connection->delete(
108
				$tableName,
109
				array( 'subject_id' => $subjectIdSerialization )
110
			);
111
		}
112
		catch ( DBALException $ex ) {
113
			throw new QueryEngineException( $ex->getMessage(), 0, $ex );
114
		}
115
	}
116
117
}
118