Passed
Pull Request — master (#376)
by Alexander
05:11 queued 02:37
created

validateIntervalStartColumn()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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