diff --git a/tests/framework/db/CommandTest.php b/tests/framework/db/CommandTest.php index 8fb0bdb4178..8b67da243be 100644 --- a/tests/framework/db/CommandTest.php +++ b/tests/framework/db/CommandTest.php @@ -741,10 +741,6 @@ public function testCreateTable(): void public function testAlterTable(): void { - if ($this->driverName === 'sqlite') { - $this->markTestSkipped('Sqlite does not support alterTable'); - } - $db = $this->getConnection(); if ($db->getSchema()->getTableSchema('testAlterTable') !== null) { @@ -1081,64 +1077,151 @@ public function testRenameColumn() } */ - public function testAddDropPrimaryKey(): void + public static function addPrimaryKeyProvider(): array + { + return [ + [ + '{{test_pk_constraint_1}}', + '{{test_pk}}', + 'int1', + ], + [ + '{{test_pk_constraint_2}}', + '{{test_pk}}', + ['int1'], + ], + [ + '{{test_pk_constraint_3}}', + '{{test_pk}}', + [ + 'int1', + 'int2', + ], + ], + ]; + } + + /** + * @dataProvider addPrimaryKeyProvider + * + * @param string $name + * @param string $tableName + * @param array|string $pk + * + * @phpstan-param list $pk + */ + public function testAddDropPrimaryKey(string $name, string $tableName, $pk): void { $db = $this->getConnection(false); - $tableName = 'test_pk'; - $name = 'test_pk_constraint'; - /** @var \yii\db\pgsql\Schema $schema */ + $schema = $db->getSchema(); if ($schema->getTableSchema($tableName) !== null) { $db->createCommand()->dropTable($tableName)->execute(); } - $db->createCommand()->createTable($tableName, [ - 'int1' => 'integer not null', - 'int2' => 'integer not null', - ])->execute(); + + $db->createCommand()->createTable( + $tableName, + [ + 'int1' => 'integer not null', + 'int2' => 'integer not null', + ], + )->execute(); $this->assertNull($schema->getTablePrimaryKey($tableName, true)); - $db->createCommand()->addPrimaryKey($name, $tableName, ['int1'])->execute(); - $this->assertEquals(['int1'], $schema->getTablePrimaryKey($tableName, true)->columnNames); + + $db->createCommand()->addPrimaryKey($name, $tableName, $pk)->execute(); + + $this->assertSame((array) $pk, $schema->getTablePrimaryKey($tableName, true)->columnNames); $db->createCommand()->dropPrimaryKey($name, $tableName)->execute(); + $this->assertNull($schema->getTablePrimaryKey($tableName, true)); - $db->createCommand()->addPrimaryKey($name, $tableName, ['int1', 'int2'])->execute(); - $this->assertEquals(['int1', 'int2'], $schema->getTablePrimaryKey($tableName, true)->columnNames); + $db->createCommand()->dropTable($tableName)->execute(); + } + + public static function addForeignKeyProvider(): array + { + return [ + [ + '{{test_fk_constraint_1}}', + '{{test_fk}}', + 'int1', + 'int3', + ], + [ + '{{test_fk_constraint_2}}', + '{{test_fk}}', + ['int1'], + ['int3'], + ], + [ + '{{test_fk_constraint_3}}', + '{{test_fk}}', + [ + 'int1', + 'int2', + ], + [ + 'int3', + 'int4', + ], + ], + ]; } - public function testAddDropForeignKey(): void + /** + * @dataProvider addForeignKeyProvider + * + * @param string $name + * @param string $tableName + * @param array|string $fkColumns + * @param array|string $refColumns + * + * @phpstan-param list $fkColumns + * @phpstan-param list $refColumns + */ + public function testAddDropForeignKey(string $name, string $tableName, $fkColumns, $refColumns): void { $db = $this->getConnection(false); - $tableName = 'test_fk'; - $name = 'test_fk_constraint'; - /** @var \yii\db\pgsql\Schema $schema */ + $schema = $db->getSchema(); if ($schema->getTableSchema($tableName) !== null) { $db->createCommand()->dropTable($tableName)->execute(); } - $db->createCommand()->createTable($tableName, [ - 'int1' => 'integer not null unique', - 'int2' => 'integer not null unique', - 'int3' => 'integer not null unique', - 'int4' => 'integer not null unique', - 'unique ([[int1]], [[int2]])', - 'unique ([[int3]], [[int4]])', - ])->execute(); + + $db->createCommand()->createTable( + $tableName, + [ + 'int1' => 'integer not null unique', + 'int2' => 'integer not null unique', + 'int3' => 'integer not null unique', + 'int4' => 'integer not null unique', + 'unique ([[int1]], [[int2]])', + 'unique ([[int3]], [[int4]])', + ], + )->execute(); $this->assertEmpty($schema->getTableForeignKeys($tableName, true)); - $db->createCommand()->addForeignKey($name, $tableName, ['int1'], $tableName, ['int3'])->execute(); - $this->assertEquals(['int1'], $schema->getTableForeignKeys($tableName, true)[0]->columnNames); - $this->assertEquals(['int3'], $schema->getTableForeignKeys($tableName, true)[0]->foreignColumnNames); + + $db->createCommand()->addForeignKey( + $name, + $tableName, + (array) $fkColumns, + $tableName, + (array) $refColumns, + )->execute(); + + $this->assertSame((array) $fkColumns, $schema->getTableForeignKeys($tableName, true)[0]->columnNames); + $this->assertSame((array) $refColumns, $schema->getTableForeignKeys($tableName, true)[0]->foreignColumnNames); $db->createCommand()->dropForeignKey($name, $tableName)->execute(); + $this->assertEmpty($schema->getTableForeignKeys($tableName, true)); - $db->createCommand()->addForeignKey($name, $tableName, ['int1', 'int2'], $tableName, ['int3', 'int4'])->execute(); - $this->assertEquals(['int1', 'int2'], $schema->getTableForeignKeys($tableName, true)[0]->columnNames); - $this->assertEquals(['int3', 'int4'], $schema->getTableForeignKeys($tableName, true)[0]->foreignColumnNames); + $db->createCommand()->dropTable($tableName)->execute(); } public function testCreateDropIndex(): void @@ -1185,54 +1268,96 @@ public function testCreateDropIndex(): void $this->assertTrue($schema->getTableIndexes($tableName, true)[0]->isUnique); } - public function testAddDropUnique(): void + public static function addUniqueProvider(): array + { + return [ + [ + '{{test_unique_constraint_1}}', + '{{test_unique}}', + 'int1', + ], + [ + '{{test_unique_constraint_2}}', + '{{test_unique}}', + ['int1'], + ], + [ + '{{test_unique_constraint_3}}', + '{{test_unique}}', + [ + 'int1', + 'int2', + ], + ], + ]; + } + + /** + * @dataProvider addUniqueProvider + * + * @param string $name + * @param string $tableName + * @param array|string $columns + * + * @phpstan-param list $columns + */ + public function testAddDropUnique(string $name, string $tableName, $columns): void { $db = $this->getConnection(false); - $tableName = 'test_uq'; - $name = 'test_uq_constraint'; - /** @var \yii\db\pgsql\Schema $schema */ + $schema = $db->getSchema(); if ($schema->getTableSchema($tableName) !== null) { $db->createCommand()->dropTable($tableName)->execute(); } - $db->createCommand()->createTable($tableName, [ - 'int1' => 'integer not null', - 'int2' => 'integer not null', - ])->execute(); + + $db->createCommand()->createTable( + $tableName, + [ + 'int1' => 'integer not null', + 'int2' => 'integer not null', + ], + )->execute(); $this->assertEmpty($schema->getTableUniques($tableName, true)); - $db->createCommand()->addUnique($name, $tableName, ['int1'])->execute(); - $this->assertEquals(['int1'], $schema->getTableUniques($tableName, true)[0]->columnNames); + + $db->createCommand()->addUnique($name, $tableName, $columns)->execute(); + + $this->assertSame((array) $columns, $schema->getTableUniques($tableName, true)[0]->columnNames); $db->createCommand()->dropUnique($name, $tableName)->execute(); + $this->assertEmpty($schema->getTableUniques($tableName, true)); - $db->createCommand()->addUnique($name, $tableName, ['int1', 'int2'])->execute(); - $this->assertEquals(['int1', 'int2'], $schema->getTableUniques($tableName, true)[0]->columnNames); + $db->createCommand()->dropTable($tableName)->execute(); } public function testAddDropCheck(): void { $db = $this->getConnection(false); - if (version_compare($db->getServerVersion(), '8.0.16', '<')) { + if ($db->getDriverName() === 'mysql' && version_compare($db->getServerVersion(), '8.0.16', '<')) { $this->markTestSkipped('MySQL < 8.0.16 does not support CHECK constraints.'); } $tableName = 'test_ck'; $name = 'test_ck_constraint'; + $schema = $db->getSchema(); if ($schema->getTableSchema($tableName) !== null) { $db->createCommand()->dropTable($tableName)->execute(); } - $db->createCommand()->createTable($tableName, [ - 'int1' => 'integer', - ])->execute(); + + $db->createCommand()->createTable( + $tableName, + ['int1' => 'integer'], + )->execute(); $this->assertEmpty($schema->getTableChecks($tableName, true)); + $db->createCommand()->addCheck($name, $tableName, '[[int1]] > 1')->execute(); + $this->assertMatchesRegularExpression( '/^.*int1.*>.*1.*$/', $schema->getTableChecks($tableName, true)[0]->expression diff --git a/tests/framework/db/sqlite/CommandTest.php b/tests/framework/db/sqlite/CommandTest.php index 2d697b6b077..08cd0ea4481 100644 --- a/tests/framework/db/sqlite/CommandTest.php +++ b/tests/framework/db/sqlite/CommandTest.php @@ -8,6 +8,8 @@ namespace yiiunit\framework\db\sqlite; +use yii\base\InvalidArgumentException; +use yii\base\NotSupportedException; use yii\db\sqlite\Schema; /** @@ -42,67 +44,133 @@ public function testUpsert(array $firstData, array $secondData): void parent::testUpsert($firstData, $secondData); } - public function testAddDropPrimaryKey(): void + /** + * @dataProvider addPrimaryKeyProvider + * + * @param string $name + * @param string $tableName + * @param array|string $pk + * + * @phpstan-param list $pk + */ + public function testAddDropPrimaryKey(string $name, string $tableName, $pk): void { - $this->markTestSkipped('SQLite does not support adding/dropping primary keys.'); + $this->expectException(NotSupportedException::class); + $this->expectExceptionMessageMatches( + '/^.*::(addPrimaryKey|dropPrimaryKey) is not supported by SQLite\.$/', + ); + + parent::testAddDropPrimaryKey($name, $tableName, $pk); } - public function testAddDropForeignKey(): void + /** + * @dataProvider addForeignKeyProvider + * + * @param string $name + * @param string $tableName + * @param array|string $fkColumns + * @param array|string $refColumns + * + * @phpstan-param list $fkColumns + * @phpstan-param list $refColumns + */ + public function testAddDropForeignKey(string $name, string $tableName, $fkColumns, $refColumns): void { - $this->markTestSkipped('SQLite does not support adding/dropping foreign keys.'); + $this->expectException(NotSupportedException::class); + $this->expectExceptionMessageMatches( + '/^.*::(addForeignKey|dropForeignKey) is not supported by SQLite\.$/', + ); + + parent::testAddDropForeignKey($name, $tableName, $fkColumns, $refColumns); } - public function testAddDropUnique(): void + /** + * @dataProvider addUniqueProvider + * + * @param string $name + * @param string $tableName + * @param array|string $columns + * + * @phpstan-param list $columns + */ + public function testAddDropUnique(string $name, string $tableName, $columns): void { - $this->markTestSkipped('SQLite does not support adding/dropping unique constraints.'); + $this->expectException(NotSupportedException::class); + $this->expectExceptionMessageMatches( + '/^.*::(addUnique|dropUnique) is not supported by SQLite\.$/', + ); + + parent::testAddDropUnique($name, $tableName, $columns); } public function testAddDropCheck(): void { - $this->markTestSkipped('SQLite does not support adding/dropping check constraints.'); + $this->expectException(NotSupportedException::class); + $this->expectExceptionMessageMatches( + '/^.*::(addCheck|dropCheck) is not supported by SQLite\.$/', + ); + + parent::testAddDropCheck(); } public function testMultiStatementSupport(): void { $db = $this->getConnection(false); - $sql = <<<'SQL' -DROP TABLE IF EXISTS {{T_multistatement}}; -CREATE TABLE {{T_multistatement}} ( - [[intcol]] INTEGER, - [[textcol]] TEXT -); -INSERT INTO {{T_multistatement}} VALUES(41, :val1); -INSERT INTO {{T_multistatement}} VALUES(42, :val2); -SQL; - $db->createCommand($sql, [ - 'val1' => 'foo', - 'val2' => 'bar', - ])->execute(); - $this->assertSame([ + + $sql = <<createCommand( + $sql, [ - 'intcol' => '41', - 'textcol' => 'foo', + 'val1' => 'foo', + 'val2' => 'bar', ], + )->execute(); + + $this->assertSame( [ - 'intcol' => '42', - 'textcol' => 'bar', + [ + 'intcol' => '41', + 'textcol' => 'foo', + ], + [ + 'intcol' => '42', + 'textcol' => 'bar', + ], ], - ], $db->createCommand('SELECT * FROM {{T_multistatement}}')->queryAll()); - $sql = <<<'SQL' -UPDATE {{T_multistatement}} SET [[intcol]] = :newInt WHERE [[textcol]] = :val1; -DELETE FROM {{T_multistatement}} WHERE [[textcol]] = :val2; -SELECT * FROM {{T_multistatement}} -SQL; - $this->assertSame([ + $db->createCommand('SELECT * FROM {{T_multistatement}}')->queryAll(), + ); + + $sql = <<assertSame( [ - 'intcol' => '410', - 'textcol' => 'foo', + [ + 'intcol' => '410', + 'textcol' => 'foo', + ], ], - ], $db->createCommand($sql, [ - 'newInt' => 410, - 'val1' => 'foo', - 'val2' => 'bar', - ])->queryAll()); + $db->createCommand( + $sql, + [ + 'newInt' => 410, + 'val1' => 'foo', + 'val2' => 'bar', + ], + )->queryAll(), + ); } public static function batchInsertSqlProvider(): array @@ -153,19 +221,65 @@ public function testResetSequence(): void public function testResetSequenceExceptionTableNoExist(): void { - $this->expectException('yii\base\InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Table not found: no_exist_table'); - $db = $this->getConnection(); + $db = $this->getConnection(false); $db->createCommand()->resetSequence('no_exist_table', 5)->execute(); } - public function testResetSequenceExceptionSquenceNoExist(): void + public function testResetSequenceExceptionSequenceNoExist(): void { - $this->expectException('yii\base\InvalidArgumentException'); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage("There is not sequence associated with table 'type'."); - $db = $this->getConnection(); + $db = $this->getConnection(false); $db->createCommand()->resetSequence('type', 5)->execute(); } + + public function testAlterTable(): void + { + $this->expectException(NotSupportedException::class); + $this->expectExceptionMessage( + 'yii\db\sqlite\QueryBuilder::alterColumn is not supported by SQLite.', + ); + + $db = $this->getConnection(false); + $db->createCommand()->alterColumn('table1', 'column1', 'INTEGER')->execute(); + } + + public function testAddDropDefaultValue(): void + { + $db = $this->getConnection(false); + + try { + $db->createCommand()->addDefaultValue( + 'test_def_constraint', + 'test_def', + 'int1', + 41, + )->execute(); + + $this->fail("Expected 'NotSupportedException' for 'addDefaultValue' not thrown."); + } catch (NotSupportedException $e) { + $this->assertStringContainsString( + 'yii\db\sqlite\QueryBuilder::addDefaultValue is not supported by SQLite.', + $e->getMessage(), + ); + } + + try { + $db->createCommand()->dropDefaultValue( + 'test_def_constraint', + 'test_def', + )->execute(); + + $this->fail("Expected 'NotSupportedException' for 'dropDefaultValue' not thrown."); + } catch (NotSupportedException $e) { + $this->assertStringContainsString( + 'yii\db\sqlite\QueryBuilder::dropDefaultValue is not supported by SQLite.', + $e->getMessage(), + ); + } + } }