Failed Conditions
Push — master ( 11c8ec...b620eb )
by Bas
05:48 queued 10s
created

Indexes::executeIndexCommand()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.0961

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 11
nc 3
nop 1
dl 0
loc 20
ccs 9
cts 11
cp 0.8182
crap 4.0961
rs 9.9
c 1
b 0
f 0
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Schema\Concerns;
4
5
use ArangoDBClient\Exception;
6
use Illuminate\Support\Fluent;
7
8
trait Indexes
9
{
10
    /**
11
     * Add a new index command to the blueprint.
12
     *
13
     * @param string            $type
14
     * @param string|array|null $columns
15
     * @param $name
16
     * @param array $indexOptions
17
     *
18
     * @return Fluent
19
     */
20 7
    protected function indexCommand($type = '', $columns = null, $name = null, $indexOptions = [])
21
    {
22 7
        if ($type == '') {
23
            $type = $this->mapIndexAlgorithm('persistent');
24
        }
25
26 7
        if ($columns === null) {
27 3
            $columns = end($this->columns);
28
        }
29
30 7
        if (is_string($columns)) {
31 3
            $columns = [$columns];
32
        }
33
34 7
        $indexOptions['name'] = $name ?: $this->createIndexName($type, $columns, $indexOptions);
0 ignored issues
show
Bug introduced by
It seems like $columns can also be of type null and string; however, parameter $columns of LaravelFreelancerNL\Aran...exes::createIndexName() does only seem to accept array, 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

34
        $indexOptions['name'] = $name ?: $this->createIndexName($type, /** @scrutinizer ignore-type */ $columns, $indexOptions);
Loading history...
35
36 7
        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

36
        return $this->/** @scrutinizer ignore-call */ addCommand('index', compact('type', 'columns', 'indexOptions'));
Loading history...
37
    }
38
39
    /**
40
     * Specify an index for the table.
41
     *
42
     * @param string|array $columns
43
     * @param string       $name
44
     * @param string|null  $algorithm
45
     *
46
     * @return Fluent
47
     */
48 7
    public function index($columns = null, $name = null, $algorithm = null)
49
    {
50 7
        $type = $this->mapIndexAlgorithm($algorithm);
51
52 7
        return $this->indexCommand($type, $columns, $name);
53
    }
54
55
    /**
56
     * Create a hash index for fast exact matching.
57
     *
58
     * @param null  $columns
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $columns is correct as it would always require null to be passed?
Loading history...
59
     * @param array $indexOptions
60
     *
61
     * @return Fluent
62
     */
63
    public function hashIndex($columns = null, $indexOptions = [])
64
    {
65
        return $this->indexCommand('hash', $columns, $indexOptions);
66
    }
67
68
    /**
69
     * @param null|string $column
70
     * @param $name
71
     * @param array $indexOptions
72
     *
73
     * @return Fluent
74
     */
75
    public function fulltextIndex($column = null, $name = null, $indexOptions = [])
76
    {
77
        return $this->indexCommand('fulltext', $column, $name, $indexOptions);
78
    }
79
80
    /**
81
     *  Specify a spatial index for the table.
82
     *
83
     * @param $columns
84
     * @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...
85
     * @param array $indexOptions
86
     *
87
     * @return Fluent
88
     */
89
    public function geoIndex($columns, $name = null, $indexOptions = [])
90
    {
91
        return $this->indexCommand('geo', $columns, $name, $indexOptions);
92
    }
93
94
    /**
95
     * Specify a spatial index for the table.
96
     *
97
     * @param string|array $columns
98
     * @param string       $name
99
     *
100
     * @return Fluent
101
     */
102
    public function spatialIndex($columns, $name = null)
103
    {
104
        return $this->geoIndex($columns, $name);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type string; however, parameter $name of LaravelFreelancerNL\Aran...rns\Indexes::geoIndex() does only seem to accept null, 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

104
        return $this->geoIndex($columns, /** @scrutinizer ignore-type */ $name);
Loading history...
105
    }
106
107
    /**
108
     * @param $columns
109
     * @param string|null $name
110
     * @param array       $indexOptions
111
     *
112
     * @return Fluent
113
     */
114
    public function skiplistIndex($columns, $name = null, $indexOptions = [])
115
    {
116
        return $this->indexCommand('skiplist', $columns, $name, $indexOptions);
117
    }
118
119
    public function persistentIndex($columns, $name = null, $indexOptions = [])
120
    {
121
        return $this->indexCommand('persistent', $columns, $name, $indexOptions);
122
    }
123
124
    /**
125
     * Create a TTL index for the table.
126
     *
127
     * @param $columns
128
     * @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...
129
     * @param array $indexOptions
130
     *
131
     * @return Fluent
132
     */
133
    public function ttlIndex($columns, $name = null, $indexOptions = [])
134
    {
135
        return $this->indexCommand('ttl', $columns, $name, $indexOptions);
136
    }
137
138
    /**
139
     * Specify a unique index for the table.
140
     *
141
     * @param string|array $columns
142
     * @param string       $name
143
     * @param string|null  $algorithm
144
     *
145
     * @return Fluent
146
     */
147 1
    public function unique($columns = null, $name = null, $algorithm = null)
148
    {
149 1
        $type = $this->mapIndexAlgorithm($algorithm);
150
151 1
        $indexOptions = [];
152 1
        $indexOptions['unique'] = true;
153
154 1
        return $this->indexCommand($type, $columns, $name, $indexOptions);
155
    }
156
157
    /**
158
     * @param $command
159
     *
160
     * @throws Exception
161
     */
162 7
    public function executeIndexCommand($command)
163
    {
164 7
        if ($this->connection->pretending()) {
165
            $this->connection->logQuery('/* ' . $command->explanation . " */\n", []);
166
167
            return;
168
        }
169
170
        $options = [
171 7
            'type'    => $command->type,
172 7
            'fields'  => $command->columns,
173 7
            'unique'  => $command->unique,
174 7
            'options' => $command->indexOptions,
175
        ];
176
177 7
        if (isset($command->indexOptions) && is_array($command->indexOptions)) {
178 7
            $options = array_merge($options, $command->indexOptions);
179
        }
180
181 7
        $this->collectionHandler->createIndex($this->table, $options);
182 7
    }
183
184
    /**
185
     * Indicate that the given index should be dropped.
186
     *
187
     * @param $name
188
     *
189
     * @return Fluent
190
     */
191 3
    public function dropIndex($name)
192
    {
193 3
        $parameters = [];
194 3
        $parameters['name'] = 'dropIndex';
195 3
        $parameters['index'] = $name;
196 3
        $parameters['explanation'] = "Drop the '" . $name . "' index on the {$this->table} table.";
197 3
        $parameters['handler'] = 'collection';
198
199 3
        return $this->addCommand('dropIndex', $parameters);
200
    }
201
202
    /**
203
     * Drop the index by first getting all the indexes on the table; then selecting the matching one
204
     * by type and columns.
205
     *
206
     * @param $command
207
     */
208 3
    public function executeDropIndexCommand($command)
209
    {
210 3
        if ($this->connection->pretending()) {
211
            $this->connection->logQuery('/* ' . $command->explanation . " */\n", []);
212
213
            return;
214
        }
215 3
        $this->collectionHandler->dropIndex($this->table, $command->index);
216 3
    }
217
218
    /**
219
     * @param string|null $algorithm
220
     *
221
     * @return mixed|string
222
     */
223 7
    protected function mapIndexAlgorithm($algorithm)
224
    {
225
        $algorithmConversion = [
226 7
            'HASH'  => 'hash',
227
            'BTREE' => 'persistent',
228
            'RTREE' => 'geo',
229
            'TTL'   => 'ttl',
230
        ];
231 7
        $algorithm = strtoupper($algorithm);
232
233 7
        return (isset($algorithmConversion[$algorithm])) ? $algorithmConversion[$algorithm] : 'persistent';
234
    }
235
236
    /**
237
     * Create a default index name for the table.
238
     *
239
     * @param string $type
240
     * @param array  $columns
241
     * @param array  $options
242
     *
243
     * @return string
244
     */
245 9
    public function createIndexName($type, array $columns, array $options = [])
246
    {
247 9
        $nameParts = [];
248 9
        $nameParts[] = $this->prefix . $this->table;
249 9
        $nameParts = array_merge($nameParts, $columns);
250 9
        $nameParts[] = $type;
251 9
        $nameParts = array_merge($nameParts, array_keys($options));
252 9
        array_filter($nameParts);
253
254 9
        $index = strtolower(implode('_', $nameParts));
255 9
        $index = preg_replace("/\[\*+\]+/", '_array', $index);
256
257 9
        return preg_replace('/[^A-Za-z0-9]+/', '_', $index);
258
    }
259
}
260