Test Failed
Pull Request — master (#98)
by Wilmer
21:47 queued 09:55
created

QueryBuilderPDOPgsql::schema()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Pgsql\PDO;
6
7
use Generator;
8
use JsonException;
9
use PDO;
10
use Yiisoft\Db\Command\CommandInterface;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Command\CommandInterface 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...
11
use Yiisoft\Db\Connection\ConnectionInterface;
12
use Yiisoft\Db\Exception\Exception;
13
use Yiisoft\Db\Exception\InvalidArgumentException;
14
use Yiisoft\Db\Exception\InvalidConfigException;
15
use Yiisoft\Db\Exception\NotSupportedException;
16
use Yiisoft\Db\Expression\ArrayExpression;
17
use Yiisoft\Db\Expression\Expression;
18
use Yiisoft\Db\Expression\ExpressionInterface;
19
use Yiisoft\Db\Expression\JsonExpression;
20
use Yiisoft\Db\Pdo\PdoValue;
21
use Yiisoft\Db\Pgsql\ArrayExpressionBuilder;
22
use Yiisoft\Db\Pgsql\DDLQueryBuilder;
23
use Yiisoft\Db\Pgsql\DMLQueryBuilder;
24
use Yiisoft\Db\Pgsql\JsonExpressionBuilder;
25
use Yiisoft\Db\Query\Conditions\LikeCondition;
26
use Yiisoft\Db\Query\Query;
27
use Yiisoft\Db\Query\QueryBuilder;
28
use Yiisoft\Db\Schema\ColumnSchemaBuilder;
29
use Yiisoft\Db\Schema\QuoterInterface;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Db\Schema\QuoterInterface 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...
30
use Yiisoft\Db\Schema\Schema;
31
use Yiisoft\Db\Schema\SchemaInterface;
32
use Yiisoft\Strings\NumericHelper;
33
34
use function array_diff;
35
use function array_merge;
36
use function array_unshift;
37
use function explode;
38
use function implode;
39
use function is_bool;
40
use function is_float;
41
use function is_string;
42
use function preg_match;
43
use function preg_replace;
44
use function reset;
45
46
/**
47
 * The class QueryBuilder is the query builder for PostgresSQL databases.
48
 */
49
final class QueryBuilderPDOPgsql extends QueryBuilder
50
{
51
    /**
52
     * Defines a UNIQUE index for {@see createIndex()}.
53
     */
54
    public const INDEX_UNIQUE = 'unique';
55
56
    /**
57
     * Defines a B-tree index for {@see createIndex()}.
58
     */
59
    public const INDEX_B_TREE = 'btree';
60
61
    /**
62
     * Defines a hash index for {@see createIndex()}.
63
     */
64
    public const INDEX_HASH = 'hash';
65
66
    /**
67
     * Defines a GiST index for {@see createIndex()}.
68
     */
69
    public const INDEX_GIST = 'gist';
70
71
    /**
72
     * Defines a GIN index for {@see createIndex()}.
73
     */
74
    public const INDEX_GIN = 'gin';
75
76
    /**
77
     * @var array mapping from abstract column types (keys) to physical column types (values).
78
     *
79
     * @psalm-var array<string, string>
80
     */
81
    protected array $typeMap = [
82
        Schema::TYPE_PK => 'serial NOT NULL PRIMARY KEY',
83
        Schema::TYPE_UPK => 'serial NOT NULL PRIMARY KEY',
84
        Schema::TYPE_BIGPK => 'bigserial NOT NULL PRIMARY KEY',
85
        Schema::TYPE_UBIGPK => 'bigserial NOT NULL PRIMARY KEY',
86
        Schema::TYPE_CHAR => 'char(1)',
87
        Schema::TYPE_STRING => 'varchar(255)',
88
        Schema::TYPE_TEXT => 'text',
89
        Schema::TYPE_TINYINT => 'smallint',
90
        Schema::TYPE_SMALLINT => 'smallint',
91
        Schema::TYPE_INTEGER => 'integer',
92
        Schema::TYPE_BIGINT => 'bigint',
93
        Schema::TYPE_FLOAT => 'double precision',
94
        Schema::TYPE_DOUBLE => 'double precision',
95
        Schema::TYPE_DECIMAL => 'numeric(10,0)',
96
        Schema::TYPE_DATETIME => 'timestamp(0)',
97
        Schema::TYPE_TIMESTAMP => 'timestamp(0)',
98
        Schema::TYPE_TIME => 'time(0)',
99
        Schema::TYPE_DATE => 'date',
100
        Schema::TYPE_BINARY => 'bytea',
101
        Schema::TYPE_BOOLEAN => 'boolean',
102
        Schema::TYPE_MONEY => 'numeric(19,4)',
103
        Schema::TYPE_JSON => 'jsonb',
104
    ];
105
106
    public function __construct(
107
        private CommandInterface $command,
108
        private QuoterInterface $quoter,
109
        private SchemaInterface $schema
110
    ) {
111
        $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...
112
        $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...
113
        parent::__construct($quoter, $schema);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Db\Query\QueryBuilder::__construct() has too many arguments starting with $schema. ( Ignorable by Annotation )

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

113
        parent::/** @scrutinizer ignore-call */ 
114
                __construct($quoter, $schema);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
114
    }
115
116
    public function alterColumn(string $table, string $column, $type): string
117
    {
118
        return $this->ddlBuilder->alterColumn($table, $column, $type);
119
    }
120
121
    public function batchInsert(string $table, array $columns, iterable|Generator $rows, array &$params = []): string
122
    {
123
        return $this->dmlBuilder->batchInsert($table, $columns, $rows, $params);
124
    }
125
126
    public function checkIntegrity(string $schema = '', string $table = '', bool $check = true): string
127
    {
128
        return $this->ddlBuilder->checkIntegrity($schema, $table, $check);
129
    }
130
131
    public function createIndex(string $name, string $table, array|string $columns, $unique = false): string
132
    {
133
        return $this->ddlBuilder->createIndex($name, $table, $columns, $unique);
134
    }
135
136
    public function dropIndex(string $name, string $table): string
137
    {
138
        return $this->ddlBuilder->dropIndex($name, $table);
139
    }
140
141
    public function renameTable(string $oldName, string $newName): string
142
    {
143
        return $this->ddlBuilder->renameTable($oldName, $newName);
144
    }
145
146
    public function command(): CommandInterface
147
    {
148
        return $this->command;
149
    }
150
151
    /**
152
     * Normalizes data to be saved into the table, performing extra preparations and type converting, if necessary.
153
     *
154
     * @param string $table the table that data will be saved into.
155
     * @param array|Query $columns the column data (name => value) to be saved into the table or instance of
156
     * {@see Query} to perform INSERT INTO ... SELECT SQL statement. Passing of
157
     * {@see Query}.
158
     *
159
     * @return array|Query normalized columns.
160
     */
161
    public function normalizeTableRowData(string $table, Query|array $columns): Query|array
162
    {
163
        if ($columns instanceof Query) {
0 ignored issues
show
introduced by
$columns is never a sub-type of Yiisoft\Db\Query\Query.
Loading history...
164
            return $columns;
165
        }
166
167
        if (($tableSchema = $this->schema->getTableSchema($table)) !== null) {
168
            $columnSchemas = $tableSchema->getColumns();
169
            /** @var mixed $value */
170
            foreach ($columns as $name => $value) {
171
                if (
172
                    isset($columnSchemas[$name]) &&
173
                    $columnSchemas[$name]->getType() === Schema::TYPE_BINARY &&
174
                    is_string($value)
175
                ) {
176
                    /** explicitly setup PDO param type for binary column */
177
                    $columns[$name] = new PdoValue($value, PDO::PARAM_LOB);
178
                }
179
            }
180
        }
181
182
        return $columns;
183
    }
184
185
    public function quoter(): QuoterInterface
186
    {
187
        return $this->quoter;
188
    }
189
190
    public function schema(): SchemaInterface
191
    {
192
        return $this->schema;
193
    }
194
195
    public function truncateTable(string $table): string
196
    {
197
        return $this->ddlBuilder->truncateTable($table);
198
    }
199
200
    /**
201
     * Contains array of default condition classes. Extend this method, if you want to change default condition classes
202
     * for the query builder.
203
     *
204
     * @return array
205
     *
206
     * See {@see conditionClasses} docs for details.
207
     */
208
    protected function defaultConditionClasses(): array
209
    {
210
        return array_merge(parent::defaultConditionClasses(), [
211
            'ILIKE' => LikeCondition::class,
212
            'NOT ILIKE' => LikeCondition::class,
213
            'OR ILIKE' => LikeCondition::class,
214
            'OR NOT ILIKE' => LikeCondition::class,
215
        ]);
216
    }
217
218
    /**
219
     * Contains array of default expression builders. Extend this method and override it, if you want to change default
220
     * expression builders for this query builder.
221
     *
222
     * @return array
223
     *
224
     * See {@see ExpressionBuilder} docs for details.
225
     */
226
    protected function defaultExpressionBuilders(): array
227
    {
228
        return array_merge(parent::defaultExpressionBuilders(), [
229
            ArrayExpression::class => ArrayExpressionBuilder::class,
230
            JsonExpression::class => JsonExpressionBuilder::class,
231
        ]);
232
    }
233
}
234