From 538252a4bf83594f4b05372d436b93a0957d70fb Mon Sep 17 00:00:00 2001 From: gjeck Date: Thu, 23 Jan 2020 13:24:42 -0800 Subject: [PATCH] Allow column rename on custom sqlite target --- .../Schema/TableDefinition.swift | 68 ++++++++++--------- Tests/GRDBTests/TableDefinitionTests.swift | 10 +-- 2 files changed, 41 insertions(+), 37 deletions(-) diff --git a/GRDB/QueryInterface/Schema/TableDefinition.swift b/GRDB/QueryInterface/Schema/TableDefinition.swift index e95f7960d9..455a347352 100644 --- a/GRDB/QueryInterface/Schema/TableDefinition.swift +++ b/GRDB/QueryInterface/Schema/TableDefinition.swift @@ -656,8 +656,13 @@ public final class TableDefinition { /// See https://www.sqlite.org/lang_altertable.html public final class TableAlteration { private let name: String - private var addedColumns: [ColumnDefinition] = [] - private var renamedColumns: [(oldColumn: ColumnDefinition, newColumn: ColumnDefinition)] = [] + + private enum TableAlterationKind { + case add(ColumnDefinition) + case rename(old: String, new: String) + } + + private var alterations: [TableAlterationKind] = [] init(name: String) { self.name = name @@ -678,11 +683,11 @@ public final class TableAlteration { @discardableResult public func add(column name: String, _ type: Database.ColumnType? = nil) -> ColumnDefinition { let column = ColumnDefinition(name: name, type: type) - addedColumns.append(column) + alterations.append(.add(column)) return column } - #if !os(OSX) + #if !os(OSX) || GRDBCUSTOMSQLITE || GRDBCIPHER /// Renames a column in a table. /// /// try db.alter(table: "player") { t in @@ -695,43 +700,40 @@ public final class TableAlteration { /// - parameter newName: the new name of the column. @available(iOS 13.0, tvOS 13.0, watchOS 6.0, *) public func rename(column name: String, to newName: String) { - let old = ColumnDefinition(name: name, type: nil) - let new = ColumnDefinition(name: newName, type: nil) - renamedColumns.append((oldColumn: old, newColumn: new)) + alterations.append(.rename(old: name, new: newName)) } #endif fileprivate func sql(_ db: Database) throws -> String { var statements: [String] = [] - #if !os(OSX) - for (oldColumn, newColumn) in renamedColumns { - var chunks: [String] = [] - chunks.append("ALTER TABLE") - chunks.append(name.quotedDatabaseIdentifier) - chunks.append("RENAME COLUMN") - chunks.append(oldColumn.name.quotedDatabaseIdentifier) - chunks.append("TO") - chunks.append(newColumn.name.quotedDatabaseIdentifier) - let statement = chunks.joined(separator: " ") - statements.append(statement) - } - #endif - - for column in addedColumns { - var chunks: [String] = [] - chunks.append("ALTER TABLE") - chunks.append(name.quotedDatabaseIdentifier) - chunks.append("ADD COLUMN") - try chunks.append(column.sql(db, tableName: name, primaryKeyColumns: nil)) - let statement = chunks.joined(separator: " ") - statements.append(statement) - - if let indexDefinition = column.indexDefinition(in: name) { - statements.append(indexDefinition.sql()) + for alteration in alterations { + switch alteration { + case let .add(column): + var chunks: [String] = [] + chunks.append("ALTER TABLE") + chunks.append(name.quotedDatabaseIdentifier) + chunks.append("ADD COLUMN") + try chunks.append(column.sql(db, tableName: name, primaryKeyColumns: nil)) + let statement = chunks.joined(separator: " ") + statements.append(statement) + + if let indexDefinition = column.indexDefinition(in: name) { + statements.append(indexDefinition.sql()) + } + case let .rename(oldName, newName): + var chunks: [String] = [] + chunks.append("ALTER TABLE") + chunks.append(name.quotedDatabaseIdentifier) + chunks.append("RENAME COLUMN") + chunks.append(oldName.quotedDatabaseIdentifier) + chunks.append("TO") + chunks.append(newName.quotedDatabaseIdentifier) + let statement = chunks.joined(separator: " ") + statements.append(statement) } } - + return statements.joined(separator: "; ") } } diff --git a/Tests/GRDBTests/TableDefinitionTests.swift b/Tests/GRDBTests/TableDefinitionTests.swift index 6176c7b437..5566f82591 100644 --- a/Tests/GRDBTests/TableDefinitionTests.swift +++ b/Tests/GRDBTests/TableDefinitionTests.swift @@ -496,7 +496,7 @@ class TableDefinitionTests: GRDBTestCase { } } - #if !os(OSX) + #if !os(OSX) || GRDBCUSTOMSQLITE || GRDBCIPHER @available(iOS 13.0, tvOS 13.0, watchOS 6.0, *) func testAlterTableRenameColumn() throws { let dbQueue = try makeDatabaseQueue() @@ -508,11 +508,13 @@ class TableDefinitionTests: GRDBTestCase { sqlQueries.removeAll() try db.alter(table: "test") { t in t.rename(column: "a", to: "b") - t.add(column: "e") + t.add(column: "c") + t.rename(column: "c", to: "d") } - assertEqualSQL(sqlQueries[sqlQueries.count - 2], "ALTER TABLE \"test\" RENAME COLUMN \"a\" TO \"b\"") - assertEqualSQL(sqlQueries[sqlQueries.count - 1], "ALTER TABLE \"test\" ADD COLUMN \"e\"") + assertEqualSQL(sqlQueries[sqlQueries.count - 3], "ALTER TABLE \"test\" RENAME COLUMN \"a\" TO \"b\"") + assertEqualSQL(sqlQueries[sqlQueries.count - 2], "ALTER TABLE \"test\" ADD COLUMN \"c\"") + assertEqualSQL(sqlQueries[sqlQueries.count - 1], "ALTER TABLE \"test\" RENAME COLUMN \"c\" TO \"d\"") } } #endif