Passed
Push — main ( 436d8c...f01a67 )
by Peter
02:36
created

SelectTest::testToStringWithOuterLimits()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 15
nc 1
nop 0
dl 0
loc 21
rs 9.7666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace QB\PostgreSQL\Statement;
6
7
use QB\Generic\Clause\Column;
8
use QB\Generic\Clause\Table;
9
use QB\Generic\Expr\Expr;
10
use QB\Generic\Statement\SelectTest as GenericSelectTest;
11
use QB\PostgreSQL\Clause\Lock;
12
13
class SelectTest extends GenericSelectTest
14
{
15
    public function testToStringModifiers()
16
    {
17
        $sql = $this->getSut('foo')
18
            ->addModifier(Select::ALL, Select::DISTINCT)
19
            ->addColumns('id', 'bar_id')
20
            ->__toString();
21
22
        $parts   = [];
23
        $parts[] = 'SELECT ALL DISTINCT id, bar_id';
24
        $parts[] = 'FROM foo';
25
26
        $expectedSql = implode(PHP_EOL, $parts);
27
28
        $this->assertSame($expectedSql, $sql);
29
    }
30
31
    public function testToStringComplex()
32
    {
33
        $unionQuery = $this->getSut('baz')
34
            ->addColumns('id');
35
36
        $sql = (string)$this->getSut('foo')
37
            ->addColumns('id')
38
            ->addUnion($unionQuery)
39
            ->setOuterOffset(20)
40
            ->setOuterLimit(10)
41
            ->setOuterOrderBy('id', 'DESC');
42
43
        $parts   = [];
44
        $parts[] = '(SELECT id';
45
        $parts[] = 'FROM foo';
46
        $parts[] = 'UNION';
47
        $parts[] = 'SELECT id';
48
        $parts[] = 'FROM baz)';
49
        $parts[] = 'ORDER BY id DESC';
50
        $parts[] = 'LIMIT 10';
51
        $parts[] = 'OFFSET 20 ROWS';
52
53
        $expectedSql = implode(PHP_EOL, $parts);
54
55
        $this->assertSame($expectedSql, $sql);
56
    }
57
58
    public function testToStringComplexWithUnion()
59
    {
60
        $columnQuery = $this->getSut('quix')
61
            ->addColumns('b')
62
            ->addWhere(new Expr('id = ?', [7]));
63
64
        $columnExpr = new Expr('NOW()');
65
66
        $unionQuery = $this->getSut('baz')
67
            ->addColumns('b', 'f');
68
69
        $sql = (string)$this->getSut('foo', 'bar')
70
            ->addModifier('DISTINCT')
71
            ->addColumns('COUNT(DISTINCT baz) AS baz_count', new Column($columnQuery, 'quix_b'))
72
            ->addColumns(new Column($columnExpr, 'now'))
73
            ->addColumn('bar.id', 'bar_id')
74
            ->addInnerJoin('quix', 'foo.id = q.foo_id', 'q')
75
            ->addWhere('foo.bar = "foo-bar"', new Expr('bar.foo = ?', ['bar-foo']))
76
            ->addGroupBy('q.foo_id', new Expr('q.bar.id'))
77
            ->addHaving('baz_count > 0')
78
            ->addOrderBy('baz_count', 'ASC')
79
            ->setLock(new Lock(Lock::FOR_UPDATE, [], Lock::MODIFIER_NOWAIT))
80
            ->setLimit(10)
81
            ->setOffset(20)
82
            ->addUnion($unionQuery);
83
84
        $parts   = [];
85
        $parts[] = 'SELECT DISTINCT COUNT(DISTINCT baz) AS baz_count, (SELECT b FROM quix WHERE id = ?) AS quix_b, NOW() AS now, bar.id AS bar_id'; // nolint
86
        $parts[] = 'FROM foo, bar';
87
        $parts[] = 'INNER JOIN quix AS q ON foo.id = q.foo_id';
88
        $parts[] = 'WHERE foo.bar = "foo-bar" AND bar.foo = ?';
89
        $parts[] = 'GROUP BY q.foo_id, q.bar.id';
90
        $parts[] = 'HAVING baz_count > 0';
91
        $parts[] = 'ORDER BY baz_count ASC';
92
        $parts[] = 'OFFSET 20 ROWS';
93
        $parts[] = 'FETCH FIRST 10 ROWS ONLY';
94
        $parts[] = 'FOR UPDATE NOWAIT';
95
        $parts[] = 'UNION';
96
        $parts[] = 'SELECT b, f';
97
        $parts[] = 'FROM baz';
98
99
        $expectedSql = implode(PHP_EOL, $parts);
100
101
        $this->assertSame($expectedSql, $sql);
102
    }
103
104
    public function testToStringComplexWithIntersect()
105
    {
106
        $columnQuery = $this->getSut('quix')
107
            ->addColumns('b')
108
            ->addWhere(new Expr('id = ?', [7]));
109
110
        $columnExpr = new Expr('NOW()');
111
112
        $intersectQuery = $this->getSut('baz')
113
            ->addColumns('b', 'f');
114
115
        $sql = (string)$this->getSut('foo', 'bar')
116
            ->addModifier('DISTINCT')
117
            ->addColumns('COUNT(DISTINCT baz) AS baz_count', new Column($columnQuery, 'quix_b'))
118
            ->addColumns(new Column($columnExpr, 'now'))
119
            ->addColumn('bar.id', 'bar_id')
120
            ->addInnerJoin('quix', 'foo.id = q.foo_id', 'q')
121
            ->addWhere('foo.bar = "foo-bar"', new Expr('bar.foo = ?', ['bar-foo']))
122
            ->addGroupBy('q.foo_id', new Expr('q.bar.id'))
123
            ->addHaving('baz_count > 0')
124
            ->addOrderBy('baz_count', 'ASC')
125
            ->setLock(new Lock(Lock::FOR_UPDATE, ['foo'], Lock::MODIFIER_NOWAIT))
126
            ->setLimit(10)
127
            ->setOffset(20)
128
            ->addIntersect($intersectQuery);
129
130
        $parts   = [];
131
        $parts[] = 'SELECT DISTINCT COUNT(DISTINCT baz) AS baz_count, (SELECT b FROM quix WHERE id = ?) AS quix_b, NOW() AS now, bar.id AS bar_id'; // nolint
132
        $parts[] = 'FROM foo, bar';
133
        $parts[] = 'INNER JOIN quix AS q ON foo.id = q.foo_id';
134
        $parts[] = 'WHERE foo.bar = "foo-bar" AND bar.foo = ?';
135
        $parts[] = 'GROUP BY q.foo_id, q.bar.id';
136
        $parts[] = 'HAVING baz_count > 0';
137
        $parts[] = 'ORDER BY baz_count ASC';
138
        $parts[] = 'OFFSET 20 ROWS';
139
        $parts[] = 'FETCH FIRST 10 ROWS ONLY';
140
        $parts[] = 'FOR UPDATE OF foo NOWAIT';
141
        $parts[] = 'INTERSECT';
142
        $parts[] = 'SELECT b, f';
143
        $parts[] = 'FROM baz';
144
145
        $expectedSql = implode(PHP_EOL, $parts);
146
147
        $this->assertSame($expectedSql, $sql);
148
    }
149
150
    public function testToStringComplexWithUnionAndExcept()
151
    {
152
        $columnQuery = $this->getSut('quix')
153
            ->addColumns('b')
154
            ->addWhere(new Expr('id = ?', [7]));
155
156
        $columnExpr = new Expr('NOW()');
157
158
        $unionQuery = $this->getSut('baz')
159
            ->addColumns('b', 'f');
160
161
        $exceptQuery = $this->getSut('sec')
162
            ->addColumns('v', 'w');
163
164
        $sql = (string)$this->getSut('foo', 'bar')
165
            ->addModifier('DISTINCT')
166
            ->addColumns('COUNT(DISTINCT baz) AS baz_count', new Column($columnQuery, 'quix_b'))
167
            ->addColumns(new Column($columnExpr, 'now'))
168
            ->addColumn('bar.id', 'bar_id')
169
            ->addInnerJoin('quix', 'foo.id = q.foo_id', 'q')
170
            ->addWhere('foo.bar = "foo-bar"', new Expr('bar.foo = ?', ['bar-foo']))
171
            ->addGroupBy('q.foo_id', new Expr('q.bar.id'))
172
            ->addHaving('baz_count > 0')
173
            ->addOrderBy('baz_count', 'ASC')
174
            ->setLock(new Lock(Lock::FOR_KEY_SHARE))
175
            ->setLimit(10)
176
            ->setOffset(20)
177
            ->addUnion($unionQuery)
178
            ->addExcept($exceptQuery);
179
180
        $parts   = [];
181
        $parts[] = 'SELECT DISTINCT COUNT(DISTINCT baz) AS baz_count, (SELECT b FROM quix WHERE id = ?) AS quix_b, NOW() AS now, bar.id AS bar_id'; // nolint
182
        $parts[] = 'FROM foo, bar';
183
        $parts[] = 'INNER JOIN quix AS q ON foo.id = q.foo_id';
184
        $parts[] = 'WHERE foo.bar = "foo-bar" AND bar.foo = ?';
185
        $parts[] = 'GROUP BY q.foo_id, q.bar.id';
186
        $parts[] = 'HAVING baz_count > 0';
187
        $parts[] = 'ORDER BY baz_count ASC';
188
        $parts[] = 'OFFSET 20 ROWS';
189
        $parts[] = 'FETCH FIRST 10 ROWS ONLY';
190
        $parts[] = 'FOR KEY SHARE';
191
        $parts[] = 'UNION';
192
        $parts[] = 'SELECT b, f';
193
        $parts[] = 'FROM baz';
194
        $parts[] = 'EXCEPT';
195
        $parts[] = 'SELECT v, w';
196
        $parts[] = 'FROM sec';
197
198
        $expectedSql = implode(PHP_EOL, $parts);
199
200
        $this->assertSame($expectedSql, $sql);
201
    }
202
203
    /**
204
     * @param string|Table ...$tables
205
     *
206
     * @return Select
207
     */
208
    protected function getSut(string|Table ...$tables): Select
209
    {
210
        return (new Select())->addFrom(...$tables);
211
    }
212
}
213