Fix SQLite CommandTest skipped tests and minor fixes. (#20648)

This commit is contained in:
Wilmer Arambula
2025-10-29 11:51:58 -03:00
committed by GitHub
parent d1ecf2ec2a
commit ed6989d87b
2 changed files with 345 additions and 106 deletions

View File

@@ -741,10 +741,6 @@ SQL;
public function testAlterTable(): void public function testAlterTable(): void
{ {
if ($this->driverName === 'sqlite') {
$this->markTestSkipped('Sqlite does not support alterTable');
}
$db = $this->getConnection(); $db = $this->getConnection();
if ($db->getSchema()->getTableSchema('testAlterTable') !== null) { if ($db->getSchema()->getTableSchema('testAlterTable') !== null) {
@@ -1081,64 +1077,151 @@ SQL;
} }
*/ */
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<string> $pk
*/
public function testAddDropPrimaryKey(string $name, string $tableName, $pk): void
{ {
$db = $this->getConnection(false); $db = $this->getConnection(false);
$tableName = 'test_pk';
$name = 'test_pk_constraint';
/** @var \yii\db\pgsql\Schema $schema */
$schema = $db->getSchema(); $schema = $db->getSchema();
if ($schema->getTableSchema($tableName) !== null) { if ($schema->getTableSchema($tableName) !== null) {
$db->createCommand()->dropTable($tableName)->execute(); $db->createCommand()->dropTable($tableName)->execute();
} }
$db->createCommand()->createTable($tableName, [
$db->createCommand()->createTable(
$tableName,
[
'int1' => 'integer not null', 'int1' => 'integer not null',
'int2' => 'integer not null', 'int2' => 'integer not null',
])->execute(); ],
)->execute();
$this->assertNull($schema->getTablePrimaryKey($tableName, true)); $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(); $db->createCommand()->dropPrimaryKey($name, $tableName)->execute();
$this->assertNull($schema->getTablePrimaryKey($tableName, true)); $this->assertNull($schema->getTablePrimaryKey($tableName, true));
$db->createCommand()->addPrimaryKey($name, $tableName, ['int1', 'int2'])->execute(); $db->createCommand()->dropTable($tableName)->execute();
$this->assertEquals(['int1', 'int2'], $schema->getTablePrimaryKey($tableName, true)->columnNames);
} }
public function testAddDropForeignKey(): void 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',
],
],
];
}
/**
* @dataProvider addForeignKeyProvider
*
* @param string $name
* @param string $tableName
* @param array|string $fkColumns
* @param array|string $refColumns
*
* @phpstan-param list<string> $fkColumns
* @phpstan-param list<string> $refColumns
*/
public function testAddDropForeignKey(string $name, string $tableName, $fkColumns, $refColumns): void
{ {
$db = $this->getConnection(false); $db = $this->getConnection(false);
$tableName = 'test_fk';
$name = 'test_fk_constraint';
/** @var \yii\db\pgsql\Schema $schema */
$schema = $db->getSchema(); $schema = $db->getSchema();
if ($schema->getTableSchema($tableName) !== null) { if ($schema->getTableSchema($tableName) !== null) {
$db->createCommand()->dropTable($tableName)->execute(); $db->createCommand()->dropTable($tableName)->execute();
} }
$db->createCommand()->createTable($tableName, [
$db->createCommand()->createTable(
$tableName,
[
'int1' => 'integer not null unique', 'int1' => 'integer not null unique',
'int2' => 'integer not null unique', 'int2' => 'integer not null unique',
'int3' => 'integer not null unique', 'int3' => 'integer not null unique',
'int4' => 'integer not null unique', 'int4' => 'integer not null unique',
'unique ([[int1]], [[int2]])', 'unique ([[int1]], [[int2]])',
'unique ([[int3]], [[int4]])', 'unique ([[int3]], [[int4]])',
])->execute(); ],
)->execute();
$this->assertEmpty($schema->getTableForeignKeys($tableName, true)); $this->assertEmpty($schema->getTableForeignKeys($tableName, true));
$db->createCommand()->addForeignKey($name, $tableName, ['int1'], $tableName, ['int3'])->execute();
$this->assertEquals(['int1'], $schema->getTableForeignKeys($tableName, true)[0]->columnNames); $db->createCommand()->addForeignKey(
$this->assertEquals(['int3'], $schema->getTableForeignKeys($tableName, true)[0]->foreignColumnNames); $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(); $db->createCommand()->dropForeignKey($name, $tableName)->execute();
$this->assertEmpty($schema->getTableForeignKeys($tableName, true)); $this->assertEmpty($schema->getTableForeignKeys($tableName, true));
$db->createCommand()->addForeignKey($name, $tableName, ['int1', 'int2'], $tableName, ['int3', 'int4'])->execute(); $db->createCommand()->dropTable($tableName)->execute();
$this->assertEquals(['int1', 'int2'], $schema->getTableForeignKeys($tableName, true)[0]->columnNames);
$this->assertEquals(['int3', 'int4'], $schema->getTableForeignKeys($tableName, true)[0]->foreignColumnNames);
} }
public function testCreateDropIndex(): void public function testCreateDropIndex(): void
@@ -1185,54 +1268,96 @@ SQL;
$this->assertTrue($schema->getTableIndexes($tableName, true)[0]->isUnique); $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<string> $columns
*/
public function testAddDropUnique(string $name, string $tableName, $columns): void
{ {
$db = $this->getConnection(false); $db = $this->getConnection(false);
$tableName = 'test_uq';
$name = 'test_uq_constraint';
/** @var \yii\db\pgsql\Schema $schema */
$schema = $db->getSchema(); $schema = $db->getSchema();
if ($schema->getTableSchema($tableName) !== null) { if ($schema->getTableSchema($tableName) !== null) {
$db->createCommand()->dropTable($tableName)->execute(); $db->createCommand()->dropTable($tableName)->execute();
} }
$db->createCommand()->createTable($tableName, [
$db->createCommand()->createTable(
$tableName,
[
'int1' => 'integer not null', 'int1' => 'integer not null',
'int2' => 'integer not null', 'int2' => 'integer not null',
])->execute(); ],
)->execute();
$this->assertEmpty($schema->getTableUniques($tableName, true)); $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(); $db->createCommand()->dropUnique($name, $tableName)->execute();
$this->assertEmpty($schema->getTableUniques($tableName, true)); $this->assertEmpty($schema->getTableUniques($tableName, true));
$db->createCommand()->addUnique($name, $tableName, ['int1', 'int2'])->execute(); $db->createCommand()->dropTable($tableName)->execute();
$this->assertEquals(['int1', 'int2'], $schema->getTableUniques($tableName, true)[0]->columnNames);
} }
public function testAddDropCheck(): void public function testAddDropCheck(): void
{ {
$db = $this->getConnection(false); $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.'); $this->markTestSkipped('MySQL < 8.0.16 does not support CHECK constraints.');
} }
$tableName = 'test_ck'; $tableName = 'test_ck';
$name = 'test_ck_constraint'; $name = 'test_ck_constraint';
$schema = $db->getSchema(); $schema = $db->getSchema();
if ($schema->getTableSchema($tableName) !== null) { if ($schema->getTableSchema($tableName) !== null) {
$db->createCommand()->dropTable($tableName)->execute(); $db->createCommand()->dropTable($tableName)->execute();
} }
$db->createCommand()->createTable($tableName, [
'int1' => 'integer', $db->createCommand()->createTable(
])->execute(); $tableName,
['int1' => 'integer'],
)->execute();
$this->assertEmpty($schema->getTableChecks($tableName, true)); $this->assertEmpty($schema->getTableChecks($tableName, true));
$db->createCommand()->addCheck($name, $tableName, '[[int1]] > 1')->execute(); $db->createCommand()->addCheck($name, $tableName, '[[int1]] > 1')->execute();
$this->assertMatchesRegularExpression( $this->assertMatchesRegularExpression(
'/^.*int1.*>.*1.*$/', '/^.*int1.*>.*1.*$/',
$schema->getTableChecks($tableName, true)[0]->expression $schema->getTableChecks($tableName, true)[0]->expression

View File

@@ -8,6 +8,8 @@
namespace yiiunit\framework\db\sqlite; namespace yiiunit\framework\db\sqlite;
use yii\base\InvalidArgumentException;
use yii\base\NotSupportedException;
use yii\db\sqlite\Schema; use yii\db\sqlite\Schema;
/** /**
@@ -42,30 +44,80 @@ class CommandTest extends \yiiunit\framework\db\CommandTest
parent::testUpsert($firstData, $secondData); parent::testUpsert($firstData, $secondData);
} }
public function testAddDropPrimaryKey(): void /**
* @dataProvider addPrimaryKeyProvider
*
* @param string $name
* @param string $tableName
* @param array|string $pk
*
* @phpstan-param list<string> $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<string> $fkColumns
* @phpstan-param list<string> $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<string> $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 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 public function testMultiStatementSupport(): void
{ {
$db = $this->getConnection(false); $db = $this->getConnection(false);
$sql = <<<'SQL'
$sql = <<<SQL
DROP TABLE IF EXISTS {{T_multistatement}}; DROP TABLE IF EXISTS {{T_multistatement}};
CREATE TABLE {{T_multistatement}} ( CREATE TABLE {{T_multistatement}} (
[[intcol]] INTEGER, [[intcol]] INTEGER,
@@ -74,11 +126,17 @@ CREATE TABLE {{T_multistatement}} (
INSERT INTO {{T_multistatement}} VALUES(41, :val1); INSERT INTO {{T_multistatement}} VALUES(41, :val1);
INSERT INTO {{T_multistatement}} VALUES(42, :val2); INSERT INTO {{T_multistatement}} VALUES(42, :val2);
SQL; SQL;
$db->createCommand($sql, [
$db->createCommand(
$sql,
[
'val1' => 'foo', 'val1' => 'foo',
'val2' => 'bar', 'val2' => 'bar',
])->execute(); ],
$this->assertSame([ )->execute();
$this->assertSame(
[
[ [
'intcol' => '41', 'intcol' => '41',
'textcol' => 'foo', 'textcol' => 'foo',
@@ -87,22 +145,32 @@ SQL;
'intcol' => '42', 'intcol' => '42',
'textcol' => 'bar', 'textcol' => 'bar',
], ],
], $db->createCommand('SELECT * FROM {{T_multistatement}}')->queryAll()); ],
$sql = <<<'SQL' $db->createCommand('SELECT * FROM {{T_multistatement}}')->queryAll(),
);
$sql = <<<SQL
UPDATE {{T_multistatement}} SET [[intcol]] = :newInt WHERE [[textcol]] = :val1; UPDATE {{T_multistatement}} SET [[intcol]] = :newInt WHERE [[textcol]] = :val1;
DELETE FROM {{T_multistatement}} WHERE [[textcol]] = :val2; DELETE FROM {{T_multistatement}} WHERE [[textcol]] = :val2;
SELECT * FROM {{T_multistatement}} SELECT * FROM {{T_multistatement}}
SQL; SQL;
$this->assertSame([
$this->assertSame(
[
[ [
'intcol' => '410', 'intcol' => '410',
'textcol' => 'foo', 'textcol' => 'foo',
], ],
], $db->createCommand($sql, [ ],
$db->createCommand(
$sql,
[
'newInt' => 410, 'newInt' => 410,
'val1' => 'foo', 'val1' => 'foo',
'val2' => 'bar', 'val2' => 'bar',
])->queryAll()); ],
)->queryAll(),
);
} }
public static function batchInsertSqlProvider(): array public static function batchInsertSqlProvider(): array
@@ -153,19 +221,65 @@ SQL;
public function testResetSequenceExceptionTableNoExist(): void public function testResetSequenceExceptionTableNoExist(): void
{ {
$this->expectException('yii\base\InvalidArgumentException'); $this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Table not found: no_exist_table'); $this->expectExceptionMessage('Table not found: no_exist_table');
$db = $this->getConnection(); $db = $this->getConnection(false);
$db->createCommand()->resetSequence('no_exist_table', 5)->execute(); $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'."); $this->expectExceptionMessage("There is not sequence associated with table 'type'.");
$db = $this->getConnection(); $db = $this->getConnection(false);
$db->createCommand()->resetSequence('type', 5)->execute(); $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(),
);
}
}
} }