Passed
Push — 152-support-field-properties-f... ( af2be7 )
by Bas
04:09
created

Builder::rename()   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
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LaravelFreelancerNL\Aranguent\Schema;
6
7
use ArangoClient\Exceptions\ArangoException;
8
use ArangoClient\Schema\SchemaManager;
9
use Closure;
10
use Illuminate\Support\Facades\Log;
11
use Illuminate\Support\Fluent;
12
use LaravelFreelancerNL\Aranguent\Connection;
13
use LaravelFreelancerNL\Aranguent\Exceptions\QueryException;
14
use LaravelFreelancerNL\Aranguent\Schema\Concerns\HandlesAnalyzers;
15
use LaravelFreelancerNL\Aranguent\Schema\Concerns\HandlesViews;
16
use LaravelFreelancerNL\Aranguent\Schema\Concerns\UsesBlueprints;
17
18
class Builder extends \Illuminate\Database\Schema\Builder
19
{
20
    use HandlesAnalyzers;
21
    use HandlesViews;
0 ignored issues
show
Bug introduced by
The trait LaravelFreelancerNL\Aran...a\Concerns\HandlesViews requires the property $name which is not provided by LaravelFreelancerNL\Aranguent\Schema\Builder.
Loading history...
22
    use UsesBlueprints;
23
24
    /**
25
     * The database connection instance.
26
     *
27
     * @var Connection
28
     */
29
    protected $connection;
30
31
    public SchemaManager $schemaManager;
32
33
    /**
34
     * The schema grammar instance.
35
     *
36
     * @var Grammar
37
     */
38
    public $grammar;
39
40
41
    /**
42
     * index prefixes?
43
     */
44
    public ?bool $prefixIndexes;
45
46
    /**
47
     * The table prefix.
48
     */
49
    public string $prefix;
50
51
    /**
52
     * Create a new database Schema manager.
53
     *
54
     * Builder constructor.
55
     */
56 93
    public function __construct(Connection $connection)
57
    {
58 93
        $this->connection = $connection;
59
60 93
        $this->grammar = $connection->getSchemaGrammar();
61
62 93
        $this->schemaManager = $connection->getArangoClient()->schema();
63
64 93
        $this->prefixIndexes = $this->connection->getConfig('prefix_indexes');
65
66 93
        $this->prefix = $this->prefixIndexes
67
            ? $this->connection->getConfig('prefix')
68 93
            : '';
69
70
    }
71
72
    /**
73
     * Determine if the given table exists.
74
     *
75
     * @param  string  $table
76
     * @return bool
77
     */
78 53
    public function hasTable($table)
79
    {
80 53
        return $this->handleExceptionsAsQueryExceptions(function () use ($table) {
81 53
            return $this->schemaManager->hasCollection($table);
82 53
        });
83
    }
84
85
    /**
86
     * @throws ArangoException
87
     */
88 14
    public function dropIfExists($table): void
89
    {
90 14
        $tableExists = $this->hasTable($table);
91 14
        if ($tableExists) {
92 14
            $this->drop($table);
93
        }
94
    }
95
96
    /**
97
     * Get all the tables for the database; excluding ArangoDB system collections
98
     *
99
     * @return array<mixed>
100
     *
101
     * @throws ArangoException
102
     */
103 33
    public function getAllTables(): array
104
    {
105 33
        return $this->schemaManager->getCollections(true);
106
    }
107
108
    /**
109
     * Get the tables that belong to the database.
110
     *
111
     * @return array
112
     * @throws ArangoException
113
     */
114 1
    public function getTables()
115
    {
116 1
        return $this->schemaManager->getCollections(true);
117
    }
118
119
    /**
120
     * Rename a table (collection).
121
     *
122
     * @param  string  $from
123
     * @param  string  $to
124
     *
125
     * @throws ArangoException
126
     */
127 2
    public function rename($from, $to): bool
128
    {
129 2
        return (bool) $this->schemaManager->renameCollection($from, $to);
130
    }
131
132
    /**
133
     * Drop a table (collection) from the schema.
134
     *
135
     * @throws ArangoException
136
     */
137 19
    public function drop($table)
138
    {
139 19
        $this->schemaManager->deleteCollection($table);
140
    }
141
142
    /**
143
     * Drop all tables (collections) from the schema.
144
     *
145
     * @throws ArangoException
146
     */
147 33
    public function dropAllTables(): void
148
    {
149 33
        $collections = $this->getAllTables();
150
151 33
        foreach ($collections as $name) {
152 33
            $this->schemaManager->deleteCollection($name->name);
153
        }
154
    }
155
156
    /**
157
     * Determine if the given table has a given column.
158
     *
159
     * @param  string  $table
160
     * @param string|string[] $column
161
     * @return bool
162
     */
163 7
    public function hasColumn($table, $column)
164
    {
165 7
        return $this->hasColumns($table, $column);
166
    }
167
168
    /**
169
     * Determine if the given table has given columns.
170
     *
171
     * @param string $table
172
     * @param string|string[] $columns
173
     * @return bool
174
     */
175 7
    public function hasColumns($table, $columns)
176
    {
177 7
        if (is_string($columns)) {
178 5
            $columns = [$columns];
179
        }
180
181 7
        $parameters = [];
182 7
        $parameters['name'] = 'hasColumn';
183 7
        $parameters['handler'] = 'aql';
184 7
        $parameters['columns'] = $columns;
185
186 7
        $command = new Fluent($parameters);
187
188 7
        $compilation = $this->grammar->compileHasColumn($table, $command);
189 7
        return $this->connection->select($compilation['aqb'])[0];
190
    }
191
192
    /**
193
     * Create a default index name for the table.
194
     *
195
     * @param  string  $type
196
     */
197 1
    public function createIndexName(string $table, string $type, array $columns, array $options = []): string
198
    {
199 1
        $nameParts = [];
200 1
        $nameParts[] = $this->prefix . $table;
201 1
        $nameParts = array_merge($nameParts, $columns);
202 1
        $nameParts[] = $type;
203 1
        $nameParts = array_merge($nameParts, array_keys($options));
204 1
        array_filter($nameParts);
205
206 1
        $index = strtolower(implode('_', $nameParts));
207 1
        $index = preg_replace("/\[\*+\]+/", '_array', $index);
208
209 1
        return preg_replace('/[^A-Za-z0-9]+/', '_', $index);
210
    }
211
212
    /**
213
     * Determine if the given table has a given index.
214
     *
215
     * @param  string  $table
216
     * @param  string|array<string>  $index
217
     * @param  string|null  $type
218
     * @return bool
219
     */
220 2
    public function hasIndex($table, $index, $type = null, array $options = [])
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

220
    public function hasIndex($table, $index, $type = null, /** @scrutinizer ignore-unused */ array $options = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
221
    {
222 2
        $name = $index;
223
224 2
        if ($type === null) {
225 2
            $type = 'persistent';
226
        }
227
228 2
        if (is_array($index)) {
229 1
            $name = $this->createIndexName($table, $type, $index, $options = []);
230
        }
231
232 2
        return !!$this->schemaManager->getIndexByName($table, $name);
0 ignored issues
show
Bug introduced by
It seems like $name can also be of type string[]; however, parameter $name of ArangoClient\Schema\Sche...nager::getIndexByName() 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

232
        return !!$this->schemaManager->getIndexByName($table, /** @scrutinizer ignore-type */ $name);
Loading history...
233
    }
234
235
    /**
236
     * Create a database in the schema.
237
     *
238
     * @param  string  $name
239
     * @return bool
240
     *
241
     * @throws ArangoException
242
     */
243 4
    public function createDatabase($name)
244
    {
245 4
        return $this->schemaManager->createDatabase($name);
246
    }
247
248
    /**
249
     * Drop a database from the schema if the database exists.
250
     *
251
     * @param  string  $name
252
     * @return bool
253
     *
254
     * @throws ArangoException
255
     */
256 4
    public function dropDatabaseIfExists($name)
257
    {
258 4
        if ($this->schemaManager->hasDatabase($name)) {
259 2
            return $this->schemaManager->deleteDatabase($name);
260
        }
261
262 2
        return true;
263
    }
264
265
    /**
266
     * Get the database connection instance.
267
     *
268
     * @return Connection
269
     */
270 1
    public function getConnection()
271
    {
272 1
        return $this->connection;
273
    }
274
275
    /**
276
     * @throws QueryException
277
     */
278 55
    protected function handleExceptionsAsQueryExceptions(Closure $callback): mixed
279
    {
280
        try {
281 55
            return $callback();
282 1
        } catch (\Exception $e) {
283 1
            throw new QueryException($this->connection->getName(), $e->getMessage(), [], $e);
284
        }
285
    }
286
287
    /**
288
     * Disable foreign key constraints during the execution of a callback.
289
     *
290
     * ArangoDB doesn't have foreign keys so this is just a dummy to keep things working
291
     * for functionality that expect this method.
292
     *
293
     * @param  \Closure  $callback
294
     * @return mixed
295
     */
296 1
    public function withoutForeignKeyConstraints(Closure $callback)
297
    {
298 1
        return $callback();
299
    }
300
301
    /**
302
     * Silently catch the use of unsupported builder methods.
303
     */
304 2
    public function __call($method, $parameters)
305
    {
306 2
        Log::warning("The ArangoDB driver's schema builder doesn't support method '$method'\n");
307
    }
308
}
309