DatabaseTermIdsAcquirer   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 255
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 2
dl 0
loc 255
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A acquireTermIds() 0 6 1
A mapToTypeIds() 0 10 2
A mapToTextIds() 0 15 1
A acquireTextIds() 0 18 3
B mapToTextInLangIds() 0 32 7
A acquireTextInLangIds() 0 21 4
A mapToTermInLangIds() 0 26 5
A acquireTermInLangIds() 0 24 4
A __construct() 0 7 1
1
<?php
2
3
namespace Wikibase\TermStore\MediaWiki\PackagePrivate;
4
5
use AppendIterator;
6
use ArrayIterator;
7
use Wikibase\TermStore\MediaWiki\PackagePrivate\Util\ReplicaMasterAwareRecordIdsAcquirer;
8
use Wikimedia\Rdbms\IDatabase;
9
use Wikimedia\Rdbms\ILoadBalancer;
10
11
class DatabaseTermIdsAcquirer implements TermIdsAcquirer {
12
13
	const TABLE_TEXT = 'wbt_text';
14
	const TABLE_TEXT_IN_LANG = 'wbt_text_in_lang';
15
	const TABLE_TERM_IN_LANG = 'wbt_term_in_lang';
16
17
	/**
18
	 * @var ILoadBalancer
19
	 */
20
	private $loadBalancer;
21
22
	/**
23
	 * @var TypeIdsAcquirer
24
	 */
25
	private $typeIdsAcquirer;
26
27
	public function __construct(
28
		ILoadBalancer $loadBalancer,
29
		TypeIdsAcquirer $typeIdsAcquirer
30
	) {
31
		$this->loadBalancer = $loadBalancer;
32
		$this->typeIdsAcquirer = $typeIdsAcquirer;
33
	}
34
35
	public function acquireTermIds( array $termsArray ): array {
36
		$termsArray = $this->mapToTextIds( $termsArray );
37
		$termsArray = $this->mapToTextInLangIds( $termsArray );
38
		$termsArray = $this->mapToTypeIds( $termsArray );
39
		return $this->mapToTermInLangIds( $termsArray );
40
	}
41
42
	/**
43
	 * replace root keys containing type names in termsArray
44
	 * with their respective ids in wbt_type table
45
	 *
46
	 * @param array $termsArray terms per type per language:
47
	 *	[
48
	 *		'type1' => [ ... ],
49
	 *		'type2' => [ ... ],
50
	 *		...
51
	 *	]
52
	 *
53
	 * @return array
54
	 *	[
55
	 *		<typeId1> => [ ... ],
56
	 *		<typeId2> => [ ... ],
57
	 *		...
58
	 *	]
59
	 */
60
	private function mapToTypeIds( array $termsArray ) {
61
		$typeIds = $this->typeIdsAcquirer->acquireTypeIds( array_keys( $termsArray ) );
62
63
		$termsArrayByTypeId = [];
64
		foreach ( $typeIds as $type => $typeId ) {
65
			$termsArrayByTypeId[$typeId] = $termsArray[$type];
66
		}
67
68
		return $termsArrayByTypeId;
69
	}
70
71
	/**
72
	 * replace text at termsArray leaves with their ids in wbt_text table
73
	 * and return resulting array
74
	 *
75
	 * @param array $termsArray terms per type per language:
76
	 *	[
77
	 *		'type' => [
78
	 *			[ 'language' => 'term' | [ 'term1', 'term2', ... ] ], ...
79
	 *		], ...
80
	 *	]
81
	 *
82
	 * @return array
83
	 *	[
84
	 *		'type' => [
85
	 *			[ 'language' => [ <textId1>, <textId2>, ... ] ], ...
86
	 *		], ...
87
	 *	]
88
	 */
89
	private function mapToTextIds( array $termsArray ) {
90
		$texts = [];
91
92
		array_walk_recursive( $termsArray, function ( $text ) use ( &$texts ) {
93
			$texts[] = $text;
94
		} );
95
96
		$textIds = $this->acquireTextIds( $texts );
97
98
		array_walk_recursive( $termsArray, function ( &$text ) use ( $textIds ) {
99
			$text = $textIds[$text];
100
		} );
101
102
		return $termsArray;
103
	}
104
105
	private function acquireTextIds( array $texts ) {
106
		$textIdsAcquirer = new ReplicaMasterAwareRecordIdsAcquirer(
107
			$this->loadBalancer, 'wbt_text', 'wbx_id' );
108
109
		$textRecords = [];
110
		foreach ( $texts as $text ) {
111
			$textRecords[] = [ 'wbx_text' => $text ];
112
		}
113
114
		$acquiredIds = $textIdsAcquirer->acquireIds( $textRecords );
115
116
		$textIds = [];
117
		foreach ( $acquiredIds as $acquiredId ) {
118
			$textIds[$acquiredId['wbx_text']] = $acquiredId['wbx_id'];
119
		}
120
121
		return $textIds;
122
	}
123
124
	/**
125
	 * replace ( lang => [ textId, ... ] ) entries with their respective ids
126
	 * in wbt_text_in_lang table and return resulting array
127
	 *
128
	 * @param array $termsArray text ids per type per langauge
129
	 *	[
130
	 *		'type' => [
131
	 *			[ 'language' => [ <textId1>, <textId2>, ... ] ], ...
132
	 *		], ...
133
	 *	]
134
	 *
135
	 * @return array
136
	 *	[
137
	 *		'type' => [ <textInLangId1>, <textInLangId2>, ... ],
138
	 *		...
139
	 *	]
140
	 */
141
	private function mapToTextInLangIds( array $termsArray ) {
142
		$flattenedLangTextIds = [];
143
		foreach ( $termsArray as $langTextIds ) {
144
			foreach ( $langTextIds as $lang => $textIds ) {
145
				if ( !isset( $flattenedLangTextIds[$lang] ) ) {
146
					$flattenedLangTextIds[$lang] = [];
147
				}
148
149
				$flattenedLangTextIds[$lang] = array_unique(
150
					array_merge(
151
						(array)$textIds,
152
						(array)$flattenedLangTextIds[$lang]
153
					)
154
				);
155
156
			}
157
		}
158
159
		$textInLangIds = $this->acquireTextInLangIds( $flattenedLangTextIds );
160
161
		$newTermsArray = [];
162
		foreach ( $termsArray as $type => $langTextIds ) {
163
			$newTermsArray[$type] = [];
164
			foreach ( $langTextIds as $lang => $textIds ) {
165
				foreach ( (array)$textIds as $textId ) {
166
					$newTermsArray[$type][] = $textInLangIds[$lang][$textId];
167
				}
168
			}
169
		}
170
171
		return $newTermsArray;
172
	}
173
174
	private function acquireTextInLangIds( array $langTextIds ) {
175
		$textInLangIdsAcquirer = new ReplicaMasterAwareRecordIdsAcquirer(
176
			$this->loadBalancer, 'wbt_text_in_lang', 'wbxl_id' );
177
178
		$textInLangRecords = [];
179
		foreach ( $langTextIds as $lang => $textIds ) {
180
			foreach ( $textIds as $textId ) {
181
				$textInLangRecords[] = [ 'wbxl_text_id' => $textId, 'wbxl_language' => $lang ];
182
			}
183
		}
184
185
		$acquiredIds = $textInLangIdsAcquirer->acquireIds( $textInLangRecords );
186
187
		$textInLangIds = [];
188
		foreach ( $acquiredIds as $acquiredId ) {
189
			$textInLangIds[$acquiredId['wbxl_language']][$acquiredId['wbxl_text_id']]
190
				= $acquiredId['wbxl_id'];
191
		}
192
193
		return $textInLangIds;
194
	}
195
196
	/**
197
	 * replace root ( type => [ textInLangId, ... ] ) entries with their respective ids
198
	 * in wbt_term_in_lang table and return resulting array
199
	 *
200
	 * @param array $termsArray text in lang ids per type
201
	 *	[
202
	 *		'type' => [ <textInLangId1>, <textInLangId2>, ... ],
203
	 *		...
204
	 *	]
205
	 *
206
	 * @return array
207
	 *	[
208
	 *		<termInLang1>,
209
	 *		<termInLang2>,
210
	 *		...
211
	 *	]
212
	 */
213
	private function mapToTermInLangIds( array $termsArray ) {
214
		$flattenedTypeTextInLangIds = [];
215
		foreach ( $termsArray as $typeId => $textInLangIds ) {
216
			if ( !isset( $flattenedTypeTextInLangIds[$typeId] ) ) {
217
				$flattenedTypeTextInLangIds[$typeId] = [];
218
			}
219
220
			$flattenedTypeTextInLangIds[$typeId] = array_unique(
221
				array_merge(
222
					(array)$textInLangIds,
223
					(array)$flattenedTypeTextInLangIds[$typeId]
224
				)
225
			);
226
		}
227
228
		$termInLangIds = $this->acquireTermInLangIds( $flattenedTypeTextInLangIds );
229
230
		$newTermsArray = [];
231
		foreach ( $termsArray as $typeId => $textInLangIds ) {
232
			foreach ( $textInLangIds as $textInLangId ) {
233
				$newTermsArray[] = $termInLangIds[$typeId][$textInLangId];
234
			}
235
		}
236
237
		return $newTermsArray;
238
	}
239
240
	private function acquireTermInLangIds( array $typeTextInLangIds ) {
241
		$termInLangIdsAcquirer = new ReplicaMasterAwareRecordIdsAcquirer(
242
			$this->loadBalancer, 'wbt_term_in_lang', 'wbtl_id' );
243
244
		$termInLangRecords = [];
245
		foreach ( $typeTextInLangIds as $typeId => $textInLangIds ) {
246
			foreach ( $textInLangIds as $textInLangId ) {
247
				$termInLangRecords[] = [
248
					'wbtl_text_in_lang_id' => $textInLangId,
249
					'wbtl_type_id' => (string)$typeId
250
				];
251
			}
252
		}
253
254
		$acquiredIds = $termInLangIdsAcquirer->acquireIds( $termInLangRecords );
255
256
		$termInLangIds = [];
257
		foreach ( $acquiredIds as $acquiredId ) {
258
			$termInLangIds[$acquiredId['wbtl_type_id']][$acquiredId['wbtl_text_in_lang_id']]
259
				= $acquiredId['wbtl_id'];
260
		}
261
262
		return $termInLangIds;
263
	}
264
265
}
266