Completed
Pull Request — master (#3340)
by Michael
63:56
created

QueryBuilderTest::testSelectWithDistinct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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()
21
    {
22
        $this->conn = $this->createMock(Connection::class);
1 ignored issue
show
Documentation Bug introduced by
It seems like $this->createMock(Doctri...DBAL\Connection::class) of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Doctrine\DBAL\Connection of property $conn.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

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