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

Builder   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 298
Duplicated Lines 0 %

Test Coverage

Coverage 98.63%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 64
dl 0
loc 298
ccs 72
cts 73
cp 0.9863
rs 10
c 2
b 1
f 0
wmc 25

19 Methods

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

172
        /** @scrutinizer ignore-call */ 
173
        $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...
173
174 45
        foreach ($collections as $name) {
175 45
            $this->schemaManager->deleteCollection($name['name']);
176
        }
177
    }
178
179
    /**
180
     * Determine if the given table has a given column.
181
     *
182
     * @param  string  $table
183
     * @param string|string[] $column
184
     * @return bool
185
     */
186 7
    public function hasColumn($table, $column)
187
    {
188 7
        return $this->hasColumns($table, $column);
189
    }
190
191
    /**
192
     * Determine if the given table has given columns.
193
     *
194
     * @param string $table
195
     * @param string|string[] $columns
196
     * @return array<mixed>
197
     */
198 8
    public function getColumns($table)
199
    {
200 8
        $parameters = [];
201 8
        $parameters['name'] = 'columns';
202 8
        $parameters['handler'] = 'aql';
203 8
        $parameters['table'] = $table;
204
205 8
        $command = new Fluent($parameters);
206
207 8
        $compilation = $this->grammar->compileColumns($table, $command);
208
209 8
        $rawColumns = $this->connection->select($compilation['aqb'], $compilation['bindings']);
210
211 8
        return $this->mapResultsToArray($rawColumns);
212
    }
213
214
    /**
215
     * Determine if the given table has given columns.
216
     *
217
     * @param string $table
218
     * @param string|string[] $columns
219
     * @return bool
220
     */
221 7
    public function hasColumns($table, $columns)
222
    {
223 7
        if (is_string($columns)) {
224 5
            $columns = [$columns];
225
        }
226
227 7
        $parameters = [];
228 7
        $parameters['name'] = 'hasColumn';
229 7
        $parameters['handler'] = 'aql';
230 7
        $parameters['columns'] = $columns;
231
232 7
        $command = new Fluent($parameters);
233
234 7
        $compilation = $this->grammar->compileHasColumn($table, $command);
235 7
        return $this->connection->select($compilation['aqb'])[0];
236
    }
237
238
    /**
239
     * Create a database in the schema.
240
     *
241
     * @param  string  $name
242
     * @return bool
243
     *
244
     * @throws ArangoException
245
     */
246 4
    public function createDatabase($name)
247
    {
248 4
        return $this->schemaManager->createDatabase($name);
249
    }
250
251
    /**
252
     * Drop a database from the schema if the database exists.
253
     *
254
     * @param  string  $name
255
     * @return bool
256
     *
257
     * @throws ArangoException
258
     */
259 4
    public function dropDatabaseIfExists($name)
260
    {
261 4
        if ($this->schemaManager->hasDatabase($name)) {
262 2
            return $this->schemaManager->deleteDatabase($name);
263
        }
264
265 2
        return true;
266
    }
267
268
    /**
269
     * Get the database connection instance.
270
     *
271
     * @return Connection
272
     */
273 1
    public function getConnection()
274
    {
275 1
        return $this->connection;
276
    }
277
278
    /**
279
     * @throws QueryException
280
     */
281 70
    protected function handleExceptionsAsQueryExceptions(Closure $callback): mixed
282
    {
283
        try {
284 70
            return $callback();
285 1
        } catch (\Exception $e) {
286 1
            throw new QueryException($this->connection->getName(), $e->getMessage(), [], $e);
287
        }
288
    }
289
290
    /**
291
     * Disable foreign key constraints during the execution of a callback.
292
     *
293
     * ArangoDB doesn't have foreign keys so this is just a dummy to keep things working
294
     * for functionality that expect this method.
295
     *
296
     * @param  \Closure  $callback
297
     * @return mixed
298
     */
299 1
    public function withoutForeignKeyConstraints(Closure $callback)
300
    {
301 1
        return $callback();
302
    }
303
304
    /**
305
     * @param mixed[] $results
306
     * @return mixed[]
307
     */
308 65
    protected function mapResultsToArray($results)
309
    {
310 65
        return array_map(function ($result) { return (array) $result; }, $results);
311
    }
312
313
    /**
314
     * Silently catch the use of unsupported builder methods.
315
     */
316 2
    public function __call($method, $parameters)
317
    {
318 2
        Log::warning("The ArangoDB driver's schema builder doesn't support method '$method'\n");
319
    }
320
}
321