Completed
Pull Request — master (#3832)
by Benjamin
62:49
created

QueryBuilderTest::testSelectHavingAndHaving()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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