Condition::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 4
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace mav3rick177\RapidPagination\Base\Query;
4
5
use mav3rick177\RapidPagination\Base\Exceptions\Query\BadKeywordException;
6
7
/**
8
 * Class Condition
9
 */
10
class Condition
11
{
12
    const LT = '<';
13
    const GT = '>';
14
    const EQ = '=';
15
    const LE = '<=';
16
    const GE = '>=';
17
18
    protected static $comparatorInverseMap = [
19
        // inverse map for non-primary key condition
20
        [
21
            self::LT => self::GT,
22
            self::EQ => self::EQ,
23
            self::GT => self::LT,
24
        ],
25
        // inverse map for primary key condition
26
        [
27
            self::LT => self::GE,
28
            self::GT => self::LE,
29
            self::LE => self::GT,
30
            self::GE => self::LT,
31
        ],
32
    ];
33
34
    protected static $comparatorOrderDirectionMap = [
35
        Order::ASCENDING => [
36
            Direction::FORWARD => self::GT,
37
            Direction::BACKWARD => self::LT,
38
        ],
39
        Order::DESCENDING => [
40
            Direction::FORWARD => self::LT,
41
            Direction::BACKWARD => self::GT,
42
        ],
43
    ];
44
45
    /**
46
     * @var string
47
     */
48
    protected $left;
49
50
    /**
51
     * @var string
52
     */
53
    protected $comparator;
54
55
    /**
56
     * @var int|string
57
     */
58
    protected $right;
59
60
    /**
61
     * @var bool
62
     */
63
    protected $isPrimaryKey;
64
65
    /**
66
     * @param  Order      $order
67
     * @param  int|string $value
68
     * @param  Direction  $direction
69
     * @param  bool       $exclusive
70
     * @param  bool       $isPrimaryKey
71
     * @param  bool       $isLastKey
72
     * @param  bool       $isSupportQuery
73
     * @return Condition
74
     */
75 10
    public static function create(Order $order, $value, Direction $direction, $exclusive, $isPrimaryKey, $isLastKey, $isSupportQuery = false)
76
    {
77 10
        return new self(
78 10
            $order->column(),
79 10
            static::compileComparator(
80 10
                $order,
81
                $direction,
82
                $exclusive,
83
                $isPrimaryKey,
84
                $isLastKey,
85
                $isSupportQuery
86
            ),
87
            $value,
88
            $isPrimaryKey
89
        );
90
    }
91
92
    /**
93
     * @param  Order     $order
94
     * @param  Direction $direction
95
     * @param  bool      $exclusive
96
     * @param  bool      $isPrimaryKey
97
     * @param  bool      $isLastKey
98
     * @param  bool      $isSupportQuery
99
     * @return string
100
     */
101 10
    protected static function compileComparator(Order $order, Direction $direction, $exclusive, $isPrimaryKey, $isLastKey, $isSupportQuery)
102
    {
103 10
        if (!$isLastKey) {
104
            // Comparator for keys except the last one is always "=".
105
            // e.g. updated_at = ? AND created_at = ? AND id > ?
106 8
            return static::EQ;
107
        }
108
109
        // e.g. Ascending forward uses the condition "column > ?"
110 10
        $base = static::$comparatorOrderDirectionMap[$order->order()][(string)$direction];
111
112
        // For main query, we append "=" to the primary key condition when it is inclusive.
113 10
        $shouldAppendEquals = $isPrimaryKey && (!$isSupportQuery && !$exclusive || $isSupportQuery && $exclusive);
114
115 10
        return $base . ($shouldAppendEquals ? self::EQ : '');
116
    }
117
118
    /**
119
     * Condition constructor.
120
     *
121
     * @param string     $left
122
     * @param string     $comparator
123
     * @param int|string $right
124
     * @param bool       $isPrimaryKey
125
     */
126 10
    public function __construct($left, $comparator, $right, $isPrimaryKey = false)
127
    {
128 10
        $this->left = (string)$left;
129 10
        $this->comparator = (string)static::validate($comparator, $isPrimaryKey);
130 10
        $this->right = $right;
131 10
        $this->isPrimaryKey = (bool)$isPrimaryKey;
132
    }
133
134
    /**
135
     * @param  string $comparator
136
     * @param  bool   $isPrimaryKey
137
     * @return string
138
     */
139 10
    protected static function validate($comparator, $isPrimaryKey)
140
    {
141 10
        if (!isset(static::$comparatorInverseMap[$isPrimaryKey][$comparator])) {
142
            throw new BadKeywordException(
143
                $isPrimaryKey
144
                    ? 'Comparator for primary key condition must be "<", ">", "<=" or ">="'
145
                    : 'Comparator for non-primary key condition must be "<", ">" or "="'
146
            );
147
        }
148 10
        return $comparator;
149
    }
150
151
    /**
152
     * @return array
153
     */
154
    public function toArray()
155
    {
156
        return [$this->left, $this->comparator, $this->right];
157
    }
158
159
    /**
160
     * @return string
161
     */
162 10
    public function left()
163
    {
164 10
        return $this->left;
165
    }
166
167
    /**
168
     * @return string
169
     */
170 10
    public function comparator()
171
    {
172 10
        return $this->comparator;
173
    }
174
175
    /**
176
     * @return int|string
177
     */
178 10
    public function right()
179
    {
180 10
        return $this->right;
181
    }
182
183
    /**
184
     * @return bool
185
     */
186
    public function isPrimaryKey()
187
    {
188
        return $this->isPrimaryKey;
189
    }
190
191
    /**
192
     * @return static
193
     */
194 10
    public function inverse()
195
    {
196 10
        return new static(
197 10
            $this->left,
198 10
            static::$comparatorInverseMap[$this->isPrimaryKey][$this->comparator],
199 10
            $this->right,
200 10
            $this->isPrimaryKey
201
        );
202
    }
203
}
204