From 150fa23552845b45dbdb5cc36544d7f477784e5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 5 Apr 2024 18:23:42 +0200 Subject: [PATCH] Fix unwanted SQLite schema emulation in SqliteSchemaManager --- psalm.xml.dist | 3 ++ src/Platforms/SqlitePlatform.php | 2 +- src/Schema/SqliteSchemaManager.php | 12 +++-- .../Schema/SqliteSchemaManagerTest.php | 54 +++++++++++++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/psalm.xml.dist b/psalm.xml.dist index 31e4a8b6638..d685b545c1a 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -519,6 +519,9 @@ + + + diff --git a/src/Platforms/SqlitePlatform.php b/src/Platforms/SqlitePlatform.php index ea9a4441326..75f5141ec92 100644 --- a/src/Platforms/SqlitePlatform.php +++ b/src/Platforms/SqlitePlatform.php @@ -908,7 +908,7 @@ public function getTemporaryTableName($tableName) */ public function canEmulateSchemas() { - Deprecation::trigger( + Deprecation::triggerIfCalledFromOutside( 'doctrine/dbal', 'https://github.com/doctrine/dbal/pull/4805', 'SqlitePlatform::canEmulateSchemas() is deprecated.', diff --git a/src/Schema/SqliteSchemaManager.php b/src/Schema/SqliteSchemaManager.php index 84361ae8286..2693758d77a 100644 --- a/src/Schema/SqliteSchemaManager.php +++ b/src/Schema/SqliteSchemaManager.php @@ -704,7 +704,9 @@ protected function selectTableColumns(string $databaseName, ?string $tableName = if ($tableName !== null) { $conditions[] = 't.name = ?'; - $params[] = str_replace('.', '__', $tableName); + $params[] = $this->_platform->canEmulateSchemas() + ? str_replace('.', '__', $tableName) + : $tableName; } $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY t.name, c.cid'; @@ -729,7 +731,9 @@ protected function selectIndexColumns(string $databaseName, ?string $tableName = if ($tableName !== null) { $conditions[] = 't.name = ?'; - $params[] = str_replace('.', '__', $tableName); + $params[] = $this->_platform->canEmulateSchemas() + ? str_replace('.', '__', $tableName) + : $tableName; } $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY t.name, i.seq'; @@ -755,7 +759,9 @@ protected function selectForeignKeyColumns(string $databaseName, ?string $tableN if ($tableName !== null) { $conditions[] = 't.name = ?'; - $params[] = str_replace('.', '__', $tableName); + $params[] = $this->_platform->canEmulateSchemas() + ? str_replace('.', '__', $tableName) + : $tableName; } $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY t.name, p.id DESC, p.seq'; diff --git a/tests/Functional/Schema/SqliteSchemaManagerTest.php b/tests/Functional/Schema/SqliteSchemaManagerTest.php index 2bfd0927001..55a2ef86455 100644 --- a/tests/Functional/Schema/SqliteSchemaManagerTest.php +++ b/tests/Functional/Schema/SqliteSchemaManagerTest.php @@ -10,8 +10,11 @@ use Doctrine\DBAL\Types\BlobType; use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Types; +use ReflectionMethod; +use function array_map; use function array_shift; +use function assert; use function dirname; class SqliteSchemaManagerTest extends SchemaManagerFunctionalTestCase @@ -371,4 +374,55 @@ public function testShorthandInForeignKeyReferenceWithMultipleColumns(): void $createTableTrackSql, ); } + + public function testListTableNoSchemaEmulation(): void + { + $databasePlatform = $this->connection->getDatabasePlatform(); + assert($databasePlatform instanceof SqlitePlatform); + $databasePlatform->disableSchemaEmulation(); + + $this->dropTableIfExists('`list_table_no_schema_emulation.test`'); + + $this->connection->executeStatement(<<<'DDL' + CREATE TABLE `list_table_no_schema_emulation.test` ( + id INTEGER, + parent_id INTEGER, + PRIMARY KEY (id), + FOREIGN KEY (parent_id) REFERENCES `list_table_no_schema_emulation.test` (id) + ); + DDL); + + $this->connection->executeStatement(<<<'DDL' + CREATE INDEX i ON `list_table_no_schema_emulation.test` (parent_id); + DDL); + + $schemaManager = $this->schemaManager; + $refl = new ReflectionMethod($schemaManager, 'selectTableColumns'); + $refl->setAccessible(true); + $res = $refl->invoke($schemaManager, 'main', 'list_table_no_schema_emulation.test') + ->fetchAllAssociative(); + + self::assertSame([ + ['list_table_no_schema_emulation.test', 'id'], + ['list_table_no_schema_emulation.test', 'parent_id'], + ], array_map(static fn (array $row) => [$row['table_name'], $row['name']], $res)); + + $refl = new ReflectionMethod($schemaManager, 'selectIndexColumns'); + $refl->setAccessible(true); + $res = $refl->invoke($schemaManager, 'main', 'list_table_no_schema_emulation.test') + ->fetchAllAssociative(); + + self::assertSame([ + ['list_table_no_schema_emulation.test', 'i'], + ], array_map(static fn (array $row) => [$row['table_name'], $row['name']], $res)); + + $refl = new ReflectionMethod($schemaManager, 'selectForeignKeyColumns'); + $refl->setAccessible(true); + $res = $refl->invoke($schemaManager, 'main', 'list_table_no_schema_emulation.test') + ->fetchAllAssociative(); + + self::assertSame([ + ['list_table_no_schema_emulation.test', 'parent_id', 'id'], + ], array_map(static fn (array $row) => [$row['table_name'], $row['from'], $row['to']], $res)); + } }