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

SelectTest::testToStringWithLimitAndLock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 23
rs 9.7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace QB\MySQL\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\MySQL\Clause\Lock;
12
13
class SelectTest extends GenericSelectTest
14
{
15
    public function testToStringModifiers()
16
    {
17
        $modifiers = [
18
            Select::DISTINCT,
19
            Select::HIGH_PRIORITY,
20
            Select::STRAIGHT_JOIN,
21
            Select::SQL_SMALL_RESULT,
22
            Select::SQL_BIG_RESULT,
23
            Select::SQL_BUFFER_RESULT,
24
            Select::SQL_NO_CACHE,
25
            Select::SQL_CALC_FOUND_ROWS,
26
        ];
27
28
        $sql = (string)$this->getSut('foo')
29
            ->addModifier(...$modifiers)
30
            ->addColumns('id', 'bar_id');
31
32
        $parts   = [];
33
        $parts[] = sprintf('SELECT %s id, bar_id', implode(' ', $modifiers));
34
        $parts[] = 'FROM foo';
35
36
        $expectedSql = implode(PHP_EOL, $parts);
37
38
        $this->assertSame($expectedSql, $sql);
39
    }
40
41
    public function testToStringWithOuterLimits()
42
    {
43
        $unionQuery = $this->getSut('baz')
44
            ->addColumns('id');
45
46
        $sql = (string)$this->getSut('foo')
47
            ->addColumns('id')
48
            ->addUnion($unionQuery)
49
            ->setOuterLimit(10);
50
51
        $parts   = [];
52
        $parts[] = '(SELECT id';
53
        $parts[] = 'FROM foo';
54
        $parts[] = 'UNION';
55
        $parts[] = 'SELECT id';
56
        $parts[] = 'FROM baz)';
57
        $parts[] = 'LIMIT 10';
58
59
        $expectedSql = implode(PHP_EOL, $parts);
60
61
        $this->assertSame($expectedSql, $sql);
62
    }
63
64
    public function testToStringWithOuterLock()
65
    {
66
        $unionQuery = $this->getSut('baz')
67
            ->addColumns('id');
68
69
        $sql = (string)$this->getSut('foo')
70
            ->addColumns('id')
71
            ->addUnion($unionQuery)
72
            ->setOuterLock(new Lock(Lock::FOR_UPDATE, [], Lock::MODIFIER_NOWAIT));
73
74
        $parts   = [];
75
        $parts[] = '(SELECT id';
76
        $parts[] = 'FROM foo';
77
        $parts[] = 'UNION';
78
        $parts[] = 'SELECT id';
79
        $parts[] = 'FROM baz)';
80
        $parts[] = 'FOR UPDATE NOWAIT';
81
82
        $expectedSql = implode(PHP_EOL, $parts);
83
84
        $this->assertSame($expectedSql, $sql);
85
    }
86
87
    public function testToStringWithLimitAndLock()
88
    {
89
        $unionQuery = $this->getSut('baz')
90
            ->addColumns('id');
91
92
        $sql = (string)$this->getSut('foo')
93
            ->addColumns('id')
94
            ->setLimit(10)
95
            ->addUnion($unionQuery)
96
            ->setOuterLock(new Lock(Lock::FOR_UPDATE, [], Lock::MODIFIER_SKIP_LOCKED));
97
98
        $parts   = [];
99
        $parts[] = '(SELECT id';
100
        $parts[] = 'FROM foo';
101
        $parts[] = 'LIMIT 10';
102
        $parts[] = 'UNION';
103
        $parts[] = 'SELECT id';
104
        $parts[] = 'FROM baz)';
105
        $parts[] = 'FOR UPDATE SKIP LOCKED';
106
107
        $expectedSql = implode(PHP_EOL, $parts);
108
109
        $this->assertSame($expectedSql, $sql);
110
    }
111
112
    public function testToStringComplex()
113
    {
114
        $columnQuery = $this->getSut('quix')
115
            ->addColumns('b')
116
            ->addWhere(new Expr('id = ?', [7]));
117
118
        $columnExpr = new Expr('NOW()');
119
120
        $unionQuery = $this->getSut('baz')
121
            ->addColumns('b', 'f');
122
123
        $sql = (string)$this->getSut('foo', 'bar')
124
            ->addModifier('DISTINCT')
125
            ->addColumns('COUNT(DISTINCT baz) AS baz_count', new Column($columnQuery, 'quix_b'))
126
            ->addColumns(new Column($columnExpr, 'now'))
127
            ->addColumn('bar.id', 'bar_id')
128
            ->addInnerJoin('quix', 'foo.id = q.foo_id', 'q')
129
            ->addWhere('foo.bar = "foo-bar"', new Expr('bar.foo = ?', ['bar-foo']))
130
            ->addGroupBy('q.foo_id', new Expr('q.bar.id'))
131
            ->setGroupWithRollup()
132
            ->addHaving('baz_count > 0')
133
            ->addOrderBy('baz_count', 'ASC')
134
            ->setLimit(10)
135
            ->setOffset(20)
136
            ->setLock(new Lock(Lock::FOR_UPDATE, [], Lock::MODIFIER_NOWAIT))
137
            ->addUnion($unionQuery)
138
            ->setOuterLimit(25)
139
            ->addOuterOrderBy('baz_count', 'DESC');
140
141
        $parts   = [];
142
        $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
143
        $parts[] = 'FROM foo, bar';
144
        $parts[] = 'INNER JOIN quix AS q ON foo.id = q.foo_id';
145
        $parts[] = 'WHERE foo.bar = "foo-bar" AND bar.foo = ?';
146
        $parts[] = 'GROUP BY q.foo_id, q.bar.id WITH ROLLUP';
147
        $parts[] = 'HAVING baz_count > 0';
148
        $parts[] = 'ORDER BY baz_count ASC';
149
        $parts[] = 'LIMIT 20, 10';
150
        $parts[] = 'FOR UPDATE NOWAIT';
151
        $parts[] = 'UNION';
152
        $parts[] = 'SELECT b, f';
153
        $parts[] = 'FROM baz)';
154
        $parts[] = 'ORDER BY baz_count DESC';
155
        $parts[] = 'LIMIT 25';
156
157
        $expectedSql = implode(PHP_EOL, $parts);
158
159
        $this->assertSame($expectedSql, $sql);
160
    }
161
162
    /**
163
     * @param string|Table ...$tables
164
     *
165
     * @return Select
166
     */
167
    protected function getSut(string|Table ...$tables): Select
168
    {
169
        return (new Select())->addFrom(...$tables);
170
    }
171
}
172