BetweenColumnsCondition   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 19
eloc 32
dl 0
loc 112
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getValue() 0 3 1
A getIntervalEndColumn() 0 3 1
A getOperator() 0 3 1
A validateIntervalStartColumn() 0 13 3
A getIntervalStartColumn() 0 3 1
A fromArrayDefinition() 0 11 2
A validateIntervalEndColumn() 0 13 3
A __construct() 0 6 1
A validateValue() 0 16 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\QueryBuilder\Condition;
6
7
use Iterator;
8
use Yiisoft\Db\Exception\InvalidArgumentException;
9
use Yiisoft\Db\Expression\ExpressionInterface;
10
use Yiisoft\Db\QueryBuilder\Condition\Interface\BetweenColumnsConditionInterface;
11
12
use function is_array;
13
use function is_int;
14
use function is_string;
15
16
/**
17
 * Represents a `BETWEEN` operator where values are between two columns.
18
 *
19
 * For example:.
20
 *
21
 * ```php
22
 * new BetweenColumnsCondition(42, 'BETWEEN', 'min_value', 'max_value')
23
 * // Will be build to:
24
 * // 42 BETWEEN min_value AND max_value
25
 * ```
26
 *
27
 * And a more complex example:
28
 *
29
 * ```php
30
 * new BetweenColumnsCondition(
31
 *    new Expression('NOW()'),
32
 *    'NOT BETWEEN',
33
 *    (new Query)->select('time')->from('log')->orderBy('id ASC')->limit(1),
34
 *    'update_time'
35
 * );
36
 *
37
 * // Will be built to:
38
 * // NOW() NOT BETWEEN (SELECT time FROM log ORDER BY id ASC LIMIT 1) AND update_time
39
 * ```
40
 */
41
final class BetweenColumnsCondition implements BetweenColumnsConditionInterface
42
{
43
    public function __construct(
44
        private array|int|string|Iterator|ExpressionInterface $value,
45
        private string $operator,
46
        private string|ExpressionInterface $intervalStartColumn,
47
        private string|ExpressionInterface $intervalEndColumn
48
    ) {
49
    }
50
51
    public function getIntervalEndColumn(): string|ExpressionInterface
52
    {
53
        return $this->intervalEndColumn;
54
    }
55
56
    public function getIntervalStartColumn(): string|ExpressionInterface
57
    {
58
        return $this->intervalStartColumn;
59
    }
60
61
    public function getOperator(): string
62
    {
63
        return $this->operator;
64
    }
65
66
    public function getValue(): array|int|string|Iterator|ExpressionInterface
67
    {
68
        return $this->value;
69
    }
70
71
    /**
72
     * Creates a condition based on the given operator and operands.
73
     *
74
     * @throws InvalidArgumentException If the number of operands isn't 3.
75
     */
76
    public static function fromArrayDefinition(string $operator, array $operands): self
77
    {
78
        if (!isset($operands[0], $operands[1], $operands[2])) {
79
            throw new InvalidArgumentException("Operator '$operator' requires three operands.");
80
        }
81
82
        return new self(
83
            self::validateValue($operator, $operands[0]),
84
            $operator,
85
            self::validateIntervalStartColumn($operator, $operands[1]),
86
            self::validateIntervalEndColumn($operator, $operands[2]),
87
        );
88
    }
89
90
    /**
91
     * Validates the given value to be `array`, `int`, `string`, `Iterator` or `ExpressionInterface`.
92
     *
93
     * @throws InvalidArgumentException If the value isn't `array`, `int`, `string`, `Iterator` or `ExpressionInterface`.
94
     */
95
    private static function validateValue(
96
        string $operator,
97
        mixed $value
98
    ): array|int|string|Iterator|ExpressionInterface {
99
        if (
100
            is_array($value) ||
101
            is_int($value) ||
102
            is_string($value) ||
103
            ($value instanceof Iterator) ||
104
            ($value instanceof ExpressionInterface)
105
        ) {
106
            return $value;
107
        }
108
109
        throw new InvalidArgumentException(
110
            "Operator '$operator' requires value to be array, int, string, Iterator or ExpressionInterface."
111
        );
112
    }
113
114
    /**
115
     * Validates the given interval start column to be string or `ExpressionInterface`.
116
     *
117
     * @throws InvalidArgumentException If the interval start column isn't string or `ExpressionInterface`.
118
     */
119
    private static function validateIntervalStartColumn(
120
        string $operator,
121
        mixed $intervalStartColumn
122
    ): string|ExpressionInterface {
123
        if (
124
            is_string($intervalStartColumn) ||
125
            $intervalStartColumn instanceof ExpressionInterface
126
        ) {
127
            return $intervalStartColumn;
128
        }
129
130
        throw new InvalidArgumentException(
131
            "Operator '$operator' requires interval start column to be string or ExpressionInterface."
132
        );
133
    }
134
135
    /**
136
     * Validates the given interval end column to be string or ExpressionInterface.
137
     *
138
     * @throws InvalidArgumentException If the interval end column isn't a string or ExpressionInterface.
139
     */
140
    private static function validateIntervalEndColumn(
141
        string $operator,
142
        mixed $intervalEndColumn
143
    ): string|ExpressionInterface {
144
        if (
145
            is_string($intervalEndColumn) ||
146
            $intervalEndColumn instanceof ExpressionInterface
147
        ) {
148
            return $intervalEndColumn;
149
        }
150
151
        throw new InvalidArgumentException(
152
            "Operator '$operator' requires interval end column to be string or ExpressionInterface."
153
        );
154
    }
155
}
156