BetweenColumnsConditionBuilder   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 66
rs 10
c 0
b 0
f 0
wmc 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A escapeColumnName() 0 18 4
A build() 0 7 1
A createPlaceholder() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\QueryBuilder\Condition\Builder;
6
7
use Yiisoft\Db\Exception\Exception;
8
use Yiisoft\Db\Exception\InvalidArgumentException;
9
use Yiisoft\Db\Exception\InvalidConfigException;
10
use Yiisoft\Db\Exception\NotSupportedException;
11
use Yiisoft\Db\Expression\ExpressionBuilderInterface;
12
use Yiisoft\Db\Expression\ExpressionInterface;
13
use Yiisoft\Db\QueryBuilder\QueryBuilderInterface;
14
use Yiisoft\Db\QueryBuilder\Condition\Interface\BetweenColumnsConditionInterface;
15
use Yiisoft\Db\Query\QueryInterface;
16
17
use function str_contains;
18
19
/**
20
 * Build an object of {@see BetweenColumnsCondition} into SQL expressions.
21
 */
22
class BetweenColumnsConditionBuilder implements ExpressionBuilderInterface
23
{
24
    public function __construct(private QueryBuilderInterface $queryBuilder)
25
    {
26
    }
27
28
    /**
29
     * Build SQL for {@see BetweenColumnsCondition}.
30
     *
31
     * @throws Exception
32
     * @throws InvalidArgumentException
33
     * @throws InvalidConfigException
34
     * @throws NotSupportedException
35
     */
36
    public function build(BetweenColumnsConditionInterface $expression, array &$params = []): string
37
    {
38
        $operator = $expression->getOperator();
39
        $startColumn = $this->escapeColumnName($expression->getIntervalStartColumn(), $params);
40
        $endColumn = $this->escapeColumnName($expression->getIntervalEndColumn(), $params);
41
        $value = $this->createPlaceholder($expression->getValue(), $params);
42
        return "$value $operator $startColumn AND $endColumn";
43
    }
44
45
    /**
46
     * Attaches `$value` to `$params` array and return placeholder.
47
     *
48
     * @throws Exception
49
     * @throws InvalidArgumentException
50
     * @throws InvalidConfigException
51
     * @throws NotSupportedException
52
     */
53
    protected function createPlaceholder(mixed $value, array &$params): string
54
    {
55
        if ($value instanceof ExpressionInterface) {
56
            return $this->queryBuilder->buildExpression($value, $params);
57
        }
58
59
        return $this->queryBuilder->bindParam($value, $params);
60
    }
61
62
    /**
63
     * Prepares column name to use in SQL statement.
64
     *
65
     * @throws Exception
66
     * @throws InvalidArgumentException
67
     * @throws InvalidConfigException
68
     * @throws NotSupportedException
69
     */
70
    protected function escapeColumnName(
71
        ExpressionInterface|QueryInterface|string $columnName,
72
        array &$params = []
73
    ): string {
74
        if ($columnName instanceof QueryInterface) {
75
            [$sql, $params] = $this->queryBuilder->build($columnName, $params);
76
            return "($sql)";
77
        }
78
79
        if ($columnName instanceof ExpressionInterface) {
80
            return $this->queryBuilder->buildExpression($columnName, $params);
81
        }
82
83
        if (!str_contains($columnName, '(')) {
84
            return $this->queryBuilder->quoter()->quoteColumnName($columnName);
85
        }
86
87
        return $columnName;
88
    }
89
}
90