From 57b3823fb5c564a351539f38dbdf6c29ed79a32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Fri, 23 Feb 2024 22:59:38 +0100 Subject: [PATCH] wip --- .../Sqlite/debug-attach/SqlitePlatform.php | 7 +- .../debug-attach/SqliteSchemaManager.php | 77 +++++++++++++------ tests/RandomTest.php | 8 +- 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/Persistence/Sql/Sqlite/debug-attach/SqlitePlatform.php b/src/Persistence/Sql/Sqlite/debug-attach/SqlitePlatform.php index 7b20fc66c6..1bd1753a26 100644 --- a/src/Persistence/Sql/Sqlite/debug-attach/SqlitePlatform.php +++ b/src/Persistence/Sql/Sqlite/debug-attach/SqlitePlatform.php @@ -1097,7 +1097,12 @@ public function getAlterTableSQL(TableDiff $diff) $sql = []; $tableSql = []; if (! $this->onSchemaAlterTable($diff, $tableSql)) { - $dataTable = new Table('__temp__' . $table->getName()); + if (str_contains($table->getName(), '.')) { + $nameArr = explode('.', $table->getName(), 2); + $dataTable = new Table(/* $nameArr[0] . '.' . */ '__temp__' . $nameArr[1]); + } else { + $dataTable = new Table('__temp__' . $table->getName()); + } $newTable = new Table( $table->getQuotedName($this), diff --git a/src/Persistence/Sql/Sqlite/debug-attach/SqliteSchemaManager.php b/src/Persistence/Sql/Sqlite/debug-attach/SqliteSchemaManager.php index 45c5825905..7221ec8786 100644 --- a/src/Persistence/Sql/Sqlite/debug-attach/SqliteSchemaManager.php +++ b/src/Persistence/Sql/Sqlite/debug-attach/SqliteSchemaManager.php @@ -222,6 +222,31 @@ protected function _getPortableTableDefinition($table) return $table['table_name']; } + /** + * @return array{?string, string} + */ + public static function extractSchemaFromTableName(string $tableName, $fallbackDatabaseName = null): array + { + if (!str_contains($tableName, '.')) { + return [$fallbackDatabaseName, $tableName]; + } + + return explode('.', $tableName, 2); + } + + /** + * @return array{?string, string} + */ + public static function extractSchemaAsPrefixFromTableName(string $tableName, $fallbackDatabaseName = null): array + { + [$schemaName, $tableName] = self::extractSchemaFromTableName($tableName); + + return [ + ($schemaName ?? $fallbackDatabaseName) === null ? null : ($schemaName ?? $fallbackDatabaseName) . '.', + $tableName, + ]; + } + /** * {@inheritDoc} * @@ -231,8 +256,10 @@ protected function _getPortableTableIndexesList($tableIndexes, $tableName = null { $indexBuffer = []; + [$schemaPrefix, $tableName] = self::extractSchemaAsPrefixFromTableName($tableName); + // fetch primary - $indexArray = $this->_conn->fetchAllAssociative('SELECT * FROM PRAGMA_TABLE_INFO (?)', [$tableName]); + $indexArray = $this->_conn->fetchAllAssociative('SELECT * FROM ' . $schemaPrefix . 'PRAGMA_TABLE_INFO (?)', [$tableName]); usort( $indexArray, @@ -550,19 +577,21 @@ private function parseColumnCommentFromSQL(string $column, string $sql): ?string /** @throws Exception */ private function getCreateTableSQL(string $table): string { + [$schema, $table] = self::extractSchemaAsPrefixFromTableName($table); + $sql = $this->_conn->fetchOne( - <<<'SQL' + ' SELECT sql FROM ( SELECT * - FROM sqlite_master + FROM ' . $schema . 'sqlite_master UNION ALL SELECT * - FROM sqlite_temp_master + FROM temp.sqlite_master ) -WHERE type = 'table' +WHERE type = \'table\' AND name = ? -SQL +' , [$table], ); @@ -663,31 +692,33 @@ public function getSchemaSearchPaths() protected function selectTableNames(string $databaseName): Result { - $sql = <<<'SQL' + $sql = ' SELECT name AS table_name -FROM sqlite_master -WHERE type = 'table' - AND name != 'sqlite_sequence' - AND name != 'geometry_columns' - AND name != 'spatial_ref_sys' +FROM ' . $databaseName . '.sqlite_master +WHERE type = \'table\' + AND name != \'sqlite_sequence\' + AND name != \'geometry_columns\' + AND name != \'spatial_ref_sys\' UNION ALL SELECT name -FROM sqlite_temp_master -WHERE type = 'table' +FROM temp.sqlite_master +WHERE type = \'table\' ORDER BY name -SQL; +'; return $this->_conn->executeQuery($sql); } protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result { - $sql = <<<'SQL' + [$databaseName, $tableName] = self::extractSchemaAsPrefixFromTableName($tableName); + + $sql = ' SELECT t.name AS table_name, c.* - FROM sqlite_master t + FROM ' . $databaseName . 'sqlite_master t JOIN pragma_table_info(t.name) c -SQL; +'; $conditions = [ "t.type = 'table'", @@ -707,12 +738,14 @@ protected function selectTableColumns(string $databaseName, ?string $tableName = protected function selectIndexColumns(string $databaseName, ?string $tableName = null): Result { - $sql = <<<'SQL' + [$databaseName, $tableName] = self::extractSchemaAsPrefixFromTableName($tableName, $databaseName); + + $sql = ' SELECT t.name AS table_name, i.* - FROM sqlite_master t - JOIN pragma_index_list(t.name) i -SQL; + FROM ' . $databaseName . 'sqlite_master t + JOIN ' . $databaseName . 'pragma_index_list(t.name) i +'; $conditions = [ "t.type = 'table'", diff --git a/tests/RandomTest.php b/tests/RandomTest.php index fb6ebb4d80..61bf3f987c 100644 --- a/tests/RandomTest.php +++ b/tests/RandomTest.php @@ -591,7 +591,13 @@ public function testTableWithSchema(): void $this->createMigrator($user)->create(); $this->createMigrator($doc)->create(); $this->debug = true; - $this->createMigrator()->createForeignKey($doc->getReference('user_id')); + if (!$this->getDatabasePlatform() instanceof SQLitePlatform) { + $this->createMigrator()->createForeignKey($doc->getReference('user_id')); + } + // TODO once https://sqlite.org/forum/info/f8f0c1a1069bb40a is resolved + if (!$this->getDatabasePlatform() instanceof SQLitePlatform) { + $this->createMigrator()->createIndex([$doc->getField('user_id')], true); + } $user->createEntity() ->set('name', 'Sarah')