Passed
Push — next ( 381d12...e3594a )
by Bas
05:57
created

Builder   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 284
Duplicated Lines 0 %

Test Coverage

Coverage 98.46%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 58
dl 0
loc 284
ccs 64
cts 65
cp 0.9846
rs 10
c 2
b 1
f 0
wmc 26

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __call() 0 3 1
A __construct() 0 13 2
A dropIfExists() 0 5 2
A hasTable() 0 4 1
A rename() 0 3 1
A drop() 0 3 1
A getAllTables() 0 3 1
A createDatabase() 0 3 1
A getConnection() 0 3 1
A dropAllTables() 0 6 2
A hasColumn() 0 3 1
A handleExceptionsAsQueryExceptions() 0 6 2
A getTable() 0 3 1
A hasColumns() 0 15 2
A dropDatabaseIfExists() 0 7 2
A withoutForeignKeyConstraints() 0 3 1
A hasIndex() 0 13 3
A getTables() 0 3 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\HandlesIndexNaming;
16
use LaravelFreelancerNL\Aranguent\Schema\Concerns\HandlesGraphs;
17
use LaravelFreelancerNL\Aranguent\Schema\Concerns\HandlesViews;
18
use LaravelFreelancerNL\Aranguent\Schema\Concerns\UsesBlueprints;
19
20
class Builder extends \Illuminate\Database\Schema\Builder
21
{
22
    use HandlesAnalyzers;
23
    use HandlesIndexNaming;
0 ignored issues
show
Bug introduced by
The trait LaravelFreelancerNL\Aran...erns\HandlesIndexNaming requires the property $table which is not provided by LaravelFreelancerNL\Aranguent\Schema\Builder.
Loading history...
24
    use HandlesGraphs;
25
    use HandlesViews;
26
    use UsesBlueprints;
27
28
    /**
29
     * The database connection instance.
30
     *
31
     * @var Connection
32
     */
33
    protected $connection;
34
35
    public SchemaManager $schemaManager;
36
37
    /**
38
     * The schema grammar instance.
39
     *
40
     * @var Grammar
41
     */
42
    public $grammar;
43
44
45
    /**
46
     * index prefixes?
47
     */
48
    public ?bool $prefixIndexes;
49
50
    /**
51
     * The table prefix.
52
     */
53
    public string $prefix;
54
55
    /**
56
     * Create a new database Schema manager.
57
     *
58
     * Builder constructor.
59
     */
60 122
    public function __construct(Connection $connection)
61
    {
62 122
        $this->connection = $connection;
63
64 122
        $this->grammar = $connection->getSchemaGrammar();
65
66 122
        $this->schemaManager = $connection->getArangoClient()->schema();
67
68 122
        $this->prefixIndexes = $this->connection->getConfig('prefix_indexes');
69
70 122
        $this->prefix = $this->prefixIndexes
71
            ? $this->connection->getConfig('prefix')
72 122
            : '';
73
74
    }
75
76
    /**
77
     * Determine if the given table exists.
78
     *
79
     * @param  string  $table
80
     * @return bool
81
     */
82 66
    public function hasTable($table)
83
    {
84 66
        return $this->handleExceptionsAsQueryExceptions(function () use ($table) {
85 66
            return $this->schemaManager->hasCollection($table);
86 66
        });
87
    }
88
89
    /**
90
     * @throws ArangoException
91
     */
92 14
    public function dropIfExists($table): void
93
    {
94 14
        $tableExists = $this->hasTable($table);
95 14
        if ($tableExists) {
96 14
            $this->drop($table);
97
        }
98
    }
99
100
    /**
101
     * Get all the tables for the database; excluding ArangoDB system collections
102
     *
103
     * @param string $name
104
     * @return array<mixed>
105
     *
106
     * @throws ArangoException
107
     */
108 6
    public function getTable($name): array
109
    {
110 6
        return (array) $this->schemaManager->getCollectionStatistics($name);
111
    }
112
113
    /**
114
     * Get all the tables for the database; including ArangoDB system tables
115
     *
116
     * @return array<mixed>
117
     *
118
     * @throws ArangoException
119
     */
120 1
    public function getAllTables(): array
121
    {
122 1
        return $this->schemaManager->getCollections(false);
123
    }
124
125
    /**
126
     * Get the tables that belong to the database.
127
     *
128
     * @return array<mixed>
129
     * @throws ArangoException
130
     */
131 51
    public function getTables()
132
    {
133 51
        return $this->schemaManager->getCollections(true);
134
    }
135
136
    /**
137
     * Rename a table (collection).
138
     *
139
     * @param  string  $from
140
     * @param  string  $to
141
     *
142
     * @throws ArangoException
143
     */
144 2
    public function rename($from, $to): bool
145
    {
146 2
        return (bool) $this->schemaManager->renameCollection($from, $to);
147
    }
148
149
    /**
150
     * Drop a table (collection) from the schema.
151
     *
152
     * @throws ArangoException
153
     */
154 19
    public function drop($table)
155
    {
156 19
        $this->schemaManager->deleteCollection($table);
157
    }
158
159
    /**
160
     * Drop all tables (collections) from the schema.
161
     *
162
     * @throws ArangoException
163
     */
164 45
    public function dropAllTables(): void
165
    {
166 45
        $collections = $this->getTables(true);
0 ignored issues
show
Unused Code introduced by
The call to LaravelFreelancerNL\Aran...ma\Builder::getTables() has too many arguments starting with true. ( Ignorable by Annotation )

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

166
        /** @scrutinizer ignore-call */ 
167
        $collections = $this->getTables(true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
167
168 45
        foreach ($collections as $name) {
169 45
            $this->schemaManager->deleteCollection($name->name);
170
        }
171
    }
172
173
    /**
174
     * Determine if the given table has a given column.
175
     *
176
     * @param  string  $table
177
     * @param string|string[] $column
178
     * @return bool
179
     */
180 7
    public function hasColumn($table, $column)
181
    {
182 7
        return $this->hasColumns($table, $column);
183
    }
184
185
    /**
186
     * Determine if the given table has given columns.
187
     *
188
     * @param string $table
189
     * @param string|string[] $columns
190
     * @return bool
191
     */
192 7
    public function hasColumns($table, $columns)
193
    {
194 7
        if (is_string($columns)) {
195 5
            $columns = [$columns];
196
        }
197
198 7
        $parameters = [];
199 7
        $parameters['name'] = 'hasColumn';
200 7
        $parameters['handler'] = 'aql';
201 7
        $parameters['columns'] = $columns;
202
203 7
        $command = new Fluent($parameters);
204
205 7
        $compilation = $this->grammar->compileHasColumn($table, $command);
206 7
        return $this->connection->select($compilation['aqb'])[0];
207
    }
208
209
    /**
210
     * Determine if the given table has a given index.
211
     *
212
     * @param  string  $table
213
     * @param  string|array<string>  $index
214
     * @param  string|null  $type
215
     * @return bool
216
     */
217 2
    public function hasIndex($table, $index, $type = null, array $options = [])
218
    {
219 2
        $name = $index;
220
221 2
        if ($type === null) {
222 2
            $type = 'persistent';
223
        }
224
225 2
        if (is_array($index)) {
226 1
            $name = $this->createIndexName($type, $index, $options, $table);
227
        }
228
229 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

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