Passed
Push — next ( e3594a...9991ed )
by Bas
10:46 queued 05:19
created

Builder::hasIndex()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 4
nop 4
dl 0
loc 13
ccs 7
cts 7
cp 1
crap 3
rs 10
c 0
b 0
f 0
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 126
    public function __construct(Connection $connection)
63
    {
64 126
        $this->connection = $connection;
65
66 126
        $this->grammar = $connection->getSchemaGrammar();
67
68 126
        $this->schemaManager = $connection->getArangoClient()->schema();
69
70 126
        $this->prefixIndexes = $this->connection->getConfig('prefix_indexes');
71
72 126
        $this->prefix = $this->prefixIndexes
73
            ? $this->connection->getConfig('prefix')
74 126
            : '';
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 10
    public function getTable($name): array
111
    {
112 10
        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->schemaManager->getCollections(false);
125
    }
126
127
    /**
128
     * Get the tables that belong to the database.
129
     *
130
     * @return array<mixed>
131
     * @throws ArangoException
132
     */
133 55
    public function getTables()
134
    {
135 55
        return $this->schemaManager->getCollections(true);
136
    }
137
138
    /**
139
     * Rename a table (collection).
140
     *
141
     * @param  string  $from
142
     * @param  string  $to
143
     *
144
     * @throws ArangoException
145
     */
146 2
    public function rename($from, $to): bool
147
    {
148 2
        return (bool) $this->schemaManager->renameCollection($from, $to);
149
    }
150
151
    /**
152
     * Drop a table (collection) from the schema.
153
     *
154
     * @throws ArangoException
155
     */
156 19
    public function drop($table)
157
    {
158 19
        $this->schemaManager->deleteCollection($table);
159
    }
160
161
    /**
162
     * Drop all tables (collections) from the schema.
163
     *
164
     * @throws ArangoException
165
     */
166 45
    public function dropAllTables(): void
167
    {
168 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

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