Failed Conditions
Pull Request — master (#3260)
by Michael
61:30
created

testSimpleSelectWithMatchingTableAlias()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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