Passed
Pull Request — master (#380)
by Wilmer
03:09
created

AbstractCommandTest::testDropIndex()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 10
nc 1
nop 0
dl 0
loc 15
rs 9.9332
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Tests;
6
7
use PHPUnit\Framework\TestCase;
8
use Yiisoft\Cache\Dependency\TagDependency;
9
use Yiisoft\Db\Command\CommandInterface;
10
use Yiisoft\Db\Command\Param;
11
use Yiisoft\Db\Command\ParamInterface;
12
use Yiisoft\Db\Driver\PDO\ConnectionPDOInterface;
13
use Yiisoft\Db\Exception\Exception;
14
use Yiisoft\Db\Exception\InvalidCallException;
15
use Yiisoft\Db\Exception\InvalidConfigException;
16
use Yiisoft\Db\Exception\InvalidParamException;
17
use Yiisoft\Db\Exception\NotSupportedException;
18
use Yiisoft\Db\Expression\Expression;
19
use Yiisoft\Db\Query\Data\DataReader;
20
use Yiisoft\Db\Schema\Schema;
21
use Yiisoft\Db\Schema\SchemaBuilderTrait;
22
use Yiisoft\Db\Tests\Support\Assert;
23
use Yiisoft\Db\Tests\Support\DbHelper;
24
use Yiisoft\Db\Tests\Support\TestTrait;
25
26
abstract class AbstractCommandTest extends TestCase
27
{
28
    use SchemaBuilderTrait;
29
    use TestTrait;
30
31
    protected ConnectionPDOInterface $db;
32
    protected string $upsertTestCharCast = '';
33
34
    public function testAddCheck(): void
35
    {
36
        $db = $this->getConnection();
37
38
        $command = $db->createCommand();
39
        $sql = $command->addCheck('name', 'table', 'id > 0')->getSql();
40
41
42
        $this->assertSame(
43
            DbHelper::replaceQuotes(
44
                <<<SQL
45
                ALTER TABLE [[table]] ADD CONSTRAINT [[name]] CHECK (id > 0)
46
                SQL,
47
                $db->getName(),
48
            ),
49
            $sql,
50
        );
51
    }
52
53
    public function testAddColumn(): void
54
    {
55
        $db = $this->getConnection();
56
57
        $command = $db->createCommand();
58
        $sql = $command->addColumn('table', 'column', Schema::TYPE_INTEGER)->getSql();
59
60
        $this->assertSame(
61
            <<<SQL
62
            ALTER TABLE `table` ADD `column` integer
63
            SQL,
64
            $sql,
65
        );
66
    }
67
68
    public function testAddCommentOnColumn(): void
69
    {
70
        $db = $this->getConnectionWithData();
71
72
        $command = $db->createCommand();
73
        $sql = $command->addCommentOnColumn('customer', 'id', 'Primary key.')->getSql();
74
75
        $this->assertStringContainsString(
76
            DbHelper::replaceQuotes(
77
                <<<SQL
78
                COMMENT ON COLUMN [[customer]].[[id]] IS 'Primary key.'
79
                SQL,
80
                $db->getName(),
81
            ),
82
            $sql,
83
        );
84
    }
85
86
    public function testAddCommentOnTable(): void
87
    {
88
        $db = $this->getConnection();
89
90
        $command = $db->createCommand();
91
        $sql = $command->addCommentOnTable('table', 'comment')->getSql();
92
93
        $this->assertSame(
94
            DbHelper::replaceQuotes(
95
                <<<SQL
96
                COMMENT ON TABLE [[table]] IS 'comment'
97
                SQL,
98
                $db->getName(),
99
            ),
100
            $sql,
101
        );
102
    }
103
104
    public function testAddForeignKey(): void
105
    {
106
        $db = $this->getConnection();
107
108
        $command = $db->createCommand();
109
        $sql = $command->addForeignKey('name', 'table', 'column', 'ref_table', 'ref_column')->getSql();
110
111
        $this->assertSame(
112
            DbHelper::replaceQuotes(
113
                <<<SQL
114
                ALTER TABLE [[table]] ADD CONSTRAINT [[name]] FOREIGN KEY ([[column]]) REFERENCES [[ref_table]] ([[ref_column]])
115
                SQL,
116
                $db->getName(),
117
            ),
118
            $sql,
119
        );
120
121
        $sql = $command->addForeignKey('name', 'table', 'column', 'ref_table', 'ref_column', 'CASCADE')->getSql();
122
123
        $this->assertSame(
124
            DbHelper::replaceQuotes(
125
                <<<SQL
126
                ALTER TABLE [[table]] ADD CONSTRAINT [[name]] FOREIGN KEY ([[column]]) REFERENCES [[ref_table]] ([[ref_column]]) ON DELETE CASCADE
127
                SQL,
128
                $db->getName(),
129
            ),
130
            $sql,
131
        );
132
133
        $sql = $command
134
            ->addForeignKey('name', 'table', 'column', 'ref_table', 'ref_column', 'CASCADE', 'CASCADE')
135
            ->getSql();
136
137
        $this->assertSame(
138
            DbHelper::replaceQuotes(
139
                <<<SQL
140
                ALTER TABLE [[table]] ADD CONSTRAINT [[name]] FOREIGN KEY ([[column]]) REFERENCES [[ref_table]] ([[ref_column]]) ON DELETE CASCADE ON UPDATE CASCADE
141
                SQL,
142
                $db->getName(),
143
            ),
144
            $sql,
145
        );
146
    }
147
148
    public function testAddPrimaryKey(): void
149
    {
150
        $db = $this->getConnection();
151
152
        $command = $db->createCommand();
153
        $sql = $command->addPrimaryKey('name', 'table', 'column')->getSql();
154
155
156
        $this->assertSame(
157
            DbHelper::replaceQuotes(
158
                <<<SQL
159
                ALTER TABLE [[table]] ADD CONSTRAINT [[name]] PRIMARY KEY ([[column]])
160
                SQL,
161
                $db->getName(),
162
            ),
163
            $sql,
164
        );
165
166
        $sql = $command->addPrimaryKey('name', 'table', ['column1', 'column2'])->getSql();
167
168
169
        $this->assertSame(
170
            DbHelper::replaceQuotes(
171
                <<<SQL
172
                ALTER TABLE [[table]] ADD CONSTRAINT [[name]] PRIMARY KEY ([[column1]], [[column2]])
173
                SQL,
174
                $db->getName(),
175
            ),
176
            $sql,
177
        );
178
    }
179
180
    public function testAddUnique(): void
181
    {
182
        $db = $this->getConnection();
183
184
        $command = $db->createCommand();
185
        $sql = $command->addUnique('name', 'table', 'column')->getSql();
186
187
        $this->assertSame(
188
            DbHelper::replaceQuotes(
189
                <<<SQL
190
                ALTER TABLE [[table]] ADD CONSTRAINT [[name]] UNIQUE ([[column]])
191
                SQL,
192
                $db->getName(),
193
            ),
194
            $sql,
195
        );
196
197
        $sql = $command->addUnique('name', 'table', ['column1', 'column2'])->getSql();
198
199
        $this->assertSame(
200
            DbHelper::replaceQuotes(
201
                <<<SQL
202
                ALTER TABLE [[table]] ADD CONSTRAINT [[name]] UNIQUE ([[column1]], [[column2]])
203
                SQL,
204
                $db->getName(),
205
            ),
206
            $sql,
207
        );
208
    }
209
210
    public function testAlterColumn(): void
211
    {
212
        $db = $this->getConnection();
213
214
        $command = $db->createCommand();
215
        $sql = $command->alterColumn('table', 'column', Schema::TYPE_INTEGER)->getSql();
216
217
        $this->assertSame(
218
            <<<SQL
219
            ALTER TABLE `table` CHANGE `column` `column` integer
220
            SQL,
221
            $sql,
222
        );
223
    }
224
225
    public function testBindValues(): void
226
    {
227
        $db = $this->getConnection();
228
229
        $command = $db->createCommand();
230
231
        $values = ['int' => 1, 'string' => 'str'];
232
        $command->bindValues($values);
233
        $bindedValues = $command->getParams(false);
234
235
        $this->assertIsArray($bindedValues);
236
        $this->assertContainsOnlyInstancesOf(ParamInterface::class, $bindedValues);
237
        $this->assertCount(2, $bindedValues);
238
239
        $param = new Param('str', 99);
240
        $command->bindValues(['param' => $param]);
241
        $bindedValues = $command->getParams(false);
242
243
        $this->assertIsArray($bindedValues);
244
        $this->assertContainsOnlyInstancesOf(ParamInterface::class, $bindedValues);
245
        $this->assertCount(3, $bindedValues);
246
        $this->assertSame($param, $bindedValues['param']);
247
        $this->assertNotEquals($param, $bindedValues['int']);
248
249
        /* Replace test */
250
        $command->bindValues(['int' => $param]);
251
        $bindedValues = $command->getParams(false);
252
253
        $this->assertIsArray($bindedValues);
254
        $this->assertContainsOnlyInstancesOf(ParamInterface::class, $bindedValues);
255
        $this->assertCount(3, $bindedValues);
256
        $this->assertSame($param, $bindedValues['int']);
257
    }
258
259
    public function testCache(): void
260
    {
261
        $db = $this->getConnection();
262
263
        $tagDependency = new TagDependency('tag');
264
        $command = $db->createCommand();
265
        $command->cache(100, $tagDependency);
266
267
        $this->assertInstanceOf(CommandInterface::class, $command);
268
        $this->assertSame(100, Assert::getInaccessibleProperty($command, 'queryCacheDuration'));
269
        $this->assertSame($tagDependency, Assert::getInaccessibleProperty($command, 'queryCacheDependency'));
270
    }
271
272
    public function testConstruct(): void
273
    {
274
        $db = $this->getConnection();
275
276
        $command = $db->createCommand();
277
278
        $this->assertEmpty($command->getSql());
279
280
        $sql = <<<SQL
281
        SELECT * FROM customer WHERE name=:name
282
        SQL;
283
        $command = $db->createCommand($sql, [':name' => 'John']);
284
285
        $this->assertSame($sql, $command->getSql());
286
        $this->assertSame([':name' => 'John'], $command->getParams());
287
    }
288
289
    /**
290
     * @dataProvider \Yiisoft\Db\Tests\Provider\CommandProvider::createIndex()
291
     */
292
    public function testCreateIndex(
293
        string $name,
294
        string $table,
295
        array|string $column,
296
        string $indexType,
297
        string $indexMethod,
298
        string $expected,
299
    ): void {
300
        $db = $this->getConnection();
301
302
        $command = $db->createCommand();
303
304
        $sql = $command->createIndex($name, $table, $column, $indexType, $indexMethod)->getSql();
305
306
        $this->assertSame($expected, $sql);
307
    }
308
309
    public function testCreateView(): void
310
    {
311
        $db = $this->getConnection();
312
313
        $command = $db->createCommand();
314
315
        $sql = $command->createView(
316
            'view',
317
            <<<SQL
318
            SELECT * FROM table
319
            SQL,
320
        )->getSql();
321
322
        $this->assertSame(
323
            DbHelper::replaceQuotes(
324
                <<<SQL
325
                CREATE VIEW [[view]] AS SELECT * FROM table
326
                SQL,
327
                $db->getName(),
328
            ),
329
            $sql,
330
        );
331
    }
332
333
    public function testDataReaderCreationException(): void
334
    {
335
        $db = $this->getConnection();
336
337
        $this->expectException(InvalidParamException::class);
338
        $this->expectExceptionMessage('The PDOStatement cannot be null.');
339
340
        $sql = 'SELECT * FROM {{customer}}';
341
        new DataReader($db->createCommand($sql));
342
    }
343
344
    public function testDelete(): void
345
    {
346
        $db = $this->getConnection();
347
348
        $command = $db->createCommand();
349
        $sql = $command->delete('table', ['column' => 'value'])->getSql();
350
351
        $this->assertSame(
352
            DbHelper::replaceQuotes(
353
                <<<SQL
354
                DELETE FROM [[table]] WHERE [[column]]=:qp0
355
                SQL,
356
                $db->getName(),
357
            ),
358
            $sql,
359
        );
360
    }
361
362
    public function testDropCheck(): void
363
    {
364
        $db = $this->getConnection();
365
366
        $command = $db->createCommand();
367
        $sql = $command->dropCheck('name', 'table')->getSql();
368
369
        $this->assertSame(
370
            DbHelper::replaceQuotes(
371
                <<<SQL
372
                ALTER TABLE [[table]] DROP CONSTRAINT [[name]]
373
                SQL,
374
                $db->getName(),
375
            ),
376
            $sql,
377
        );
378
    }
379
380
    public function testDropColumn(): void
381
    {
382
        $db = $this->getConnection();
383
384
        $command = $db->createCommand();
385
        $sql = $command->dropColumn('table', 'column')->getSql();
386
387
        $this->assertSame(
388
            DbHelper::replaceQuotes(
389
                <<<SQL
390
                ALTER TABLE [[table]] DROP COLUMN [[column]]
391
                SQL,
392
                $db->getName(),
393
            ),
394
            $sql,
395
        );
396
    }
397
398
    public function testDropCommentFromColumn(): void
399
    {
400
        $db = $this->getConnection();
401
402
        $command = $db->createCommand();
403
        $sql = $command->dropCommentFromColumn('table', 'column')->getSql();
404
405
        $this->assertSame(
406
            DbHelper::replaceQuotes(
407
                <<<SQL
408
                COMMENT ON COLUMN [[table]].[[column]] IS NULL
409
                SQL,
410
                $db->getName(),
411
            ),
412
            $sql,
413
        );
414
    }
415
416
    public function testDropCommentFromTable(): void
417
    {
418
        $db = $this->getConnection();
419
420
        $command = $db->createCommand();
421
        $sql = $command->dropCommentFromTable('table')->getSql();
422
423
        $this->assertSame(
424
            DbHelper::replaceQuotes(
425
                <<<SQL
426
                COMMENT ON TABLE [[table]] IS NULL
427
                SQL,
428
                $db->getName(),
429
            ),
430
            $sql,
431
        );
432
    }
433
434
    public function testDropForeingKey(): void
435
    {
436
        $db = $this->getConnection();
437
438
        $command = $db->createCommand();
439
        $sql = $command->dropForeignKey('name', 'table')->getSql();
440
441
        $this->assertSame(
442
            DbHelper::replaceQuotes(
443
                <<<SQL
444
                ALTER TABLE [[table]] DROP CONSTRAINT [[name]]
445
                SQL,
446
                $db->getName(),
447
            ),
448
            $sql,
449
        );
450
    }
451
452
    public function testDropIndex(): void
453
    {
454
        $db = $this->getConnection();
455
456
        $command = $db->createCommand();
457
        $sql = $command->dropIndex('name', 'table')->getSql();
458
459
        $this->assertSame(
460
            DbHelper::replaceQuotes(
461
                <<<SQL
462
                DROP INDEX [[name]] ON [[table]]
463
                SQL,
464
                $db->getName(),
465
            ),
466
            $sql,
467
        );
468
    }
469
470
    public function testDropPrimaryKey(): void
471
    {
472
        $db = $this->getConnection();
473
474
        $command = $db->createCommand();
475
        $sql = $command->dropPrimaryKey('name', 'table')->getSql();
476
477
        $this->assertSame(
478
            DbHelper::replaceQuotes(
479
                <<<SQL
480
                ALTER TABLE [[table]] DROP CONSTRAINT [[name]]
481
                SQL,
482
                $db->getName(),
483
            ),
484
            $sql,
485
        );
486
    }
487
488
    public function testDropTable(): void
489
    {
490
        $db = $this->getConnection();
491
492
        $command = $db->createCommand();
493
        $sql = $command->dropTable('table')->getSql();
494
495
        $this->assertSame(
496
            DbHelper::replaceQuotes(
497
                <<<SQL
498
                DROP TABLE [[table]]
499
                SQL,
500
                $db->getName(),
501
            ),
502
            $sql,
503
        );
504
    }
505
506
    public function testDropView(): void
507
    {
508
        $db = $this->getConnection();
509
510
        $command = $db->createCommand();
511
        $sql = $command->dropView('view')->getSql();
512
513
        $this->assertSame(
514
            DbHelper::replaceQuotes(
515
                <<<SQL
516
                DROP VIEW [[view]]
517
                SQL,
518
                $db->getName(),
519
            ),
520
            $sql,
521
        );
522
    }
523
524
    public function testDropUnique(): void
525
    {
526
        $db = $this->getConnection();
527
528
        $command = $db->createCommand();
529
        $sql = $command->dropUnique('name', 'table')->getSql();
530
531
        $this->assertSame(
532
            DbHelper::replaceQuotes(
533
                <<<SQL
534
                ALTER TABLE [[table]] DROP CONSTRAINT [[name]]
535
                SQL,
536
                $db->getName(),
537
            ),
538
            $sql,
539
        );
540
    }
541
542
    public function testExecuteWithSqlEmtpy(): void
543
    {
544
        $db = $this->getConnection();
545
546
        $command = $db->createCommand();
547
548
        $this->assertSame(0, $command->execute());
549
    }
550
551
    public function testGetParams(): void
552
    {
553
        $db = $this->getConnection();
554
555
        $command = $db->createCommand();
556
        $values = [
557
            'int' => 1,
558
            'string' => 'str',
559
        ];
560
        $command->bindValues($values);
561
        $bindedValues = $command->getParams(false);
562
563
        $this->assertIsArray($bindedValues);
564
        $this->assertContainsOnlyInstancesOf(ParamInterface::class, $bindedValues);
565
        $this->assertCount(2, $bindedValues);
566
567
        $param = new Param('str', 99);
568
        $command->bindValues(['param' => $param]);
569
        $bindedValues = $command->getParams(false);
570
571
        $this->assertIsArray($bindedValues);
572
        $this->assertContainsOnlyInstancesOf(ParamInterface::class, $bindedValues);
573
        $this->assertCount(3, $bindedValues);
574
        $this->assertEquals($param, $bindedValues['param']);
575
        $this->assertNotEquals($param, $bindedValues['int']);
576
577
        /* Replace test */
578
        $command->bindValues(['int' => $param]);
579
        $bindedValues = $command->getParams(false);
580
581
        $this->assertIsArray($bindedValues);
582
        $this->assertContainsOnlyInstancesOf(ParamInterface::class, $bindedValues);
583
        $this->assertCount(3, $bindedValues);
584
        $this->assertEquals($param, $bindedValues['int']);
585
    }
586
587
    /**
588
     * Test command getRawSql.
589
     *
590
     * @dataProvider \Yiisoft\Db\Tests\Provider\CommandProvider::rawSql()
591
     *
592
     * @throws Exception
593
     * @throws InvalidConfigException
594
     * @throws NotSupportedException
595
     *
596
     * {@see https://github.com/yiisoft/yii2/issues/8592}
597
     */
598
    public function testGetRawSql(string $sql, array $params, string $expectedRawSql): void
599
    {
600
        $db = $this->getConnection();
601
602
        $command = $db->createCommand($sql, $params);
603
604
        $this->assertSame($expectedRawSql, $command->getRawSql());
605
    }
606
607
    public function testGetSetSql(): void
608
    {
609
        $db = $this->getConnection();
610
611
        $sql = <<<SQL
612
        SELECT * FROM customer
613
        SQL;
614
        $command = $db->createCommand($sql);
615
        $this->assertSame($sql, $command->getSql());
616
617
        $sql2 = <<<SQL
618
        SELECT * FROM order
619
        SQL;
620
        $command->setSql($sql2);
621
        $this->assertSame($sql2, $command->getSql());
622
    }
623
624
    public function testLastInsertIdException(): void
625
    {
626
        $db = $this->getConnection();
627
628
        $db->close();
629
630
        $this->expectException(InvalidCallException::class);
631
632
        $db->getLastInsertID();
633
    }
634
635
    public function testNoCache(): void
636
    {
637
        $db = $this->getConnection();
638
639
        $command = $db->createCommand()->noCache();
640
641
        $this->assertSame(-1, Assert::getInaccessibleProperty($command, 'queryCacheDuration'));
642
        $this->assertInstanceOf(CommandInterface::class, $command);
643
    }
644
645
    public function testPrepareCancel(): void
646
    {
647
        $db = $this->getConnectionWithData();
648
649
        $command = $db->createCommand(
650
            <<<SQL
651
            SELECT * FROM {{customer}}
652
            SQL
653
        );
654
655
        $this->assertNull($command->getPdoStatement());
656
657
        $command->prepare();
658
659
        $this->assertNotNull($command->getPdoStatement());
660
661
        $command->cancel();
662
663
        $this->assertNull($command->getPdoStatement());
0 ignored issues
show
Bug introduced by
Are you sure the usage of $command->getPdoStatement() targeting Yiisoft\Db\Driver\PDO\Co...dPDO::getPdoStatement() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
664
    }
665
666
    public function testRenameColumn(): void
667
    {
668
        $db = $this->getConnection();
669
670
        $sql = $db->createCommand()->renameColumn('table', 'oldname', 'newname')->getSql();
671
672
        $this->assertSame(
673
            <<<SQL
674
            ALTER TABLE `table` RENAME COLUMN `oldname` TO `newname`
675
            SQL,
676
            $sql,
677
        );
678
    }
679
680
    public function testSetRawSql(): void
681
    {
682
        $db = $this->getConnection();
683
684
        $command = $db->createCommand();
685
        $command->setRawSql(
686
            <<<SQL
687
            SELECT 123
688
            SQL
689
        );
690
691
        $this->assertSame('SELECT 123', $command->getRawSql());
692
    }
693
694
    public function testSetRetryHandler(): void
695
    {
696
        $db = $this->getConnection();
697
698
        $command = $db->createCommand();
699
700
        $handler = static fn (): bool => true;
701
702
        Assert::invokeMethod($command, 'setRetryHandler', [$handler]);
703
704
        $this->assertSame($handler, Assert::getInaccessibleProperty($command, 'retryHandler'));
705
    }
706
707
    public function testTruncateTable(): void
708
    {
709
        $db = $this->getConnectionWithData();
710
711
        $command = $db->createCommand();
712
        $sql = $command->truncateTable('table')->getSql();
713
714
        $this->assertSame(
715
            <<<SQL
716
            TRUNCATE TABLE `table`
717
            SQL,
718
            $sql,
719
        );
720
    }
721
722
    protected function performAndCompareUpsertResult(ConnectionPDOInterface $db, array $data): void
723
    {
724
        $params = $data['params'];
725
        $expected = $data['expected'] ?? $params[1];
726
727
        $command = $db->createCommand();
728
        call_user_func_array([$command, 'upsert'], $params);
729
        $command->execute();
730
731
        $actual = $this->getQuery($db)
732
            ->select(['email', 'address' => new Expression($this->upsertTestCharCast), 'status'])
733
            ->from('T_upsert')
734
            ->one();
735
        $this->assertEquals($expected, $actual, $this->upsertTestCharCast);
736
    }
737
}
738