Completed
Pull Request — 2.10 (#3832)
by Benjamin
64:37
created

QueryBuilderTest   F

Complexity

Total Complexity 69

Size/Duplication

Total Lines 908
Duplicated Lines 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
wmc 69
eloc 453
c 3
b 1
f 0
dl 0
loc 908
rs 2.88

69 Methods

Rating   Name   Duplication   Size   Complexity  
A testSimpleSelect() 0 8 1
A testSimpleSelectWithoutFrom() 0 7 1
A setUp() 0 9 1
A testSelectWithLeftJoin() 0 10 1
A testSelectWithJoin() 0 10 1
A testSimpleSelectWithDistinct() 0 9 1
A testSelectWithSimpleWhere() 0 10 1
A testEmptySelect() 0 7 1
A testCreateNamedParameter() 0 11 1
A testSelectMultipleFrom() 0 11 1
A testSimpleSelectWithoutTableAlias() 0 8 1
A testInsertValues() 0 13 1
A testSelectOrHavingOrHaving() 0 12 1
A testEmptyDelete() 0 7 1
A testResetQueryParts() 0 9 1
A testSelectWithAndWhereConditions() 0 11 1
A testEmptyInsert() 0 7 1
A testSelectAddGroupBys() 0 11 1
A testSelectFromMasterWithWhereOnJoinedTables() 0 13 1
A testSelectAddAddOrderBy() 0 11 1
A testSelectEmptyGroupBy() 0 10 1
A testGetState() 0 14 1
A testUpdateWithoutAlias() 0 8 1
A testSelectGroupBy() 0 10 1
A testInsertValuesSetValue() 0 11 1
A testClone() 0 18 1
A testSelectEmptyAddGroupBy() 0 10 1
A testSelectWithOrOrWhereConditions() 0 11 1
A testSelectWithJoinNoCondition() 0 9 1
A testSetFirstResult() 0 7 1
A testCreateNamedParameterCustomPlaceholder() 0 11 1
A testSelectWithInnerJoin() 0 10 1
A testSelectWithMultipleFromsAndJoinsWithMultipleOnConditionsParseOrder() 0 23 1
A testJoinWithNonUniqueAliasThrowsException() 0 12 1
A testResetQueryPart() 0 9 1
A testComplexSelectWithSomeTableAliases() 0 11 1
A testSetMaxResults() 0 7 1
A testSelectWithSimpleWhereWithoutTableAlias() 0 9 1
A testComplexSelectWithoutTableAliases() 0 13 1
A testSelectAddOrderBy() 0 11 1
A testInsertSetValue() 0 10 1
A testUpdateWhere() 0 8 1
A testUpdate() 0 9 1
A testSelectAllWithoutTableAlias() 0 8 1
A testSelectWithAndOrWhereConditions() 0 13 1
A testDeleteWhere() 0 7 1
A testEmptyAddSelect() 0 7 1
A testDelete() 0 7 1
A testSelectAllFromTableWithoutTableAlias() 0 8 1
A testSelectAddGroupBy() 0 11 1
A testSelectWithOrWhereConditions() 0 11 1
A testSelectHavingAndHaving() 0 12 1
A testGetParameterTypes() 0 22 1
A testInsertReplaceValues() 0 19 1
A testSelectAddSelect() 0 10 1
A testEmptyUpdate() 0 7 1
A testGetParameterType() 0 16 1
A testSelectWithRightJoin() 0 10 1
A testSelectHavingAndOrHaving() 0 13 1
A testSelectWithJoinsWithMultipleOnConditionsParseOrder() 0 19 1
A testReferenceJoinFromJoin() 0 14 1
A testSelectOrderBy() 0 10 1
A testSelectHavingOrHaving() 0 12 1
A testDeleteWithoutAlias() 0 7 1
A testGetConnection() 0 4 1
A testSelectHaving() 0 11 1
A testSelectWithMultipleFromAndJoins() 0 13 1
A testCreatePositionalParameter() 0 11 1
A testSelectAndHaving() 0 11 1

How to fix   Complexity   

Complex Class

Complex classes like QueryBuilderTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use QueryBuilderTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Doctrine\Tests\DBAL\Query;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\ParameterType;
7
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
8
use Doctrine\DBAL\Query\QueryBuilder;
9
use Doctrine\DBAL\Query\QueryException;
10
use Doctrine\Tests\DbalTestCase;
11
12
/**
13
 * @group DBAL-12
14
 */
15
class QueryBuilderTest extends DbalTestCase
16
{
17
    /** @var Connection */
18
    protected $conn;
19
20
    protected function setUp() : void
21
    {
22
        $this->conn = $this->createMock(Connection::class);
23
24
        $expressionBuilder = new ExpressionBuilder($this->conn);
25
26
        $this->conn->expects($this->any())
27
                   ->method('getExpressionBuilder')
28
                   ->will($this->returnValue($expressionBuilder));
29
    }
30
31
    /**
32
     * @group DBAL-2291
33
     */
34
    public function testSimpleSelectWithoutFrom() : void
35
    {
36
        $qb = new QueryBuilder($this->conn);
37
38
        $qb->select('some_function()');
39
40
        self::assertEquals('SELECT some_function()', (string) $qb);
41
    }
42
43
    public function testSimpleSelect() : void
44
    {
45
        $qb = new QueryBuilder($this->conn);
46
47
        $qb->select('u.id')
48
           ->from('users', 'u');
49
50
        self::assertEquals('SELECT u.id FROM users u', (string) $qb);
51
    }
52
53
    public function testSimpleSelectWithDistinct() : void
54
    {
55
        $qb = new QueryBuilder($this->conn);
56
57
        $qb->select('u.id')
58
           ->distinct()
59
           ->from('users', 'u');
60
61
        self::assertEquals('SELECT DISTINCT u.id FROM users u', (string) $qb);
62
    }
63
64
    public function testSelectWithSimpleWhere() : void
65
    {
66
        $qb   = new QueryBuilder($this->conn);
67
        $expr = $qb->expr();
68
69
        $qb->select('u.id')
70
           ->from('users', 'u')
71
           ->where($expr->andX($expr->eq('u.nickname', '?')));
72
73
        self::assertEquals('SELECT u.id FROM users u WHERE u.nickname = ?', (string) $qb);
74
    }
75
76
    public function testSelectWithLeftJoin() : void
77
    {
78
        $qb   = new QueryBuilder($this->conn);
79
        $expr = $qb->expr();
80
81
        $qb->select('u.*', 'p.*')
82
           ->from('users', 'u')
83
           ->leftJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
84
85
        self::assertEquals('SELECT u.*, p.* FROM users u LEFT JOIN phones p ON p.user_id = u.id', (string) $qb);
86
    }
87
88
    public function testSelectWithJoin() : void
89
    {
90
        $qb   = new QueryBuilder($this->conn);
91
        $expr = $qb->expr();
92
93
        $qb->select('u.*', 'p.*')
94
           ->from('users', 'u')
95
           ->join('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
96
97
        self::assertEquals('SELECT u.*, p.* FROM users u INNER JOIN phones p ON p.user_id = u.id', (string) $qb);
98
    }
99
100
    public function testSelectWithJoinNoCondition() : void
101
    {
102
        $qb = new QueryBuilder($this->conn);
103
104
        $qb->select('u.*', 'p.*')
105
            ->from('users', 'u')
106
            ->join('u', 'phones', 'p');
107
108
        self::assertEquals('SELECT u.*, p.* FROM users u INNER JOIN phones p', (string) $qb);
109
    }
110
111
    public function testSelectWithInnerJoin() : void
112
    {
113
        $qb   = new QueryBuilder($this->conn);
114
        $expr = $qb->expr();
115
116
        $qb->select('u.*', 'p.*')
117
           ->from('users', 'u')
118
           ->innerJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
119
120
        self::assertEquals('SELECT u.*, p.* FROM users u INNER JOIN phones p ON p.user_id = u.id', (string) $qb);
121
    }
122
123
    public function testSelectWithRightJoin() : void
124
    {
125
        $qb   = new QueryBuilder($this->conn);
126
        $expr = $qb->expr();
127
128
        $qb->select('u.*', 'p.*')
129
           ->from('users', 'u')
130
           ->rightJoin('u', 'phones', 'p', $expr->eq('p.user_id', 'u.id'));
131
132
        self::assertEquals('SELECT u.*, p.* FROM users u RIGHT JOIN phones p ON p.user_id = u.id', (string) $qb);
133
    }
134
135
    public function testSelectWithAndWhereConditions() : void
136
    {
137
        $qb   = new QueryBuilder($this->conn);
138
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
139
140
        $qb->select('u.*', 'p.*')
141
           ->from('users', 'u')
142
           ->where('u.username = ?')
143
           ->andWhere('u.name = ?');
144
145
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) AND (u.name = ?)', (string) $qb);
146
    }
147
148
    public function testSelectWithOrWhereConditions() : void
149
    {
150
        $qb   = new QueryBuilder($this->conn);
151
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
152
153
        $qb->select('u.*', 'p.*')
154
           ->from('users', 'u')
155
           ->where('u.username = ?')
156
           ->orWhere('u.name = ?');
157
158
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) OR (u.name = ?)', (string) $qb);
159
    }
160
161
    public function testSelectWithOrOrWhereConditions() : void
162
    {
163
        $qb   = new QueryBuilder($this->conn);
164
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
165
166
        $qb->select('u.*', 'p.*')
167
           ->from('users', 'u')
168
           ->orWhere('u.username = ?')
169
           ->orWhere('u.name = ?');
170
171
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (u.username = ?) OR (u.name = ?)', (string) $qb);
172
    }
173
174
    public function testSelectWithAndOrWhereConditions() : void
175
    {
176
        $qb   = new QueryBuilder($this->conn);
177
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
178
179
        $qb->select('u.*', 'p.*')
180
           ->from('users', 'u')
181
           ->where('u.username = ?')
182
           ->andWhere('u.username = ?')
183
           ->orWhere('u.name = ?')
184
           ->andWhere('u.name = ?');
185
186
        self::assertEquals('SELECT u.*, p.* FROM users u WHERE (((u.username = ?) AND (u.username = ?)) OR (u.name = ?)) AND (u.name = ?)', (string) $qb);
187
    }
188
189
    public function testSelectGroupBy() : void
190
    {
191
        $qb   = new QueryBuilder($this->conn);
192
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
193
194
        $qb->select('u.*', 'p.*')
195
           ->from('users', 'u')
196
           ->groupBy('u.id');
197
198
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id', (string) $qb);
199
    }
200
201
    public function testSelectEmptyGroupBy() : void
202
    {
203
        $qb   = new QueryBuilder($this->conn);
204
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
205
206
        $qb->select('u.*', 'p.*')
207
           ->groupBy([])
208
           ->from('users', 'u');
209
210
        self::assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
211
    }
212
213
    public function testSelectEmptyAddGroupBy() : void
214
    {
215
        $qb   = new QueryBuilder($this->conn);
216
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
217
218
        $qb->select('u.*', 'p.*')
219
           ->addGroupBy([])
220
           ->from('users', 'u');
221
222
        self::assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
223
    }
224
225
    public function testSelectAddGroupBy() : void
226
    {
227
        $qb   = new QueryBuilder($this->conn);
228
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
229
230
        $qb->select('u.*', 'p.*')
231
           ->from('users', 'u')
232
           ->groupBy('u.id')
233
           ->addGroupBy('u.foo');
234
235
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id, u.foo', (string) $qb);
236
    }
237
238
    public function testSelectAddGroupBys() : void
239
    {
240
        $qb   = new QueryBuilder($this->conn);
241
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
242
243
        $qb->select('u.*', 'p.*')
244
           ->from('users', 'u')
245
           ->groupBy('u.id')
246
           ->addGroupBy('u.foo', 'u.bar');
247
248
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id, u.foo, u.bar', (string) $qb);
249
    }
250
251
    public function testSelectHaving() : void
252
    {
253
        $qb   = new QueryBuilder($this->conn);
254
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
255
256
        $qb->select('u.*', 'p.*')
257
           ->from('users', 'u')
258
           ->groupBy('u.id')
259
           ->having('u.name = ?');
260
261
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING u.name = ?', (string) $qb);
262
    }
263
264
    public function testSelectAndHaving() : void
265
    {
266
        $qb   = new QueryBuilder($this->conn);
267
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
268
269
        $qb->select('u.*', 'p.*')
270
           ->from('users', 'u')
271
           ->groupBy('u.id')
272
           ->andHaving('u.name = ?');
273
274
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING u.name = ?', (string) $qb);
275
    }
276
277
    public function testSelectHavingAndHaving() : void
278
    {
279
        $qb   = new QueryBuilder($this->conn);
280
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
281
282
        $qb->select('u.*', 'p.*')
283
           ->from('users', 'u')
284
           ->groupBy('u.id')
285
           ->having('u.name = ?')
286
           ->andHaving('u.username = ?');
287
288
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) AND (u.username = ?)', (string) $qb);
289
    }
290
291
    public function testSelectHavingOrHaving() : void
292
    {
293
        $qb   = new QueryBuilder($this->conn);
294
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
295
296
        $qb->select('u.*', 'p.*')
297
           ->from('users', 'u')
298
           ->groupBy('u.id')
299
           ->having('u.name = ?')
300
           ->orHaving('u.username = ?');
301
302
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
303
    }
304
305
    public function testSelectOrHavingOrHaving() : void
306
    {
307
        $qb   = new QueryBuilder($this->conn);
308
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
309
310
        $qb->select('u.*', 'p.*')
311
           ->from('users', 'u')
312
           ->groupBy('u.id')
313
           ->orHaving('u.name = ?')
314
           ->orHaving('u.username = ?');
315
316
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING (u.name = ?) OR (u.username = ?)', (string) $qb);
317
    }
318
319
    public function testSelectHavingAndOrHaving() : void
320
    {
321
        $qb   = new QueryBuilder($this->conn);
322
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
323
324
        $qb->select('u.*', 'p.*')
325
           ->from('users', 'u')
326
           ->groupBy('u.id')
327
           ->having('u.name = ?')
328
           ->orHaving('u.username = ?')
329
           ->andHaving('u.username = ?');
330
331
        self::assertEquals('SELECT u.*, p.* FROM users u GROUP BY u.id HAVING ((u.name = ?) OR (u.username = ?)) AND (u.username = ?)', (string) $qb);
332
    }
333
334
    public function testSelectOrderBy() : void
335
    {
336
        $qb   = new QueryBuilder($this->conn);
337
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
338
339
        $qb->select('u.*', 'p.*')
340
           ->from('users', 'u')
341
           ->orderBy('u.name');
342
343
        self::assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC', (string) $qb);
344
    }
345
346
    public function testSelectAddOrderBy() : void
347
    {
348
        $qb   = new QueryBuilder($this->conn);
349
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
350
351
        $qb->select('u.*', 'p.*')
352
           ->from('users', 'u')
353
           ->orderBy('u.name')
354
           ->addOrderBy('u.username', 'DESC');
355
356
        self::assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC, u.username DESC', (string) $qb);
357
    }
358
359
    public function testSelectAddAddOrderBy() : void
360
    {
361
        $qb   = new QueryBuilder($this->conn);
362
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
363
364
        $qb->select('u.*', 'p.*')
365
           ->from('users', 'u')
366
           ->addOrderBy('u.name')
367
           ->addOrderBy('u.username', 'DESC');
368
369
        self::assertEquals('SELECT u.*, p.* FROM users u ORDER BY u.name ASC, u.username DESC', (string) $qb);
370
    }
371
372
    public function testEmptySelect() : void
373
    {
374
        $qb  = new QueryBuilder($this->conn);
375
        $qb2 = $qb->select();
376
377
        self::assertSame($qb, $qb2);
378
        self::assertEquals(QueryBuilder::SELECT, $qb->getType());
379
    }
380
381
    public function testSelectAddSelect() : void
382
    {
383
        $qb   = new QueryBuilder($this->conn);
384
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
385
386
        $qb->select('u.*')
387
           ->addSelect('p.*')
388
           ->from('users', 'u');
389
390
        self::assertEquals('SELECT u.*, p.* FROM users u', (string) $qb);
391
    }
392
393
    public function testEmptyAddSelect() : void
394
    {
395
        $qb  = new QueryBuilder($this->conn);
396
        $qb2 = $qb->addSelect();
397
398
        self::assertSame($qb, $qb2);
399
        self::assertEquals(QueryBuilder::SELECT, $qb->getType());
400
    }
401
402
    public function testSelectMultipleFrom() : void
403
    {
404
        $qb   = new QueryBuilder($this->conn);
405
        $expr = $qb->expr();
0 ignored issues
show
Unused Code introduced by
The assignment to $expr is dead and can be removed.
Loading history...
406
407
        $qb->select('u.*')
408
           ->addSelect('p.*')
409
           ->from('users', 'u')
410
           ->from('phonenumbers', 'p');
411
412
        self::assertEquals('SELECT u.*, p.* FROM users u, phonenumbers p', (string) $qb);
413
    }
414
415
    public function testUpdate() : void
416
    {
417
        $qb = new QueryBuilder($this->conn);
418
        $qb->update('users', 'u')
419
           ->set('u.foo', '?')
420
           ->set('u.bar', '?');
421
422
        self::assertEquals(QueryBuilder::UPDATE, $qb->getType());
423
        self::assertEquals('UPDATE users u SET u.foo = ?, u.bar = ?', (string) $qb);
424
    }
425
426
    public function testUpdateWithoutAlias() : void
427
    {
428
        $qb = new QueryBuilder($this->conn);
429
        $qb->update('users')
430
           ->set('foo', '?')
431
           ->set('bar', '?');
432
433
        self::assertEquals('UPDATE users SET foo = ?, bar = ?', (string) $qb);
434
    }
435
436
    public function testUpdateWhere() : void
437
    {
438
        $qb = new QueryBuilder($this->conn);
439
        $qb->update('users', 'u')
440
           ->set('u.foo', '?')
441
           ->where('u.foo = ?');
442
443
        self::assertEquals('UPDATE users u SET u.foo = ? WHERE u.foo = ?', (string) $qb);
444
    }
445
446
    public function testEmptyUpdate() : void
447
    {
448
        $qb  = new QueryBuilder($this->conn);
449
        $qb2 = $qb->update();
450
451
        self::assertEquals(QueryBuilder::UPDATE, $qb->getType());
452
        self::assertSame($qb2, $qb);
453
    }
454
455
    public function testDelete() : void
456
    {
457
        $qb = new QueryBuilder($this->conn);
458
        $qb->delete('users', 'u');
459
460
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
461
        self::assertEquals('DELETE FROM users u', (string) $qb);
462
    }
463
464
    public function testDeleteWithoutAlias() : void
465
    {
466
        $qb = new QueryBuilder($this->conn);
467
        $qb->delete('users');
468
469
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
470
        self::assertEquals('DELETE FROM users', (string) $qb);
471
    }
472
473
    public function testDeleteWhere() : void
474
    {
475
        $qb = new QueryBuilder($this->conn);
476
        $qb->delete('users', 'u')
477
           ->where('u.foo = ?');
478
479
        self::assertEquals('DELETE FROM users u WHERE u.foo = ?', (string) $qb);
480
    }
481
482
    public function testEmptyDelete() : void
483
    {
484
        $qb  = new QueryBuilder($this->conn);
485
        $qb2 = $qb->delete();
486
487
        self::assertEquals(QueryBuilder::DELETE, $qb->getType());
488
        self::assertSame($qb2, $qb);
489
    }
490
491
    public function testInsertValues() : void
492
    {
493
        $qb = new QueryBuilder($this->conn);
494
        $qb->insert('users')
495
            ->values(
496
                [
497
                    'foo' => '?',
498
                    'bar' => '?',
499
                ]
500
            );
501
502
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
503
        self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
504
    }
505
506
    public function testInsertReplaceValues() : void
507
    {
508
        $qb = new QueryBuilder($this->conn);
509
        $qb->insert('users')
510
            ->values(
511
                [
512
                    'foo' => '?',
513
                    'bar' => '?',
514
                ]
515
            )
516
            ->values(
517
                [
518
                    'bar' => '?',
519
                    'foo' => '?',
520
                ]
521
            );
522
523
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
524
        self::assertEquals('INSERT INTO users (bar, foo) VALUES(?, ?)', (string) $qb);
525
    }
526
527
    public function testInsertSetValue() : void
528
    {
529
        $qb = new QueryBuilder($this->conn);
530
        $qb->insert('users')
531
            ->setValue('foo', 'bar')
532
            ->setValue('bar', '?')
533
            ->setValue('foo', '?');
534
535
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
536
        self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
537
    }
538
539
    public function testInsertValuesSetValue() : void
540
    {
541
        $qb = new QueryBuilder($this->conn);
542
        $qb->insert('users')
543
            ->values(
544
                ['foo' => '?']
545
            )
546
            ->setValue('bar', '?');
547
548
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
549
        self::assertEquals('INSERT INTO users (foo, bar) VALUES(?, ?)', (string) $qb);
550
    }
551
552
    public function testEmptyInsert() : void
553
    {
554
        $qb  = new QueryBuilder($this->conn);
555
        $qb2 = $qb->insert();
556
557
        self::assertEquals(QueryBuilder::INSERT, $qb->getType());
558
        self::assertSame($qb2, $qb);
559
    }
560
561
    public function testGetConnection() : void
562
    {
563
        $qb = new QueryBuilder($this->conn);
564
        self::assertSame($this->conn, $qb->getConnection());
565
    }
566
567
    public function testGetState() : void
568
    {
569
        $qb = new QueryBuilder($this->conn);
570
571
        self::assertEquals(QueryBuilder::STATE_CLEAN, $qb->getState());
572
573
        $qb->select('u.*')->from('users', 'u');
574
575
        self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
576
577
        $sql1 = $qb->getSQL();
578
579
        self::assertEquals(QueryBuilder::STATE_CLEAN, $qb->getState());
580
        self::assertEquals($sql1, $qb->getSQL());
581
    }
582
583
    public function testSetMaxResults() : void
584
    {
585
        $qb = new QueryBuilder($this->conn);
586
        $qb->setMaxResults(10);
587
588
        self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
589
        self::assertEquals(10, $qb->getMaxResults());
590
    }
591
592
    public function testSetFirstResult() : void
593
    {
594
        $qb = new QueryBuilder($this->conn);
595
        $qb->setFirstResult(10);
596
597
        self::assertEquals(QueryBuilder::STATE_DIRTY, $qb->getState());
598
        self::assertEquals(10, $qb->getFirstResult());
599
    }
600
601
    public function testResetQueryPart() : void
602
    {
603
        $qb = new QueryBuilder($this->conn);
604
605
        $qb->select('u.*')->from('users', 'u')->where('u.name = ?');
606
607
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string) $qb);
608
        $qb->resetQueryPart('where');
609
        self::assertEquals('SELECT u.* FROM users u', (string) $qb);
610
    }
611
612
    public function testResetQueryParts() : void
613
    {
614
        $qb = new QueryBuilder($this->conn);
615
616
        $qb->select('u.*')->from('users', 'u')->where('u.name = ?')->orderBy('u.name');
617
618
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ? ORDER BY u.name ASC', (string) $qb);
619
        $qb->resetQueryParts(['where', 'orderBy']);
620
        self::assertEquals('SELECT u.* FROM users u', (string) $qb);
621
    }
622
623
    public function testCreateNamedParameter() : void
624
    {
625
        $qb = new QueryBuilder($this->conn);
626
627
        $qb->select('u.*')->from('users', 'u')->where(
628
            $qb->expr()->eq('u.name', $qb->createNamedParameter(10, ParameterType::INTEGER))
629
        );
630
631
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = :dcValue1', (string) $qb);
632
        self::assertEquals(10, $qb->getParameter('dcValue1'));
633
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType('dcValue1'));
634
    }
635
636
    public function testCreateNamedParameterCustomPlaceholder() : void
637
    {
638
        $qb = new QueryBuilder($this->conn);
639
640
        $qb->select('u.*')->from('users', 'u')->where(
641
            $qb->expr()->eq('u.name', $qb->createNamedParameter(10, ParameterType::INTEGER, ':test'))
642
        );
643
644
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = :test', (string) $qb);
645
        self::assertEquals(10, $qb->getParameter('test'));
646
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType('test'));
647
    }
648
649
    public function testCreatePositionalParameter() : void
650
    {
651
        $qb = new QueryBuilder($this->conn);
652
653
        $qb->select('u.*')->from('users', 'u')->where(
654
            $qb->expr()->eq('u.name', $qb->createPositionalParameter(10, ParameterType::INTEGER))
655
        );
656
657
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string) $qb);
658
        self::assertEquals(10, $qb->getParameter(1));
659
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType(1));
660
    }
661
662
    /**
663
     * @group DBAL-172
664
     */
665
    public function testReferenceJoinFromJoin() : void
666
    {
667
        $qb = new QueryBuilder($this->conn);
668
669
        $qb->select('COUNT(DISTINCT news.id)')
670
            ->from('cb_newspages', 'news')
671
            ->innerJoin('news', 'nodeversion', 'nv', 'nv.refId = news.id AND nv.refEntityname=\'News\'')
672
            ->innerJoin('invalid', 'nodetranslation', 'nt', 'nv.nodetranslation = nt.id')
673
            ->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
674
            ->where('nt.lang = :lang AND n.deleted != 1');
675
676
        $this->expectException(QueryException::class);
677
        $this->expectExceptionMessage("The given alias 'invalid' is not part of any FROM or JOIN clause table. The currently registered aliases are: news, nv.");
678
        self::assertEquals('', $qb->getSQL());
679
    }
680
681
    /**
682
     * @group DBAL-172
683
     */
684
    public function testSelectFromMasterWithWhereOnJoinedTables() : void
685
    {
686
        $qb = new QueryBuilder($this->conn);
687
688
        $qb->select('COUNT(DISTINCT news.id)')
689
            ->from('newspages', 'news')
690
            ->innerJoin('news', 'nodeversion', 'nv', "nv.refId = news.id AND nv.refEntityname='Entity\\News'")
691
            ->innerJoin('nv', 'nodetranslation', 'nt', 'nv.nodetranslation = nt.id')
692
            ->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
693
            ->where('nt.lang = ?')
694
            ->andWhere('n.deleted = 0');
695
696
        self::assertEquals("SELECT COUNT(DISTINCT news.id) FROM newspages news INNER JOIN nodeversion nv ON nv.refId = news.id AND nv.refEntityname='Entity\\News' INNER JOIN nodetranslation nt ON nv.nodetranslation = nt.id INNER JOIN node n ON nt.node = n.id WHERE (nt.lang = ?) AND (n.deleted = 0)", $qb->getSQL());
697
    }
698
699
    /**
700
     * @group DBAL-442
701
     */
702
    public function testSelectWithMultipleFromAndJoins() : void
703
    {
704
        $qb = new QueryBuilder($this->conn);
705
706
        $qb->select('DISTINCT u.id')
707
            ->from('users', 'u')
708
            ->from('articles', 'a')
709
            ->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
710
            ->innerJoin('a', 'comments', 'c', 'c.article_id = a.id')
711
            ->where('u.id = a.user_id')
712
            ->andWhere('p.read = 1');
713
714
        self::assertEquals('SELECT DISTINCT u.id FROM users u INNER JOIN permissions p ON p.user_id = u.id, articles a INNER JOIN comments c ON c.article_id = a.id WHERE (u.id = a.user_id) AND (p.read = 1)', $qb->getSQL());
715
    }
716
717
    /**
718
     * @group DBAL-774
719
     */
720
    public function testSelectWithJoinsWithMultipleOnConditionsParseOrder() : void
721
    {
722
        $qb = new QueryBuilder($this->conn);
723
724
        $qb->select('a.id')
725
            ->from('table_a', 'a')
726
            ->join('a', 'table_b', 'b', 'a.fk_b = b.id')
727
            ->join('b', 'table_c', 'c', 'c.fk_b = b.id AND b.language = ?')
728
            ->join('a', 'table_d', 'd', 'a.fk_d = d.id')
729
            ->join('c', 'table_e', 'e', 'e.fk_c = c.id AND e.fk_d = d.id');
730
731
        self::assertEquals(
732
            'SELECT a.id ' .
733
            'FROM table_a a ' .
734
            'INNER JOIN table_b b ON a.fk_b = b.id ' .
735
            'INNER JOIN table_d d ON a.fk_d = d.id ' .
736
            'INNER JOIN table_c c ON c.fk_b = b.id AND b.language = ? ' .
737
            'INNER JOIN table_e e ON e.fk_c = c.id AND e.fk_d = d.id',
738
            (string) $qb
739
        );
740
    }
741
742
    /**
743
     * @group DBAL-774
744
     */
745
    public function testSelectWithMultipleFromsAndJoinsWithMultipleOnConditionsParseOrder() : void
746
    {
747
        $qb = new QueryBuilder($this->conn);
748
749
        $qb->select('a.id')
750
            ->from('table_a', 'a')
751
            ->from('table_f', 'f')
752
            ->join('a', 'table_b', 'b', 'a.fk_b = b.id')
753
            ->join('b', 'table_c', 'c', 'c.fk_b = b.id AND b.language = ?')
754
            ->join('a', 'table_d', 'd', 'a.fk_d = d.id')
755
            ->join('c', 'table_e', 'e', 'e.fk_c = c.id AND e.fk_d = d.id')
756
            ->join('f', 'table_g', 'g', 'f.fk_g = g.id');
757
758
        self::assertEquals(
759
            'SELECT a.id ' .
760
            'FROM table_a a ' .
761
            'INNER JOIN table_b b ON a.fk_b = b.id ' .
762
            'INNER JOIN table_d d ON a.fk_d = d.id ' .
763
            'INNER JOIN table_c c ON c.fk_b = b.id AND b.language = ? ' .
764
            'INNER JOIN table_e e ON e.fk_c = c.id AND e.fk_d = d.id, ' .
765
            'table_f f ' .
766
            'INNER JOIN table_g g ON f.fk_g = g.id',
767
            (string) $qb
768
        );
769
    }
770
771
    public function testClone() : void
772
    {
773
        $qb = new QueryBuilder($this->conn);
774
775
        $qb->select('u.id')
776
            ->from('users', 'u')
777
            ->where('u.id = :test');
778
779
        $qb->setParameter(':test', (object) 1);
780
781
        $qb_clone = clone $qb;
782
783
        self::assertEquals((string) $qb, (string) $qb_clone);
784
785
        $qb->andWhere('u.id = 1');
786
787
        self::assertNotSame($qb->getQueryParts(), $qb_clone->getQueryParts());
788
        self::assertNotSame($qb->getParameters(), $qb_clone->getParameters());
789
    }
790
791
    public function testSimpleSelectWithoutTableAlias() : void
792
    {
793
        $qb = new QueryBuilder($this->conn);
794
795
        $qb->select('id')
796
            ->from('users');
797
798
        self::assertEquals('SELECT id FROM users', (string) $qb);
799
    }
800
801
    public function testSelectWithSimpleWhereWithoutTableAlias() : void
802
    {
803
        $qb = new QueryBuilder($this->conn);
804
805
        $qb->select('id', 'name')
806
            ->from('users')
807
            ->where('awesome=9001');
808
809
        self::assertEquals('SELECT id, name FROM users WHERE awesome=9001', (string) $qb);
810
    }
811
812
    public function testComplexSelectWithoutTableAliases() : void
813
    {
814
        $qb = new QueryBuilder($this->conn);
815
816
        $qb->select('DISTINCT users.id')
817
            ->from('users')
818
            ->from('articles')
819
            ->innerJoin('users', 'permissions', 'p', 'p.user_id = users.id')
820
            ->innerJoin('articles', 'comments', 'c', 'c.article_id = articles.id')
821
            ->where('users.id = articles.user_id')
822
            ->andWhere('p.read = 1');
823
824
        self::assertEquals('SELECT DISTINCT users.id FROM users INNER JOIN permissions p ON p.user_id = users.id, articles INNER JOIN comments c ON c.article_id = articles.id WHERE (users.id = articles.user_id) AND (p.read = 1)', $qb->getSQL());
825
    }
826
827
    public function testComplexSelectWithSomeTableAliases() : void
828
    {
829
        $qb = new QueryBuilder($this->conn);
830
831
        $qb->select('u.id')
832
            ->from('users', 'u')
833
            ->from('articles')
834
            ->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
835
            ->innerJoin('articles', 'comments', 'c', 'c.article_id = articles.id');
836
837
        self::assertEquals('SELECT u.id FROM users u INNER JOIN permissions p ON p.user_id = u.id, articles INNER JOIN comments c ON c.article_id = articles.id', $qb->getSQL());
838
    }
839
840
    public function testSelectAllFromTableWithoutTableAlias() : void
841
    {
842
        $qb = new QueryBuilder($this->conn);
843
844
        $qb->select('users.*')
845
            ->from('users');
846
847
        self::assertEquals('SELECT users.* FROM users', (string) $qb);
848
    }
849
850
    public function testSelectAllWithoutTableAlias() : void
851
    {
852
        $qb = new QueryBuilder($this->conn);
853
854
        $qb->select('*')
855
            ->from('users');
856
857
        self::assertEquals('SELECT * FROM users', (string) $qb);
858
    }
859
860
    /**
861
     * @group DBAL-959
862
     */
863
    public function testGetParameterType() : void
864
    {
865
        $qb = new QueryBuilder($this->conn);
866
867
        $qb->select('*')->from('users');
868
869
        self::assertNull($qb->getParameterType('name'));
870
871
        $qb->where('name = :name');
872
        $qb->setParameter('name', 'foo');
873
874
        self::assertNull($qb->getParameterType('name'));
875
876
        $qb->setParameter('name', 'foo', ParameterType::STRING);
877
878
        self::assertSame(ParameterType::STRING, $qb->getParameterType('name'));
879
    }
880
881
    /**
882
     * @group DBAL-959
883
     */
884
    public function testGetParameterTypes() : void
885
    {
886
        $qb = new QueryBuilder($this->conn);
887
888
        $qb->select('*')->from('users');
889
890
        self::assertSame([], $qb->getParameterTypes());
891
892
        $qb->where('name = :name');
893
        $qb->setParameter('name', 'foo');
894
895
        self::assertSame([], $qb->getParameterTypes());
896
897
        $qb->setParameter('name', 'foo', ParameterType::STRING);
898
899
        $qb->where('is_active = :isActive');
900
        $qb->setParameter('isActive', true, ParameterType::BOOLEAN);
901
902
        self::assertSame([
903
            'name'     => ParameterType::STRING,
904
            'isActive' => ParameterType::BOOLEAN,
905
        ], $qb->getParameterTypes());
906
    }
907
908
    /**
909
     * @group DBAL-1137
910
     */
911
    public function testJoinWithNonUniqueAliasThrowsException() : void
912
    {
913
        $qb = new QueryBuilder($this->conn);
914
915
        $qb->select('a.id')
916
            ->from('table_a', 'a')
917
            ->join('a', 'table_b', 'a', 'a.fk_b = a.id');
918
919
        $this->expectException(QueryException::class);
920
        $this->expectExceptionMessage("The given alias 'a' is not unique in FROM and JOIN clause table. The currently registered aliases are: a.");
921
922
        $qb->getSQL();
923
    }
924
}
925