Skip to content

Commit 5de1420

Browse files
committed
Support ifNotExists
1 parent 673367b commit 5de1420

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

Sources/SQLite/Schema/SchemaChanger.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public class SchemaChanger: CustomStringConvertible {
4747
case dropColumn(String)
4848
case renameColumn(String, String)
4949
case renameTable(String)
50-
case createTable(columns: [ColumnDefinition])
50+
case createTable(columns: [ColumnDefinition], ifNotExists: Bool)
5151

5252
/// Returns non-nil if the operation can be executed with a simple SQL statement
5353
func toSQL(_ table: String, version: SQLiteVersion) -> String? {
@@ -64,8 +64,8 @@ public class SchemaChanger: CustomStringConvertible {
6464
return "ALTER TABLE \(table.quote()) RENAME COLUMN \(from.quote()) TO \(to.quote())"
6565
case .dropColumn(let column) where SQLiteFeature.dropColumn.isSupported(by: version):
6666
return "ALTER TABLE \(table.quote()) DROP COLUMN \(column.quote())"
67-
case .createTable(let columns):
68-
return "CREATE TABLE \(table.quote()) (" +
67+
case .createTable(let columns, let ifNotExists):
68+
return "CREATE TABLE \(ifNotExists ? " IF NOT EXISTS " : "") \(table.quote()) (" +
6969
columns.map { $0.toSQL() }.joined(separator: ", ") +
7070
")"
7171
default: return nil
@@ -125,9 +125,11 @@ public class SchemaChanger: CustomStringConvertible {
125125
fileprivate var indexDefinitions: [IndexDefinition] = []
126126

127127
let name: String
128+
let ifNotExists: Bool
128129

129-
init(name: String) {
130+
init(name: String, ifNotExists: Bool) {
130131
self.name = name
132+
self.ifNotExists = ifNotExists
131133
}
132134

133135
public func add(column: ColumnDefinition) {
@@ -141,7 +143,7 @@ public class SchemaChanger: CustomStringConvertible {
141143
var operations: [Operation] {
142144
precondition(!columnDefinitions.isEmpty)
143145
return [
144-
.createTable(columns: columnDefinitions)
146+
.createTable(columns: columnDefinitions, ifNotExists: ifNotExists)
145147
] + indexDefinitions.map { .addIndex($0) }
146148
}
147149
}
@@ -181,7 +183,7 @@ public class SchemaChanger: CustomStringConvertible {
181183
}
182184

183185
public func create(table: String, ifNotExists: Bool = false, block: CreateTableDefinitionBlock) throws {
184-
let createTableDefinition = CreateTableDefinition(name: table)
186+
let createTableDefinition = CreateTableDefinition(name: table, ifNotExists: ifNotExists)
185187
block(createTableDefinition)
186188

187189
for operation in createTableDefinition.operations {

Tests/SQLiteTests/Schema/SchemaChangerTests.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,26 @@ class SchemaChangerTests: SQLiteTestCase {
200200
IndexDefinition(table: "foo", name: "nameIndex", unique: true, columns: ["name"], where: nil, orders: nil)
201201
])
202202
}
203+
204+
func test_create_table_if_not_exists() throws {
205+
try schemaChanger.create(table: "foo") { table in
206+
table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER))
207+
}
208+
209+
try schemaChanger.create(table: "foo", ifNotExists: true) { table in
210+
table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER))
211+
}
212+
213+
XCTAssertThrowsError(
214+
try schemaChanger.create(table: "foo", ifNotExists: false) { table in
215+
table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER))
216+
}
217+
) { error in
218+
if case Result.error(_, let code, _) = error {
219+
XCTAssertEqual(code, 1)
220+
} else {
221+
XCTFail("unexpected error: \(error)")
222+
}
223+
}
224+
}
203225
}

0 commit comments

Comments
 (0)