Passed
Push — main ( 5e0bcd...9ce40a )
by Peter
02:12
created

SelectTest::testSelectComplexWithIntersect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 45
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

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