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

QueryBuilderTest::testUpdate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
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::assertEquals(10, $qb->getDistinct());
597
    }
598
599
    public function testResetQueryPart()
600
    {
601
        $qb = new QueryBuilder($this->conn);
602
603
        $qb->select('u.*')->from('users', 'u')->where('u.name = ?');
604
605
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string) $qb);
606
        $qb->resetQueryPart('where');
607
        self::assertEquals('SELECT u.* FROM users u', (string) $qb);
608
    }
609
610
    public function testResetQueryParts()
611
    {
612
        $qb = new QueryBuilder($this->conn);
613
614
        $qb->select('u.*')->from('users', 'u')->where('u.name = ?')->orderBy('u.name');
615
616
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ? ORDER BY u.name ASC', (string) $qb);
617
        $qb->resetQueryParts(['where', 'orderBy']);
618
        self::assertEquals('SELECT u.* FROM users u', (string) $qb);
619
    }
620
621
    public function testCreateNamedParameter()
622
    {
623
        $qb = new QueryBuilder($this->conn);
624
625
        $qb->select('u.*')->from('users', 'u')->where(
626
            $qb->expr()->eq('u.name', $qb->createNamedParameter(10, ParameterType::INTEGER))
627
        );
628
629
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = :dcValue1', (string) $qb);
630
        self::assertEquals(10, $qb->getParameter('dcValue1'));
631
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType('dcValue1'));
632
    }
633
634
    public function testCreateNamedParameterCustomPlaceholder()
635
    {
636
        $qb = new QueryBuilder($this->conn);
637
638
        $qb->select('u.*')->from('users', 'u')->where(
639
            $qb->expr()->eq('u.name', $qb->createNamedParameter(10, ParameterType::INTEGER, ':test'))
640
        );
641
642
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = :test', (string) $qb);
643
        self::assertEquals(10, $qb->getParameter('test'));
644
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType('test'));
645
    }
646
647
    public function testCreatePositionalParameter()
648
    {
649
        $qb = new QueryBuilder($this->conn);
650
651
        $qb->select('u.*')->from('users', 'u')->where(
652
            $qb->expr()->eq('u.name', $qb->createPositionalParameter(10, ParameterType::INTEGER))
653
        );
654
655
        self::assertEquals('SELECT u.* FROM users u WHERE u.name = ?', (string) $qb);
656
        self::assertEquals(10, $qb->getParameter(1));
657
        self::assertEquals(ParameterType::INTEGER, $qb->getParameterType(1));
658
    }
659
660
    /**
661
     * @group DBAL-172
662
     */
663
    public function testReferenceJoinFromJoin()
664
    {
665
        $qb = new QueryBuilder($this->conn);
666
667
        $qb->select('COUNT(DISTINCT news.id)')
668
            ->from('cb_newspages', 'news')
669
            ->innerJoin('news', 'nodeversion', 'nv', 'nv.refId = news.id AND nv.refEntityname=\'News\'')
670
            ->innerJoin('invalid', 'nodetranslation', 'nt', 'nv.nodetranslation = nt.id')
671
            ->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
672
            ->where('nt.lang = :lang AND n.deleted != 1');
673
674
        $this->expectException(QueryException::class);
675
        $this->expectExceptionMessage("The given alias 'invalid' is not part of any FROM or JOIN clause table. The currently registered aliases are: news, nv.");
676
        self::assertEquals('', $qb->getSQL());
677
    }
678
679
    /**
680
     * @group DBAL-172
681
     */
682
    public function testSelectFromMasterWithWhereOnJoinedTables()
683
    {
684
        $qb = new QueryBuilder($this->conn);
685
686
        $qb->select('COUNT(DISTINCT news.id)')
687
            ->from('newspages', 'news')
688
            ->innerJoin('news', 'nodeversion', 'nv', "nv.refId = news.id AND nv.refEntityname='Entity\\News'")
689
            ->innerJoin('nv', 'nodetranslation', 'nt', 'nv.nodetranslation = nt.id')
690
            ->innerJoin('nt', 'node', 'n', 'nt.node = n.id')
691
            ->where('nt.lang = ?')
692
            ->andWhere('n.deleted = 0');
693
694
        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());
695
    }
696
697
    /**
698
     * @group DBAL-442
699
     */
700
    public function testSelectWithMultipleFromAndJoins()
701
    {
702
        $qb = new QueryBuilder($this->conn);
703
704
        $qb->select('DISTINCT u.id')
705
            ->from('users', 'u')
706
            ->from('articles', 'a')
707
            ->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
708
            ->innerJoin('a', 'comments', 'c', 'c.article_id = a.id')
709
            ->where('u.id = a.user_id')
710
            ->andWhere('p.read = 1');
711
712
        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());
713
    }
714
715
    /**
716
     * @group DBAL-774
717
     */
718
    public function testSelectWithJoinsWithMultipleOnConditionsParseOrder()
719
    {
720
        $qb = new QueryBuilder($this->conn);
721
722
        $qb->select('a.id')
723
            ->from('table_a', 'a')
724
            ->join('a', 'table_b', 'b', 'a.fk_b = b.id')
725
            ->join('b', 'table_c', 'c', 'c.fk_b = b.id AND b.language = ?')
726
            ->join('a', 'table_d', 'd', 'a.fk_d = d.id')
727
            ->join('c', 'table_e', 'e', 'e.fk_c = c.id AND e.fk_d = d.id');
728
729
        self::assertEquals(
730
            'SELECT a.id ' .
731
            'FROM table_a a ' .
732
            'INNER JOIN table_b b ON a.fk_b = b.id ' .
733
            'INNER JOIN table_d d ON a.fk_d = d.id ' .
734
            'INNER JOIN table_c c ON c.fk_b = b.id AND b.language = ? ' .
735
            'INNER JOIN table_e e ON e.fk_c = c.id AND e.fk_d = d.id',
736
            (string) $qb
737
        );
738
    }
739
740
    /**
741
     * @group DBAL-774
742
     */
743
    public function testSelectWithMultipleFromsAndJoinsWithMultipleOnConditionsParseOrder()
744
    {
745
        $qb = new QueryBuilder($this->conn);
746
747
        $qb->select('a.id')
748
            ->from('table_a', 'a')
749
            ->from('table_f', 'f')
750
            ->join('a', 'table_b', 'b', 'a.fk_b = b.id')
751
            ->join('b', 'table_c', 'c', 'c.fk_b = b.id AND b.language = ?')
752
            ->join('a', 'table_d', 'd', 'a.fk_d = d.id')
753
            ->join('c', 'table_e', 'e', 'e.fk_c = c.id AND e.fk_d = d.id')
754
            ->join('f', 'table_g', 'g', 'f.fk_g = g.id');
755
756
        self::assertEquals(
757
            'SELECT a.id ' .
758
            'FROM table_a a ' .
759
            'INNER JOIN table_b b ON a.fk_b = b.id ' .
760
            'INNER JOIN table_d d ON a.fk_d = d.id ' .
761
            'INNER JOIN table_c c ON c.fk_b = b.id AND b.language = ? ' .
762
            'INNER JOIN table_e e ON e.fk_c = c.id AND e.fk_d = d.id, ' .
763
            'table_f f ' .
764
            'INNER JOIN table_g g ON f.fk_g = g.id',
765
            (string) $qb
766
        );
767
    }
768
769
    public function testClone()
770
    {
771
        $qb = new QueryBuilder($this->conn);
772
773
        $qb->select('u.id')
774
            ->from('users', 'u')
775
            ->where('u.id = :test');
776
777
        $qb->setParameter(':test', (object) 1);
778
779
        $qb_clone = clone $qb;
780
781
        self::assertEquals((string) $qb, (string) $qb_clone);
782
783
        $qb->andWhere('u.id = 1');
784
785
        self::assertNotSame($qb->getQueryParts(), $qb_clone->getQueryParts());
786
        self::assertNotSame($qb->getParameters(), $qb_clone->getParameters());
787
    }
788
789
    public function testSimpleSelectWithoutTableAlias()
790
    {
791
        $qb = new QueryBuilder($this->conn);
792
793
        $qb->select('id')
794
            ->from('users');
795
796
        self::assertEquals('SELECT id FROM users', (string) $qb);
797
    }
798
799
    public function testSelectWithSimpleWhereWithoutTableAlias()
800
    {
801
        $qb = new QueryBuilder($this->conn);
802
803
        $qb->select('id', 'name')
804
            ->from('users')
805
            ->where('awesome=9001');
806
807
        self::assertEquals('SELECT id, name FROM users WHERE awesome=9001', (string) $qb);
808
    }
809
810
    public function testComplexSelectWithoutTableAliases()
811
    {
812
        $qb = new QueryBuilder($this->conn);
813
814
        $qb->select('DISTINCT users.id')
815
            ->from('users')
816
            ->from('articles')
817
            ->innerJoin('users', 'permissions', 'p', 'p.user_id = users.id')
818
            ->innerJoin('articles', 'comments', 'c', 'c.article_id = articles.id')
819
            ->where('users.id = articles.user_id')
820
            ->andWhere('p.read = 1');
821
822
        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());
823
    }
824
825
    public function testComplexSelectWithSomeTableAliases()
826
    {
827
        $qb = new QueryBuilder($this->conn);
828
829
        $qb->select('u.id')
830
            ->from('users', 'u')
831
            ->from('articles')
832
            ->innerJoin('u', 'permissions', 'p', 'p.user_id = u.id')
833
            ->innerJoin('articles', 'comments', 'c', 'c.article_id = articles.id');
834
835
        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());
836
    }
837
838
    public function testSelectAllFromTableWithoutTableAlias()
839
    {
840
        $qb = new QueryBuilder($this->conn);
841
842
        $qb->select('users.*')
843
            ->from('users');
844
845
        self::assertEquals('SELECT users.* FROM users', (string) $qb);
846
    }
847
848
    public function testSelectAllWithoutTableAlias()
849
    {
850
        $qb = new QueryBuilder($this->conn);
851
852
        $qb->select('*')
853
            ->from('users');
854
855
        self::assertEquals('SELECT * FROM users', (string) $qb);
856
    }
857
858
    /**
859
     * @group DBAL-959
860
     */
861
    public function testGetParameterType()
862
    {
863
        $qb = new QueryBuilder($this->conn);
864
865
        $qb->select('*')->from('users');
866
867
        self::assertNull($qb->getParameterType('name'));
868
869
        $qb->where('name = :name');
870
        $qb->setParameter('name', 'foo');
871
872
        self::assertNull($qb->getParameterType('name'));
873
874
        $qb->setParameter('name', 'foo', ParameterType::STRING);
875
876
        self::assertSame(ParameterType::STRING, $qb->getParameterType('name'));
877
    }
878
879
    /**
880
     * @group DBAL-959
881
     */
882
    public function testGetParameterTypes()
883
    {
884
        $qb = new QueryBuilder($this->conn);
885
886
        $qb->select('*')->from('users');
887
888
        self::assertSame([], $qb->getParameterTypes());
889
890
        $qb->where('name = :name');
891
        $qb->setParameter('name', 'foo');
892
893
        self::assertSame([], $qb->getParameterTypes());
894
895
        $qb->setParameter('name', 'foo', ParameterType::STRING);
896
897
        $qb->where('is_active = :isActive');
898
        $qb->setParameter('isActive', true, ParameterType::BOOLEAN);
899
900
        self::assertSame([
901
            'name'     => ParameterType::STRING,
902
            'isActive' => ParameterType::BOOLEAN,
903
        ], $qb->getParameterTypes());
904
    }
905
906
    /**
907
     * @group DBAL-1137
908
     */
909
    public function testJoinWithNonUniqueAliasThrowsException()
910
    {
911
        $qb = new QueryBuilder($this->conn);
912
913
        $qb->select('a.id')
914
            ->from('table_a', 'a')
915
            ->join('a', 'table_b', 'a', 'a.fk_b = a.id');
916
917
        $this->expectException(QueryException::class);
918
        $this->expectExceptionMessage("The given alias 'a' is not unique in FROM and JOIN clause table. The currently registered aliases are: a.");
919
920
        $qb->getSQL();
921
    }
922
}
923