Passed
Pull Request — master (#376)
by Wilmer
02:26
created

BetweenColumnsCondition   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 29
c 2
b 0
f 0
dl 0
loc 81
rs 10
wmc 19

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getOperator() 0 3 1
A getIntervalEndColumn() 0 3 1
A __construct() 0 6 1
A getIntervalStartColumn() 0 3 1
A getValue() 0 3 1
A fromArrayDefinition() 0 11 2
A validateIntervalStartColumn() 0 8 3
A validateIntervalEndColumn() 0 8 3
A validateValue() 0 11 6
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
        self::validateValue($operator, $operands[0]);
77
        self::validateIntervalStartColumn($operator, $operands[1]);
78
        self::validateIntervalEndColumn($operator, $operands[2]);
79
80
        return new self($operands[0], $operator, $operands[1], $operands[2]);
81
    }
82
83
    private static function validateValue(string $operator, mixed $operand): void
84
    {
85
        if (
86
            !is_array($operand) &&
87
            !is_int($operand) &&
88
            !is_string($operand) &&
89
            !($operand instanceof Iterator) &&
90
            !($operand instanceof ExpressionInterface)
91
        ) {
92
            throw new InvalidArgumentException(
93
                "Operator '$operator' requires value to be array, int, string, Iterator or ExpressionInterface."
94
            );
95
        }
96
    }
97
98
    private static function validateIntervalStartColumn(string $operator, mixed $operand): void
99
    {
100
        if (
101
            !is_string($operand) &&
102
            !($operand instanceof ExpressionInterface)
103
        ) {
104
            throw new InvalidArgumentException(
105
                "Operator '$operator' requires interval start column to be string or ExpressionInterface."
106
            );
107
        }
108
    }
109
110
    private static function validateIntervalEndColumn(string $operator, mixed $operand): void
111
    {
112
        if (
113
            !is_string($operand) &&
114
            !($operand instanceof ExpressionInterface)
115
        ) {
116
            throw new InvalidArgumentException(
117
                "Operator '$operator' requires interval end column to be string or ExpressionInterface."
118
            );
119
        }
120
    }
121
}
122