Completed
Pull Request — develop (#3695)
by
unknown
63:26
created

QueryBuilderTest::testSimpleSelectWithDistinct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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