Skip to content

Commit

Permalink
Add support for renaming columns within a table
Browse files Browse the repository at this point in the history
SQLite introduced enhancements to the `ALTER TABLE` command in 3.25.0.
iOS 13.0+, macOS 10.15+, tvOS 13.0+, and watchOS 6.0+ have a SQLite
library bundled higher than 3.25.0.

For more information see https://www.sqlite.org/lang_altertable.html
  • Loading branch information
gjeck committed Jan 23, 2020
1 parent 349e34b commit e87e42d
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
34 changes: 34 additions & 0 deletions GRDB/QueryInterface/Schema/TableDefinition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,7 @@ public final class TableDefinition {
public final class TableAlteration {
private let name: String
private var addedColumns: [ColumnDefinition] = []
private var renamedColumns: [(oldColumn: ColumnDefinition, newColumn: ColumnDefinition)] = []

init(name: String) {
self.name = name
Expand All @@ -680,9 +681,42 @@ public final class TableAlteration {
addedColumns.append(column)
return column
}

#if !os(OSX)
/// Renames a column in a table.
///
/// try db.alter(table: "player") { t in
/// t.rename(column: "url", to: "home_url")
/// }
///
/// See https://www.sqlite.org/lang_altertable.html
///
/// - parameter name: the column name to rename.
/// - 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))
}
#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] = []
Expand Down
21 changes: 21 additions & 0 deletions Tests/GRDBTests/TableDefinitionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,27 @@ class TableDefinitionTests: GRDBTestCase {
assertEqualSQL(sqlQueries[sqlQueries.count - 1], "ALTER TABLE \"test\" ADD COLUMN \"e\"")
}
}

#if !os(OSX)
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)
func testAlterTableRenameColumn() throws {
let dbQueue = try makeDatabaseQueue()
try dbQueue.inDatabase { db in
try db.create(table: "test") { t in
t.column("a", .text)
}

sqlQueries.removeAll()
try db.alter(table: "test") { t in
t.rename(column: "a", to: "b")
t.add(column: "e")
}

assertEqualSQL(sqlQueries[sqlQueries.count - 2], "ALTER TABLE \"test\" RENAME COLUMN \"a\" TO \"b\"")
assertEqualSQL(sqlQueries[sqlQueries.count - 1], "ALTER TABLE \"test\" ADD COLUMN \"e\"")
}
}
#endif

func testDropTable() throws {
let dbQueue = try makeDatabaseQueue()
Expand Down

0 comments on commit e87e42d

Please sign in to comment.