Skip to content

Commit a6a151b

Browse files
committed
Reuse SQLiteFeature in SchemaChanger
1 parent 2fc0dec commit a6a151b

File tree

6 files changed

+37
-30
lines changed

6 files changed

+37
-30
lines changed

Sources/SQLite/Core/SQLiteFeature.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@ import Foundation
33
enum SQLiteFeature {
44
case partialIntegrityCheck // PRAGMA integrity_check(table)
55
case sqliteSchemaTable // sqlite_master => sqlite_schema
6+
case renameColumn // ALTER TABLE ... RENAME COLUMN
7+
case dropColumn // ALTER TABLE ... DROP COLUMN
68

79
func isSupported(by version: SQLiteVersion) -> Bool {
810
switch self {
911
case .partialIntegrityCheck, .sqliteSchemaTable:
10-
return version > SQLiteVersion(major: 3, minor: 33)
12+
return version >= .init(major: 3, minor: 33)
13+
case .renameColumn:
14+
return version >= .init(major: 3, minor: 25)
15+
case .dropColumn:
16+
return version >= .init(major: 3, minor: 35)
1117
}
1218
}
1319
}

Sources/SQLite/Schema/Connection+Schema.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Foundation
22

33
public extension Connection {
4-
var schemaReader: SchemaReader { SchemaReader(connection: self) }
4+
var schema: SchemaReader { SchemaReader(connection: self) }
55

66
// There are four columns in each result row.
77
// The first column is the name of the table that
@@ -14,7 +14,7 @@ public extension Connection {
1414
// https://sqlite.org/pragma.html#pragma_foreign_key_check
1515
func foreignKeyCheck(table: String? = nil) throws -> [ForeignKeyError] {
1616
try run("PRAGMA foreign_key_check" + (table.map { "(\($0.quote()))" } ?? ""))
17-
.compactMap { row -> ForeignKeyError? in
17+
.compactMap { (row: [Binding?]) -> ForeignKeyError? in
1818
guard let table = row[0] as? String,
1919
let rowId = row[1] as? Int64,
2020
let target = row[2] as? String else { return nil }

Sources/SQLite/Schema/SchemaChanger.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public class SchemaChanger: CustomStringConvertible {
5252
switch self {
5353
case .addColumn(let definition):
5454
return "ALTER TABLE \(table.quote()) ADD COLUMN \(definition.toSQL())"
55-
case .renameColumn(let from, let to) where version >= .init(major: 3, minor: 25):
55+
case .renameColumn(let from, let to) where SQLiteFeature.renameColumn.isSupported(by: version):
5656
return "ALTER TABLE \(table.quote()) RENAME COLUMN \(from.quote()) TO \(to.quote())"
57-
case .dropColumn(let column) where version >= .init(major: 3, minor: 35):
57+
case .dropColumn(let column) where SQLiteFeature.dropColumn.isSupported(by: version):
5858
return "ALTER TABLE \(table.quote()) DROP COLUMN \(column.quote())"
5959
default: return nil
6060
}
@@ -128,7 +128,7 @@ public class SchemaChanger: CustomStringConvertible {
128128

129129
init(connection: Connection, version: SQLiteVersion) {
130130
self.connection = connection
131-
schemaReader = connection.schemaReader
131+
schemaReader = connection.schema
132132
self.version = version
133133
}
134134

Sources/SQLite/Schema/SchemaDefinitions.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,9 @@ public struct IndexDefinition: Equatable {
245245
}
246246

247247
func orders(sql: String) -> [String: IndexDefinition.Order] {
248-
IndexDefinition.orderRe.matches(in: sql, range: NSRange(location: 0, length: sql.count))
249-
.reduce([String: IndexDefinition.Order]()) { (memo, result) in
248+
IndexDefinition.orderRe
249+
.matches(in: sql, range: NSRange(location: 0, length: sql.count))
250+
.reduce([String: IndexDefinition.Order]()) { (memo, result) in
250251
var memo2 = memo
251252
let column = (sql as NSString).substring(with: result.range(at: 1))
252253
memo2[column] = .DESC

Sources/SQLite/Schema/SchemaReader.swift

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class SchemaReader {
3838
public func objectDefinitions(name: String? = nil,
3939
type: ObjectDefinition.ObjectType? = nil,
4040
temp: Bool = false) throws -> [ObjectDefinition] {
41-
var query: QueryType = connection.schemaTable(temp: temp)
41+
var query: QueryType = SchemaTable.get(for: connection, temp: temp)
4242
if let name = name {
4343
query = query.where(SchemaTable.nameColumn == name)
4444
}
@@ -125,22 +125,30 @@ public class SchemaReader {
125125
}
126126
}
127127

128-
private class SchemaTable {
129-
internal static let name = Table("sqlite_schema", database: "main")
130-
internal static let tempName = Table("sqlite_schema", database: "temp")
128+
private enum SchemaTable {
129+
private static let name = Table("sqlite_schema", database: "main")
130+
private static let tempName = Table("sqlite_schema", database: "temp")
131+
// legacy names (< 3.33.0)
132+
private static let masterName = Table("sqlite_master")
133+
private static let tempMasterName = Table("sqlite_temp_master")
131134

132-
// legacy table names
133-
internal static let masterName = Table("sqlite_master")
134-
internal static let tempMasterName = Table("sqlite_temp_master")
135+
static func get(for connection: Connection, temp: Bool = false) -> Table {
136+
if connection.supports(.sqliteSchemaTable) {
137+
return temp ? SchemaTable.tempName : SchemaTable.name
138+
} else {
139+
return temp ? SchemaTable.tempMasterName : SchemaTable.masterName
140+
}
141+
}
135142

143+
// columns
136144
static let typeColumn = Expression<String>("type")
137145
static let nameColumn = Expression<String>("name")
138146
static let tableNameColumn = Expression<String>("tbl_name")
139147
static let rootPageColumn = Expression<Int64?>("rootpage")
140148
static let sqlColumn = Expression<String?>("sql")
141149
}
142150

143-
private class TableInfoTable {
151+
private enum TableInfoTable {
144152
static let idColumn = Expression<Int64>("cid")
145153
static let nameColumn = Expression<String>("name")
146154
static let typeColumn = Expression<String>("type")
@@ -149,7 +157,7 @@ private class TableInfoTable {
149157
static let primaryKeyColumn = Expression<Int64?>("pk")
150158
}
151159

152-
private class IndexInfoTable {
160+
private enum IndexInfoTable {
153161
// The rank of the column within the index. (0 means left-most.)
154162
static let seqnoColumn = Expression<Int64>("seqno")
155163
// The rank of the column within the table being indexed.
@@ -159,7 +167,7 @@ private class IndexInfoTable {
159167
static let nameColumn = Expression<String?>("name")
160168
}
161169

162-
private class IndexListTable {
170+
private enum IndexListTable {
163171
// A sequence number assigned to each index for internal tracking purposes.
164172
static let seqColumn = Expression<Int64>("seq")
165173
// The name of the index
@@ -174,7 +182,7 @@ private class IndexListTable {
174182
static let partialColumn = Expression<Int64>("partial")
175183
}
176184

177-
private class ForeignKeyListTable {
185+
private enum ForeignKeyListTable {
178186
static let idColumn = Expression<Int64>("id")
179187
static let seqColumn = Expression<Int64>("seq")
180188
static let tableColumn = Expression<String>("table")
@@ -184,13 +192,3 @@ private class ForeignKeyListTable {
184192
static let onDeleteColumn = Expression<String>("on_delete")
185193
static let matchColumn = Expression<String>("match")
186194
}
187-
188-
private extension Connection {
189-
func schemaTable(temp: Bool = false) -> Table {
190-
if supports(.sqliteSchemaTable) {
191-
return temp ? SchemaTable.tempName : SchemaTable.name
192-
} else {
193-
return temp ? SchemaTable.tempMasterName : SchemaTable.masterName
194-
}
195-
}
196-
}

Tests/SQLiteTests/Schema/SchemaReaderTests.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class SchemaReaderTests: SQLiteTestCase {
88
try super.setUpWithError()
99
try createUsersTable()
1010

11-
schemaReader = db.schemaReader
11+
schemaReader = db.schema
1212
}
1313

1414
func test_columnDefinitions() throws {
@@ -168,6 +168,7 @@ class SchemaReaderTests: SQLiteTestCase {
168168
XCTAssertEqual(tables.map { table in [table.name, table.tableName, table.type.rawValue]}, [
169169
["users", "users", "table"]
170170
])
171+
XCTAssertTrue((try schemaReader.objectDefinitions(type: .trigger)).isEmpty)
171172
}
172173

173174
func test_objectDefinitionsFilterByName() throws {
@@ -176,5 +177,6 @@ class SchemaReaderTests: SQLiteTestCase {
176177
XCTAssertEqual(tables.map { table in [table.name, table.tableName, table.type.rawValue]}, [
177178
["users", "users", "table"]
178179
])
180+
XCTAssertTrue((try schemaReader.objectDefinitions(name: "xxx")).isEmpty)
179181
}
180182
}

0 commit comments

Comments
 (0)