Completed
Pull Request — master (#3696)
by
unknown
13:44
created

QueryBuilderTest::testInsertReplaceValues()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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