Passed
Push — master ( 8a94f4...7081df )
by Wilmer
04:14
created

Command   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Test Coverage

Coverage 97.5%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 15
eloc 39
c 1
b 0
f 0
dl 0
loc 75
ccs 39
cts 40
cp 0.975
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getQueryBuilder() 0 3 1
A showDatabases() 0 7 1
B internalExecute() 0 27 9
A insertWithReturningPks() 0 25 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Mysql;
6
7
use PDOException;
8
use Throwable;
9
use Yiisoft\Db\Driver\Pdo\AbstractPdoCommand;
10
use Yiisoft\Db\Exception\ConvertException;
11
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
12
13
/**
14
 * Implements a database command that can be executed with a PDO (PHP Data Object) database connection for MySQL,
15
 * MariaDB.
16
 */
17
final class Command extends AbstractPdoCommand
18
{
19 6
    public function insertWithReturningPks(string $table, array $columns): bool|array
20
    {
21 6
        $params = [];
22 6
        $sql = $this->db->getQueryBuilder()->insert($table, $columns, $params);
23 6
        $this->setSql($sql)->bindValues($params);
24
25 6
        if (!$this->execute()) {
26
            return false;
27
        }
28
29 6
        $tableSchema = $this->db->getSchema()->getTableSchema($table);
30 6
        $tablePrimaryKeys = $tableSchema?->getPrimaryKey() ?? [];
31 6
        $result = [];
32
33 6
        foreach ($tablePrimaryKeys as $name) {
34 6
            if ($tableSchema?->getColumn($name)?->isAutoIncrement()) {
35 5
                $result[$name] = $this->db->getLastInsertID((string) $tableSchema?->getSequenceName());
36 5
                continue;
37
            }
38
39
            /** @psalm-var mixed */
40 1
            $result[$name] = $columns[$name] ?? $tableSchema?->getColumn($name)?->getDefaultValue();
41
        }
42
43 6
        return $result;
44
    }
45
46 1
    public function showDatabases(): array
47
    {
48 1
        $sql = <<<SQL
49
        SHOW DATABASES WHERE `Database` NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys')
50 1
        SQL;
51
52 1
        return $this->setSql($sql)->queryColumn();
53
    }
54
55 268
    protected function getQueryBuilder(): QueryBuilderInterface
56
    {
57 268
        return $this->db->getQueryBuilder();
58
    }
59
60
    /**
61
     * @psalm-suppress UnusedClosureParam
62
     *
63
     * @throws Throwable
64
     */
65 246
    protected function internalExecute(string|null $rawSql): void
66
    {
67 246
        $attempt = 0;
68
69 246
        while (true) {
70
            try {
71
                if (
72 246
                    ++$attempt === 1
73 246
                    && $this->isolationLevel !== null
74 246
                    && $this->db->getTransaction() === null
75
                ) {
76 1
                    $this->db->transaction(
77 1
                        function () use ($rawSql): void {
78 1
                            $this->internalExecute($rawSql);
79 1
                        },
80 1
                        $this->isolationLevel,
81 1
                    );
82
                } else {
83 246
                    $this->pdoStatement?->execute();
84
                }
85 246
                break;
86 43
            } catch (PDOException $e) {
87 43
                $rawSql = $rawSql ?: $this->getRawSql();
88 43
                $e = (new ConvertException($e, $rawSql))->run();
89
90 43
                if ($this->retryHandler === null || !($this->retryHandler)($e, $attempt)) {
91 43
                    throw $e;
92
                }
93
            }
94
        }
95
    }
96
}
97