Passed
Push — main ( bbfba8...2e1d9e )
by Peter
02:52
created

Select::getCombiningQueries()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 8
rs 10
ccs 5
cts 5
cp 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace QB\PostgreSQL\Statement;
6
7
use QB\Generic\IQueryPart;
8
use QB\Generic\Statement\Select as GenericSelect;
9
use QB\PostgreSQL\Clause\CombiningQuery;
10
use QB\PostgreSQL\Clause\Lock;
11
12
class Select extends GenericSelect
13
{
14
    protected const UNION     = 'union';
15
    protected const INTERSECT = 'intersect';
16
    protected const EXCEPT    = 'except';
17
18
    /** @var CombiningQuery[] */
19
    protected array $combiningQueries = [];
20
21
    protected ?Lock $lock = null;
22
23
    protected ?string $lockTable = null;
24
25
    protected ?int $outerOffset = null;
26
27
    protected ?int $outerLimit = null;
28
29
    /** @var array<string,string> */
30
    protected array $outerOrderByParts = [];
31
32
    /**
33
     * @param int|null $offset
34
     *
35
     * @return $this
36
     */
37
    public function setOuterOffset(?int $offset): static
38
    {
39
        $this->outerOffset = $offset;
40
41
        return $this;
42
    }
43
44
    /**
45
     * @param int|null $limit
46
     *
47
     * @return $this
48
     */
49 1
    public function setOuterLimit(?int $limit): static
50
    {
51 1
        $this->outerLimit = $limit;
52
53 1
        return $this;
54
    }
55
56
    /**
57
     * @param string $column
58
     * @param string $direction
59
     *
60
     * @return Select
61
     */
62
    public function addOuterOrderBy(string $column, string $direction = 'ASC'): static
63
    {
64
        $this->outerOrderByParts[$column] = $direction;
65
66
        return $this;
67
    }
68
69
    /**
70
     * @param Lock $lock
71
     *
72
     * @return $this
73
     */
74 3
    public function setLock(Lock $lock): static
75
    {
76 3
        $this->lock = $lock;
77
78 3
        return $this;
79
    }
80
81
    /**
82
     * @param IQueryPart  $select
83
     * @param string|null $modifier
84
     *
85
     * @return $this
86
     */
87 3
    public function addUnion(IQueryPart $select, ?string $modifier = null): static
88
    {
89 3
        $this->combiningQueries[] = new CombiningQuery(CombiningQuery::TYPE_UNION, $select, $modifier);
90
91 3
        return $this;
92
    }
93
94
    /**
95
     * @param IQueryPart  $select
96
     * @param string|null $modifier
97
     *
98
     * @return $this
99
     */
100 1
    public function addIntersect(IQueryPart $select, ?string $modifier = null): static
101
    {
102 1
        $this->combiningQueries[] = new CombiningQuery(CombiningQuery::TYPE_INTERSECT, $select, $modifier);
103
104 1
        return $this;
105
    }
106
107
    /**
108
     * @param IQueryPart  $select
109
     * @param string|null $modifier
110
     *
111
     * @return $this
112
     */
113 1
    public function addExcept(IQueryPart $select, ?string $modifier = null): static
114
    {
115 1
        $this->combiningQueries[] = new CombiningQuery(CombiningQuery::TYPE_EXCEPT, $select, $modifier);
116
117 1
        return $this;
118
    }
119
120 24
    public function __toString(): string
121
    {
122 24
        $parts = array_merge(
123 24
            [parent::__toString()],
124 23
            $this->getLock(),
125 23
            $this->getCombiningQueries()
126
        );
127
128 23
        $parts = array_filter($parts);
129
130 23
        $sql = implode(PHP_EOL, $parts);
131
132 23
        if ($this->outerLimit === null && $this->outerOffset === null && count($this->outerOrderByParts) === 0) {
133 23
            return $sql;
134
        }
135
136 1
        $parts = array_merge(
137 1
            ['(' . $sql . ')'],
138 1
            $this->getOuterOrderBy(),
139 1
            $this->getOuterLimit()
140
        );
141
142 1
        $parts = array_filter($parts);
143
144 1
        return implode(PHP_EOL, $parts);
145
    }
146
147
    /**
148
     * @return string[]
149
     */
150 23
    protected function getLock(): array
151
    {
152 23
        if ($this->lock === null) {
153 23
            return [];
154
        }
155
156 3
        return [(string)$this->lock];
157
    }
158
159
    /**
160
     * @return string[]
161
     */
162 23
    protected function getCombiningQueries(): array
163
    {
164 23
        $parts = [];
165 23
        foreach ($this->combiningQueries as $query) {
166 4
            $parts[] = (string)$query;
167
        }
168
169 23
        return $parts;
170
    }
171
172
    /**
173
     * @return string[]
174
     */
175 1
    protected function getOuterOrderBy(): array
176
    {
177 1
        if (count($this->outerOrderByParts) === 0) {
178 1
            return [];
179
        }
180
181
        $parts = [];
182
        foreach ($this->outerOrderByParts as $column => $direction) {
183
            $parts[] = "$column $direction";
184
        }
185
186
        return ['ORDER BY ' . implode(', ', $parts)];
187
    }
188
189
    /**
190
     * @return string[]
191
     */
192 1
    protected function getOuterLimit(): array
193
    {
194 1
        $parts = [];
195 1
        if ($this->outerLimit !== null && $this->outerOffset !== null) {
196
            $parts[] = 'LIMIT ' . $this->outerOffset . ', ' . $this->outerLimit;
197 1
        } elseif ($this->outerLimit !== null) {
198 1
            $parts[] = 'LIMIT ' . $this->outerLimit;
199
        }
200
201 1
        return $parts;
202
    }
203
}
204