Completed
Push — master ( 6b0411...a61b3b )
by Bas
04:04
created

Connection::disconnect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 5
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent;
4
5
use ArangoDBClient\Exception;
6
use ArangoDBClient\Statement;
7
use ArangoDBClient\Connection as ArangoConnection;
8
use ArangoDBClient\GraphHandler as ArangoGraphHandler;
9
use ArangoDBClient\UserHandler as ArangoUserHandler;
10
use Illuminate\Database\Connection as IlluminateConnection;
11
use ArangoDBClient\DocumentHandler as ArangoDocumentHandler;
12
use Iterator;
13
use LaravelFreelancerNL\Aranguent\Concerns\DetectsDeadlocks;
14
use LaravelFreelancerNL\Aranguent\Query\Processors\Processor;
15
use LaravelFreelancerNL\Aranguent\Concerns\ManagesTransactions;
16
use ArangoDBClient\CollectionHandler as ArangoCollectionHandler;
17
use ArangoDBClient\ConnectionOptions as ArangoConnectionOptions;
18
use LaravelFreelancerNL\Aranguent\Query\Builder as QueryBuilder;
19
use LaravelFreelancerNL\Aranguent\Concerns\DetectsLostConnections;
20
use LaravelFreelancerNL\Aranguent\Schema\Builder as SchemaBuilder;
21
use LaravelFreelancerNL\Aranguent\Query\Grammars\Grammar as QueryGrammar;
22
use LaravelFreelancerNL\FluentAQL\QueryBuilder as FluentAQL;
23
use triagens\ArangoDb\ViewHandler as ArangoViewHandler;
0 ignored issues
show
Bug introduced by
The type triagens\ArangoDb\ViewHandler was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
25
class Connection extends IlluminateConnection
26
{
27
    use DetectsDeadlocks,
0 ignored issues
show
Bug introduced by
The trait LaravelFreelancerNL\Aran...rns\ManagesTransactions requires the property $collections which is not provided by LaravelFreelancerNL\Aranguent\Connection.
Loading history...
28
        DetectsLostConnections,
29
        ManagesTransactions;
30
31
    /**
32
     * {@inheritdoc}
33
     *
34
     * @var array
35
     */
36
    protected $defaultConfig = [
37
        ArangoConnectionOptions::OPTION_ENDPOINT => 'tcp://localhost:8529',
38
        ArangoConnectionOptions::OPTION_CONNECTION  => 'Keep-Alive',
39
        ArangoConnectionOptions::OPTION_AUTH_USER => null,
40
        ArangoConnectionOptions::OPTION_AUTH_PASSWD => null,
41
        'tablePrefix' => '',
42
    ];
43
44
    protected $config;
45
46
    protected $arangoConnection;
47
48
    protected $readArangoConnection;
49
50
    protected $reconnector;
51
52
    protected $database;
53
54
    protected $schemaGrammar;
55
56
    protected $queryGrammar;
57
58
    protected $pretending;
59
60
    protected $recordsModified;
61
62
    protected $loggingQueries;
63
64
    protected $queryLog;
65
66
    protected $collectionHandler;
67
68
    protected $viewHandler;
69
70
    protected $documentHandler;
71
72
    protected $graphHandler;
73
74
    protected $userHandler;
75
76
    /**
77
     * The ArangoDB driver name.
78
     *
79
     * @var string
80
     */
81
    protected $driverName = 'arangodb';
82
83
    /**
84
     * Connection constructor.
85
     *
86
     * @param array $config
87
     * @throws Exception
88
     */
89
    public function __construct($config = [])
90
    {
91
        $this->config = array_merge($this->defaultConfig, $config);
92
93
        if (isset($this->config ['database'])) {
94
            $this->database = $this->config ['database'];
95
        }
96
97
        $this->tablePrefix = $this->config['tablePrefix'];
98
99
        // activate and set the database client connection
100
        $this->arangoConnection = new ArangoConnection($this->config);
101
102
        // We need to initialize a query grammar and the query post processors
103
        // which are both very important parts of the database abstractions
104
        // so we initialize these to their default values while starting.
105
        $this->useDefaultQueryGrammar();
106
107
        $this->useDefaultPostProcessor();
108
    }
109
110
    /**
111
     * Get a schema builder instance for the connection.
112
     *
113
     * @return \LaravelFreelancerNL\Aranguent\Schema\Builder
114
     */
115
    public function getSchemaBuilder()
116
    {
117
        if (is_null($this->schemaGrammar)) {
118
            $this->useDefaultSchemaGrammar();
119
        }
120
121
        return new SchemaBuilder($this);
122
    }
123
124
    /**
125
     * Get the default query grammar instance.
126
     *
127
     * @return \LaravelFreelancerNL\Aranguent\Query\Grammars\Grammar
128
     */
129
    protected function getDefaultQueryGrammar()
130
    {
131
        return new QueryGrammar;
132
    }
133
134
    /**
135
     * Get the default post processor instance.
136
     *
137
     * @return \LaravelFreelancerNL\Aranguent\Query\Processors\Processor
138
     */
139
    protected function getDefaultPostProcessor()
140
    {
141
        return new Processor;
142
    }
143
144
    /**
145
     * Run a select statement against the database and returns a generator.
146
     * ($useReadPdo is a dummy to adhere to the interface).
147
     *
148
     * @param string $query
149
     * @param array $bindings
150
     * @param bool $useReadPdo
151
     * @param array|null $transactionCollections
152
     * @return Iterator|null
153
     * @throws Exception
154
     */
155
    public function cursor($query, $bindings = [], $useReadPdo = null, $transactionCollections = null)
156
    {
157
        return $this->run($query, $bindings, function ($query, $bindings) use ($transactionCollections) {
158
            if ($this->pretending()) {
159
                return [];
160
            }
161
            if ($this->transactionLevel() > 0) {
162
                $this->addQueryToTransaction($query, $bindings, $transactionCollections);
163
164
                return [];
165
            }
166
167
            $statement = new Statement($this->arangoConnection, ['query' => $query, 'bindVars' => $bindings]);
168
169
            return $statement->execute();
170
171
        });
172
    }
173
174
    /**
175
     * Execute an AQL statement and return the boolean result.
176
     *
177
     * @param  string|FluentAQL  $query
178
     * @param  array   $bindings
179
     * @param  array|null   $transactionCollections
180
     * @return bool
181
     */
182
    public function statement($query, $bindings = [], $transactionCollections = null)
183
    {
184
        if ($query instanceof FluentAQL) {
185
            $bindings = $query->binds;
186
            $transactionCollections = $query->collections;
187
            $query = $query->query;
188
        }
189
190
        return $this->run($query, $bindings, function ($query, $bindings) use ($transactionCollections) {
191
            if ($this->pretending()) {
192
                return true;
193
            }
194
            if ($this->transactionLevel() > 0) {
195
                $this->addQueryToTransaction($query, $bindings, $transactionCollections);
196
197
                return true;
198
            }
199
200
            $statement = new Statement($this->arangoConnection, ['query' => $query, 'bindVars' => $bindings]);
201
202
            $cursor = $statement->execute();
203
204
            $affectedDocumentCount = $cursor->getWritesExecuted();
205
            $this->recordsHaveBeenModified($changed = $affectedDocumentCount > 0);
206
207
            return $changed;
208
        });
209
    }
210
211
    /**
212
     * Run an AQL statement and get the number of rows affected.
213
     *
214
     * @param  string|FluentAQL  $query
215
     * @param  array   $bindings
216
     * @param  array|null   $transactionCollections
217
     * @return int
218
     */
219
    public function affectingStatement($query, $bindings = [], $transactionCollections = null)
220
    {
221
        if ($query instanceof FluentAQL) {
222
            $bindings = $query->binds;
223
            $transactionCollections = $query->collections;
224
            $query = $query->query;
225
        }
226
227
        return $this->run($query, $bindings, function ($query, $bindings) use ($transactionCollections) {
228
            if ($this->pretending()) {
229
                return 0;
230
            }
231
            if ($this->transactionLevel() > 0) {
232
                $this->addQueryToTransaction($query, $bindings, $transactionCollections);
233
234
                return 0;
235
            }
236
237
            // For update or delete statements, we want to get the number of rows affected
238
            // by the statement and return that back to the developer. We'll first need
239
            // to execute the statement and get the executed writes from the extra.
240
            $statement = new Statement($this->arangoConnection, ['query' => $query, 'bindVars' => $bindings]);
241
242
            $cursor = $statement->execute();
243
244
            $affectedDocumentCount = $cursor->getWritesExecuted();
245
246
            $this->recordsHaveBeenModified($affectedDocumentCount > 0);
247
248
            return $affectedDocumentCount;
249
        });
250
    }
251
252
    /**
253
     * Run a raw, unprepared query against the connection.
254
     *
255
     * @param string $query
256
     * @param array|null $collections
257
     * @return bool
258
     * @throws Exception
259
     */
260
    public function unprepared($query)
261
    {
262
        return $this->run($query, [], function ($query) {
263
            if ($this->pretending()) {
264
                return true;
265
            }
266
            if ($this->transactionLevel() > 0) {
267
                $this->addQueryToTransaction($query);
268
269
                return [];
270
            }
271
272
            $statement = new Statement($this->arangoConnection, ['query' => $query, 'bindVars' => []]);
273
274
            $cursor = $statement->execute();
275
276
            $affectedDocumentCount = $cursor->getWritesExecuted();
277
278
            $change = $affectedDocumentCount > 0;
279
280
            $this->recordsHaveBeenModified($change);
281
282
            return $change;
283
        });
284
    }
285
286
    /**
287
     * Returns the query execution plan. The query will not be executed.
288
     *
289
     * @param string $query
290
     * @param array $bindings
291
     * @return array
292
     * @throws Exception
293
     */
294
    public function explain($query, $bindings = [])
295
    {
296
        $statement = new Statement($this->arangoConnection, ['query' => $query, 'bindVars' => $bindings]);
297
298
        return $statement->explain();
299
    }
300
301
    /**
302
     * Run a select statement against the database.
303
     *
304
     * @param string|FluentAQL $query
305
     * @param array $bindings
306
     * @param bool $useReadPdo
307
     * @param null|array $transactionCollections
308
     * @return array
309
     */
310
    public function select($query, $bindings = [], $useReadPdo = true, $transactionCollections = null)
311
    {
312
        return $this->execute($query, $bindings, $useReadPdo, $transactionCollections);
313
    }
314
315
    /**
316
     * Run an AQL query against the database and return the results.
317
     *
318
     * @param string|FluentAQL $query
319
     * @param array $bindings
320
     * @param bool $useReadPdo
321
     * @param null|array $transactionCollections
322
     * @return array
323
     */
324
    public function execute($query, $bindings = [], $useReadPdo = true, $transactionCollections = null)
0 ignored issues
show
Unused Code introduced by
The parameter $transactionCollections 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

324
    public function execute($query, $bindings = [], $useReadPdo = true, /** @scrutinizer ignore-unused */ $transactionCollections = null)

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...
Unused Code introduced by
The parameter $useReadPdo 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

324
    public function execute($query, $bindings = [], /** @scrutinizer ignore-unused */ $useReadPdo = true, $transactionCollections = null)

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...
325
    {
326
        if ($query instanceof FluentAQL) {
327
            $bindings = $query->binds;
328
            $transactionCollections = $query->collections;
0 ignored issues
show
Unused Code introduced by
The assignment to $transactionCollections is dead and can be removed.
Loading history...
329
            $query = $query->query;
330
        }
331
332
        return $this->run($query, $bindings, function ($query, $bindings, $transactionCollections= null) {
333
            if ($this->pretending()) {
334
                return [];
335
            }
336
            if ($this->transactionLevel() > 0) {
337
                $this->addQueryToTransaction($query, $bindings, $transactionCollections);
338
339
                return [];
340
            }
341
342
            $statement = new Statement($this->arangoConnection, ['query' => $query, 'bindVars' => $bindings]);
343
344
            $cursor = $statement->execute();
345
346
            return $cursor->getAll();
347
        });
348
    }
349
350
    /**
351
     * Run an insert statement against the database.
352
     *
353
     * @param  string|FluentAQL  $query
354
     * @param  array   $bindings
355
     * @param  array|null   $transactionCollections
356
     * @return bool
357
     */
358
    public function insert($query, $bindings = [], $transactionCollections = null)
359
    {
360
        return $this->statement($query, $bindings, $transactionCollections);
361
    }
362
363
    /**
364
     * Run an update statement against the database.
365
     *
366
     * @param  string|FluentAQL  $query
367
     * @param  array   $bindings
368
     * @param  array|null   $transactionCollections
369
     * @return int
370
     */
371
    public function update($query, $bindings = [], $transactionCollections = null)
372
    {
373
374
        return $this->affectingStatement($query, $bindings, $transactionCollections);
375
    }
376
377
    /**
378
     * Run a delete statement against the database.
379
     *
380
     * @param  string  $query
381
     * @param  array   $bindings
382
     * @param  array|null   $transactionCollections
383
     * @return int
384
     */
385
    public function delete($query, $bindings = [], $transactionCollections = null)
386
    {
387
        return $this->affectingStatement($query, $bindings, $transactionCollections);
388
    }
389
390
    /**
391
     * Get a new query builder instance.
392
     *
393
     * @return QueryBuilder
394
     */
395
    public function query()
396
    {
397
        return new QueryBuilder(
398
            $this, $this->getQueryGrammar(), $this->getPostProcessor()
0 ignored issues
show
Bug introduced by
$this->getQueryGrammar() of type Illuminate\Database\Query\Grammars\Grammar is incompatible with the type LaravelFreelancerNL\Aran...y\Grammars\Grammar|null expected by parameter $grammar of LaravelFreelancerNL\Aran...\Builder::__construct(). ( Ignorable by Annotation )

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

398
            $this, /** @scrutinizer ignore-type */ $this->getQueryGrammar(), $this->getPostProcessor()
Loading history...
399
        );
400
    }
401
402
    /**
403
     * Get the collection prefix for the connection.
404
     *
405
     * @return string
406
     */
407
    public function getTablePrefix()
408
    {
409
        return $this->tablePrefix;
410
    }
411
412
    /**
413
     * Disconnect from the underlying ArangoDB connection.
414
     *
415
     * @return void
416
     */
417
    public function disconnect()
418
    {
419
        $this->transactions = 0;
420
421
        $this->arangoConnection = null;
422
    }
423
424
    /**
425
     * Reconnect to the database if a Arango connection is missing.
426
     *
427
     * @return void
428
     */
429
    protected function reconnectIfMissingConnection()
430
    {
431
        if (is_null($this->arangoConnection)) {
432
            $this->reconnect();
433
        }
434
    }
435
436
    public function getArangoConnection()
437
    {
438
        return $this->arangoConnection;
439
    }
440
441
    public function getCollectionHandler()
442
    {
443
        if (!isset($this->collectionHandler)) {
444
            $this->collectionHandler = new ArangoCollectionHandler($this->arangoConnection);
445
        }
446
447
        return $this->collectionHandler;
448
    }
449
450
    public function getDocumentHandler()
451
    {
452
        if (!isset($this->documentHandler)) {
453
            $this->documentHandler = new ArangoDocumentHandler($this->arangoConnection);
454
        }
455
        return $this->documentHandler;
456
    }
457
458
    public function getUserHandler()
459
    {
460
        if (!isset($this->userHandler)) {
461
            $this->userHandler = new ArangoUserHandler($this->arangoConnection);
462
        }
463
        return $this->userHandler;
464
    }
465
466
    public function getGraphHandler()
467
    {
468
        if (!isset($this->graphHandler)) {
469
            $this->graphHandler = new ArangoGraphHandler($this->arangoConnection);
470
        }
471
        return $this->graphHandler;
472
    }
473
474
    public function getViewHandler()
475
    {
476
        if (!isset($this->viewHandler)) {
477
            $this->viewHandler = new ArangoViewHandler($this->arangoConnection);
478
        }
479
        return $this->viewHandler;
480
    }
481
482
    public function setDatabase($database)
483
    {
484
        $this->database = $database;
485
    }
486
487
    public function getDatabase()
488
    {
489
        return $this->database;
490
    }
491
}
492