Passed
Push — main ( ddbd64...0c2f80 )
by Peter
02:39
created

Select   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 187
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 54
c 3
b 0
f 0
dl 0
loc 187
rs 10
ccs 59
cts 59
cp 1
wmc 21

12 Methods

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