AbstractQueryBuilder::buildHaving()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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