Passed
Push — next ( bea07e...b4e6e6 )
by Bas
05:12 queued 01:45
created

IndexCommands::dropPersistentIndex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
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 79
        $indexOptions['name'] = $name ?: $this->createIndexName($type, $columns, $indexOptions);
34
35 79
        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 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
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...
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
introduced by
The condition $command->type === 'persistent' is always false.
Loading history...
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
introduced by
The condition is_array($command->indexOptions) is always false.
Loading history...
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
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

274
        $algorithm = strtoupper(/** @scrutinizer ignore-type */ $algorithm);
Loading history...
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