Passed
Branch dev (d14b82)
by Wilmer
12:57
created

QueryBuilderPDOPgsql   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Test Coverage

Coverage 94.87%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 60
c 1
b 0
f 0
dl 0
loc 182
ccs 37
cts 39
cp 0.9487
rs 10
wmc 20

14 Methods

Rating   Name   Duplication   Size   Complexity  
A truncateTable() 0 3 1
A createIndex() 0 3 1
A renameTable() 0 3 1
A batchInsert() 0 3 1
A checkIntegrity() 0 3 1
B normalizeTableRowData() 0 22 7
A schema() 0 3 1
A dropIndex() 0 3 1
A command() 0 3 1
A alterColumn() 0 3 1
A quoter() 0 3 1
A __construct() 0 8 1
A defaultConditionClasses() 0 7 1
A defaultExpressionBuilders() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Pgsql\PDO;
6
7
use Generator;
8
use PDO;
9
use Yiisoft\Db\Command\CommandInterface;
10
use Yiisoft\Db\Expression\ArrayExpression;
11
use Yiisoft\Db\Expression\JsonExpression;
12
use Yiisoft\Db\Pdo\PdoValue;
13
use Yiisoft\Db\Pgsql\Builder\ArrayExpressionBuilder;
14
use Yiisoft\Db\Pgsql\Builder\JsonExpressionBuilder;
15
use Yiisoft\Db\Pgsql\DDLQueryBuilder;
16
use Yiisoft\Db\Pgsql\DMLQueryBuilder;
17
use Yiisoft\Db\Query\Conditions\LikeCondition;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Query\Conditions\LikeCondition 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...
18
use Yiisoft\Db\Query\Query;
19
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...
20
use Yiisoft\Db\Schema\QuoterInterface;
21
use Yiisoft\Db\Schema\Schema;
22
use Yiisoft\Db\Schema\SchemaInterface;
23
24
use function array_merge;
25
use function is_string;
26
27
/**
28
 * The class QueryBuilder is the query builder for PostgresSQL databases.
29
 */
30
final class QueryBuilderPDOPgsql extends QueryBuilder
31
{
32
    /**
33
     * Defines a UNIQUE index for {@see createIndex()}.
34
     */
35
    public const INDEX_UNIQUE = 'unique';
36
37
    /**
38
     * Defines a B-tree index for {@see createIndex()}.
39
     */
40
    public const INDEX_B_TREE = 'btree';
41
42
    /**
43
     * Defines a hash index for {@see createIndex()}.
44
     */
45
    public const INDEX_HASH = 'hash';
46
47
    /**
48
     * Defines a GiST index for {@see createIndex()}.
49
     */
50
    public const INDEX_GIST = 'gist';
51
52
    /**
53
     * Defines a GIN index for {@see createIndex()}.
54
     */
55
    public const INDEX_GIN = 'gin';
56
57
    /**
58
     * @var array mapping from abstract column types (keys) to physical column types (values).
59
     *
60
     * @psalm-var array<string, string>
61
     */
62
    protected array $typeMap = [
63
        Schema::TYPE_PK => 'serial NOT NULL PRIMARY KEY',
64
        Schema::TYPE_UPK => 'serial NOT NULL PRIMARY KEY',
65
        Schema::TYPE_BIGPK => 'bigserial NOT NULL PRIMARY KEY',
66
        Schema::TYPE_UBIGPK => 'bigserial NOT NULL PRIMARY KEY',
67
        Schema::TYPE_CHAR => 'char(1)',
68
        Schema::TYPE_STRING => 'varchar(255)',
69
        Schema::TYPE_TEXT => 'text',
70
        Schema::TYPE_TINYINT => 'smallint',
71
        Schema::TYPE_SMALLINT => 'smallint',
72
        Schema::TYPE_INTEGER => 'integer',
73
        Schema::TYPE_BIGINT => 'bigint',
74
        Schema::TYPE_FLOAT => 'double precision',
75
        Schema::TYPE_DOUBLE => 'double precision',
76
        Schema::TYPE_DECIMAL => 'numeric(10,0)',
77
        Schema::TYPE_DATETIME => 'timestamp(0)',
78
        Schema::TYPE_TIMESTAMP => 'timestamp(0)',
79
        Schema::TYPE_TIME => 'time(0)',
80
        Schema::TYPE_DATE => 'date',
81
        Schema::TYPE_BINARY => 'bytea',
82
        Schema::TYPE_BOOLEAN => 'boolean',
83
        Schema::TYPE_MONEY => 'numeric(19,4)',
84
        Schema::TYPE_JSON => 'jsonb',
85
    ];
86
87 401
    public function __construct(
88
        private CommandInterface $command,
89
        private QuoterInterface $quoter,
90
        private SchemaInterface $schema
91
    ) {
92 401
        $this->ddlBuilder = new DDLQueryBuilder($this);
0 ignored issues
show
Bug Best Practice introduced by
The property ddlBuilder does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
93 401
        $this->dmlBuilder = new DMLQueryBuilder($this);
0 ignored issues
show
Bug Best Practice introduced by
The property dmlBuilder does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
94 401
        parent::__construct($quoter, $schema);
95
    }
96
97 2
    public function alterColumn(string $table, string $column, $type): string
98
    {
99 2
        return $this->ddlBuilder->alterColumn($table, $column, $type);
100
    }
101
102 20
    public function batchInsert(string $table, array $columns, iterable|Generator $rows, array &$params = []): string
103
    {
104 20
        return $this->dmlBuilder->batchInsert($table, $columns, $rows, $params);
105
    }
106
107 1
    public function checkIntegrity(string $schema = '', string $table = '', bool $check = true): string
108
    {
109 1
        return $this->ddlBuilder->checkIntegrity($schema, $table, $check);
110
    }
111
112 6
    public function createIndex(string $name, string $table, array|string $columns, $unique = false): string
113
    {
114 6
        return $this->ddlBuilder->createIndex($name, $table, $columns, $unique);
115
    }
116
117 3
    public function dropIndex(string $name, string $table): string
118
    {
119 3
        return $this->ddlBuilder->dropIndex($name, $table);
120
    }
121
122 2
    public function renameTable(string $oldName, string $newName): string
123
    {
124 2
        return $this->ddlBuilder->renameTable($oldName, $newName);
125
    }
126
127
    public function command(): CommandInterface
128
    {
129
        return $this->command;
130
    }
131
132
    /**
133
     * Normalizes data to be saved into the table, performing extra preparations and type converting, if necessary.
134
     *
135
     * @param string $table the table that data will be saved into.
136
     * @param array|Query $columns the column data (name => value) to be saved into the table or instance of
137
     * {@see Query} to perform INSERT INTO ... SELECT SQL statement. Passing of
138
     * {@see Query}.
139
     *
140
     * @return array|Query normalized columns.
141
     */
142 48
    public function normalizeTableRowData(string $table, Query|array $columns): Query|array
143
    {
144 48
        if ($columns instanceof Query) {
0 ignored issues
show
introduced by
$columns is never a sub-type of Yiisoft\Db\Query\Query.
Loading history...
145 14
            return $columns;
146
        }
147
148 40
        if (($tableSchema = $this->schema->getTableSchema($table)) !== null) {
149 40
            $columnSchemas = $tableSchema->getColumns();
150
            /** @var mixed $value */
151 40
            foreach ($columns as $name => $value) {
152
                if (
153 40
                    isset($columnSchemas[$name]) &&
154 40
                    $columnSchemas[$name]->getType() === Schema::TYPE_BINARY &&
155 40
                    is_string($value)
156
                ) {
157
                    /** explicitly setup PDO param type for binary column */
158 2
                    $columns[$name] = new PdoValue($value, PDO::PARAM_LOB);
159
                }
160
            }
161
        }
162
163 40
        return $columns;
164
    }
165
166 337
    public function quoter(): QuoterInterface
167
    {
168 337
        return $this->quoter;
169
    }
170
171 140
    public function schema(): SchemaInterface
172
    {
173 140
        return $this->schema;
174
    }
175
176 1
    public function truncateTable(string $table): string
177
    {
178 1
        return $this->ddlBuilder->truncateTable($table);
179
    }
180
181
    /**
182
     * Contains array of default condition classes. Extend this method, if you want to change default condition classes
183
     * for the query builder.
184
     *
185
     * @return array
186
     *
187
     * See {@see conditionClasses} docs for details.
188
     */
189 401
    protected function defaultConditionClasses(): array
190
    {
191 401
        return array_merge(parent::defaultConditionClasses(), [
192
            'ILIKE' => LikeCondition::class,
193
            'NOT ILIKE' => LikeCondition::class,
194
            'OR ILIKE' => LikeCondition::class,
195
            'OR NOT ILIKE' => LikeCondition::class,
196
        ]);
197
    }
198
199
    /**
200
     * Contains array of default expression builders. Extend this method and override it, if you want to change default
201
     * expression builders for this query builder.
202
     *
203
     * @return array
204
     *
205
     * See {@see ExpressionBuilder} docs for details.
206
     */
207 401
    protected function defaultExpressionBuilders(): array
208
    {
209 401
        return array_merge(parent::defaultExpressionBuilders(), [
210
            ArrayExpression::class => ArrayExpressionBuilder::class,
211
            JsonExpression::class => JsonExpressionBuilder::class,
212
        ]);
213
    }
214
}
215