Passed
Pull Request — master (#405)
by Wilmer
05:12 queued 02:35
created

AbstractQueryBuilderTest::testDropView()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 14
rs 9.9666
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Tests;
6
7
use Closure;
8
use PHPUnit\Framework\TestCase;
9
use stdClass;
10
use Yiisoft\Arrays\ArrayHelper;
11
use Yiisoft\Db\Expression\Expression;
12
use Yiisoft\Db\Expression\ExpressionBuilderInterface;
13
use Yiisoft\Db\Expression\ExpressionInterface;
14
use Yiisoft\Db\Query\Query;
15
use Yiisoft\Db\Query\QueryInterface;
16
use Yiisoft\Db\QueryBuilder\Condition\SimpleCondition;
17
use Yiisoft\Db\Schema\QuoterInterface;
18
use Yiisoft\Db\Schema\Schema;
19
use Yiisoft\Db\Tests\Support\Assert;
20
use Yiisoft\Db\Tests\Support\DbHelper;
21
use Yiisoft\Db\Tests\Support\TestTrait;
22
23
abstract class AbstractQueryBuilderTest extends TestCase
24
{
25
    use TestTrait;
26
27
    public function testAddCheck(): void
28
    {
29
        $db = $this->getConnection();
30
31
        $qb = $db->getQueryBuilder();
32
        $sql = $qb->addCheck('T_constraints_1', 'CN_check', '[[C_not_null]] > 100');
33
34
        $this->assertSame(
35
            DbHelper::replaceQuotes(
36
                <<<SQL
37
                ALTER TABLE [[CN_check]] ADD CONSTRAINT [[T_constraints_1]] CHECK ([[C_not_null]] > 100)
38
                SQL,
39
                $db->getName(),
40
            ),
41
            $sql,
42
        );
43
    }
44
45
    public function testAddColumn(): void
46
    {
47
        $db = $this->getConnection();
48
49
        $qb = $db->getQueryBuilder();
50
        $schema = $db->getSchema();
51
        $sql = $qb->addColumn('table', 'column', $schema::TYPE_STRING);
0 ignored issues
show
Bug introduced by
The constant Yiisoft\Db\Schema\SchemaInterface::TYPE_STRING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
52
53
        $this->assertSame(
54
            DbHelper::replaceQuotes(
55
                <<<SQL
56
                ALTER TABLE [[table]] ADD [[column]]
57
                SQL . ' ' . $qb->getColumnType($schema::TYPE_STRING),
58
                $db->getName(),
59
            ),
60
            $sql,
61
        );
62
    }
63
64
    public function testAddCommentOnColumn(): void
65
    {
66
        $db = $this->getConnection();
67
68
        $qb = $db->getQueryBuilder();
69
        $sql = $qb->addCommentOnColumn('customer', 'id', 'Primary key.');
70
71
        $this->assertSame(
72
            DbHelper::replaceQuotes(
73
                <<<SQL
74
                COMMENT ON COLUMN [[customer]].[[id]] IS 'Primary key.'
75
                SQL,
76
                $db->getName(),
77
            ),
78
            $sql,
79
        );
80
    }
81
82
    public function testAddCommentOnTable(): void
83
    {
84
        $db = $this->getConnection();
85
86
        $qb = $db->getQueryBuilder();
87
        $sql = $qb->addCommentOnTable('customer', 'Customer table.');
88
89
        $this->assertSame(
90
            DbHelper::replaceQuotes(
91
                <<<SQL
92
                COMMENT ON TABLE [[customer]] IS 'Customer table.'
93
                SQL,
94
                $db->getName(),
95
            ),
96
            $sql,
97
        );
98
    }
99
100
    public function testAddDefaultValue(): void
101
    {
102
        $db = $this->getConnection();
103
104
        $qb = $db->getQueryBuilder();
105
        $sql = $qb->addDefaultValue('CN_pk', 'T_constraints_1', 'C_default', 1);
106
107
        $this->assertSame(
108
            DbHelper::replaceQuotes(
109
                <<<SQL
110
                ALTER TABLE [[T_constraints_1]] ALTER COLUMN [[C_default]] SET DEFAULT 1
111
                SQL,
112
                $db->getName(),
113
            ),
114
            $sql,
115
        );
116
    }
117
118
    /**
119
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::addForeignKey()
120
     */
121
    public function testAddForeignKey(
122
        string $name,
123
        string $table,
124
        array|string $columns,
125
        string $refTable,
126
        array|string $refColumns,
127
        string|null $delete,
128
        string|null $update,
129
        string $expected
130
    ): void {
131
        $db = $this->getConnection();
132
133
        $qb = $db->getQueryBuilder();
134
        $sql = $qb->addForeignKey($name, $table, $columns, $refTable, $refColumns, $delete, $update);
135
136
        $this->assertSame($expected, $sql);
137
    }
138
139
    /**
140
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::addPrimaryKey()
141
     */
142
    public function testAddPrimaryKey(string $name, string $table, array|string $columns, string $expected): void
143
    {
144
        $db = $this->getConnection();
145
146
        $qb = $db->getQueryBuilder();
147
        $sql = $qb->addPrimaryKey($name, $table, $columns);
148
149
        $this->assertSame($expected, $sql);
150
    }
151
152
    /**
153
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::addUnique()
154
     */
155
    public function testAddUnique(string $name, string $table, array|string $columns, string $expected): void
156
    {
157
        $db = $this->getConnection();
158
159
        $qb = $db->getQueryBuilder();
160
        $sql = $qb->addUnique($name, $table, $columns);
161
162
        $this->assertSame($expected, $sql);
163
    }
164
165
    public function testAlterColumn(): void
166
    {
167
        $db = $this->getConnection();
168
169
        $qb = $db->getQueryBuilder();
170
        $schema = $db->getSchema();
171
        $sql = $qb->alterColumn('customer', 'email', $schema::TYPE_STRING);
0 ignored issues
show
Bug introduced by
The constant Yiisoft\Db\Schema\SchemaInterface::TYPE_STRING was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
172
173
        $this->assertSame(
174
            DbHelper::replaceQuotes(
175
                <<<SQL
176
                ALTER TABLE [[customer]] CHANGE [[email]] [[email]]
177
                SQL . ' ' . $qb->getColumnType($schema::TYPE_STRING),
178
                $db->getName(),
179
            ),
180
            $sql,
181
        );
182
    }
183
184
    /**
185
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::batchInsert()
186
     */
187
    public function testBatchInsert(string $table, array $columns, array $rows, string $expected): void
188
    {
189
        $db = $this->getConnection();
190
191
        $qb = $db->getQueryBuilder();
192
        $sql = $qb->batchInsert($table, $columns, $rows);
193
194
        $this->assertSame($expected, $sql);
195
    }
196
197
    /**
198
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::buildCondition()
199
     */
200
    public function testBuildCondition(
201
        array|ExpressionInterface|string $condition,
202
        string|null $expected,
203
        array $expectedParams
204
    ): void {
205
        $db = $this->getConnection();
206
207
        $query = (new Query($db))->where($condition);
208
209
        [$sql, $params] = $db->getQueryBuilder()->build($query);
210
211
        $replacedQuotes = DbHelper::replaceQuotes($expected, $db->getName());
0 ignored issues
show
Bug introduced by
It seems like $expected can also be of type null; however, parameter $sql of Yiisoft\Db\Tests\Support\DbHelper::replaceQuotes() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

211
        $replacedQuotes = DbHelper::replaceQuotes(/** @scrutinizer ignore-type */ $expected, $db->getName());
Loading history...
212
213
        $this->assertIsString($replacedQuotes);
214
        $this->assertEquals('SELECT *' . (empty($expected) ? '' : ' WHERE ' . $replacedQuotes), $sql);
215
        $this->assertEquals($expectedParams, $params);
216
    }
217
218
    public function testBuildColumnsWithString(): void
219
    {
220
        $db = $this->getConnection();
221
222
        $qb = $db->getQueryBuilder();
223
224
        $this->assertSame('(id)', $qb->buildColumns('(id)'));
225
    }
226
227
    public function testBuildColumnsWithArray(): void
228
    {
229
        $db = $this->getConnection();
230
231
        $qb = $db->getQueryBuilder();
232
233
        $this->assertSame(
234
            DbHelper::replaceQuotes('[[id]], [[name]], [[email]], [[address]], [[status]]', $db->getName()),
235
            $qb->buildColumns(['id', 'name', 'email', 'address', 'status']),
236
        );
237
    }
238
239
    public function testBuildColumnsWithExpression(): void
240
    {
241
        $db = $this->getConnection();
242
243
        $qb = $db->getQueryBuilder();
244
245
        $this->assertSame(
246
            DbHelper::replaceQuotes(
247
                '[[id]], [[name]], [[email]], [[address]], [[status]], COUNT(*)',
248
                $db->getName(),
249
            ),
250
            $qb->buildColumns(['id', 'name', 'email', 'address', 'status', new Expression('COUNT(*)')]),
251
        );
252
    }
253
254
    /**
255
     * {@see https://github.com/yiisoft/yii2/issues/15653}
256
     */
257
    public function testBuildIssue15653(): void
258
    {
259
        $db = $this->getConnection();
260
261
        $qb = $db->getQueryBuilder();
262
        $query = (new Query($db))->from('admin_user')->where(['is_deleted' => false]);
263
        $query->where([])->andWhere(['in', 'id', ['1', '0']]);
264
265
        [$sql, $params] = $qb->build($query);
266
267
        $this->assertSame(
268
            DbHelper::replaceQuotes(
269
                <<<SQL
270
                SELECT * FROM [[admin_user]] WHERE [[id]] IN (:qp0, :qp1)
271
                SQL,
272
                $db->getName(),
273
            ),
274
            $sql,
275
        );
276
        $this->assertSame([':qp0' => '1', ':qp1' => '0'], $params);
277
    }
278
279
    /**
280
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::buildFilterCondition()
281
     */
282
    public function testBuildFilterCondition(array $condition, string $expected, array $expectedParams): void
283
    {
284
        $db = $this->getConnection();
285
286
        $qb = $db->getQueryBuilder();
287
        $query = (new Query($db))->filterWhere($condition);
288
289
        [$sql, $params] = $qb->build($query);
290
291
        $this->assertSame(
292
            'SELECT *' . (
293
                empty($expected) ? '' : ' WHERE ' . DbHelper::replaceQuotes($expected, $db->getName())
294
            ),
295
            $sql,
296
        );
297
        $this->assertSame($expectedParams, $params);
298
    }
299
300
    public function testBuildFrom(): void
301
    {
302
        $db = $this->getConnection();
303
304
        $qb = $db->getQueryBuilder();
305
        $query = (new Query($db))->from('admin_user');
306
        $params = [];
307
308
        $this->assertSame(
309
            DbHelper::replaceQuotes(
310
                <<<SQL
311
                FROM [[admin_user]]
312
                SQL,
313
                $db->getName(),
314
            ),
315
            $qb->buildFrom($query->getFrom(), $params),
316
        );
317
    }
318
319
    public function testBuildGroupBy(): void
320
    {
321
        $db = $this->getConnection();
322
323
        $qb = $db->getQueryBuilder();
324
        $query = (new Query($db))->from('admin_user')->groupBy(['id', 'name']);
325
        $params = [];
326
327
        $this->assertSame(
328
            DbHelper::replaceQuotes(
329
                <<<SQL
330
                GROUP BY [[id]], [[name]]
331
                SQL,
332
                $db->getName(),
333
            ),
334
            $qb->buildGroupBy($query->getGroupBy(), $params),
335
        );
336
    }
337
338
    public function testBuildHaving(): void
339
    {
340
        $db = $this->getConnection();
341
342
        $qb = $db->getQueryBuilder();
343
        $query = (new Query($db))->from('admin_user')->having(['id' => 1]);
344
        $params = [];
345
346
        $this->assertSame(
347
            DbHelper::replaceQuotes(
348
                <<<SQL
349
                HAVING [[id]]=:qp0
350
                SQL,
351
                $db->getName(),
352
            ),
353
            $qb->buildHaving($query->getHaving(), $params),
354
        );
355
    }
356
357
    public function testBuildJoin(): void
358
    {
359
        $db = $this->getConnection();
360
361
        $qb = $db->getQueryBuilder();
362
        $query = (new Query($db))
363
            ->from('admin_user')
364
            ->join('INNER JOIN', 'admin_profile', 'admin_user.id = admin_profile.user_id');
365
        $params = [];
366
367
        $this->assertSame(
368
            DbHelper::replaceQuotes(
369
                <<<SQL
370
                INNER JOIN [[admin_profile]] ON admin_user.id = admin_profile.user_id
371
                SQL,
372
                $db->getName(),
373
            ),
374
            $qb->buildJoin($query->getJoin(), $params),
375
        );
376
    }
377
378
    /**
379
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::buildLikeCondition()
380
     */
381
    public function testBuildLikeCondition(
382
        array|ExpressionInterface $condition,
383
        string $expected,
384
        array $expectedParams
385
    ): void {
386
        $db = $this->getConnection();
387
388
        $query = (new Query($db))->where($condition);
389
390
        [$sql, $params] = $db->getQueryBuilder()->build($query);
391
392
        $replacedQuotes = DbHelper::replaceQuotes($expected, $db->getName());
393
394
        $this->assertIsString($replacedQuotes);
395
        $this->assertSame('SELECT *' . (empty($expected) ? '' : ' WHERE ' . $replacedQuotes), $sql);
396
        $this->assertSame($expectedParams, $params);
397
    }
398
399
    public function testBuildLimit(): void
400
    {
401
        $db = $this->getConnection();
402
403
        $qb = $db->getQueryBuilder();
404
        $query = (new Query($db))->from('admin_user')->limit(10);
405
406
        $this->assertSame('LIMIT 10', $qb->buildLimit($query->getLimit(), 0));
407
    }
408
409
    public function testBuildLimitOffset(): void
410
    {
411
        $db = $this->getConnection();
412
413
        $qb = $db->getQueryBuilder();
414
        $query = (new Query($db))->from('admin_user')->limit(10)->offset(5);
415
416
        $this->assertSame('LIMIT 10 OFFSET 5', $qb->buildLimit($query->getLimit(), $query->getOffset()));
417
    }
418
419
    public function testBuildOrderBy(): void
420
    {
421
        $db = $this->getConnection();
422
423
        $qb = $db->getQueryBuilder();
424
        $query = (new Query($db))->from('admin_user')->orderBy(['id' => SORT_ASC, 'name' => SORT_DESC]);
425
        $params = [];
426
427
        $this->assertSame(
428
            DbHelper::replaceQuotes(
429
                <<<SQL
430
                ORDER BY [[id]], [[name]] DESC
431
                SQL,
432
                $db->getName(),
433
            ),
434
            $qb->buildOrderBy($query->getOrderBy(), $params),
435
        );
436
    }
437
438
    public function testBuildOrderByAndLimit(): void
439
    {
440
        $db = $this->getConnection();
441
442
        $qb = $db->getQueryBuilder();
443
        $query = (new Query($db))
444
            ->from('admin_user')
445
            ->orderBy(['id' => SORT_ASC, 'name' => SORT_DESC])
446
            ->limit(10)
447
            ->offset(5);
448
449
        $this->assertSame(
450
            DbHelper::replaceQuotes(
451
                <<<SQL
452
                SELECT * FROM [[admin_user]] ORDER BY [[id]], [[name]] DESC LIMIT 10 OFFSET 5
453
                SQL,
454
                $db->getName(),
455
            ),
456
            $qb->buildOrderByAndLimit(
457
                DbHelper::replaceQuotes(
458
                    <<<SQL
459
                    SELECT * FROM [[admin_user]]
460
                    SQL,
461
                    $db->getName(),
462
                ),
463
                $query->getOrderBy(),
464
                $query->getLimit(),
465
                $query->getOffset(),
466
            ),
467
        );
468
    }
469
470
    public function testBuildSelect(): void
471
    {
472
        $db = $this->getConnection();
473
474
        $qb = $db->getQueryBuilder();
475
        $query = (new Query($db))->select(['id', 'name', 'email', 'address', 'status']);
476
        $params = [];
477
478
        $this->assertSame(
479
            DbHelper::replaceQuotes(
480
                <<<SQL
481
                SELECT [[id]], [[name]], [[email]], [[address]], [[status]]
482
                SQL,
483
                $db->getName(),
484
            ),
485
            $qb->buildSelect($query->getSelect(), $params),
486
        );
487
    }
488
489
    public function testBuildSelectWithDistinct(): void
490
    {
491
        $db = $this->getConnection();
492
493
        $qb = $db->getQueryBuilder();
494
        $query = (new Query($db))->select(['id', 'name', 'email', 'address', 'status'])->distinct();
495
        $params = [];
496
497
        $this->assertSame(
498
            DbHelper::replaceQuotes(
499
                <<<SQL
500
                SELECT DISTINCT [[id]], [[name]], [[email]], [[address]], [[status]]
501
                SQL,
502
                $db->getName(),
503
            ),
504
            $qb->buildSelect($query->getSelect(), $params, true),
505
        );
506
    }
507
508
    public function testBuildUnion(): void
509
    {
510
        $db = $this->getConnection();
511
512
        $qb = $db->getQueryBuilder();
513
        $query = (new Query($db))->from('admin_user')->union((new Query($db))->from('admin_profile'));
514
        $params = [];
515
516
        $this->assertSame(
517
            DbHelper::replaceQuotes(
518
                <<<SQL
519
                UNION ( SELECT * FROM [[admin_profile]] )
520
                SQL,
521
                $db->getName(),
522
            ),
523
            $qb->buildUnion($query->getUnion(), $params),
524
        );
525
    }
526
527
    public function testBuildWithQueries(): void
528
    {
529
        $db = $this->getConnection();
530
531
        $qb = $db->getQueryBuilder();
532
        $query = (new Query($db))->withQuery((new Query($db))->from('admin_user')->from('admin_profile'), 'cte');
533
        $params = [];
534
535
        $this->assertSame(
536
            DbHelper::replaceQuotes(
537
                <<<SQL
538
                WITH cte AS (SELECT * FROM [[admin_profile]])
539
                SQL,
540
                $db->getName(),
541
            ),
542
            $qb->buildWithQueries($query->getWithQueries(), $params),
543
        );
544
    }
545
546
    public function testBuildWithComplexSelect(): void
547
    {
548
        $db = $this->getConnection();
549
550
        $qb = $db->getQueryBuilder();
551
        $expressionString = DbHelper::replaceQuotes(
552
            <<<SQL
553
            case t.Status_Id when 1 then 'Acknowledge' when 2 then 'No Action' else 'Unknown Action' END as [[Next Action]]
554
            SQL,
555
            $db->getName(),
556
        );
557
558
        $this->assertIsString($expressionString);
559
560
        $query = (new Query($db))
561
            ->select(
562
                [
563
                    'ID' => 't.id',
564
                    'gsm.username as GSM',
565
                    'part.Part',
566
                    'Part Cost' => 't.Part_Cost',
567
                    'st_x(location::geometry) as lon',
568
                    new Expression($expressionString),
569
                ]
570
            )
571
            ->from('tablename');
572
573
        [$sql, $params] = $qb->build($query);
574
575
        $this->assertSame(
576
            DbHelper::replaceQuotes(
577
                <<<SQL
578
                SELECT [[t]].[[id]] AS [[ID]], [[gsm]].[[username]] AS [[GSM]], [[part]].[[Part]], [[t]].[[Part_Cost]] AS [[Part Cost]], st_x(location::geometry) AS [[lon]], case t.Status_Id when 1 then 'Acknowledge' when 2 then 'No Action' else 'Unknown Action' END as [[Next Action]] FROM [[tablename]]
579
                SQL,
580
                $db->getName(),
581
            ),
582
            $sql,
583
        );
584
        $this->assertEmpty($params);
585
    }
586
587
    /**
588
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::buildFrom()
589
     */
590
    public function testBuildWithFrom(mixed $table, string $expectedSql, array $expectedParams = []): void
591
    {
592
        $db = $this->getConnection();
593
594
        $query = (new Query($db))->from($table);
595
        $queryBuilder = $db->getQueryBuilder();
596
597
        [$sql, $params] = $queryBuilder->build($query);
598
599
        $this->assertSame($expectedSql, $sql);
600
        $this->assertSame($expectedParams, $params);
601
    }
602
603
    public function testBuildWithFromAliasesNoExist(): void
604
    {
605
        $db = $this->getConnection();
606
607
        $qb = $db->getQueryBuilder();
608
        $query = (new Query($db))->from('no_exist_table');
609
610
        [$sql, $params] = $qb->build($query);
611
612
        $this->assertSame(
613
            DbHelper::replaceQuotes(
614
                <<<SQL
615
                SELECT * FROM [[no_exist_table]]
616
                SQL,
617
                $db->getName(),
618
            ),
619
            $sql,
620
        );
621
622
        $this->assertSame([], $params);
623
    }
624
625
    /**
626
     * {@see https://github.com/yiisoft/yii2/issues/10869}
627
     */
628
    public function testBuildWithFromIndexHint(): void
629
    {
630
        $db = $this->getConnection();
631
632
        $qb = $db->getQueryBuilder();
633
        $query = (new Query($db))->from([new Expression('{{%user}} USE INDEX (primary)')]);
634
635
        [$sql, $params] = $qb->build($query);
636
637
        $this->assertSame(
638
            DbHelper::replaceQuotes(
639
                <<<SQL
640
                SELECT * FROM {{%user}} USE INDEX (primary)
641
                SQL,
642
                $db->getName(),
643
            ),
644
            $sql,
645
        );
646
647
        $this->assertEmpty($params);
648
649
        $query = (new Query($db))
650
            ->from([new Expression('{{user}} {{t}} FORCE INDEX (primary) IGNORE INDEX FOR ORDER BY (i1)')])
651
            ->leftJoin(['p' => 'profile'], 'user.id = profile.user_id USE INDEX (i2)');
652
653
        [$sql, $params] = $qb->build($query);
654
655
        $this->assertSame(
656
            DbHelper::replaceQuotes(
657
                <<<SQL
658
                SELECT * FROM {{user}} {{t}} FORCE INDEX (primary) IGNORE INDEX FOR ORDER BY (i1) LEFT JOIN [[profile]] [[p]] ON user.id = profile.user_id USE INDEX (i2)
659
                SQL,
660
                $db->getName(),
661
            ),
662
            $sql,
663
        );
664
665
        $this->assertEmpty($params);
666
    }
667
668
    public function testBuildWithFromSubquery(): void
669
    {
670
        $db = $this->getConnection();
671
672
        $qb = $db->getQueryBuilder();
673
674
        /* subquery */
675
        $subquery = (new Query($db))->from('user')->where('account_id = accounts.id');
676
        $query = (new Query($db))->from(['activeusers' => $subquery]);
677
678
        /* SELECT * FROM (SELECT * FROM [[user]] WHERE [[active]] = 1) [[activeusers]]; */
679
        [$sql, $params] = $qb->build($query);
680
681
        $this->assertSame(
682
            DbHelper::replaceQuotes(
683
                <<<SQL
684
                SELECT * FROM (SELECT * FROM [[user]] WHERE account_id = accounts.id) [[activeusers]]
685
                SQL,
686
                $db->getName(),
687
            ),
688
            $sql,
689
        );
690
        $this->assertEmpty($params);
691
692
        /* subquery with params */
693
        $subquery = (new Query($db))->from('user')->where('account_id = :id', ['id' => 1]);
694
        $query = (new Query($db))->from(['activeusers' => $subquery])->where('abc = :abc', ['abc' => 'abc']);
695
696
        /* SELECT * FROM (SELECT * FROM [[user]] WHERE [[active]] = 1) [[activeusers]]; */
697
        [$sql, $params] = $qb->build($query);
698
699
        $this->assertSame(
700
            DbHelper::replaceQuotes(
701
                <<<SQL
702
                SELECT * FROM (SELECT * FROM [[user]] WHERE account_id = :id) [[activeusers]] WHERE abc = :abc
703
                SQL,
704
                $db->getName(),
705
            ),
706
            $sql,
707
        );
708
        $this->assertSame(['abc' => 'abc', 'id' => 1], $params);
709
710
        /* simple subquery */
711
        $subquery = '(SELECT * FROM user WHERE account_id = accounts.id)';
712
        $query = (new Query($db))->from(['activeusers' => $subquery]);
713
714
        /* SELECT * FROM (SELECT * FROM [[user]] WHERE [[active]] = 1) [[activeusers]]; */
715
        [$sql, $params] = $qb->build($query);
716
717
        $this->assertSame(
718
            DbHelper::replaceQuotes(
719
                <<<SQL
720
                SELECT * FROM (SELECT * FROM user WHERE account_id = accounts.id) [[activeusers]]
721
                SQL,
722
                $db->getName(),
723
            ),
724
            $sql,
725
        );
726
        $this->assertEmpty($params);
727
    }
728
729
    public function testBuildWithGroupBy(): void
730
    {
731
        $db = $this->getConnection();
732
733
        $qb = $db->getQueryBuilder();
734
735
        /* simple string */
736
        $query = (new Query($db))->select('*')->from('operations')->groupBy('name, date');
737
738
        [$sql, $params] = $qb->build($query);
739
740
        $this->assertSame(
741
            DbHelper::replaceQuotes(
742
                <<<SQL
743
                SELECT * FROM [[operations]] GROUP BY [[name]], [[date]]
744
                SQL,
745
                $db->getName(),
746
            ),
747
            $sql,
748
        );
749
        $this->assertEmpty($params);
750
751
        /* array syntax */
752
        $query = (new Query($db))->select('*')->from('operations')->groupBy(['name', 'date']);
753
754
        [$sql, $params] = $qb->build($query);
755
756
        $this->assertSame(
757
            DbHelper::replaceQuotes(
758
                <<<SQL
759
                SELECT * FROM [[operations]] GROUP BY [[name]], [[date]]
760
                SQL,
761
                $db->getName(),
762
            ),
763
            $sql,
764
        );
765
        $this->assertEmpty($params);
766
767
        /* expression */
768
        $query = (new Query($db))
769
            ->select('*')
770
            ->from('operations')
771
            ->where('account_id = accounts.id')
772
            ->groupBy(new Expression('SUBSTR(name, 0, 1), x'));
773
774
        [$sql, $params] = $qb->build($query);
775
776
        $this->assertSame(
777
            DbHelper::replaceQuotes(
778
                <<<SQL
779
                SELECT * FROM [[operations]] WHERE account_id = accounts.id GROUP BY SUBSTR(name, 0, 1), x
780
                SQL,
781
                $db->getName(),
782
            ),
783
            $sql,
784
        );
785
        $this->assertEmpty($params);
786
787
        /* expression with params */
788
        $query = (new Query($db))
789
            ->select('*')
790
            ->from('operations')
791
            ->groupBy(new Expression('SUBSTR(name, 0, :to), x', [':to' => 4]));
792
793
        [$sql, $params] = $qb->build($query);
794
795
        $this->assertSame(
796
            DbHelper::replaceQuotes(
797
                <<<SQL
798
                SELECT * FROM [[operations]] GROUP BY SUBSTR(name, 0, :to), x
799
                SQL,
800
                $db->getName(),
801
            ),
802
            $sql,
803
        );
804
        $this->assertSame([':to' => 4], $params);
805
    }
806
807
    public function testBuildWithLimit(): void
808
    {
809
        $db = $this->getConnection();
810
811
        $qb = $db->getQueryBuilder();
812
        $query = (new Query($db))->limit(10);
813
814
        [$sql, $params] = $qb->build($query);
815
816
        $this->assertSame(
817
            <<<SQL
818
            SELECT * LIMIT 10
819
            SQL,
820
            $sql,
821
        );
822
823
        $this->assertSame([], $params);
824
    }
825
826
    public function testBuildWithOffset(): void
827
    {
828
        $db = $this->getConnection();
829
830
        $qb = $db->getQueryBuilder();
831
        $query = (new Query($db))->offset(10);
832
833
        [$sql, $params] = $qb->build($query);
834
835
        $this->assertSame(
836
            <<<SQL
837
            SELECT * OFFSET 10
838
            SQL,
839
            $sql,
840
        );
841
        $this->assertSame([], $params);
842
    }
843
844
    public function testBuildWithOrderBy(): void
845
    {
846
        $db = $this->getConnection();
847
848
        $qb = $db->getQueryBuilder();
849
850
        /* simple string */
851
        $query = (new Query($db))->select('*')->from('operations')->orderBy('name ASC, date DESC');
852
853
        [$sql, $params] = $qb->build($query);
854
855
        $this->assertSame(
856
            DbHelper::replaceQuotes(
857
                <<<SQL
858
                SELECT * FROM [[operations]] ORDER BY [[name]], [[date]] DESC
859
                SQL,
860
                $db->getName(),
861
            ),
862
            $sql,
863
        );
864
        $this->assertEmpty($params);
865
866
        /* array syntax */
867
        $query = (new Query($db))->select('*')->from('operations')->orderBy(['name' => SORT_ASC, 'date' => SORT_DESC]);
868
869
        [$sql, $params] = $qb->build($query);
870
871
        $this->assertSame(
872
            DbHelper::replaceQuotes(
873
                <<<SQL
874
                SELECT * FROM [[operations]] ORDER BY [[name]], [[date]] DESC
875
                SQL,
876
                $db->getName(),
877
            ),
878
            $sql,
879
        );
880
        $this->assertEmpty($params);
881
882
        /* expression */
883
        $query = (new Query($db))
884
            ->select('*')
885
            ->from('operations')
886
            ->where('account_id = accounts.id')
887
            ->orderBy(new Expression('SUBSTR(name, 3, 4) DESC, x ASC'));
888
889
        [$sql, $params] = $qb->build($query);
890
891
        $this->assertSame(
892
            DbHelper::replaceQuotes(
893
                <<<SQL
894
                SELECT * FROM [[operations]] WHERE account_id = accounts.id ORDER BY SUBSTR(name, 3, 4) DESC, x ASC
895
                SQL,
896
                $db->getName(),
897
            ),
898
            $sql,
899
        );
900
        $this->assertEmpty($params);
901
902
        /* expression with params */
903
        $query = (new Query($db))
904
            ->select('*')
905
            ->from('operations')
906
            ->orderBy(new Expression('SUBSTR(name, 3, :to) DESC, x ASC', [':to' => 4]));
907
908
        [$sql, $params] = $qb->build($query);
909
910
        $this->assertSame(
911
            DbHelper::replaceQuotes(
912
                <<<SQL
913
                SELECT * FROM [[operations]] ORDER BY SUBSTR(name, 3, :to) DESC, x ASC
914
                SQL,
915
                $db->getName(),
916
            ),
917
            $sql,
918
        );
919
        $this->assertSame([':to' => 4], $params);
920
    }
921
922
    public function testBuildWithQuery(): void
923
    {
924
        $db = $this->getConnection();
925
926
        $qb = $db->getQueryBuilder();
927
        $with1Query = (new query($db))->select('id')->from('t1')->where('expr = 1');
928
        $with2Query = (new query($db))->select('id')->from('t2')->innerJoin('a1', 't2.id = a1.id')->where('expr = 2');
929
        $with3Query = (new query($db))->select('id')->from('t3')->where('expr = 3');
930
        $query = (new query($db))
931
            ->withQuery($with1Query, 'a1')
932
            ->withQuery($with2Query->union($with3Query), 'a2')
933
            ->from('a2');
934
935
        [$sql, $params] = $qb->build($query);
936
937
        $this->assertSame(
938
            DbHelper::replaceQuotes(
939
                <<<SQL
940
                WITH a1 AS (SELECT [[id]] FROM [[t1]] WHERE expr = 1), a2 AS ((SELECT [[id]] FROM [[t2]] INNER JOIN [[a1]] ON t2.id = a1.id WHERE expr = 2) UNION ( SELECT [[id]] FROM [[t3]] WHERE expr = 3 )) SELECT * FROM [[a2]]
941
                SQL,
942
                $db->getName(),
943
            ),
944
            $sql,
945
        );
946
947
        $this->assertSame([], $params);
948
    }
949
950
    public function testBuildWithQueryRecursive(): void
951
    {
952
        $db = $this->getConnection();
953
954
        $qb = $db->getQueryBuilder();
955
        $with1Query = (new Query($db))->select('id')->from('t1')->where('expr = 1');
956
        $query = (new Query($db))->withQuery($with1Query, 'a1', true)->from('a1');
957
958
        [$sql, $params] = $qb->build($query);
959
960
        $this->assertSame(
961
            DbHelper::replaceQuotes(
962
                <<<SQL
963
                WITH RECURSIVE a1 AS (SELECT [[id]] FROM [[t1]] WHERE expr = 1) SELECT * FROM [[a1]]
964
                SQL,
965
                $db->getName(),
966
            ),
967
            $sql,
968
        );
969
        $this->assertSame([], $params);
970
    }
971
972
    public function testBuildWithSelectExpression(): void
973
    {
974
        $db = $this->getConnection();
975
976
        $qb = $db->getQueryBuilder();
977
        $query = (new Query($db))->select(new Expression('1 AS ab'))->from('tablename');
978
979
        [$sql, $params] = $qb->build($query);
980
981
        $this->assertSame(
982
            DbHelper::replaceQuotes(
983
                <<<SQL
984
                SELECT 1 AS ab FROM [[tablename]]
985
                SQL,
986
                $db->getName(),
987
            ),
988
            $sql,
989
        );
990
        $this->assertEmpty($params);
991
992
        $query = (new Query($db))
993
            ->select(new Expression('1 AS ab'))
994
            ->addSelect(new Expression('2 AS cd'))
995
            ->addSelect(['ef' => new Expression('3')])
996
            ->from('tablename');
997
998
        [$sql, $params] = $qb->build($query);
999
1000
        $this->assertSame(
1001
            DbHelper::replaceQuotes(
1002
                <<<SQL
1003
                SELECT 1 AS ab, 2 AS cd, 3 AS [[ef]] FROM [[tablename]]
1004
                SQL,
1005
                $db->getName(),
1006
            ),
1007
            $sql,
1008
        );
1009
        $this->assertEmpty($params);
1010
1011
        $query = (new Query($db))
1012
            ->select(new Expression('SUBSTR(name, 0, :len)', [':len' => 4]))
1013
            ->from('tablename');
1014
1015
        [$sql, $params] = $qb->build($query);
1016
1017
        $this->assertSame(
1018
            DbHelper::replaceQuotes(
1019
                <<<SQL
1020
                SELECT SUBSTR(name, 0, :len) FROM [[tablename]]
1021
                SQL,
1022
                $db->getName(),
1023
            ),
1024
            $sql,
1025
        );
1026
        $this->assertSame([':len' => 4], $params);
1027
    }
1028
1029
    public function testBuildWithSelectSubquery(): void
1030
    {
1031
        $db = $this->getConnection();
1032
1033
        $qb = $db->getQueryBuilder();
1034
        $subquery = (new Query($db))->select('COUNT(*)')->from('operations')->where('account_id = accounts.id');
1035
        $query = (new Query($db))->select('*')->from('accounts')->addSelect(['operations_count' => $subquery]);
1036
1037
        [$sql, $params] = $qb->build($query);
1038
1039
        $this->assertSame(
1040
            DbHelper::replaceQuotes(
1041
                <<<SQL
1042
                SELECT *, (SELECT COUNT(*) FROM [[operations]] WHERE account_id = accounts.id) AS [[operations_count]] FROM [[accounts]]
1043
                SQL,
1044
                $db->getName(),
1045
            ),
1046
            $sql,
1047
        );
1048
        $this->assertEmpty($params);
1049
    }
1050
1051
    public function testBuildWithSelectOption(): void
1052
    {
1053
        $db = $this->getConnection();
1054
1055
        $qb = $db->getQueryBuilder();
1056
        $query = (new Query($db))->selectOption('DISTINCT');
1057
1058
        [$sql, $params] = $qb->build($query);
1059
1060
        $this->assertSame(
1061
            <<<SQL
1062
            SELECT DISTINCT *
1063
            SQL,
1064
            $sql,
1065
        );
1066
        $this->assertSame([], $params);
1067
    }
1068
1069
    public function testBuildWithSetSeparator(): void
1070
    {
1071
        $db = $this->getConnection();
1072
1073
        $qb = $db->getQueryBuilder();
1074
        $qb->setSeparator(' ');
1075
1076
        [$sql, $params] = $qb->build((new Query($db))->select('*')->from('table'));
1077
1078
        $this->assertSame(
1079
            DbHelper::replaceQuotes(
1080
                <<<SQL
1081
                SELECT * FROM [[table]]
1082
                SQL,
1083
                $db->getName(),
1084
            ),
1085
            $sql
1086
        );
1087
        $this->assertEmpty($params);
1088
1089
        $qb->setSeparator("\n");
1090
        [$sql, $params] = $qb->build((new Query($db))->select('*')->from('table'));
1091
1092
        $this->assertSame(
1093
            DbHelper::replaceQuotes(
1094
                <<<SQL
1095
                SELECT *
1096
                FROM [[table]]
1097
                SQL,
1098
                $db->getName(),
1099
            ),
1100
            $sql,
1101
        );
1102
        $this->assertEmpty($params);
1103
    }
1104
1105
    /**
1106
     * This test contains three select queries connected with UNION and UNION ALL constructions.
1107
     */
1108
    public function testBuildWithUnion(): void
1109
    {
1110
        $db = $this->getConnection();
1111
1112
        $qb = $db->getQueryBuilder();
1113
1114
        $secondQuery = (new Query($db))->select('id')->from('TotalTotalExample t2')->where('w > 5');
1115
        $thirdQuery = (new Query($db))->select('id')->from('TotalTotalExample t3')->where('w = 3');
1116
        $firtsQuery = (new Query($db))
1117
            ->select('id')
1118
            ->from('TotalExample t1')
1119
            ->where(['and', 'w > 0', 'x < 2'])
1120
            ->union($secondQuery)
1121
            ->union($thirdQuery, true);
1122
1123
        [$sql, $params] = $qb->build($firtsQuery);
1124
1125
        $this->assertSame(
1126
            DbHelper::replaceQuotes(
1127
                <<<SQL
1128
                (SELECT [[id]] FROM [[TotalExample]] [[t1]] WHERE (w > 0) AND (x < 2)) UNION ( SELECT [[id]] FROM [[TotalTotalExample]] [[t2]] WHERE w > 5 ) UNION ALL ( SELECT [[id]] FROM [[TotalTotalExample]] [[t3]] WHERE w = 3 )
1129
                SQL,
1130
                $db->getName(),
1131
            ),
1132
            $sql,
1133
        );
1134
        $this->assertSame([], $params);
1135
    }
1136
1137
    /**
1138
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::buildWhereExists()
1139
     */
1140
    public function testBuildWithWhereExists(string $cond, string $expectedQuerySql): void
1141
    {
1142
        $db = $this->getConnection();
1143
1144
        $expectedQueryParams = [];
1145
1146
        $subQuery = new Query($db);
1147
        $subQuery->select('1')->from('Website w');
1148
        $query = new Query($db);
1149
        $query->select('id')->from('TotalExample t')->where([$cond, $subQuery]);
1150
1151
        [$actualQuerySql, $actualQueryParams] = $db->getQueryBuilder()->build($query);
1152
1153
        $this->assertSame($expectedQuerySql, $actualQuerySql);
1154
        $this->assertSame($expectedQueryParams, $actualQueryParams);
1155
    }
1156
1157
    public function testBuildWithWhereExistsArrayParameters(): void
1158
    {
1159
        $db = $this->getConnection();
1160
1161
        $qb = $db->getQueryBuilder();
1162
        $subQuery = (new query($db))
1163
            ->select('1')
1164
            ->from('Website w')
1165
            ->where('w.id = t.website_id')
1166
            ->andWhere(['w.merchant_id' => 6, 'w.user_id' => 210]);
1167
        $query = (new query($db))
1168
            ->select('id')
1169
            ->from('TotalExample t')
1170
            ->where(['exists', $subQuery])
1171
            ->andWhere(['t.some_column' => 'asd']);
1172
1173
        [$sql, $params] = $qb->build($query);
1174
1175
        $this->assertSame(
1176
            DbHelper::replaceQuotes(
1177
                <<<SQL
1178
                SELECT [[id]] FROM [[TotalExample]] [[t]] WHERE (EXISTS (SELECT [[1]] FROM [[Website]] [[w]] WHERE (w.id = t.website_id) AND (([[w]].[[merchant_id]]=:qp0) AND ([[w]].[[user_id]]=:qp1)))) AND ([[t]].[[some_column]]=:qp2)
1179
                SQL,
1180
                $db->getName(),
1181
            ),
1182
            $sql,
1183
        );
1184
        $this->assertSame([':qp0' => 6, ':qp1' => 210, ':qp2' => 'asd'], $params);
1185
    }
1186
1187
    public function testBuildWithWhereExistsWithParameters(): void
1188
    {
1189
        $db = $this->getConnection();
1190
1191
        $qb = $db->getQueryBuilder();
1192
        $subQuery = (new query($db))
1193
            ->select('1')
1194
            ->from('Website w')
1195
            ->where('w.id = t.website_id')
1196
            ->andWhere('w.merchant_id = :merchant_id', [':merchant_id' => 6]);
1197
        $query = (new query($db))
1198
            ->select('id')
1199
            ->from('TotalExample t')
1200
            ->where(['exists', $subQuery])
1201
            ->andWhere('t.some_column = :some_value', [':some_value' => 'asd']);
1202
1203
        [$sql, $params] = $qb->build($query);
1204
1205
        $this->assertSame(
1206
            DbHelper::replaceQuotes(
1207
                <<<SQL
1208
                SELECT [[id]] FROM [[TotalExample]] [[t]] WHERE (EXISTS (SELECT [[1]] FROM [[Website]] [[w]] WHERE (w.id = t.website_id) AND (w.merchant_id = :merchant_id))) AND (t.some_column = :some_value)
1209
                SQL,
1210
                $db->getName(),
1211
            ),
1212
            $sql,
1213
        );
1214
        $this->assertSame([':some_value' => 'asd', ':merchant_id' => 6], $params);
1215
    }
1216
1217
    public function testsCreateConditionFromArray(): void
1218
    {
1219
        $db = $this->getConnection();
1220
1221
        $qb = $db->getQueryBuilder();
1222
1223
        $condition = $qb->createConditionFromArray(['and', 'a = 1', 'b = 2']);
1224
1225
        $this->assertSame('AND', $condition->getOperator());
0 ignored issues
show
Bug introduced by
The method getOperator() does not exist on Yiisoft\Db\QueryBuilder\...face\ConditionInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Yiisoft\Db\QueryBuilder\...\HashConditionInterface or Yiisoft\Db\QueryBuilder\...e\NotConditionInterface or Yiisoft\Db\QueryBuilder\Condition\HashCondition or Yiisoft\Db\QueryBuilder\Condition\NotCondition. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1225
        $this->assertSame('AND', $condition->/** @scrutinizer ignore-call */ getOperator());
Loading history...
1226
        $this->assertSame(['a = 1', 'b = 2'], $condition->getExpressions());
0 ignored issues
show
Bug introduced by
The method getExpressions() does not exist on Yiisoft\Db\QueryBuilder\...face\ConditionInterface. It seems like you code against a sub-type of Yiisoft\Db\QueryBuilder\...face\ConditionInterface such as Yiisoft\Db\QueryBuilder\...ctionConditionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1226
        $this->assertSame(['a = 1', 'b = 2'], $condition->/** @scrutinizer ignore-call */ getExpressions());
Loading history...
1227
1228
        $condition = $qb->createConditionFromArray(['or', 'a = 1', 'b = 2']);
1229
1230
        $this->assertSame('OR', $condition->getOperator());
1231
        $this->assertSame(['a = 1', 'b = 2'], $condition->getExpressions());
1232
1233
        $condition = $qb->createConditionFromArray(['and', 'a = 1', ['or', 'b = 2', 'c = 3']]);
1234
1235
        $this->assertSame('AND', $condition->getOperator());
1236
        $this->assertSame(['a = 1', ['or', 'b = 2', 'c = 3']], $condition->getExpressions());
1237
1238
        $condition = $qb->createConditionFromArray(['or', 'a = 1', ['and', 'b = 2', 'c = 3']]);
1239
1240
        $this->assertSame('OR', $condition->getOperator());
1241
        $this->assertSame(['a = 1', ['and', 'b = 2', 'c = 3']], $condition->getExpressions());
1242
1243
        $condition = $qb->createConditionFromArray(['and', 'a = 1', ['or', 'b = 2', ['and', 'c = 3', 'd = 4']]]);
1244
1245
        $this->assertSame('AND', $condition->getOperator());
1246
        $this->assertSame(['a = 1', ['or', 'b = 2', ['and', 'c = 3', 'd = 4']]], $condition->getExpressions());
1247
1248
        $condition = $qb->createConditionFromArray(['or', 'a = 1', ['and', 'b = 2', ['or', 'c = 3', 'd = 4']]]);
1249
1250
        $this->assertSame('OR', $condition->getOperator());
1251
        $this->assertSame(['a = 1', ['and', 'b = 2', ['or', 'c = 3', 'd = 4']]], $condition->getExpressions());
1252
1253
        $condition = $qb->createConditionFromArray(
1254
            ['and', 'a = 1', ['or', 'b = 2', ['and', 'c = 3', ['or', 'd = 4', 'e = 5']]]]
1255
        );
1256
        $this->assertSame('AND', $condition->getOperator());
1257
        $this->assertSame(
1258
            ['a = 1', ['or', 'b = 2', ['and', 'c = 3', ['or', 'd = 4', 'e = 5']]]],
1259
            $condition->getExpressions(),
1260
        );
1261
    }
1262
1263
    /**
1264
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::createIndex()
1265
     */
1266
    public function testCreateIndex(string $sql, Closure $builder): void
1267
    {
1268
        $db = $this->getConnection();
1269
1270
        $qb = $db->getQueryBuilder();
1271
1272
        $this->assertSame($db->getQuoter()->quoteSql($sql), $builder($qb));
1273
    }
1274
1275
    public function testCreateTable(): void
1276
    {
1277
        $db = $this->getConnection();
1278
1279
        $qb = $db->getQueryBuilder();
1280
1281
        $this->assertSame(
1282
            DbHelper::replaceQuotes(
1283
                <<<SQL
1284
                CREATE TABLE [[test]] (
1285
                \t[[id]] pk,
1286
                \t[[name]] string(255) NOT NULL,
1287
                \t[[email]] string(255) NOT NULL,
1288
                \t[[status]] integer NOT NULL,
1289
                \t[[created_at]] datetime NOT NULL
1290
                )
1291
                SQL,
1292
                $db->getName(),
1293
            ),
1294
            $qb->createTable(
1295
                'test',
1296
                [
1297
                    'id' => 'pk',
1298
                    'name' => 'string(255) NOT NULL',
1299
                    'email' => 'string(255) NOT NULL',
1300
                    'status' => 'integer NOT NULL',
1301
                    'created_at' => 'datetime NOT NULL',
1302
                ],
1303
            ),
1304
        );
1305
    }
1306
1307
    public function testCreateView(): void
1308
    {
1309
        $db = $this->getConnection();
1310
1311
        $qb = $db->getQueryBuilder();
1312
1313
        $this->assertSame(
1314
            DbHelper::replaceQuotes(
1315
                <<<SQL
1316
                CREATE VIEW [[animal_view]] AS SELECT [[1]]
1317
                SQL,
1318
                $db->getName(),
1319
            ),
1320
            $qb->createView('animal_view', (new query($db))->select('1')),
1321
        );
1322
    }
1323
1324
    /**
1325
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::delete()
1326
     */
1327
    public function testDelete(string $table, array|string $condition, string $expectedSQL, array $expectedParams): void
1328
    {
1329
        $db = $this->getConnection();
1330
1331
        $qb = $db->getQueryBuilder();
1332
        $actualParams = [];
1333
        $actualSQL = $qb->delete($table, $condition, $actualParams);
1334
1335
        $this->assertSame($expectedSQL, $actualSQL);
1336
        $this->assertSame($expectedParams, $actualParams);
1337
    }
1338
1339
    public function testDropCheck(): void
1340
    {
1341
        $db = $this->getConnection();
1342
1343
        $qb = $db->getQueryBuilder();
1344
1345
        $this->assertSame(
1346
            DbHelper::replaceQuotes(
1347
                <<<SQL
1348
                ALTER TABLE [[T_constraints_1]] DROP CONSTRAINT [[CN_check]]
1349
                SQL,
1350
                $db->getName(),
1351
            ),
1352
            $qb->dropCheck('CN_check', 'T_constraints_1'),
1353
        );
1354
    }
1355
1356
    public function testDropColumn(): void
1357
    {
1358
        $db = $this->getConnection();
1359
1360
        $qb = $db->getQueryBuilder();
1361
1362
        $this->assertSame(
1363
            DbHelper::replaceQuotes(
1364
                <<<SQL
1365
                ALTER TABLE [[customer]] DROP COLUMN [[id]]
1366
                SQL,
1367
                $db->getName(),
1368
            ),
1369
            $qb->dropColumn('customer', 'id'),
1370
        );
1371
    }
1372
1373
    public function testDropCommentFromColumn(): void
1374
    {
1375
        $db = $this->getConnection(true);
1376
1377
        $qb = $db->getQueryBuilder();
1378
1379
        $this->assertSame(
1380
            DbHelper::replaceQuotes(
1381
                <<<SQL
1382
                COMMENT ON COLUMN [customer].[id] IS NULL
1383
                SQL,
1384
                $db->getName(),
1385
            ),
1386
            $qb->dropCommentFromColumn('customer', 'id'),
1387
        );
1388
    }
1389
1390
    public function testDropCommentFromTable(): void
1391
    {
1392
        $db = $this->getConnection();
1393
1394
        $qb = $db->getQueryBuilder();
1395
1396
        $this->assertSame(
1397
            DbHelper::replaceQuotes(
1398
                <<<SQL
1399
                COMMENT ON TABLE [[customer]] IS NULL
1400
                SQL,
1401
                $db->getName(),
1402
            ),
1403
            $qb->dropCommentFromTable('customer'),
1404
        );
1405
    }
1406
1407
    public function testDropDefaultValue(): void
1408
    {
1409
        $db = $this->getConnection(true);
1410
1411
        $qb = $db->getQueryBuilder();
1412
1413
        $this->assertSame(
1414
            DbHelper::replaceQuotes(
1415
                <<<SQL
1416
                ALTER TABLE [[T_constraints_1]] ALTER COLUMN [[C_default]] DROP DEFAULT
1417
                SQL,
1418
                $db->getName(),
1419
            ),
1420
            $qb->dropDefaultValue('CN_pk', 'T_constraints_1'),
1421
        );
1422
    }
1423
1424
    public function testDropForeignKey(): void
1425
    {
1426
        $db = $this->getConnection();
1427
1428
        $qb = $db->getQueryBuilder();
1429
1430
        $this->assertSame(
1431
            DbHelper::replaceQuotes(
1432
                <<<SQL
1433
                ALTER TABLE [[T_constraints_3]] DROP CONSTRAINT [[CN_constraints_3]]
1434
                SQL,
1435
                $db->getName(),
1436
            ),
1437
            $qb->dropForeignKey('CN_constraints_3', 'T_constraints_3'),
1438
        );
1439
    }
1440
1441
    public function testDropIndex(): void
1442
    {
1443
        $db = $this->getConnection();
1444
1445
        $qb = $db->getQueryBuilder();
1446
1447
        $this->assertSame(
1448
            DbHelper::replaceQuotes(
1449
                <<<SQL
1450
                DROP INDEX [[CN_constraints_2_single]] ON [[T_constraints_2]]
1451
                SQL,
1452
                $db->getName(),
1453
            ),
1454
            $qb->dropIndex('CN_constraints_2_single', 'T_constraints_2'),
1455
        );
1456
    }
1457
1458
    public function testDropPrimaryKey(): void
1459
    {
1460
        $db = $this->getConnection();
1461
1462
        $qb = $db->getQueryBuilder();
1463
1464
        $this->assertSame(
1465
            DbHelper::replaceQuotes(
1466
                <<<SQL
1467
                ALTER TABLE [[T_constraints_1]] DROP CONSTRAINT [[CN_pk]]
1468
                SQL,
1469
                $db->getName(),
1470
            ),
1471
            $qb->dropPrimaryKey('CN_pk', 'T_constraints_1'),
1472
        );
1473
    }
1474
1475
    public function testDropTable(): void
1476
    {
1477
        $db = $this->getConnection();
1478
1479
        $qb = $db->getQueryBuilder();
1480
1481
        $this->assertSame(
1482
            DbHelper::replaceQuotes(
1483
                <<<SQL
1484
                DROP TABLE [[customer]]
1485
                SQL,
1486
                $db->getName(),
1487
            ),
1488
            $qb->dropTable('customer'),
1489
        );
1490
    }
1491
1492
    public function testDropUnique(): void
1493
    {
1494
        $db = $this->getConnection();
1495
1496
        $qb = $db->getQueryBuilder();
1497
1498
        $this->assertSame(
1499
            DbHelper::replaceQuotes(
1500
                <<<SQL
1501
                DROP INDEX `test_uq_constraint` ON `test_uq`
1502
                SQL,
1503
                $db->getName(),
1504
            ),
1505
            $qb->dropUnique('test_uq_constraint', 'test_uq', ['int1']),
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Db\QueryBuilder\...Interface::dropUnique() has too many arguments starting with array('int1'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

1505
            $qb->/** @scrutinizer ignore-call */ 
1506
                 dropUnique('test_uq_constraint', 'test_uq', ['int1']),

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
1506
        );
1507
    }
1508
1509
    public function testDropView(): void
1510
    {
1511
        $db = $this->getConnection(true);
1512
1513
        $qb = $db->getQueryBuilder();
1514
1515
        $this->assertSame(
1516
            DbHelper::replaceQuotes(
1517
                <<<SQL
1518
                DROP VIEW [[animal_view]]
1519
                SQL,
1520
                $db->getName(),
1521
            ),
1522
            $qb->dropview('animal_view'),
1523
        );
1524
    }
1525
1526
    public function testGetColumnType(): void
1527
    {
1528
        $db = $this->getConnection();
1529
1530
        $qb = $db->getQueryBuilder();
1531
1532
        $this->assertSame('pk', $qb->getColumnType(Schema::TYPE_PK));
1533
        $this->assertSame('upk', $qb->getColumnType(Schema::TYPE_UPK));
1534
        $this->assertSame('bigpk', $qb->getColumnType(Schema::TYPE_BIGPK));
1535
        $this->assertSame('ubigpk', $qb->getColumnType(Schema::TYPE_UBIGPK));
1536
        $this->assertSame('char', $qb->getColumnType(Schema::TYPE_CHAR));
1537
        $this->assertSame('string', $qb->getColumnType(Schema::TYPE_STRING));
1538
        $this->assertSame('text', $qb->getColumnType(Schema::TYPE_TEXT));
1539
        $this->assertSame('tinyint', $qb->getColumnType(Schema::TYPE_TINYINT));
1540
        $this->assertSame('smallint', $qb->getColumnType(Schema::TYPE_SMALLINT));
1541
        $this->assertSame('integer', $qb->getColumnType(Schema::TYPE_INTEGER));
1542
        $this->assertSame('bigint', $qb->getColumnType(Schema::TYPE_BIGINT));
1543
        $this->assertSame('float', $qb->getColumnType(Schema::TYPE_FLOAT));
1544
        $this->assertSame('double', $qb->getColumnType(Schema::TYPE_DOUBLE));
1545
        $this->assertSame('decimal', $qb->getColumnType(Schema::TYPE_DECIMAL));
1546
        $this->assertSame('datetime', $qb->getColumnType(Schema::TYPE_DATETIME));
1547
        $this->assertSame('timestamp', $qb->getColumnType(Schema::TYPE_TIMESTAMP));
1548
        $this->assertSame('time', $qb->getColumnType(Schema::TYPE_TIME));
1549
        $this->assertSame('date', $qb->getColumnType(Schema::TYPE_DATE));
1550
        $this->assertSame('binary', $qb->getColumnType(Schema::TYPE_BINARY));
1551
        $this->assertSame('boolean', $qb->getColumnType(Schema::TYPE_BOOLEAN));
1552
        $this->assertSame('money', $qb->getColumnType(Schema::TYPE_MONEY));
1553
        $this->assertSame('json', $qb->getColumnType(Schema::TYPE_JSON));
1554
    }
1555
1556
    public function testGetExpressionBuilder(): void
1557
    {
1558
        $db = $this->getConnection();
1559
1560
        $qb = $db->getQueryBuilder();
1561
1562
        $simpleCondition = new SimpleCondition('a', '=', 1);
1563
1564
        $this->assertInstanceOf(
1565
            ExpressionBuilderInterface::class,
1566
            $qb->getExpressionBuilder($simpleCondition),
1567
        );
1568
    }
1569
1570
    /**
1571
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::insert()
1572
     */
1573
    public function testInsert(
1574
        string $table,
1575
        array|QueryInterface $columns,
1576
        array $params,
1577
        string $expectedSQL,
1578
        array $expectedParams
1579
    ): void {
1580
        $db = $this->getConnection();
1581
1582
        $qb = $db->getQueryBuilder();
1583
1584
        $this->assertSame($expectedSQL, $qb->insert($table, $columns, $params));
1585
        $this->assertSame($expectedParams, $params);
1586
    }
1587
1588
    /**
1589
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::insertEx()
1590
     */
1591
    public function testInsertEx(
1592
        string $table,
1593
        array|QueryInterface $columns,
1594
        array $params,
1595
        string $expectedSQL,
1596
        array $expectedParams
1597
    ): void {
1598
        $db = $this->getConnection(true);
1599
1600
        $qb = $db->getQueryBuilder();
1601
1602
        $this->assertSame($expectedSQL, $qb->insertEx($table, $columns, $params));
1603
        $this->assertSame($expectedParams, $params);
1604
    }
1605
1606
    public function testQuoter(): void
1607
    {
1608
        $db = $this->getConnection();
1609
1610
        $qb = $db->getQueryBuilder();
1611
1612
        $this->assertInstanceOf(QuoterInterface::class, $qb->quoter());
1613
    }
1614
1615
    public function testRenameColumn(): void
1616
    {
1617
        $db = $this->getConnection();
1618
1619
        $qb = $db->getQueryBuilder();
1620
        $sql = $qb->renameColumn('alpha', 'string_identifier', 'string_identifier_test');
1621
1622
        $this->assertSame(
1623
            DbHelper::replaceQuotes(
1624
                <<<SQL
1625
                ALTER TABLE [[alpha]] RENAME COLUMN [[string_identifier]] TO [[string_identifier_test]]
1626
                SQL,
1627
                $db->getName(),
1628
            ),
1629
            $sql,
1630
        );
1631
    }
1632
1633
    public function testRenameTable(): void
1634
    {
1635
        $db = $this->getConnection();
1636
1637
        $qb = $db->getQueryBuilder();
1638
        $sql = $qb->renameTable('alpha', 'alpha-test');
1639
1640
        $this->assertSame(
1641
            DbHelper::replaceQuotes(
1642
                <<<SQL
1643
                RENAME TABLE [[alpha]] TO [[alpha-test]]
1644
                SQL,
1645
                $db->getName(),
1646
            ),
1647
            $sql,
1648
        );
1649
    }
1650
1651
    public function testResetSequence(): void
1652
    {
1653
        $db = $this->getConnection(true);
1654
1655
        $qb = $db->getQueryBuilder();
1656
1657
        $this->assertSame(
1658
            <<<SQL
1659
            SELECT SETVAL('"item_id_seq"',(SELECT COALESCE(MAX("id"),0) FROM "item")+1,false)
1660
            SQL,
1661
            $qb->resetSequence('item'),
1662
        );
1663
1664
        $this->assertSame(
1665
            <<<SQL
1666
            SELECT SETVAL('"item_id_seq"',3,false)
1667
            SQL,
1668
            $qb->resetSequence('item', 3),
1669
        );
1670
    }
1671
1672
    /**
1673
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::selectExist()
1674
     */
1675
    public function testSelectExists(string $sql, string $expected): void
1676
    {
1677
        $db = $this->getConnection();
1678
1679
        $qb = $db->getQueryBuilder();
1680
        $sqlSelectExist = $qb->selectExists($sql);
1681
1682
        $this->assertSame($expected, $sqlSelectExist);
1683
    }
1684
1685
    public function testSelectExpression(): void
1686
    {
1687
        $db = $this->getConnection();
1688
1689
        $qb = $db->getQueryBuilder();
1690
        $query = (new Query($db))->select(new Expression('1 AS ab'))->from('tablename');
1691
1692
        [$sql, $params] = $qb->build($query);
1693
1694
        $expected = DbHelper::replaceQuotes(
1695
            <<<SQL
1696
            SELECT 1 AS ab FROM [[tablename]]
1697
            SQL,
1698
            $db->getName(),
1699
        );
1700
1701
        $this->assertSame($expected, $sql);
1702
        $this->assertEmpty($params);
1703
1704
        $query = (new Query($db))
1705
            ->select(new Expression('1 AS ab'))
1706
            ->addSelect(new Expression('2 AS cd'))
1707
            ->addSelect(['ef' => new Expression('3')])
1708
            ->from('tablename');
1709
1710
        [$sql, $params] = $qb->build($query);
1711
1712
        $expected = DbHelper::replaceQuotes(
1713
            <<<SQL
1714
            SELECT 1 AS ab, 2 AS cd, 3 AS [[ef]] FROM [[tablename]]
1715
            SQL,
1716
            $db->getName(),
1717
        );
1718
1719
        $this->assertSame($expected, $sql);
1720
        $this->assertEmpty($params);
1721
1722
        $query = (new Query($db))
1723
            ->select(new Expression('SUBSTR(name, 0, :len)', [':len' => 4]))
1724
            ->from('tablename');
1725
1726
        [$sql, $params] = $qb->build($query);
1727
1728
        $expected = DbHelper::replaceQuotes(
1729
            <<<SQL
1730
            SELECT SUBSTR(name, 0, :len) FROM [[tablename]]
1731
            SQL,
1732
            $db->getName(),
1733
        );
1734
1735
        $this->assertSame($expected, $sql);
1736
        $this->assertSame([':len' => 4], $params);
1737
    }
1738
1739
    public function testSelectSubquery(): void
1740
    {
1741
        $db = $this->getConnection();
1742
1743
        $qb = $db->getQueryBuilder();
1744
        $expected = DbHelper::replaceQuotes(
1745
            <<<SQL
1746
            SELECT *, (SELECT COUNT(*) FROM [[operations]] WHERE account_id = accounts.id) AS [[operations_count]] FROM [[accounts]]
1747
            SQL,
1748
            $db->getName(),
1749
        );
1750
        $subquery = (new Query($db))->select('COUNT(*)')->from('operations')->where('account_id = accounts.id');
1751
        $query = (new Query($db))->select('*')->from('accounts')->addSelect(['operations_count' => $subquery]);
1752
1753
        [$sql, $params] = $qb->build($query);
1754
1755
        $this->assertSame($expected, $sql);
1756
        $this->assertEmpty($params);
1757
    }
1758
1759
    public function testSetConditionClasses(): void
1760
    {
1761
        $db = $this->getConnection();
1762
1763
        $qb = $db->getQueryBuilder();
1764
        $qb->setConditionClasses(['stdClass' => stdClass::class]);
1765
        $dqlBuilder = Assert::getInaccessibleProperty($qb, 'dqlBuilder');
1766
        $conditionClasses = Assert::getInaccessibleProperty($dqlBuilder, 'conditionClasses');
1767
1768
        $this->assertSame(stdClass::class, $conditionClasses['stdClass']);
1769
    }
1770
1771
    public function testSetExpressionBuilder(): void
1772
    {
1773
        $db = $this->getConnection();
1774
1775
        $qb = $db->getQueryBuilder();
1776
        $qb->setExpressionBuilders(['stdClass' => stdClass::class]);
1777
        $dqlBuilder = Assert::getInaccessibleProperty($qb, 'dqlBuilder');
1778
        $expressionBuilders = Assert::getInaccessibleProperty($dqlBuilder, 'expressionBuilders');
1779
1780
        $this->assertSame(stdClass::class, $expressionBuilders['stdClass']);
1781
    }
1782
1783
    public function testSetSeparator(): void
1784
    {
1785
        $db = $this->getConnection();
1786
1787
        $qb = $db->getQueryBuilder();
1788
        $qb->setSeparator(' ');
1789
        [$sql, $params] = $qb->build((new Query($db))->select('*')->from('table'));
1790
1791
        $this->assertSame(
1792
            DbHelper::replaceQuotes(
1793
                <<<SQL
1794
                SELECT * FROM [[table]]
1795
                SQL,
1796
                $db->getName(),
1797
            ),
1798
            $sql
1799
        );
1800
        $this->assertEmpty($params);
1801
1802
        $qb->setSeparator("\n");
1803
        [$sql, $params] = $qb->build((new Query($db))->select('*')->from('table'));
1804
1805
        $this->assertSame(
1806
            DbHelper::replaceQuotes(
1807
                <<<SQL
1808
                SELECT *
1809
                FROM [[table]]
1810
                SQL,
1811
                $db->getName(),
1812
            ),
1813
            $sql,
1814
        );
1815
        $this->assertEmpty($params);
1816
    }
1817
1818
    public function testTruncateTable(): void
1819
    {
1820
        $db = $this->getConnection();
1821
1822
        $qb = $db->getQueryBuilder();
1823
        $sql = $qb->truncateTable('customer');
1824
1825
        $this->assertSame(
1826
            DbHelper::replaceQuotes(
1827
                <<<SQL
1828
                TRUNCATE TABLE [[customer]]
1829
                SQL,
1830
                $db->getName(),
1831
            ),
1832
            $sql,
1833
        );
1834
1835
        $sql = $qb->truncateTable('T_constraints_1');
1836
1837
        $this->assertSame(
1838
            DbHelper::replaceQuotes(
1839
                <<<SQL
1840
                TRUNCATE TABLE [[T_constraints_1]]
1841
                SQL,
1842
                $db->getName(),
1843
            ),
1844
            $sql,
1845
        );
1846
    }
1847
1848
    /**
1849
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::update()
1850
     */
1851
    public function testUpdate(
1852
        string $table,
1853
        array $columns,
1854
        array|string $condition,
1855
        string $expectedSQL,
1856
        array $expectedParams
1857
    ): void {
1858
        $db = $this->getConnection();
1859
1860
        $qb = $db->getQueryBuilder();
1861
        $actualParams = [];
1862
1863
        $this->assertSame($expectedSQL, $qb->update($table, $columns, $condition, $actualParams));
1864
        $this->assertSame($expectedParams, $actualParams);
1865
    }
1866
1867
    /**
1868
     * @dataProvider \Yiisoft\Db\Tests\Provider\QueryBuilderProvider::upsert()
1869
     */
1870
    public function testUpsert(
1871
        string $table,
1872
        array|QueryInterface $insertColumns,
1873
        array|bool $updateColumns,
1874
        string|array $expectedSQL,
1875
        array $expectedParams
1876
    ): void {
1877
        $db = $this->getConnection();
1878
1879
        $actualParams = [];
1880
        $actualSQL = $db->getQueryBuilder()->upsert($table, $insertColumns, $updateColumns, $actualParams);
1881
1882
        if (is_string($expectedSQL)) {
0 ignored issues
show
introduced by
The condition is_string($expectedSQL) is always false.
Loading history...
1883
            $this->assertSame($expectedSQL, $actualSQL);
1884
        } else {
1885
            $this->assertContains($actualSQL, $expectedSQL);
1886
        }
1887
1888
        if (ArrayHelper::isAssociative($expectedParams)) {
1889
            $this->assertSame($expectedParams, $actualParams);
1890
        } else {
1891
            Assert::isOneOf($actualParams, $expectedParams);
1892
        }
1893
    }
1894
}
1895