1 | <?php |
||||
2 | |||||
3 | namespace LaravelFreelancerNL\Aranguent\Schema\Concerns; |
||||
4 | |||||
5 | use ArangoClient\Exceptions\ArangoException; |
||||
6 | use Illuminate\Support\Fluent; |
||||
7 | |||||
8 | trait IndexCommands |
||||
9 | { |
||||
10 | use HandlesIndexNaming; |
||||
11 | |||||
12 | /** |
||||
13 | * Add a new index command to the blueprint. |
||||
14 | * |
||||
15 | * @param string|array<string>|null $columns |
||||
16 | */ |
||||
17 | 79 | protected function indexCommand( |
|||
18 | string $type, |
||||
19 | array|null|string $columns = null, |
||||
20 | string $name = null, |
||||
21 | array $indexOptions = [], |
||||
22 | ): Fluent { |
||||
23 | 79 | if ($columns === null) { |
|||
24 | 61 | $columns = end($this->columns); |
|||
25 | } |
||||
26 | |||||
27 | 79 | if (is_string($columns)) { |
|||
28 | 66 | $columns = [$columns]; |
|||
29 | } |
||||
30 | |||||
31 | 79 | $columns = $this->renameIdField($columns); |
|||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||
32 | |||||
33 | 79 | $indexOptions['name'] = $name ?: $this->createIndexName($type, $columns, $indexOptions); |
|||
34 | |||||
35 | 79 | return $this->addCommand('index', compact('type', 'columns', 'indexOptions')); |
|||
0 ignored issues
–
show
It seems like
addCommand() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
36 | } |
||||
37 | |||||
38 | /** |
||||
39 | * Specify an index for the table. |
||||
40 | * |
||||
41 | * @param array|null|string $columns |
||||
42 | * @param null|string $name |
||||
43 | * @param null|string $algorithm |
||||
44 | * @param array<mixed> $indexOptions |
||||
45 | * @return Fluent |
||||
46 | */ |
||||
47 | 67 | public function index($columns = null, $name = null, $algorithm = null, $indexOptions = []) |
|||
48 | { |
||||
49 | 67 | $type = $this->mapIndexAlgorithm($algorithm); |
|||
50 | |||||
51 | 67 | return $this->indexCommand($type, $columns, $name, $indexOptions); |
|||
52 | } |
||||
53 | |||||
54 | /** |
||||
55 | * Specify a spatial index for the table. |
||||
56 | * |
||||
57 | * @param string|array $columns |
||||
58 | * @param null|string $name |
||||
59 | * @param array<mixed> $indexOptions |
||||
60 | * @return Fluent |
||||
61 | */ |
||||
62 | 2 | public function spatialIndex($columns, $name = null, $indexOptions = []) |
|||
63 | { |
||||
64 | 2 | return $this->indexCommand('geo', $columns, $name, $indexOptions); |
|||
65 | } |
||||
66 | |||||
67 | /** |
||||
68 | * Specify a spatial index for the table. |
||||
69 | * |
||||
70 | * @param array<mixed>|null|string $columns |
||||
71 | * @param null|string $name |
||||
72 | * @param array<mixed> $indexOptions |
||||
73 | * @return Fluent |
||||
74 | */ |
||||
75 | 1 | public function geoIndex($columns, $name = null, $indexOptions = []) |
|||
76 | { |
||||
77 | 1 | return $this->spatialIndex($columns, $name, $indexOptions); |
|||
78 | } |
||||
79 | |||||
80 | /** |
||||
81 | * Specify a inverted index for the table. |
||||
82 | * |
||||
83 | * @param array<mixed>|null|string $columns |
||||
84 | * @param null|string $name |
||||
85 | * @param array<mixed> $indexOptions |
||||
86 | * @return Fluent |
||||
87 | */ |
||||
88 | 61 | public function invertedIndex($columns = null, $name = null, $indexOptions = []) |
|||
89 | { |
||||
90 | 61 | return $this->indexCommand('inverted', $columns, $name, $indexOptions); |
|||
91 | } |
||||
92 | |||||
93 | |||||
94 | 2 | public function multiDimensionalIndex(array $columns = null, string $name = null, array $indexOptions = [], string $type = 'mdi'): Fluent |
|||
95 | { |
||||
96 | 2 | return $this->indexCommand( |
|||
97 | 2 | $type, |
|||
98 | 2 | $columns, |
|||
99 | 2 | $name, |
|||
100 | 2 | $indexOptions, |
|||
101 | 2 | ); |
|||
102 | } |
||||
103 | |||||
104 | 1 | public function persistentIndex(array $columns = null, string $name = null, array $indexOptions = []): Fluent |
|||
105 | { |
||||
106 | 1 | return $this->indexCommand('persistent', $columns, $name, $indexOptions); |
|||
107 | } |
||||
108 | |||||
109 | /** |
||||
110 | * @param array<string>|null|string $columns |
||||
111 | * @param string|null $name |
||||
112 | * @param array<mixed> $indexOptions |
||||
113 | * @return Fluent |
||||
114 | */ |
||||
115 | 61 | public function primary($columns = null, $name = null, $indexOptions = []): Fluent |
|||
116 | { |
||||
117 | 61 | $indexOptions['unique'] = true; |
|||
118 | |||||
119 | 61 | return $this->indexCommand('persistent', $columns, $name, $indexOptions); |
|||
120 | } |
||||
121 | |||||
122 | /** |
||||
123 | * Create a TTL index for the table. |
||||
124 | * |
||||
125 | * @param string $columns |
||||
126 | * @param int $expireAfter |
||||
127 | * @param null $name |
||||
0 ignored issues
–
show
|
|||||
128 | * @param array $indexOptions |
||||
129 | * @return Fluent |
||||
130 | */ |
||||
131 | 2 | public function ttlIndex($columns, $expireAfter, $name = null, $indexOptions = []): Fluent |
|||
132 | { |
||||
133 | 2 | $indexOptions['expireAfter'] = $expireAfter; |
|||
134 | 2 | return $this->indexCommand('ttl', $columns, $name, $indexOptions); |
|||
135 | } |
||||
136 | |||||
137 | /** |
||||
138 | * Specify a unique index for the table. |
||||
139 | * |
||||
140 | * @param string|array $columns |
||||
141 | * @param string $name |
||||
142 | * @param string|null $algorithm |
||||
143 | */ |
||||
144 | 60 | public function unique($columns = null, $name = null, $algorithm = null): Fluent |
|||
145 | { |
||||
146 | 60 | $type = $this->mapIndexAlgorithm($algorithm); |
|||
147 | |||||
148 | 60 | $indexOptions = []; |
|||
149 | 60 | $indexOptions['unique'] = true; |
|||
150 | |||||
151 | 60 | return $this->indexCommand($type, $columns, $name, $indexOptions); |
|||
152 | } |
||||
153 | |||||
154 | /** |
||||
155 | * @throws ArangoException |
||||
156 | */ |
||||
157 | 79 | public function executeIndexCommand(Fluent $command) |
|||
158 | { |
||||
159 | 79 | if ($this->connection->pretending()) { |
|||
160 | $this->connection->logQuery('/* ' . $command->explanation . " */\n", []); |
||||
161 | |||||
162 | return; |
||||
163 | } |
||||
164 | |||||
165 | // Skip persistent indexes set solely on id - ArangoDB already sets a unique index on _key. |
||||
166 | if ( |
||||
167 | 79 | $command->type === 'persistent' |
|||
0 ignored issues
–
show
|
|||||
168 | 79 | && count($command->columns) === 1 |
|||
169 | 79 | && $command->columns[0] === '_key' |
|||
170 | ) { |
||||
171 | 60 | return; |
|||
172 | } |
||||
173 | |||||
174 | 78 | $options = [ |
|||
175 | 78 | 'type' => $command->type, |
|||
176 | 78 | 'fields' => $command->columns, |
|||
177 | 78 | 'unique' => $command->unique, |
|||
178 | 78 | 'options' => $command->indexOptions, |
|||
179 | 78 | ]; |
|||
180 | |||||
181 | 78 | if (isset($command->indexOptions) && is_array($command->indexOptions)) { |
|||
0 ignored issues
–
show
|
|||||
182 | 78 | $options = array_merge($options, $command->indexOptions); |
|||
183 | } |
||||
184 | |||||
185 | 78 | $this->schemaManager->createIndex($this->table, $options); |
|||
186 | } |
||||
187 | |||||
188 | /** |
||||
189 | * Indicate that the given index should be dropped. |
||||
190 | */ |
||||
191 | 12 | public function dropIndex(string $name): Fluent |
|||
192 | { |
||||
193 | 12 | $parameters = []; |
|||
194 | 12 | $parameters['name'] = 'dropIndex'; |
|||
195 | 12 | $parameters['index'] = $name; |
|||
196 | 12 | $parameters['explanation'] = "Drop the '" . $name . "' index on the {$this->table} table."; |
|||
197 | 12 | $parameters['handler'] = 'collection'; |
|||
198 | |||||
199 | 12 | return $this->addCommand('dropIndex', $parameters); |
|||
200 | } |
||||
201 | |||||
202 | /** |
||||
203 | * Indicate that the given index should be dropped. |
||||
204 | */ |
||||
205 | public function dropPersistentIndex(string $name): Fluent |
||||
206 | { |
||||
207 | return $this->dropIndex($name); |
||||
208 | } |
||||
209 | |||||
210 | /** |
||||
211 | * Indicate that the given index should be dropped. |
||||
212 | */ |
||||
213 | 1 | public function dropPrimary(string $name): Fluent |
|||
214 | { |
||||
215 | 1 | return $this->dropIndex($name); |
|||
216 | } |
||||
217 | |||||
218 | /** |
||||
219 | * Indicate that the given index should be dropped. |
||||
220 | */ |
||||
221 | 1 | public function dropUnique(string $name): Fluent |
|||
222 | { |
||||
223 | 1 | return $this->dropIndex($name); |
|||
224 | } |
||||
225 | |||||
226 | /** |
||||
227 | * Indicate that the given index should be dropped. |
||||
228 | */ |
||||
229 | 2 | public function dropSpatialIndex(string $name): Fluent |
|||
230 | { |
||||
231 | 2 | return $this->dropIndex($name); |
|||
232 | } |
||||
233 | |||||
234 | /** |
||||
235 | * Indicate that the given index should be dropped. |
||||
236 | */ |
||||
237 | 2 | public function dropInvertedIndex(string $name): Fluent |
|||
238 | { |
||||
239 | 2 | return $this->dropIndex($name); |
|||
240 | } |
||||
241 | |||||
242 | /** |
||||
243 | * Indicate that the given index should be dropped. |
||||
244 | */ |
||||
245 | 2 | public function dropMultiDimensionalIndex(string $name): Fluent |
|||
246 | { |
||||
247 | 2 | return $this->dropIndex($name); |
|||
248 | } |
||||
249 | |||||
250 | /** |
||||
251 | * Drop the index by first getting all the indexes on the table; then selecting the matching one |
||||
252 | * by name. |
||||
253 | */ |
||||
254 | 12 | public function executeDropIndexCommand(Fluent $command) |
|||
255 | { |
||||
256 | 12 | if ($this->connection->pretending()) { |
|||
257 | $this->connection->logQuery('/* ' . $command->explanation . " */\n", []); // @phpstan-ignore-line |
||||
258 | |||||
259 | return; |
||||
260 | } |
||||
261 | 12 | $indexes = $this->schemaManager->getIndexes($this->table); |
|||
262 | 12 | $arrayIndex = array_search($command->index, array_column($indexes, 'name'), true); |
|||
263 | 12 | $indexId = $indexes[$arrayIndex]->id; |
|||
264 | |||||
265 | 12 | $this->schemaManager->deleteIndex($indexId); |
|||
266 | } |
||||
267 | |||||
268 | /** |
||||
269 | * @param string|null $algorithm |
||||
270 | * @return mixed|string |
||||
271 | */ |
||||
272 | 68 | protected function mapIndexAlgorithm($algorithm): mixed |
|||
273 | { |
||||
274 | 68 | $algorithm = strtoupper($algorithm); |
|||
0 ignored issues
–
show
It seems like
$algorithm can also be of type null ; however, parameter $string of strtoupper() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
275 | |||||
276 | 68 | $algorithmConversion = [ |
|||
277 | 68 | 'HASH' => 'hash', |
|||
278 | 68 | 'BTREE' => 'persistent', |
|||
279 | 68 | 'RTREE' => 'geo', |
|||
280 | 68 | 'TTL' => 'ttl', |
|||
281 | 68 | ]; |
|||
282 | |||||
283 | 68 | return (isset($algorithmConversion[$algorithm])) ? $algorithmConversion[$algorithm] : 'persistent'; |
|||
284 | } |
||||
285 | |||||
286 | } |
||||
287 |