Passed
Push — main ( 7d9f09...bbfba8 )
by Peter
02:36
created

Select::addModifier()   C

Complexity

Conditions 12
Paths 12

Size

Total Lines 36
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 30
c 1
b 0
f 0
nc 12
nop 1
dl 0
loc 36
rs 6.9666
ccs 30
cts 30
cp 1
crap 12

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace QB\MySQL\Statement;
6
7
use QB\Generic\Statement\Select as GenericSelect;
8
use QB\MySQL\Clause\Lock;
9
10
/**
11
 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
12
 */
13
class Select extends GenericSelect
14
{
15
    public const DISTINCTROW         = 'DISTINCTROW';
16
    public const HIGH_PRIORITY       = 'HIGH_PRIORITY';
17
    public const STRAIGHT_JOIN       = 'STRAIGHT_JOIN';
18
    public const SQL_SMALL_RESULT    = 'SQL_SMALL_RESULT';
19
    public const SQL_BIG_RESULT      = 'SQL_BIG_RESULT';
20
    public const SQL_BUFFER_RESULT   = 'SQL_BUFFER_RESULT';
21
    public const SQL_NO_CACHE        = 'SQL_NO_CACHE';
22
    public const SQL_CALC_FOUND_ROWS = 'SQL_CALC_FOUND_ROWS';
23
24
    protected const GROUP_WITH_ROLLUP = 'WITH ROLLUP';
25
26
    protected bool $groupWithRollup = false;
27
28
    /** @var Select[] */
29
    protected array $union = [];
30
31
    protected ?Lock $lock = null;
32
33
    protected ?int $outerOffset = null;
34
35
    protected ?int $outerLimit = null;
36
37
    /** @var array<string,string> */
38
    protected array $outerOrderByParts = [];
39
40
    protected ?Lock $outerLock = null;
41
42
    /**
43
     * @SuppressWarnings("complexity")
44
     *
45
     * @param string ...$modifiers
46
     *
47
     * @return $this
48
     */
49 2
    public function addModifier(string ...$modifiers): static
50
    {
51 2
        foreach ($modifiers as $modifier) {
52
            switch ($modifier) {
53 2
                case static::ALL:
54 2
                case static::DISTINCT:
55 1
                case static::DISTINCTROW:
56 2
                    $this->modifiers[0] = $modifier;
57 2
                    break;
58 1
                case static::HIGH_PRIORITY:
59 1
                    $this->modifiers[1] = $modifier;
60 1
                    break;
61 1
                case static::STRAIGHT_JOIN:
62 1
                    $this->modifiers[2] = $modifier;
63 1
                    break;
64 1
                case static::SQL_SMALL_RESULT:
65 1
                    $this->modifiers[3] = $modifier;
66 1
                    break;
67 1
                case static::SQL_BIG_RESULT:
68 1
                    $this->modifiers[4] = $modifier;
69 1
                    break;
70 1
                case static::SQL_BUFFER_RESULT:
71 1
                    $this->modifiers[5] = $modifier;
72 1
                    break;
73 1
                case static::SQL_NO_CACHE:
74 1
                    $this->modifiers[6] = $modifier;
75 1
                    break;
76 1
                case static::SQL_CALC_FOUND_ROWS:
77 1
                    $this->modifiers[7] = $modifier;
78 1
                    break;
79
            }
80
        }
81
82 2
        ksort($this->modifiers);
83
84 2
        return $this;
85
    }
86
87
    /**
88
     * @return $this
89
     */
90 1
    public function setGroupWithRollup(): static
91
    {
92 1
        $this->groupWithRollup = true;
93
94 1
        return $this;
95
    }
96
97
    /**
98
     * @param int|null $offset
99
     *
100
     * @return $this
101
     */
102
    public function setOuterOffset(?int $offset): static
103
    {
104
        $this->outerOffset = $offset;
105
106
        return $this;
107
    }
108
109
    /**
110
     * @param int|null $limit
111
     *
112
     * @return $this
113
     */
114 2
    public function setOuterLimit(?int $limit): static
115
    {
116 2
        $this->outerLimit = $limit;
117
118 2
        return $this;
119
    }
120
121
    /**
122
     * @param string $column
123
     * @param string $direction
124
     *
125
     * @return $this
126
     */
127 1
    public function addOuterOrderBy(string $column, string $direction = 'ASC'): static
128
    {
129 1
        $this->outerOrderByParts[$column] = $direction;
130
131 1
        return $this;
132
    }
133
134
    /**
135
     * @param Lock $lock
136
     *
137
     * @return $this
138
     */
139 1
    public function setLock(Lock $lock): static
140
    {
141 1
        $this->lock = $lock;
142
143 1
        return $this;
144
    }
145
146
    /**
147
     * @param Select $select
148
     *
149
     * @return $this
150
     */
151 4
    public function addUnion(Select $select): static
152
    {
153 4
        $this->union[] = $select;
154
155 4
        return $this;
156
    }
157
158
    /**
159
     * @param Lock $lock
160
     *
161
     * @return $this
162
     */
163 2
    public function setOuterLock(Lock $lock): static
164
    {
165 2
        $this->outerLock = $lock;
166
167 2
        return $this;
168
    }
169
170
    /**
171
     * @return string
172
     */
173 18
    public function __toString(): string
174
    {
175 18
        $parts = array_merge(
176 18
            [parent::__toString()],
177 17
            $this->getLock(),
178 17
            $this->getUnion()
179
        );
180
181 17
        $parts = array_filter($parts);
182
183 17
        $sql = implode(PHP_EOL, $parts);
184
185
        if (
186 17
            $this->outerLimit === null && $this->outerOffset === null && count($this->outerOrderByParts) === 0 &&
187 17
            $this->outerLock === null
188
        ) {
189 17
            return $sql;
190
        }
191
192 4
        $parts = array_merge(
193 4
            ['(' . $sql . ')'],
194 4
            $this->getOuterOrderBy(),
195 4
            $this->getOuterLimit(),
196 4
            $this->getOuterLocks()
197
        );
198
199 4
        $parts = array_filter($parts);
200
201 4
        return implode(PHP_EOL, $parts);
202
    }
203
204
    /**
205
     * @return string[]
206
     */
207 14
    protected function getGroupBy(): array
208
    {
209 14
        $groupBy = parent::getGroupBy();
210
211 14
        if ($this->groupWithRollup && count($groupBy) > 0) {
212 1
            $groupBy[0] = sprintf('%s %s', $groupBy[0], static::GROUP_WITH_ROLLUP);
213
        }
214
215 14
        return $groupBy;
216
    }
217
218
    /**
219
     * @return string[]
220
     */
221 14
    protected function getLimit(): array
222
    {
223 14
        $parts = [];
224 14
        if ($this->limit !== null && $this->offset !== null) {
225 1
            $parts[] = 'LIMIT ' . $this->offset . ', ' . $this->limit;
226 14
        } elseif ($this->limit !== null) {
227 1
            $parts[] = 'LIMIT ' . $this->limit;
228
        }
229
230 14
        return $parts;
231
    }
232
233
    /**
234
     * @return string[]
235
     */
236 17
    protected function getLock(): array
237
    {
238 17
        if ($this->lock === null) {
239 17
            return [];
240
        }
241
242 1
        return [(string)$this->lock];
243
    }
244
245
    /**
246
     * @return string[]
247
     */
248 17
    public function getUnion(): array
249
    {
250 17
        $parts = [];
251 17
        foreach ($this->union as $select) {
252 4
            $parts[] = 'UNION' . PHP_EOL . $select;
253
        }
254
255 17
        return $parts;
256
    }
257
258
    /**
259
     * @return string[]
260
     */
261 4
    protected function getOuterOrderBy(): array
262
    {
263 4
        if (count($this->outerOrderByParts) === 0) {
264 3
            return [];
265
        }
266
267 1
        $parts = [];
268 1
        foreach ($this->outerOrderByParts as $column => $direction) {
269 1
            $parts[] = "$column $direction";
270
        }
271
272 1
        return ['ORDER BY ' . implode(', ', $parts)];
273
    }
274
275
    /**
276
     * @return string[]
277
     */
278 4
    protected function getOuterLimit(): array
279
    {
280 4
        $parts = [];
281 4
        if ($this->outerLimit !== null && $this->outerOffset !== null) {
282
            $parts[] = 'LIMIT ' . $this->outerOffset . ', ' . $this->outerLimit;
283 4
        } elseif ($this->outerLimit !== null) {
284 2
            $parts[] = 'LIMIT ' . $this->outerLimit;
285
        }
286
287 4
        return $parts;
288
    }
289
290
    /**
291
     * @return string[]
292
     */
293 4
    protected function getOuterLocks(): array
294
    {
295 4
        if ($this->outerLock === null) {
296 2
            return [];
297
        }
298
299 2
        return [(string)$this->outerLock];
300
    }
301
}
302