Passed
Push — master ( 914087...c6011d )
by Alexander
11:22
created

Query::orderBy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
rs 10
ccs 3
cts 3
cp 1
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Query;
6
7
use Closure;
8
use Throwable;
9
use Yiisoft\Arrays\ArrayHelper;
10
use Yiisoft\Cache\Dependency\Dependency;
11
use Yiisoft\Db\Command\Command;
12
use Yiisoft\Db\Command\CommandInterface;
13
use Yiisoft\Db\Connection\ConnectionInterface;
14
use Yiisoft\Db\Exception\Exception;
15
use Yiisoft\Db\Exception\InvalidConfigException;
16
use Yiisoft\Db\Expression\Expression;
17
use Yiisoft\Db\Expression\ExpressionInterface;
18
use Yiisoft\Db\Query\Helper\QueryHelper;
19
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
20
21
use function array_merge;
22
use function count;
23
use function is_array;
24
use function is_int;
25
use function is_string;
26
use function key;
27
use function preg_match;
28
use function preg_split;
29
use function reset;
30
use function str_contains;
31
use function strcasecmp;
32
use function strlen;
33
use function substr;
34
use function trim;
35
36
/**
37
 * Query represents a SELECT SQL statement in a way that is independent of DBMS.
38
 *
39
 * Query provides a set of methods to facilitate the specification of different clauses in a SELECT statement. These
40
 * methods can be chained together.
41
 *
42
 * By calling {@see createCommand()}, we can get a {@see Command} instance which can be further used to perform/execute
43
 * the DB query against a database.
44
 *
45
 * For example,
46
 *
47
 * ```php
48
 * $query = new Query;
49
 * // compose the query
50
 * $query->select('id, name')
51
 *     ->from('user')
52
 *     ->limit(10);
53
 * // build and execute the query
54
 * $rows = $query->all();
55
 * // alternatively, you can create DB command and execute it
56
 * $command = $query->createCommand();
57
 * // $command->sql returns the actual SQL
58
 * $rows = $command->queryAll();
59
 * ```
60
 *
61
 * Query internally uses the {@see QueryBuilder} class to generate the SQL statement.
62
 *
63
 * A more detailed usage guide on how to work with Query can be found in the
64
 * [guide article on Query Builder](guide:db-query-builder).
65
 *
66
 * @property string[] $tablesUsedInFrom Table names indexed by aliases. This property is read-only.
67
 */
68
class Query implements QueryInterface
69
{
70
    protected array $select = [];
71
    protected ?string $selectOption = null;
72
    protected ?bool $distinct = null;
73
    protected array|null $from = null;
74
    protected array $groupBy = [];
75
    protected array|ExpressionInterface|string|null $having = null;
76
    protected array $join = [];
77
    private array $orderBy = [];
78
    protected array $params = [];
79
    protected array $union = [];
80
    protected array $withQueries = [];
81
    private bool $emulateExecution = false;
82
    private Closure|string|null $indexBy = null;
83
    private Expression|int|null $limit = null;
84
    private Expression|int|null $offset = null;
85
    private ?Dependency $queryCacheDependency = null;
86
    private ?int $queryCacheDuration = null;
87
    private QueryHelper|null $queryHelper = null;
88
    private array|string|ExpressionInterface|null $where = null;
89 1891
90
    public function __construct(private ConnectionInterface $db)
91 1891
    {
92 1891
    }
93
94
    /**
95
     * Returns the SQL representation of Query.
96
     *
97
     * @return string
98
     */
99
    public function __toString(): string
100
    {
101
        return serialize($this);
102
    }
103 127
104
    public function addGroupBy(array|string|ExpressionInterface $columns): QueryInterface
105 127
    {
106
        if ($columns instanceof ExpressionInterface) {
0 ignored issues
show
introduced by
$columns is never a sub-type of Yiisoft\Db\Expression\ExpressionInterface.
Loading history...
107 127
            $columns = [$columns];
108
        } elseif (!is_array($columns)) {
0 ignored issues
show
introduced by
The condition is_array($columns) is always true.
Loading history...
109 127
            $columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
110
        }
111 127
112
        if ($this->groupBy === []) {
113
            $this->groupBy = $columns;
114
        } else {
115
            $this->groupBy = array_merge($this->groupBy, $columns);
116
        }
117
118
        return $this;
119
    }
120
121
    public function addOrderBy(array|string|ExpressionInterface $columns): QueryInterface
122
    {
123
        $columns = $this->createQueryHelper()->normalizeOrderBy($columns);
124 915
125
        if ($this->orderBy === []) {
126 915
            $this->orderBy = $columns;
127
        } else {
128
            $this->orderBy = array_merge($this->orderBy, $columns);
129
        }
130
131
        return $this;
132
    }
133
134
    public function addParams(array $params): QueryInterface
135
    {
136
        if (!empty($params)) {
137
            if (empty($this->params)) {
138
                $this->params = $params;
139
            } else {
140
                /**
141
                 * @psalm-var array $params
142
                 * @psalm-var mixed $value
143
                 */
144
                foreach ($params as $name => $value) {
145
                    if (is_int($name)) {
146
                        $this->params[] = $value;
147
                    } else {
148
                        $this->params[$name] = $value;
149
                    }
150
                }
151 30
            }
152
        }
153 30
154 30
        return $this;
155 30
    }
156 30
157 30
    public function andFilterHaving(array $condition): QueryInterface
158
    {
159
        $condition = $this->filterCondition($condition);
160
161
        if ($condition !== []) {
162
            $this->andHaving($condition);
163
        }
164
165
        return $this;
166
    }
167
168
    public function andFilterWhere(array $condition): QueryInterface
169
    {
170
        $condition = $this->filterCondition($condition);
171
172
        if ($condition !== []) {
173
            $this->andWhere($condition);
174
        }
175
176
        return $this;
177 10
    }
178
179 10
    public function andHaving(array|string|ExpressionInterface $condition, array $params = []): QueryInterface
180 10
    {
181 10
        if ($this->having === null) {
182 10
            $this->having = $condition;
183 10
        } else {
184
            $this->having = ['and', $this->having, $condition];
185
        }
186
187
        $this->addParams($params);
188
189
        return $this;
190
    }
191
192
    public function addSelect(array|string|ExpressionInterface $columns): QueryInterface
193
    {
194
        if ($this->select === []) {
195 311
            return $this->select($columns);
196
        }
197 311
198 15
        $this->select = array_merge($this->select, $this->createQueryHelper()->normalizeSelect($columns));
199
200
        return $this;
201 301
    }
202
203 301
    public function andFilterCompare(string $name, ?string $value, string $defaultOperator = '='): QueryInterface
204
    {
205
        $operator = $defaultOperator;
206
207
        if (preg_match('/^(<>|>=|>|<=|<|=)/', (string) $value, $matches)) {
208
            $operator = $matches[1];
209
            $value = substr((string) $value, strlen($operator));
210
        }
211
212
        return $this->andFilterWhere([$operator, $name, $value]);
213
    }
214
215
    public function andWhere($condition, array $params = []): QueryInterface
216 520
    {
217
        if ($this->where === null) {
218 520
            $this->where = $condition;
219 500
        } elseif (is_array($this->where) && isset($this->where[0]) && strcasecmp((string) $this->where[0], 'and') === 0) {
220
            $this->where[] = $condition;
221
        } else {
222 55
            $this->where = ['and', $this->where, $condition];
223
        }
224 55
225 55
        $this->addParams($params);
226
227
        return $this;
228 55
    }
229
230
    public function all(): array
231
    {
232
        return match ($this->emulateExecution) {
233
            true => [],
234
            false => $this->populate($this->createCommand()->queryAll()),
235
        };
236
    }
237
238
    public function average(string $q): int|float|null|string
239
    {
240
        return match ($this->emulateExecution) {
241 432
            true => null,
242
            false => is_numeric($avg = $this->queryScalar("AVG($q)")) ? $avg : null,
243 432
        };
244 10
    }
245
246
    public function batch(int $batchSize = 100): BatchQueryResultInterface
247 422
    {
248
        return $this->db->createBatchQueryResult($this)->batchSize($batchSize);
249
    }
250
251
    public function cache(?int $duration = 3600, ?Dependency $dependency = null): QueryInterface
252
    {
253
        $this->queryCacheDuration = $duration;
254
        $this->queryCacheDependency = $dependency;
255
256
        return $this;
257
    }
258
259
    /**
260 25
     * @psalm-suppress MixedArrayOffset
261
     */
262 25
    public function column(): array
263 10
    {
264
        if ($this->emulateExecution) {
265
            return [];
266 15
        }
267
268
        if ($this->indexBy === null) {
269
            $result = $this->createCommand()->queryColumn();
270
            if (is_array($result)) {
271
                return $result;
272
            }
273
            return [];
274
        }
275
276
        if (is_string($this->indexBy) && count($this->select) === 1) {
277
            if (!str_contains($this->indexBy, '.') && count($tables = $this->getTablesUsedInFrom()) > 0) {
278 25
                $this->select[] = key($tables) . '.' . $this->indexBy;
279
            } else {
280 25
                $this->select[] = $this->indexBy;
281 10
            }
282
        }
283
284 15
        $rows = $this->createCommand()->queryAll();
285 15
        $results = [];
286
287
        /** @psalm-var array<array-key, array<string, string>> $rows */
288 5
        foreach ($rows as $row) {
289 5
            $value = reset($row);
290 5
291
            if ($this->indexBy instanceof Closure) {
292
                $results[($this->indexBy)($row)] = $value;
293
            } else {
294
                $results[$row[$this->indexBy]] = $value;
295
            }
296 5
        }
297 5
298 5
        return $results;
299 5
    }
300
301 5
    public function count(string $q = '*'): int|string
302 5
    {
303
        return match ($this->emulateExecution) {
304 5
            true => 0,
305
            false => is_numeric($count = $this->queryScalar("COUNT($q)")) ? (int) $count : 0,
306
        };
307
    }
308 5
309
    public function createCommand(): CommandInterface
310
    {
311
        [$sql, $params] = $this->db->getQueryBuilder()->build($this);
312
        $command = $this->db->createCommand($sql, $params);
313
        $this->setCommandCache($command);
314
315
        return $command;
316
    }
317
318
    public function distinct(?bool $value = true): QueryInterface
319
    {
320
        $this->distinct = $value;
321
322 95
        return $this;
323
    }
324 95
325 10
    public function each(int $batchSize = 100): BatchQueryResultInterface
326
    {
327
        return $this->db->createBatchQueryResult($this, true)->batchSize($batchSize);
328 95
    }
329
330
    /**
331
     * @throws Exception|InvalidConfigException|Throwable
332
     */
333
    public function exists(): bool
334
    {
335
        if ($this->emulateExecution) {
336
            return false;
337
        }
338
339
        $command = $this->createCommand();
340
        $params = $command->getParams();
341 15
        $command->setSql($this->db->getQueryBuilder()->selectExists($command->getSql()));
342
        $command->bindValues($params);
343 15
344 10
        return (bool) $command->queryScalar();
345
    }
346
347 5
    public function emulateExecution(bool $value = true): QueryInterface
348
    {
349
        $this->emulateExecution = $value;
350
351
        return $this;
352
    }
353
354
    public function filterHaving(array $condition): QueryInterface
355
    {
356
        $condition = $this->filterCondition($condition);
357
358
        if ($condition !== []) {
359
            $this->having($condition);
360 15
        }
361
362 15
        return $this;
363 10
    }
364
365
    public function filterWhere(array $condition): QueryInterface
366 5
    {
367
        $condition = $this->filterCondition($condition);
368
369
        if ($condition !== []) {
370
            $this->where($condition);
371
        }
372
373
        return $this;
374
    }
375
376
    public function from(array|ExpressionInterface|string $tables): QueryInterface
377
    {
378
        if ($tables instanceof ExpressionInterface) {
0 ignored issues
show
introduced by
$tables is never a sub-type of Yiisoft\Db\Expression\ExpressionInterface.
Loading history...
379 15
            $tables = [$tables];
380
        }
381 15
382
        if (is_string($tables)) {
0 ignored issues
show
introduced by
The condition is_string($tables) is always false.
Loading history...
383
            $tables = preg_split('/\s*,\s*/', trim($tables), -1, PREG_SPLIT_NO_EMPTY);
384
        }
385
386
        $this->from = $tables;
387
388
        return $this;
389
    }
390
391
    public function getDistinct(): ?bool
392
    {
393
        return $this->distinct;
394 15
    }
395
396 15
    public function getFrom(): array|null
397
    {
398
        return $this->from;
399
    }
400
401
    public function getGroupBy(): array
402
    {
403
        return $this->groupBy;
404
    }
405
406 25
    public function getHaving(): string|array|ExpressionInterface|null
407
    {
408 25
        return $this->having;
409 10
    }
410
411
    public function getIndexBy(): Closure|string|null
412 15
    {
413 15
        return $this->indexBy;
414 15
    }
415 15
416
    public function getJoin(): array
417 15
    {
418
        return $this->join;
419
    }
420
421
    public function getLimit(): Expression|int|null
422
    {
423
        return $this->limit;
424
    }
425
426
    public function getOffset(): Expression|int|null
427
    {
428
        return $this->offset;
429
    }
430
431 95
    public function getOrderBy(): array
432
    {
433 95
        return $this->orderBy;
434 10
    }
435
436
    public function getParams(): array
437
    {
438 95
        return $this->params;
439 95
    }
440 95
441 95
    public function getSelect(): array
442 95
    {
443
        return $this->select;
444 95
    }
445 95
446 95
    public function getSelectOption(): ?string
447 95
    {
448
        return $this->selectOption;
449 95
    }
450 95
451 95
    public function getTablesUsedInFrom(): array
452 95
    {
453
        return empty($this->from) ? [] : $this->createQueryHelper()->cleanUpTableNames(
454
            $this->from,
455 95
            $this->db->getQuoter(),
456
        );
457
    }
458
459
    public function getUnion(): array
460 95
    {
461 95
        return $this->union;
462 95
    }
463 95
464
    public function getWhere(): array|string|ExpressionInterface|null
465 95
    {
466
        return $this->where;
467
    }
468
469 95
    public function getWithQueries(): array
470
    {
471
        return $this->withQueries;
472 10
    }
473 10
474 10
    public function groupBy(array|string|ExpressionInterface $columns): QueryInterface
475 10
    {
476
        if ($columns instanceof ExpressionInterface) {
0 ignored issues
show
introduced by
$columns is never a sub-type of Yiisoft\Db\Expression\ExpressionInterface.
Loading history...
477 10
            $columns = [$columns];
478
        } elseif (!is_array($columns)) {
0 ignored issues
show
introduced by
The condition is_array($columns) is always true.
Loading history...
479 10
            $columns = preg_split('/\s*,\s*/', trim($columns), -1, PREG_SPLIT_NO_EMPTY);
480
        }
481
        $this->groupBy = $columns;
482
483
        return $this;
484
    }
485
486
    public function having(array|ExpressionInterface|string|null $condition, array $params = []): QueryInterface
487
    {
488
        $this->having = $condition;
489
        $this->addParams($params);
490
491
        return $this;
492 110
    }
493
494 110
    public function indexBy(Closure|string|null $column): QueryInterface
495
    {
496
        $this->indexBy = $column;
497
498 110
        return $this;
499 105
    }
500 5
501
    public function innerJoin(array|string $table, array|string $on = '', array $params = []): QueryInterface
502 5
    {
503
        $this->join[] = ['INNER JOIN', $table, $on];
504
505 5
        return $this->addParams($params);
506
    }
507
508 105
    public function join(string $type, array|string $table, array|string $on = '', array $params = []): QueryInterface
509
    {
510
        $this->join[] = [$type, $table, $on];
511
512
        return $this->addParams($params);
513
    }
514
515
    public function leftJoin(array|string $table, array|string $on = '', array $params = []): QueryInterface
516
    {
517
        $this->join[] = ['LEFT JOIN', $table, $on];
518
519
        return $this->addParams($params);
520
    }
521
522 260
    public function limit(Expression|int|null $limit): QueryInterface
523
    {
524 260
        $this->limit = $limit;
525 260
526 260
        return $this;
527
    }
528 225
529
    public function max(string $q): int|float|null|string
530
    {
531
        $max = $this->queryScalar("MAX($q)");
532
533
        return is_numeric($max) ? $max : null;
534
    }
535
536
    public function min(string $q): int|float|null|string
537
    {
538
        $min = $this->queryScalar("MIN($q)");
539
540
        return is_numeric($min) ? $min : null;
541
    }
542
543
    public function noCache(): QueryInterface
544
    {
545
        $this->queryCacheDuration = -1;
546
547
        return $this;
548
    }
549
550
    public function offset(Expression|int|null $offset): QueryInterface
551
    {
552
        $this->offset = $offset;
553
554
        return $this;
555
    }
556
557
    public function one(): mixed
558 225
    {
559 225
        return match ($this->emulateExecution) {
560 15
            true => false,
561
            false => $this->createCommand()->queryOne(),
562 220
        };
563
    }
564
565
    public function orderBy(array|string|ExpressionInterface $columns): QueryInterface
566
    {
567 260
        $this->orderBy = $this->createQueryHelper()->normalizeOrderBy($columns);
568 10
569 5
        return $this;
570 5
    }
571
572
    public function orFilterHaving(array $condition): QueryInterface
573 5
    {
574 250
        $condition = $this->filterCondition($condition);
575 5
576
        if ($condition !== []) {
577 245
            $this->orHaving($condition);
578
        }
579
580
        return $this;
581 255
    }
582
583
    public function orFilterWhere(array $condition): QueryInterface
584
    {
585
        $condition = $this->filterCondition($condition);
586
587
        if ($condition !== []) {
588
            $this->orWhere($condition);
589
        }
590
591 255
        return $this;
592
    }
593 255
594 255
    public function orHaving(array|string|ExpressionInterface $condition, array $params = []): QueryInterface
595 250
    {
596
        if ($this->having === null) {
597
            $this->having = $condition;
598 20
        } else {
599
            $this->having = ['or', $this->having, $condition];
600
        }
601
602
        $this->addParams($params);
603
604
        return $this;
605
    }
606
607
    public function orWhere(array|string|ExpressionInterface $condition, array $params = []): QueryInterface
608
    {
609
        if ($this->where === null) {
610
            $this->where = $condition;
611
        } else {
612
            $this->where = ['or', $this->where, $condition];
613
        }
614
615
        $this->addParams($params);
616
617
        return $this;
618
    }
619
620
    public function params(array $params): QueryInterface
621
    {
622
        $this->params = $params;
623 796
624
        return $this;
625 796
    }
626 796
627
    /**
628 796
     * @psalm-suppress MixedArrayOffset
629
     */
630
    public function populate(array $rows): array
631
    {
632
        if ($this->indexBy === null) {
633
            return $rows;
634
        }
635
636
        $result = [];
637
638
        /** @psalm-var array[][] */
639
        foreach ($rows as $row) {
640
            $result[ArrayHelper::getValueByPath($row, $this->indexBy)] = $row;
641
        }
642
643
        return $result;
644
    }
645
646
    public function prepare(QueryBuilderInterface $builder): QueryInterface
647
    {
648 15
        return $this;
649
    }
650 15
651
    public function rightJoin(array|string $table, array|string $on = '', array $params = []): QueryInterface
652
    {
653
        $this->join[] = ['RIGHT JOIN', $table, $on];
654 15
655
        return $this->addParams($params);
656
    }
657
658 15
    public function scalar(): bool|int|null|string|float
659
    {
660 15
        return match ($this->emulateExecution) {
661
            true => null,
662
            false => $this->createCommand()->queryScalar(),
663
        };
664
    }
665
666
    public function select(array|string|ExpressionInterface $columns, ?string $option = null): QueryInterface
667
    {
668
        $this->select = $this->createQueryHelper()->normalizeSelect($columns);
669
        $this->selectOption = $option;
670 796
671
        return $this;
672 796
    }
673 5
674 796
    public function selectOption(?string $value): QueryInterface
675 113
    {
676
        $this->selectOption = $value;
677
678 796
        return $this;
679 796
    }
680 355
681
    public function setJoin(array $value): QueryInterface
682 182
    {
683 182
        $this->join = $value;
684
685 348
        return $this;
686
    }
687 343
688 343
    public function setUnion(array $value): QueryInterface
689 343
    {
690
        $this->union = $value;
691
692 26
        return $this;
693 26
    }
694
695 342
    public function shouldEmulateExecution(): bool
696
    {
697 286
        return $this->emulateExecution;
698 286
    }
699
700
    public function sum(string $q): int|float|null|string
701
    {
702 106
        return match ($this->emulateExecution) {
703
            true => null,
704
            false => is_numeric($sum = $this->queryScalar("SUM($q)")) ? $sum : null,
705 796
        };
706
    }
707
708
    public function union(QueryInterface|string $sql, bool $all = false): QueryInterface
709
    {
710
        $this->union[] = ['query' => $sql, 'all' => $all];
711
712
        return $this;
713
    }
714
715 627
    public function where(array|string|ExpressionInterface|null $condition, array $params = []): QueryInterface
716
    {
717 627
        $this->where = $condition;
718
        $this->addParams($params);
719 627
720
        return $this;
721
    }
722
723
    public function withQuery(QueryInterface|string $query, string $alias, bool $recursive = false): QueryInterface
724
    {
725
        $this->withQueries[] = ['query' => $query, 'alias' => $alias, 'recursive' => $recursive];
726
727
        return $this;
728
    }
729
730
    public function withQueries(array $value): QueryInterface
731
    {
732
        $this->withQueries = $value;
733
734
        return $this;
735
    }
736
737
    /**
738
     * Queries a scalar value by setting {@see select} first.
739
     *
740
     * Restores the value of select to make this query reusable.
741
     *
742
     * @param ExpressionInterface|string $selectExpression
743
     *
744
     *@throws Exception|InvalidConfigException|Throwable
745
     *
746
     * @return bool|float|int|string|null
747
     *
748
     * @psalm-suppress PossiblyUndefinedVariable
749
     */
750
    protected function queryScalar(string|ExpressionInterface $selectExpression): bool|int|null|string|float
751
    {
752
        if ($this->emulateExecution) {
753
            return null;
754
        }
755
756
        if (
757
            !$this->distinct
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->distinct of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
758
            && empty($this->groupBy)
759 970
            && empty($this->having)
760
            && empty($this->union)
761 970
            && empty($this->with)
762 16
        ) {
763
            $select = $this->select;
764 970
            $order = $this->orderBy;
765 263
            $limit = $this->limit;
766
            $offset = $this->offset;
767 970
768
            $this->select = [$selectExpression];
769 970
            $this->orderBy = [];
770
            $this->limit = null;
771
            $this->offset = null;
772
773
            try {
774
                $command = $this->createCommand();
775
            } catch (Throwable $e) {
776
                /** throw it later */
777
            }
778
779
            $this->select = $select;
780
            $this->orderBy = $order;
781
            $this->limit = $limit;
782
            $this->offset = $offset;
783
784
            if (isset($e)) {
785
                throw $e;
786
            }
787
788
            return $command->queryScalar();
789
        }
790
791 1375
        $query = (new self($this->db))->select($selectExpression)->from(['c' => $this]);
792
        [$sql, $params] = $this->db->getQueryBuilder()->build($query);
793 1375
        $command = $this->db->createCommand($sql, $params);
794 1375
        $this->setCommandCache($command);
795
796 1375
        return $command->queryScalar();
797
    }
798
799
    /**
800
     * Sets $command cache, if this query has enabled caching.
801
     *
802
     * @param CommandInterface $command The command instance.
803
     *
804
     * @return CommandInterface
805
     */
806
    protected function setCommandCache(CommandInterface $command): CommandInterface
807
    {
808
        if ($this->queryCacheDuration !== null || $this->queryCacheDependency !== null) {
809
            $command->cache($this->queryCacheDuration, $this->queryCacheDependency);
810
        }
811
812
        return $command;
813 348
    }
814
815 348
    private function createQueryHelper(): QueryHelper
816 323
    {
817 131
        if ($this->queryHelper === null) {
818 6
            $this->queryHelper = new QueryHelper();
819
        }
820 131
821
        return $this->queryHelper;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->queryHelper could return the type null which is incompatible with the type-hinted return Yiisoft\Db\Query\Helper\QueryHelper. Consider adding an additional type-check to rule them out.
Loading history...
822
    }
823 348
824
    private function filterCondition(array $condition): array
825 348
    {
826
        return (array) $this->createQueryHelper()->filterCondition($condition);
827
    }
828
}
829