Completed
Push — master ( 58d054...1c36bc )
by Vincent
06:17
created

SimpleConnection::toDatabase()   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 1
Bugs 0 Features 0
Metric Value
eloc 1
dl 0
loc 3
c 1
b 0
f 0
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Bdf\Prime\Connection;
4
5
use Bdf\Prime\Connection\Event\ConnectionClosedListenerInterface;
6
use Bdf\Prime\Connection\Extensions\LostConnection;
7
use Bdf\Prime\Connection\Extensions\SchemaChanged;
8
use Bdf\Prime\Connection\Result\PdoResultSet;
9
use Bdf\Prime\Connection\Result\ResultSetInterface;
0 ignored issues
show
introduced by
Unused use statement
Loading history...
10
use Bdf\Prime\Connection\Result\UpdateResultSet;
11
use Bdf\Prime\Platform\Sql\SqlPlatform;
12
use Bdf\Prime\Query\Compiler\Preprocessor\PreprocessorInterface;
13
use Bdf\Prime\Query\Compiler\SqlCompiler;
14
use Bdf\Prime\Query\Contract\Compilable;
15
use Bdf\Prime\Query\Contract\Query\InsertQueryInterface;
16
use Bdf\Prime\Query\Contract\Query\KeyValueQueryInterface;
17
use Bdf\Prime\Query\Custom\BulkInsert\BulkInsertQuery;
18
use Bdf\Prime\Query\Custom\BulkInsert\BulkInsertSqlCompiler;
19
use Bdf\Prime\Query\Custom\KeyValue\KeyValueQuery;
20
use Bdf\Prime\Query\Custom\KeyValue\KeyValueSqlCompiler;
21
use Bdf\Prime\Query\Factory\DefaultQueryFactory;
22
use Bdf\Prime\Query\Factory\QueryFactoryInterface;
0 ignored issues
show
introduced by
Unused use statement
Loading history...
23
use Bdf\Prime\Query\Query;
24
use Bdf\Prime\Schema\SchemaManager;
25
use Doctrine\Common\EventManager;
26
use Doctrine\DBAL\Cache\QueryCacheProfile;
27
use Doctrine\DBAL\Configuration;
28
use Doctrine\DBAL\Connection as BaseConnection;
29
use Doctrine\DBAL\DBALException;
30
use Doctrine\DBAL\Driver;
31
use Doctrine\DBAL\Statement;
32
use PDO;
33
34
/**
35
 * Connection
36
 *
37
 * @package Bdf\Prime
0 ignored issues
show
Coding Style Documentation introduced by
@package tag is not allowed in class comment
Loading history...
38
 */
39
class SimpleConnection extends BaseConnection implements ConnectionInterface
40
{
41
    use LostConnection;
42
    use SchemaChanged;
43
44
    /**
45
     * The connection name.
46
     *
47
     * @var string
48
     */
49
    protected $name;
50
    
51
    /**
52
     * The schema manager.
53
     *
54
     * @var SchemaManager
55
     */
56
    private $schema;
57
58
    /**
59
     * @var SqlPlatform
60
     */
61
    private $platform;
62
63
    /**
64
     * @var QueryFactoryInterface
65
     */
66
    private $factory;
67
68
    /**
69
     * SimpleConnection constructor.
70
     *
71
     * @param array $params
0 ignored issues
show
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
72
     * @param Driver $driver
0 ignored issues
show
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
73
     * @param Configuration|null $config
0 ignored issues
show
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
74
     * @param EventManager|null $eventManager
0 ignored issues
show
Coding Style introduced by
Tag value for @param tag indented incorrectly; expected 2 spaces but found 1
Loading history...
75
     * @throws DBALException
0 ignored issues
show
Coding Style introduced by
Tag @throws cannot be grouped with parameter tags in a doc comment
Loading history...
introduced by
Separate the @param and @throws sections by a blank line.
Loading history...
introduced by
Comment missing for @throws tag in function comment
Loading history...
76
     */
77 148
    public function __construct(array $params, Driver $driver, Configuration $config = null, EventManager $eventManager = null)
78
    {
79 148
        parent::__construct($params, $driver, $config, $eventManager);
80
81 148
        $this->factory = new DefaultQueryFactory(
82 148
            $this,
83 148
            new SqlCompiler($this),
84
            [
85 148
                KeyValueQuery::class   => KeyValueSqlCompiler::class,
86
                BulkInsertQuery::class => BulkInsertSqlCompiler::class,
87
            ],
88
            [
89 148
                KeyValueQueryInterface::class => KeyValueQuery::class,
90
                InsertQueryInterface::class   => BulkInsertQuery::class,
91
            ]
92
        );
93 148
    }
94
95
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $name should have a doc-comment as per coding-style.
Loading history...
96
     * {@inheritdoc}
97
     */
98 149
    public function setName($name)
99
    {
100 149
        $this->name = $name;
101
        
102 149
        return $this;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 29
    public function getName()
109
    {
110 29
        return $this->name;
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116 1
    public function isConnected()
117
    {
118 1
        return $this->_conn !== null;
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124 792
    public function schema()
125
    {
126 792
        if ($this->schema === null) {
127 126
            $this->schema = new SchemaManager($this);
128
        }
129
130 792
        return $this->schema;
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136 1011
    public function platform()
137
    {
138 1011
        if ($this->platform === null) {
139 130
            $this->platform = new SqlPlatform(
140 130
                $this->getDatabasePlatform(),
141 130
                $this->getConfiguration()->getTypes()
0 ignored issues
show
introduced by
The method getTypes() does not exist on Doctrine\DBAL\Configuration. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

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

141
                $this->getConfiguration()->/** @scrutinizer ignore-call */ getTypes()
Loading history...
142
            );
143
        }
144
145 1011
        return $this->platform;
146
    }
147
148
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $value should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $type should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $fieldOptions should have a doc-comment as per coding-style.
Loading history...
149
     * {@inheritdoc}
150
     */
151 3
    public function fromDatabase($value, $type, array $fieldOptions = [])
152
    {
153 3
        return $this->platform()->types()->fromDatabase($value, $type, $fieldOptions);
0 ignored issues
show
Bug introduced by
The method fromDatabase() does not exist on Bdf\Prime\Types\TypesRegistryInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Types\TypesRegistry. Are you sure you never get one of those? ( Ignorable by Annotation )

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

153
        return $this->platform()->types()->/** @scrutinizer ignore-call */ fromDatabase($value, $type, $fieldOptions);
Loading history...
154
    }
155
156
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $value should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $type should have a doc-comment as per coding-style.
Loading history...
157
     * {@inheritdoc}
158
     */
159 4
    public function toDatabase($value, $type = null)
160
    {
161 4
        return $this->platform()->types()->toDatabase($value, $type);
0 ignored issues
show
Bug introduced by
The method toDatabase() does not exist on Bdf\Prime\Types\TypesRegistryInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Types\TypesRegistry. Are you sure you never get one of those? ( Ignorable by Annotation )

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

161
        return $this->platform()->types()->/** @scrutinizer ignore-call */ toDatabase($value, $type);
Loading history...
162
    }
163
164
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $preprocessor should have a doc-comment as per coding-style.
Loading history...
165
     * {@inheritdoc}
166
     */
167 652
    public function builder(PreprocessorInterface $preprocessor = null)
168
    {
169 652
        return $this->factory->make(Query::class, $preprocessor);
170
    }
171
172
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $query should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $preprocessor should have a doc-comment as per coding-style.
Loading history...
173
     * {@inheritdoc}
174
     */
175 177
    public function make($query, PreprocessorInterface $preprocessor = null)
176
    {
177 177
        return $this->factory->make($query, $preprocessor);
178
    }
179
180
    /**
181
     * {@inheritdoc}
182
     */
183 805
    public function factory()
184
    {
185 805
        return $this->factory;
186
    }
187
188
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $table should have a doc-comment as per coding-style.
Loading history...
189
     * {@inheritdoc}
190
     */
191 497
    public function from($table)
192
    {
193 497
        return $this->builder()->from($table);
194
    }
195
196
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $table should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $identifier should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $types should have a doc-comment as per coding-style.
Loading history...
197
     * {@inheritdoc}
198
     */
199 13
    public function delete($table, array $identifier, array $types = array())
0 ignored issues
show
Coding Style introduced by
The method parameter $types is never used
Loading history...
Coding Style introduced by
Short array syntax must be used to define arrays
Loading history...
200
    {
201 13
        return $this->from($table)->where($identifier)->delete();
0 ignored issues
show
Bug introduced by
The method where() does not exist on Bdf\Prime\Query\CommandInterface. It seems like you code against a sub-type of Bdf\Prime\Query\CommandInterface such as Bdf\Prime\Query\Contract...\KeyValueQueryInterface or Bdf\Prime\Query\QueryInterface or Bdf\Prime\Query\AbstractReadCommand. ( Ignorable by Annotation )

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

201
        return $this->from($table)->/** @scrutinizer ignore-call */ where($identifier)->delete();
Loading history...
202
    }
203
    
204
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $table should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $data should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $identifier should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $types should have a doc-comment as per coding-style.
Loading history...
205
     * {@inheritdoc}
206
     */
207 1
    public function update($table, array $data, array $identifier, array $types = array())
0 ignored issues
show
Coding Style introduced by
Short array syntax must be used to define arrays
Loading history...
208
    {
209 1
        return $this->from($table)->where($identifier)->update($data, $types);
210
    }
211
212
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $table should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $data should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $types should have a doc-comment as per coding-style.
Loading history...
213
     * {@inheritdoc}
214
     */
215 403
    public function insert($table, array $data, array $types = array())
0 ignored issues
show
Coding Style introduced by
Short array syntax must be used to define arrays
Loading history...
216
    {
217 403
        return $this->from($table)->insert($data, $types);
0 ignored issues
show
Bug introduced by
The method insert() does not exist on Bdf\Prime\Query\CommandInterface. It seems like you code against a sub-type of Bdf\Prime\Query\CommandInterface such as Bdf\Prime\Query\QueryInterface or Bdf\Prime\Query\AbstractReadCommand or Bdf\Prime\Sharding\Query\ShardingKeyValueQuery or Bdf\Prime\Query\Custom\KeyValue\KeyValueQuery. ( Ignorable by Annotation )

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

217
        return $this->from($table)->/** @scrutinizer ignore-call */ insert($data, $types);
Loading history...
218
    }
219
220
    /**
221
     * Executes select query and returns array of object
222
     * 
223
     * @param string $query
224
     * @param array  $bindings
225
     * @param array  $types
226
     * 
227
     * @return array
228
     */
229 4
    public function select($query, array $bindings = [], array $types = [])
230
    {
231 4
        $stmt = $this->executeQuery($query, $bindings, $types);
232 4
        $stmt->setFetchMode(PDO::FETCH_OBJ);
233
234 4
        $result = $stmt->fetchAll();
235
236 4
        $stmt->closeCursor();
237
        
238 4
        return $result;
239
    }
240
241
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $query should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $params should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $types should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $qcp should have a doc-comment as per coding-style.
Loading history...
242
     * {@inheritdoc}
243
     */
244 810
    public function executeQuery($query, array $params = [], $types = [], QueryCacheProfile $qcp = null)
245
    {
246 810
        $this->prepareLogger();
247
248
        return $this->runOrReconnect(function() use ($query, $params, $types, $qcp) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
249 810
            return parent::executeQuery($query, $params, $types, $qcp);
250 810
        });
251
    }
252
253
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $query should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $params should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $types should have a doc-comment as per coding-style.
Loading history...
254
     * {@inheritdoc}
255
     */
256 455
    public function executeUpdate($query, array $params = [], array $types = [])
257
    {
258 455
        $this->prepareLogger();
259
260
        return $this->runOrReconnect(function() use ($query, $params, $types) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
261 455
            return parent::executeUpdate($query, $params, $types);
262 455
        });
263
    }
264
265
    /**
266
     * {@inheritdoc}
267
     */
268 6
    public function query()
269
    {
270 6
        $this->prepareLogger();
271
        
272 6
        $args = func_get_args();
273
274
        return $this->runOrReconnect(function() use ($args) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
275 6
            return parent::query(...$args);
276 6
        });
277
    }
278
    
279
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $statement should have a doc-comment as per coding-style.
Loading history...
280
     * {@inheritdoc}
281
     */
282 791
    public function exec($statement)
283
    {
284 791
        $this->prepareLogger();
285
        
286
        return $this->runOrReconnect(function() use ($statement) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
287 791
            return parent::exec($statement);
288 791
        });
289
    }
290
291
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $statement should have a doc-comment as per coding-style.
Loading history...
292
     * {@inheritdoc}
293
     */
294 490
    public function prepare($statement)
295
    {
296
        return $this->runOrReconnect(function() use ($statement) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space after FUNCTION keyword; 0 found
Loading history...
297 490
            return parent::prepare($statement);
298 490
        });
299
    }
300
301
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $query should have a doc-comment as per coding-style.
Loading history...
302
     * {@inheritdoc}
303
     */
304 607
    public function execute(Compilable $query)
305
    {
306 607
        $statement = $query->compile();
307
308 604
        if ($statement instanceof Statement) {
309 467
            return $this->executePrepared($statement, $query);
310
        }
311
312
        // $statement is a SQL query
313 551
        if ($query->type() === Compilable::TYPE_SELECT) {
314 496
            $stmt = $this->executeQuery($statement, $query->getBindings());
315
316 496
            return new PdoResultSet($stmt);
317
        }
318
319 452
        return new UpdateResultSet($this->executeUpdate($statement, $query->getBindings()));
320
    }
321
322
    /**
323
     * Execute a prepared statement
324
     *
325
     * @param Statement $statement
326
     * @param Compilable $query
327
     *
328
     * @return ResultSetInterface The query result
329
     * @throws DBALException
0 ignored issues
show
introduced by
Separate the @return and @throws sections by a blank line.
Loading history...
introduced by
Comment missing for @throws tag in function comment
Loading history...
330
     */
331 467
    protected function executePrepared(Statement $statement, Compilable $query)
332
    {
333 467
        $bindings = $query->getBindings();
334
335 467
        $this->prepareLogger();
336
337
        try {
338 467
            $statement->execute($bindings);
339 331
        } catch (DBALException $exception) {
340
            // Prepared query on SQLite for PHP < 7.2 invalidates the query when schema change
341
            // This process may be removed on PHP 7.2
342 331
            if ($this->causedBySchemaChange($exception)) {
343 326
                $statement = $query->compile(true);
344 326
                $statement->execute($query->getBindings());
345 6
            } elseif ($this->causedByLostConnection($exception->getPrevious())) { // If the connection is lost, the query must be recompiled
0 ignored issues
show
Coding Style introduced by
Usage of ELSEIF not allowed; use ELSE IF instead
Loading history...
introduced by
There should be no white space after an opening "{"
Loading history...
Coding Style introduced by
Comments may not appear after statements
Loading history...
346
                $this->close();
347
                $this->connect();
348
349
                $statement = $query->compile(true);
350
                $statement->execute($query->getBindings());
351
            } else {
352 6
                throw $exception;
353
            }
354
        }
355
356 465
        return new PdoResultSet($statement);
357
    }
358
359
    /**
360
     * {@inheritdoc}
361
     */
362 818
    public function beginTransaction()
363
    {
364 818
        $this->prepareLogger();
365
366 818
        parent::beginTransaction();
367 818
    }
368
369
    /**
370
     * {@inheritdoc}
371
     */
372 28
    public function commit()
373
    {
374 28
        $this->prepareLogger();
375
        
376 28
        parent::commit();
377 28
    }
378
    
379
    /**
380
     * {@inheritdoc}
381
     */
382 794
    public function rollBack()
383
    {
384 794
        $this->prepareLogger();
385
        
386 794
        return parent::rollBack();
0 ignored issues
show
Bug introduced by
Are you sure the usage of parent::rollBack() targeting Doctrine\DBAL\Connection::rollBack() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
387
    }
388
389
    /**
390
     * {@inheritdoc}
391
     */
392 15
    public function close()
393
    {
394 15
        parent::close();
395
396 15
        $this->_eventManager->dispatchEvent(ConnectionClosedListenerInterface::EVENT_NAME);
397 15
    }
398
    
399
    /**
400
     * Log a query
401
     * 
402
     * @param string $query
0 ignored issues
show
Coding Style introduced by
Superfluous parameter comment
Loading history...
introduced by
Doc comment for parameter $query does not match actual variable name <undefined>
Loading history...
403
     * @param int    $seconds
0 ignored issues
show
Coding Style introduced by
Superfluous parameter comment
Loading history...
Coding Style introduced by
Expected "integer" but found "int" for parameter type
Loading history...
404
     * @param array  $bindings
0 ignored issues
show
Coding Style introduced by
Superfluous parameter comment
Loading history...
405
     * @param array  $types
0 ignored issues
show
Coding Style introduced by
Superfluous parameter comment
Loading history...
406
     */
407 946
    protected function prepareLogger()
408
    {
409 946
        $logger = $this->getConfiguration()->getSQLLogger();
410
411 946
        if ($logger && $logger instanceof ConnectionAwareInterface) {
412
            $logger->setConnection($this);
413
        }
414 946
    }
415
416
    /**
417
     * Execute a query. Try to reconnect if needed
418
     *
419
     * @param \Closure $callback
420
     *
421
     * @return mixed  The query result
422
     *
423
     * @throws DBALException
0 ignored issues
show
introduced by
Comment missing for @throws tag in function comment
Loading history...
424
     */
425 830
    protected function runOrReconnect($callback)
0 ignored issues
show
introduced by
Type hint "\Closure" missing for $callback
Loading history...
426
    {
427
        try {
428 830
            return $callback();
429 32
        } catch (DBALException $exception) {
430 32
            if ($this->causedByLostConnection($exception->getPrevious())) {
431
                // Should check for active transaction.
432
                // Only reconnect the start transaction.
433
                // Should raise exception during transaction.
434 2
                $this->close();
435 2
                $this->connect();
436
437 2
                return $callback();
438
            }
439
440 30
            throw $exception;
441
        }
442
    }
443
}
444