Passed
Push — dev ( 3c199f...a931c8 )
by Wilmer
23:00 queued 12s
created

CommandPDOOracle::internalExecute()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 9.0294

Importance

Changes 0
Metric Value
cc 9
eloc 16
nc 9
nop 1
dl 0
loc 22
ccs 13
cts 14
cp 0.9286
crap 9.0294
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Oracle\PDO;
6
7
use PDO;
8
use PDOException;
9
use Yiisoft\Db\Command\ParamInterface;
10
use Yiisoft\Db\Driver\PDO\CommandPDO;
11
use Yiisoft\Db\Exception\ConvertException;
12
use Yiisoft\Db\Query\QueryBuilder;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Query\QueryBuilder 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...
13
use Yiisoft\Db\Query\QueryBuilderInterface;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Query\QueryBuilderInterface 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...
14
use Yiisoft\Db\Schema\Schema;
15
16
use function array_keys;
17
use function count;
18
use function implode;
19
use function strlen;
20
21
/**
22
 * Command represents an Oracle SQL statement to be executed against a database.
23
 */
24
final class CommandPDOOracle extends CommandPDO
25
{
26 182
    public function queryBuilder(): QueryBuilderInterface
27
    {
28 182
        return $this->db->getQueryBuilder();
29
    }
30
31 1
    public function insertEx(string $table, array $columns): bool|array
32
    {
33 1
        $params = [];
34 1
        $sql = $this->queryBuilder()->insertEx($table, $columns, $params);
35
36 1
        $tableSchema = $this->queryBuilder()->schema()->getTableSchema($table);
37
38 1
        $returnColumns = $tableSchema?->getPrimaryKey() ?? [];
39 1
        $columnSchemas = $tableSchema?->getColumns() ?? [];
40
41 1
        $returnParams = [];
42 1
        $returning = [];
43 1
        foreach ($returnColumns as $name) {
44 1
            $phName = QueryBuilder::PARAM_PREFIX . (count($params) + count($returnParams));
45
46 1
            $returnParams[$phName] = [
47
                'column' => $name,
48
                'value' => '',
49
            ];
50
51 1
            if (!isset($columnSchemas[$name]) || $columnSchemas[$name]->getPhpType() !== Schema::PHP_TYPE_INTEGER) {
52
                $returnParams[$phName]['dataType'] = PDO::PARAM_STR;
53
            } else {
54 1
                $returnParams[$phName]['dataType'] = PDO::PARAM_INT;
55
            }
56
57 1
            $returnParams[$phName]['size'] = $columnSchemas[$name]->getSize() ?? -1;
58
59 1
            $returning[] = $this->db->getQuoter()->quoteColumnName($name);
60
        }
61
62 1
        $sql .= ' RETURNING ' . implode(', ', $returning) . ' INTO ' . implode(', ', array_keys($returnParams));
63
64 1
        $this->setSql($sql)->bindValues($params);
65 1
        $this->prepare(false);
66
67
        /** @psalm-var array<string, array{column: string, value: mixed, dataType: int, size: int}> $returnParams */
68 1
        foreach ($returnParams as $name => &$value) {
69 1
            $this->bindParam($name, $value['value'], $value['dataType'], $value['size']);
70
        }
71
72 1
        if (!$this->execute()) {
73
            return false;
74
        }
75
76 1
        $result = [];
77
78 1
        foreach ($returnParams as $value) {
79
            /** @var mixed */
80 1
            $result[$value['column']] = $value['value'];
81
        }
82
83 1
        return $result;
84
    }
85
86 172
    protected function bindPendingParams(): void
87
    {
88 172
        $paramsPassedByReference = [];
89
90
        /** @psalm-var ParamInterface[] */
91 172
        $params = $this->params;
92
93 172
        foreach ($params as $name => $value) {
94 149
            if (PDO::PARAM_STR === $value->getType()) {
95
                /** @var mixed */
96 143
                $paramsPassedByReference[$name] = $value->getValue();
97 143
                $this->pdoStatement?->bindParam(
98
                    $name,
99 143
                    $paramsPassedByReference[$name],
100 143
                    $value->getType(),
101 143
                    strlen((string) $value->getValue())
102
                );
103
            } else {
104 23
                $this->pdoStatement?->bindValue($name, $value->getValue(), $value->getType());
105
            }
106
        }
107
    }
108
109 171
    protected function internalExecute(?string $rawSql): void
110
    {
111 171
        $attempt = 0;
112
113 171
        while (true) {
114
            try {
115
                if (
116 171
                    ++$attempt === 1
117 171
                    && $this->isolationLevel !== null
118 171
                    && $this->db->getTransaction() === null
119
                ) {
120
                    $this->db->transaction(fn (string $rawSql) => $this->internalExecute($rawSql), $this->isolationLevel);
121
                } else {
122 171
                    $this->pdoStatement?->execute();
123
                }
124 171
                break;
125 6
            } catch (PDOException $e) {
126 6
                $rawSql = $rawSql ?: $this->getRawSql();
127 6
                $e = (new ConvertException($e, $rawSql))->run();
128
129 6
                if ($this->retryHandler === null || !($this->retryHandler)($e, $attempt)) {
130 6
                    throw $e;
131
                }
132
            }
133
        }
134
    }
135
}
136