Passed
Push — 127-support-multidimensional-i... ( fe24b7 )
by Bas
10:53 queued 06:57
created

Indexes::dropInvertedIndex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Schema\Concerns;
4
5
use ArangoClient\Exceptions\ArangoException;
6
use Illuminate\Support\Fluent;
7
8
trait Indexes
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 66
    protected function indexCommand(
18
        string $type,
19
        array|null|string $columns = null,
20
        string $name = null,
21
        array $indexOptions = [],
22
    ): Fluent {
23 66
        if ($columns === null) {
24 50
            $columns = end($this->columns);
25
        }
26
27 66
        if (is_string($columns)) {
28 55
            $columns = [$columns];
29
        }
30
31 66
        $columns = $this->renameIdField($columns);
0 ignored issues
show
Bug introduced by
It seems like renameIdField() 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 ignore-call  annotation

31
        /** @scrutinizer ignore-call */ 
32
        $columns = $this->renameIdField($columns);
Loading history...
32
33 66
        $indexOptions['name'] = $name ?: $this->createIndexName($type, $columns, $indexOptions);
34
35 66
        return $this->addCommand('index', compact('type', 'columns', 'indexOptions'));
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

35
        return $this->/** @scrutinizer ignore-call */ addCommand('index', compact('type', 'columns', 'indexOptions'));
Loading history...
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 56
    public function index($columns = null, $name = null, $algorithm = null, $indexOptions = [])
48
    {
49 56
        $type = $this->mapIndexAlgorithm($algorithm);
50
51 56
        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 49
    public function invertedIndex($columns = null, $name = null, $indexOptions = [])
89
    {
90 49
        return $this->indexCommand('inverted', $columns, $name, $indexOptions);
91
    }
92
93 1
    public function persistentIndex(array $columns = null, string $name = null, array $indexOptions = []): Fluent
94
    {
95 1
        return $this->indexCommand('persistent', $columns, $name, $indexOptions);
96
    }
97
98
    /**
99
     * @param array<string>|null|string $columns
100
     * @param string|null $name
101
     * @param array<mixed> $indexOptions
102
     * @return Fluent
103
     */
104 50
    public function primary($columns = null, $name = null, $indexOptions = []): Fluent
105
    {
106 50
        $indexOptions['unique'] = true;
107
108 50
        return $this->indexCommand('persistent', $columns, $name, $indexOptions);
109
    }
110
111
    /**
112
     * Create a TTL index for the table.
113
     *
114
     * @param string $columns
115
     * @param int $expireAfter
116
     * @param null $name
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $name is correct as it would always require null to be passed?
Loading history...
117
     * @param array $indexOptions
118
     * @return Fluent
119
     */
120 2
    public function ttlIndex($columns, $expireAfter, $name = null, $indexOptions = []): Fluent
121
    {
122 2
        $indexOptions['expireAfter'] = $expireAfter;
123 2
        return $this->indexCommand('ttl', $columns, $name, $indexOptions);
124
    }
125
126
    /**
127
     * Specify a unique index for the table.
128
     *
129
     * @param  string|array  $columns
130
     * @param  string  $name
131
     * @param  string|null  $algorithm
132
     */
133 49
    public function unique($columns = null, $name = null, $algorithm = null): Fluent
134
    {
135 49
        $type = $this->mapIndexAlgorithm($algorithm);
136
137 49
        $indexOptions = [];
138 49
        $indexOptions['unique'] = true;
139
140 49
        return $this->indexCommand($type, $columns, $name, $indexOptions);
141
    }
142
143
    /**
144
     * @throws ArangoException
145
     */
146 66
    public function executeIndexCommand(Fluent $command)
147
    {
148 66
        if ($this->connection->pretending()) {
149
            $this->connection->logQuery('/* ' . $command->explanation . " */\n", []);
150
151
            return;
152
        }
153
154
        // Skip persistent indexes set solely on id - ArangoDB already sets a unique index on _key.
155
        if (
156 66
            $command->type === 'persistent'
0 ignored issues
show
introduced by
The condition $command->type === 'persistent' is always false.
Loading history...
157 66
            && count($command->columns) === 1
158 66
            && $command->columns[0] === '_key'
159
        ) {
160 49
            return;
161
        }
162
163 65
        $options = [
164 65
            'type' => $command->type,
165 65
            'fields' => $command->columns,
166 65
            'unique' => $command->unique,
167 65
            'options' => $command->indexOptions,
168 65
        ];
169
170 65
        if (isset($command->indexOptions) && is_array($command->indexOptions)) {
0 ignored issues
show
introduced by
The condition is_array($command->indexOptions) is always false.
Loading history...
171 65
            $options = array_merge($options, $command->indexOptions);
172
        }
173
174 65
        $this->schemaManager->createIndex($this->table, $options);
175
    }
176
177
    /**
178
     * Indicate that the given index should be dropped.
179
     */
180 10
    public function dropIndex(string $name): Fluent
181
    {
182 10
        $parameters = [];
183 10
        $parameters['name'] = 'dropIndex';
184 10
        $parameters['index'] = $name;
185 10
        $parameters['explanation'] = "Drop the '" . $name . "' index on the {$this->table} table.";
186 10
        $parameters['handler'] = 'collection';
187
188 10
        return $this->addCommand('dropIndex', $parameters);
189
    }
190
191
    /**
192
     * Indicate that the given index should be dropped.
193
     */
194
    public function dropPersistentIndex(string $name): Fluent
195
    {
196
        return $this->dropIndex($name);
197
    }
198
199
    /**
200
     * Indicate that the given index should be dropped.
201
     */
202 1
    public function dropPrimary(string $name): Fluent
203
    {
204 1
        return $this->dropIndex($name);
205
    }
206
207
    /**
208
     * Indicate that the given index should be dropped.
209
     */
210 1
    public function dropUnique(string $name): Fluent
211
    {
212 1
        return $this->dropIndex($name);
213
    }
214
215
    /**
216
     * Indicate that the given index should be dropped.
217
     */
218 2
    public function dropSpatialIndex(string $name): Fluent
219
    {
220 2
        return $this->dropIndex($name);
221
    }
222
223
    /**
224
     * Indicate that the given index should be dropped.
225
     */
226 2
    public function dropInvertedIndex(string $name): Fluent
227
    {
228 2
        return $this->dropIndex($name);
229
    }
230
231
232
233
    /**
234
     * Drop the index by first getting all the indexes on the table; then selecting the matching one
235
     * by name.
236
     */
237 10
    public function executeDropIndexCommand(Fluent $command)
238
    {
239 10
        if ($this->connection->pretending()) {
240
            $this->connection->logQuery('/* ' . $command->explanation . " */\n", []); // @phpstan-ignore-line
241
242
            return;
243
        }
244 10
        $indexes = $this->schemaManager->getIndexes($this->table);
245 10
        $arrayIndex = array_search($command->index, array_column($indexes, 'name'), true);
246 10
        $indexId = $indexes[$arrayIndex]->id;
247
248 10
        $this->schemaManager->deleteIndex($indexId);
249
    }
250
251
    /**
252
     * @param  string|null  $algorithm
253
     * @return mixed|string
254
     */
255 57
    protected function mapIndexAlgorithm($algorithm): mixed
256
    {
257 57
        $algorithm = strtoupper($algorithm);
0 ignored issues
show
Bug introduced by
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 ignore-type  annotation

257
        $algorithm = strtoupper(/** @scrutinizer ignore-type */ $algorithm);
Loading history...
258
259 57
        $algorithmConversion = [
260 57
            'HASH' => 'hash',
261 57
            'BTREE' => 'persistent',
262 57
            'RTREE' => 'geo',
263 57
            'TTL' => 'ttl',
264 57
        ];
265
266 57
        return (isset($algorithmConversion[$algorithm])) ? $algorithmConversion[$algorithm] : 'persistent';
267
    }
268
269
}
270