Passed
Push — master ( e3e48a...a5cdfd )
by Def
02:27
created

QueryBuilder::insertWithReturningPks()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\QueryBuilder;
6
7
use Generator;
8
use Yiisoft\Db\Command\Command;
9
use Yiisoft\Db\Exception\Exception;
10
use Yiisoft\Db\Exception\InvalidArgumentException;
11
use Yiisoft\Db\Exception\InvalidConfigException;
12
use Yiisoft\Db\Exception\NotSupportedException;
13
use Yiisoft\Db\Expression\Expression;
14
use Yiisoft\Db\Expression\ExpressionInterface;
15
use Yiisoft\Db\QueryBuilder\Condition\Interface\ConditionInterface;
16
use Yiisoft\Db\Query\QueryInterface;
17
use Yiisoft\Db\Schema\ColumnSchemaBuilder;
18
use Yiisoft\Db\Schema\QuoterInterface;
19
use Yiisoft\Db\Schema\SchemaInterface;
20
21
use function count;
22
use function preg_match;
23
use function preg_replace;
24
25
/**
26
 * QueryBuilder builds a SELECT SQL statement based on the specification given as a {@see Query} object.
27
 *
28
 * SQL statements are created from {@see Query} objects using the {@see build()}-method.
29
 *
30
 * QueryBuilder is also used by {@see Command} to build SQL statements such as INSERT, UPDATE, DELETE, CREATE TABLE.
31
 *
32
 * For more details and usage information on QueryBuilder:
33
 * {@see [guide article on query builders](guide:db-query-builder)}.
34
 *
35
 * @property string[] $conditionClasses Map of condition aliases to condition classes. This property is write-only.
36
 *
37
 * For example:
38
 * ```php
39
 *     ['LIKE' => \Yiisoft\Db\Condition\LikeCondition::class]
40
 * ```
41
 * @property string[] $expressionBuilders Array of builders that should be merged with the pre-defined one's in
42
 * {@see expressionBuilders} property. This property is write-only.
43
 */
44
abstract class QueryBuilder implements QueryBuilderInterface
45
{
46
    /**
47
     * Defines a UNIQUE index type for {@see createIndex()}.
48
     */
49
    public const INDEX_UNIQUE = 'UNIQUE';
50
51
    /**
52
     * The prefix for automatically generated query binding parameters.
53
     */
54
    public const PARAM_PREFIX = ':qp';
55
56
    /**
57
     * @var array the abstract column types mapped to physical column types.
58
     * This is mainly used to support creating/modifying tables using DB-independent data type specifications.
59
     * Child classes should override this property to declare supported type mappings.
60
     *
61
     * @psalm-var string[]
62
     */
63
    protected array $typeMap = [];
64
65
    public function __construct(
66
        private QuoterInterface $quoter,
67
        private SchemaInterface $schema,
68
        private DDLQueryBuilder $ddlBuilder,
69
        private DMLQueryBuilder $dmlBuilder,
70
        private DQLQueryBuilder $dqlBuilder
71
    ) {
72
    }
73
74
    public function addCheck(string $name, string $table, string $expression): string
75
    {
76
        return $this->ddlBuilder->addCheck($name, $table, $expression);
77
    }
78
79
    public function addColumn(string $table, string $column, string $type): string
80
    {
81
        return $this->ddlBuilder->addColumn($table, $column, $type);
82
    }
83
84
    public function addCommentOnColumn(string $table, string $column, string $comment): string
85
    {
86
        return $this->ddlBuilder->addCommentOnColumn($table, $column, $comment);
87
    }
88
89
    public function addCommentOnTable(string $table, string $comment): string
90
    {
91
        return $this->ddlBuilder->addCommentOnTable($table, $comment);
92
    }
93
94
    public function addDefaultValue(string $name, string $table, string $column, mixed $value): string
95
    {
96
        return $this->ddlBuilder->addDefaultValue($name, $table, $column, $value);
97
    }
98
99
    public function addForeignKey(
100
        string $name,
101
        string $table,
102
        array|string $columns,
103
        string $refTable,
104
        array|string $refColumns,
105
        string $delete = null,
106
        string $update = null
107
    ): string {
108
        return $this->ddlBuilder->addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete, $update);
109
    }
110
111
    public function addPrimaryKey(string $name, string $table, array|string $columns): string
112
    {
113
        return $this->ddlBuilder->addPrimaryKey($name, $table, $columns);
114
    }
115
116
    public function addUnique(string $name, string $table, array|string $columns): string
117
    {
118
        return $this->ddlBuilder->addUnique($name, $table, $columns);
119
    }
120
121
    public function alterColumn(string $table, string $column, ColumnSchemaBuilder|string $type): string
122
    {
123
        return $this->ddlBuilder->alterColumn($table, $column, $type);
124
    }
125
126
    public function batchInsert(string $table, array $columns, iterable|Generator $rows, array &$params = []): string
127
    {
128
        return $this->dmlBuilder->batchInsert($table, $columns, $rows, $params);
129
    }
130
131
    public function bindParam(mixed $value, array &$params = []): string
132
    {
133
        $phName = self::PARAM_PREFIX . count($params);
134
135
        $additionalCount = 0;
136
        while (isset($params[$phName])) {
137
            $phName = self::PARAM_PREFIX . count($params) . '_' . $additionalCount;
138
            ++$additionalCount;
139
        }
140
141
        /** @psalm-var mixed */
142
        $params[$phName] = $value;
143
144
        return $phName;
145
    }
146
147
    public function build(QueryInterface $query, array $params = []): array
148
    {
149
        return $this->dqlBuilder->build($query, $params);
150
    }
151
152
    public function buildColumns(array|string $columns): string
153
    {
154
        return $this->dqlBuilder->buildColumns($columns);
155
    }
156
157
    public function buildCondition(array|string|ExpressionInterface|null $condition, array &$params = []): string
158
    {
159
        return $this->dqlBuilder->buildCondition($condition, $params);
160
    }
161
162
    public function buildExpression(ExpressionInterface $expression, array &$params = []): string
163
    {
164
        return $this->dqlBuilder->buildExpression($expression, $params);
165
    }
166
167
    public function buildFrom(array|null $tables, array &$params): string
168
    {
169
        return $this->dqlBuilder->buildFrom($tables, $params);
170
    }
171
172
    public function buildGroupBy(array $columns, array &$params = []): string
173
    {
174
        return $this->dqlBuilder->buildGroupBy($columns, $params);
175
    }
176
177
    public function buildHaving(array|ExpressionInterface|string|null $condition, array &$params = []): string
178
    {
179
        return $this->dqlBuilder->buildHaving($condition, $params);
180
    }
181
182
    public function buildJoin(array $joins, array &$params): string
183
    {
184
        return $this->dqlBuilder->buildJoin($joins, $params);
185
    }
186
187
    public function buildLimit(Expression|int|null $limit, Expression|int|null $offset): string
188
    {
189
        return $this->dqlBuilder->buildLimit($limit, $offset);
190
    }
191
192
    public function buildOrderBy(array $columns, array &$params = []): string
193
    {
194
        return $this->dqlBuilder->buildOrderBy($columns, $params);
195
    }
196
197
    public function buildOrderByAndLimit(
198
        string $sql,
199
        array $orderBy,
200
        Expression|int|null $limit,
201
        Expression|int|null $offset,
202
        array &$params = []
203
    ): string {
204
        return $this->dqlBuilder->buildOrderByAndLimit($sql, $orderBy, $limit, $offset, $params);
205
    }
206
207
    public function buildSelect(
208
        array $columns,
209
        array &$params,
210
        bool|null $distinct = false,
211
        string $selectOption = null
212
    ): string {
213
        return $this->dqlBuilder->buildSelect($columns, $params, $distinct, $selectOption);
214
    }
215
216
    public function buildUnion(array $unions, array &$params): string
217
    {
218
        return $this->dqlBuilder->buildUnion($unions, $params);
219
    }
220
221
    public function buildWhere(
222
        array|string|ConditionInterface|ExpressionInterface|null $condition,
223
        array &$params = []
224
    ): string {
225
        return $this->dqlBuilder->buildWhere($condition, $params);
226
    }
227
228
    public function buildWithQueries(array $withs, array &$params): string
229
    {
230
        return $this->dqlBuilder->buildWithQueries($withs, $params);
231
    }
232
233
    public function checkIntegrity(string $schema = '', string $table = '', bool $check = true): string
234
    {
235
        return $this->ddlBuilder->checkIntegrity($schema, $table, $check);
236
    }
237
238
    public function createConditionFromArray(array $condition): ConditionInterface
239
    {
240
        return $this->dqlBuilder->createConditionFromArray($condition);
241
    }
242
243
    public function createIndex(
244
        string $name,
245
        string $table,
246
        array|string $columns,
247
        string $indexType = null,
248
        string $indexMethod = null
249
    ): string {
250
        return $this->ddlBuilder->createIndex($name, $table, $columns, $indexType, $indexMethod);
251
    }
252
253
    public function createTable(string $table, array $columns, string $options = null): string
254
    {
255
        return $this->ddlBuilder->createTable($table, $columns, $options);
256
    }
257
258
    public function createView(string $viewName, QueryInterface|string $subQuery): string
259
    {
260
        return $this->ddlBuilder->createView($viewName, $subQuery);
261
    }
262
263
    public function delete(string $table, array|string $condition, array &$params): string
264
    {
265
        return $this->dmlBuilder->delete($table, $condition, $params);
266
    }
267
268
    public function dropCheck(string $name, string $table): string
269
    {
270
        return $this->ddlBuilder->dropCheck($name, $table);
271
    }
272
273
    public function dropColumn(string $table, string $column): string
274
    {
275
        return $this->ddlBuilder->dropColumn($table, $column);
276
    }
277
278
    public function dropCommentFromColumn(string $table, string $column): string
279
    {
280
        return $this->ddlBuilder->dropCommentFromColumn($table, $column);
281
    }
282
283
    public function dropCommentFromTable(string $table): string
284
    {
285
        return $this->ddlBuilder->dropCommentFromTable($table);
286
    }
287
288
    public function dropDefaultValue(string $name, string $table): string
289
    {
290
        return $this->ddlBuilder->dropDefaultValue($name, $table);
291
    }
292
293
    public function dropForeignKey(string $name, string $table): string
294
    {
295
        return $this->ddlBuilder->dropForeignKey($name, $table);
296
    }
297
298
    public function dropIndex(string $name, string $table): string
299
    {
300
        return $this->ddlBuilder->dropIndex($name, $table);
301
    }
302
303
    public function dropPrimaryKey(string $name, string $table): string
304
    {
305
        return $this->ddlBuilder->dropPrimaryKey($name, $table);
306
    }
307
308
    public function dropTable(string $table): string
309
    {
310
        return $this->ddlBuilder->dropTable($table);
311
    }
312
313
    public function dropUnique(string $name, string $table): string
314
    {
315
        return $this->ddlBuilder->dropUnique($name, $table);
316
    }
317
318
    public function dropView(string $viewName): string
319
    {
320
        return $this->ddlBuilder->dropView($viewName);
321
    }
322
323
    public function getColumnType(ColumnSchemaBuilder|string $type): string
324
    {
325
        if ($type instanceof ColumnSchemaBuilder) {
326
            $type = $type->__toString();
327
        }
328
329
        if (isset($this->typeMap[$type])) {
330
            return $this->typeMap[$type];
331
        }
332
333
        if (preg_match('/^(\w+)\((.+?)\)(.*)$/', $type, $matches)) {
334
            if (isset($this->typeMap[$matches[1]])) {
335
                return preg_replace(
336
                    '/\(.+\)/',
337
                    '(' . $matches[2] . ')',
338
                    $this->typeMap[$matches[1]]
339
                ) . $matches[3];
340
            }
341
        } elseif (preg_match('/^(\w+)\s+/', $type, $matches)) {
342
            if (isset($this->typeMap[$matches[1]])) {
343
                return preg_replace('/^\w+/', $this->typeMap[$matches[1]], $type);
344
            }
345
        }
346
347
        return $type;
348
    }
349
350
    public function getExpressionBuilder(ExpressionInterface $expression): object
351
    {
352
        return $this->dqlBuilder->getExpressionBuilder($expression);
353
    }
354
355
    public function insert(string $table, QueryInterface|array $columns, array &$params = []): string
356
    {
357
        return $this->dmlBuilder->insert($table, $columns, $params);
358
    }
359
360
    /**
361
     * @throws Exception|InvalidArgumentException|InvalidConfigException|NotSupportedException
362
     */
363
    public function insertWithReturningPks(string $table, QueryInterface|array $columns, array &$params = []): string
364
    {
365
        return $this->dmlBuilder->insertWithReturningPks($table, $columns, $params);
366
    }
367
368
    public function quoter(): QuoterInterface
369
    {
370
        return $this->quoter;
371
    }
372
373
    public function renameColumn(string $table, string $oldName, string $newName): string
374
    {
375
        return $this->ddlBuilder->renameColumn($table, $oldName, $newName);
376
    }
377
378
    public function renameTable(string $oldName, string $newName): string
379
    {
380
        return $this->ddlBuilder->renameTable($oldName, $newName);
381
    }
382
383
    public function resetSequence(string $tableName, int|string|null $value = null): string
384
    {
385
        return $this->dmlBuilder->resetSequence($tableName, $value);
386
    }
387
388
    public function selectExists(string $rawSql): string
389
    {
390
        return $this->dqlBuilder->selectExists($rawSql);
391
    }
392
393
    public function setConditionClasses(array $classes): void
394
    {
395
        $this->dqlBuilder->setConditionClasses($classes);
396
    }
397
398
    public function setExpressionBuilders(array $builders): void
399
    {
400
        $this->dqlBuilder->setExpressionBuilders($builders);
401
    }
402
403
    public function setSeparator(string $separator): void
404
    {
405
        $this->dqlBuilder->setSeparator($separator);
406
    }
407
408
    public function truncateTable(string $table): string
409
    {
410
        return $this->ddlBuilder->truncateTable($table);
411
    }
412
413
    public function update(string $table, array $columns, array|string $condition, array &$params = []): string
414
    {
415
        return $this->dmlBuilder->update($table, $columns, $condition, $params);
416
    }
417
418
    public function upsert(
419
        string $table,
420
        QueryInterface|array $insertColumns,
421
        bool|array $updateColumns,
422
        array &$params = []
423
    ): string {
424
        return $this->dmlBuilder->upsert($table, $insertColumns, $updateColumns, $params);
425
    }
426
}
427