Skip to content

Commit 1b64529

Browse files
committed
ColumnDefinition needs to be public
1 parent affcec8 commit 1b64529

File tree

8 files changed

+130
-111
lines changed

8 files changed

+130
-111
lines changed

SQLite.xcodeproj/project.pbxproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
03A65E941C6BB3030062603F /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B331C3F142E00AE3E12 /* ValueTests.swift */; };
4747
03A65E951C6BB3030062603F /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; };
4848
03A65E971C6BB3210062603F /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E961C6BB3210062603F /* libsqlite3.tbd */; };
49+
19A17018F250343BD0F9F4B0 /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; };
4950
19A17073552293CA063BEA66 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17E723300E5ED3771DCB5 /* Result.swift */; };
5051
19A1709C3E7A406E62293B2A /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B93B48B5560E6E51791 /* Fixtures.swift */; };
5152
19A170ACC97B19730FB7BA4D /* Connection+Aggregation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */; };
@@ -71,6 +72,7 @@
7172
19A174D78559CD30679BCCCB /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; };
7273
19A1750CEE9B05267995CF3D /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
7374
19A1750EF4A5F92954A451FF /* Connection+Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170A97B51DC5EE365F3C5 /* Connection+Schema.swift */; };
75+
19A1760CE25615CA015E2E5F /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; };
7476
19A176376CB6A94759F7980A /* Connection+Aggregation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */; };
7577
19A176406BDE9D9C80CC9FA3 /* QueryIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BA6B4E282C1315A115C /* QueryIntegrationTests.swift */; };
7678
19A1766AC10D13C4EFF349AD /* SchemaChangerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */; };
@@ -82,7 +84,9 @@
8284
19A178072B371489E6A1E839 /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; };
8385
19A17835FD5886FDC5A3228F /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
8486
19A1785195182AF8731A8BDA /* RowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A175C1F9CB3BBAB8FCEC7B /* RowTests.swift */; };
87+
19A178A8B2A34FB6B565DEDA /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; };
8588
19A1792C0520D4E83C2EB075 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1710E73A46D5AC721CDA9 /* Errors.swift */; };
89+
19A17986405D9A875698408F /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; };
8690
19A179A0C45377CB09BB358C /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17399EA9E61235D5D77BF /* CipherTests.swift */; };
8791
19A179B59450FE7C4811AB8A /* Connection+Aggregation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */; };
8892
19A179CCF9671E345E5A9811 /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; };
@@ -283,6 +287,7 @@
283287
19A17CA1DF7D0F7C9A94C51C /* ConnectionSchemaTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionSchemaTests.swift; sourceTree = "<group>"; };
284288
19A17E723300E5ED3771DCB5 /* Result.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = "<group>"; };
285289
19A17EA3A313F129011B3FA0 /* Release.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Release.md; sourceTree = "<group>"; };
290+
19A17F285B767BFACD96714B /* Connection+Pragmas.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Connection+Pragmas.swift"; sourceTree = "<group>"; };
286291
19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaChangerTests.swift; sourceTree = "<group>"; };
287292
3717F907221F5D7C00B9BD3D /* CustomAggregationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomAggregationTests.swift; sourceTree = "<group>"; };
288293
3D3C3CCB26E5568800759140 /* SQLite.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = SQLite.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
@@ -530,6 +535,7 @@
530535
19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */,
531536
3DF7B78728842972005DD8CA /* Connection+Attach.swift */,
532537
3DF7B790288449BA005DD8CA /* URIQueryParameter.swift */,
538+
19A17F285B767BFACD96714B /* Connection+Pragmas.swift */,
533539
);
534540
path = Core;
535541
sourceTree = "<group>";
@@ -920,6 +926,7 @@
920926
19A17FC07731779C1B8506FA /* SchemaChanger.swift in Sources */,
921927
19A1740EACD47904AA24B8DC /* SchemaDefinitions.swift in Sources */,
922928
19A1750EF4A5F92954A451FF /* Connection+Schema.swift in Sources */,
929+
19A17986405D9A875698408F /* Connection+Pragmas.swift in Sources */,
923930
);
924931
runOnlyForDeploymentPostprocessing = 0;
925932
};
@@ -993,6 +1000,7 @@
9931000
19A17DFE05ED8B1F7C45F7EE /* SchemaChanger.swift in Sources */,
9941001
19A17D1BEABA610ABF003D67 /* SchemaDefinitions.swift in Sources */,
9951002
19A17A33EA026C2E2CEBAF36 /* Connection+Schema.swift in Sources */,
1003+
19A178A8B2A34FB6B565DEDA /* Connection+Pragmas.swift in Sources */,
9961004
);
9971005
runOnlyForDeploymentPostprocessing = 0;
9981006
};
@@ -1031,6 +1039,7 @@
10311039
19A1773A335CAB9D0AE14E8E /* SchemaChanger.swift in Sources */,
10321040
19A17BA13FD35F058787B7D3 /* SchemaDefinitions.swift in Sources */,
10331041
19A174506543905D71BF0518 /* Connection+Schema.swift in Sources */,
1042+
19A17018F250343BD0F9F4B0 /* Connection+Pragmas.swift in Sources */,
10341043
);
10351044
runOnlyForDeploymentPostprocessing = 0;
10361045
};
@@ -1105,6 +1114,7 @@
11051114
19A177290558991BCC60E4E3 /* SchemaChanger.swift in Sources */,
11061115
19A17B0DF1DDB6BBC9C95D64 /* SchemaDefinitions.swift in Sources */,
11071116
19A17F0BF02896E1664F4090 /* Connection+Schema.swift in Sources */,
1117+
19A1760CE25615CA015E2E5F /* Connection+Pragmas.swift in Sources */,
11081118
);
11091119
runOnlyForDeploymentPostprocessing = 0;
11101120
};
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import Foundation
2+
3+
public typealias UserVersion = Int32
4+
public typealias SQLiteVersion = (Int, Int, Int)
5+
6+
public extension Connection {
7+
/// The user version of the database.
8+
/// See SQLite [PRAGMA user_version](https://sqlite.org/pragma.html#pragma_user_version)
9+
var userVersion: UserVersion? {
10+
get {
11+
(try? scalar("PRAGMA user_version") as? Int64).map(Int32.init)
12+
}
13+
set {
14+
_ = try? run("PRAGMA user_version = \(newValue ?? 0)")
15+
}
16+
}
17+
18+
/// The version of SQLite.
19+
/// See SQLite [sqlite_version()](https://sqlite.org/lang_corefunc.html#sqlite_version)
20+
var sqliteVersion: SQLiteVersion {
21+
guard let version = (try? scalar("SELECT sqlite_version()")) as? String,
22+
let splits = .some(version.split(separator: ".", maxSplits: 3)), splits.count == 3,
23+
let major = Int(splits[0]), let minor = Int(splits[1]), let point = Int(splits[2]) else {
24+
return (0, 0, 0)
25+
}
26+
return (major, minor, point)
27+
}
28+
29+
// Changing the foreign_keys setting affects the execution of all statements prepared using the database
30+
// connection, including those prepared before the setting was changed.
31+
//
32+
// https://sqlite.org/pragma.html#pragma_foreign_keys
33+
var foreignKeys: Bool {
34+
get { getBoolPragma("foreign_keys") }
35+
set { setBoolPragma("foreign_keys", newValue) }
36+
}
37+
38+
var deferForeignKeys: Bool {
39+
get { getBoolPragma("defer_foreign_keys") }
40+
set { setBoolPragma("defer_foreign_keys", newValue) }
41+
}
42+
43+
private func getBoolPragma(_ key: String) -> Bool {
44+
guard let binding = try? scalar("PRAGMA \(key)"),
45+
let intBinding = binding as? Int64 else { return false }
46+
return intBinding == 1
47+
}
48+
49+
private func setBoolPragma(_ key: String, _ newValue: Bool) {
50+
_ = try? run("PRAGMA \(key) = \(newValue ? "1" : "0")")
51+
}
52+
}

Sources/SQLite/Core/Connection.swift

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -156,17 +156,6 @@ public final class Connection {
156156
Int(sqlite3_total_changes(handle))
157157
}
158158

159-
/// The user version of the database.
160-
/// See SQLite [PRAGMA user_version](https://sqlite.org/pragma.html#pragma_user_version)
161-
public var userVersion: Int32? {
162-
get {
163-
(try? scalar("PRAGMA user_version") as? Int64).map(Int32.init)
164-
}
165-
set {
166-
_ = try? run("PRAGMA user_version = \(newValue ?? 0)")
167-
}
168-
}
169-
170159
// MARK: - Execute
171160

172161
/// Executes a batch of SQL statements.
Lines changed: 25 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,6 @@
11
import Foundation
22

33
extension Connection {
4-
var sqliteVersion: String? {
5-
(try? scalar("SELECT sqlite_version()")) as? String
6-
}
7-
8-
var sqliteVersionTriple: (Int, Int, Int) {
9-
guard let version = sqliteVersion,
10-
let splits = .some(version.split(separator: ".", maxSplits: 3)), splits.count == 3,
11-
let major = Int(splits[0]), let minor = Int(splits[1]), let point = Int(splits[2]) else {
12-
return (0, 0, 0)
13-
}
14-
return (major, minor, point)
15-
}
16-
17-
// Changing the foreign_keys setting affects the execution of all statements prepared using the database
18-
// connection, including those prepared before the setting was changed.
19-
//
20-
// https://sqlite.org/pragma.html#pragma_foreign_keys
21-
var foreignKeys: Bool {
22-
get { getBoolPragma("foreign_keys") }
23-
set { setBoolPragma("foreign_keys", newValue) }
24-
}
25-
26-
var deferForeignKeys: Bool {
27-
get { getBoolPragma("defer_foreign_keys") }
28-
set { setBoolPragma("defer_foreign_keys", newValue) }
29-
}
30-
31-
// https://sqlite.org/pragma.html#pragma_foreign_key_check
32-
33-
// There are four columns in each result row.
34-
// The first column is the name of the table that
35-
// contains the REFERENCES clause.
36-
// The second column is the rowid of the row that contains the
37-
// invalid REFERENCES clause, or NULL if the child table is a WITHOUT ROWID table.
38-
// The third column is the name of the table that is referred to.
39-
// The fourth column is the index of the specific foreign key constraint that failed.
40-
func foreignKeyCheck() throws -> [ForeignKeyError] {
41-
try run("PRAGMA foreign_key_check").compactMap { row -> ForeignKeyError? in
42-
guard let table = row[0] as? String,
43-
let rowId = row[1] as? Int64,
44-
let target = row[2] as? String else { return nil }
45-
46-
return ForeignKeyError(from: table, rowId: rowId, to: target)
47-
}
48-
}
49-
504
// https://sqlite.org/pragma.html#pragma_table_info
515
//
526
// This pragma returns one row for each column in the named table. Columns in the result set include the
@@ -58,7 +12,7 @@ extension Connection {
5812
try createTableSQL(name: table).flatMap { .init(sql: $0) }
5913
}
6014

61-
let foreignKeys: [String: [ForeignKeyDefinition]] =
15+
let foreignKeys: [String: [ColumnDefinition.ForeignKey]] =
6216
Dictionary(grouping: try foreignKeyInfo(table: table), by: { $0.column })
6317

6418
return try run("PRAGMA table_info(\(table.quote()))").compactMap { row -> ColumnDefinition? in
@@ -71,7 +25,7 @@ extension Connection {
7125
primaryKey: primaryKey == 1 ? try parsePrimaryKey(column: name) : nil,
7226
type: ColumnDefinition.Affinity.from(type),
7327
null: notNull == 0,
74-
defaultValue: LiteralValue.from(defaultValue),
28+
defaultValue: .from(defaultValue),
7529
references: foreignKeys[name]?.first)
7630
}
7731
}
@@ -119,23 +73,42 @@ extension Connection {
11973
}
12074
}
12175

122-
func foreignKeyInfo(table: String) throws -> [ForeignKeyDefinition] {
76+
func foreignKeyInfo(table: String) throws -> [ColumnDefinition.ForeignKey] {
12377
try run("PRAGMA foreign_key_list(\(table.quote()))").compactMap { row in
12478
if let table = row[2] as? String, // table
12579
let column = row[3] as? String, // from
12680
let primaryKey = row[4] as? String, // to
12781
let onUpdate = row[5] as? String,
12882
let onDelete = row[6] as? String {
129-
return ForeignKeyDefinition(table: table, column: column, primaryKey: primaryKey,
130-
onUpdate: onUpdate == TableBuilder.Dependency.noAction.rawValue ? nil : onUpdate,
131-
onDelete: onDelete == TableBuilder.Dependency.noAction.rawValue ? nil : onDelete
83+
return .init(table: table, column: column, primaryKey: primaryKey,
84+
onUpdate: onUpdate == TableBuilder.Dependency.noAction.rawValue ? nil : onUpdate,
85+
onDelete: onDelete == TableBuilder.Dependency.noAction.rawValue ? nil : onDelete
13286
)
13387
} else {
13488
return nil
13589
}
13690
}
13791
}
13892

93+
// https://sqlite.org/pragma.html#pragma_foreign_key_check
94+
95+
// There are four columns in each result row.
96+
// The first column is the name of the table that
97+
// contains the REFERENCES clause.
98+
// The second column is the rowid of the row that contains the
99+
// invalid REFERENCES clause, or NULL if the child table is a WITHOUT ROWID table.
100+
// The third column is the name of the table that is referred to.
101+
// The fourth column is the index of the specific foreign key constraint that failed.
102+
func foreignKeyCheck() throws -> [ForeignKeyError] {
103+
try run("PRAGMA foreign_key_check").compactMap { row -> ForeignKeyError? in
104+
guard let table = row[0] as? String,
105+
let rowId = row[1] as? Int64,
106+
let target = row[2] as? String else { return nil }
107+
108+
return ForeignKeyError(from: table, rowId: rowId, to: target)
109+
}
110+
}
111+
139112
private func createTableSQL(name: String) throws -> String? {
140113
try run("""
141114
SELECT sql FROM sqlite_master WHERE name=? AND type='table'
@@ -145,14 +118,4 @@ extension Connection {
145118
.compactMap { row in row[0] as? String }
146119
.first
147120
}
148-
149-
private func getBoolPragma(_ key: String) -> Bool {
150-
guard let binding = try? scalar("PRAGMA \(key)"),
151-
let intBinding = binding as? Int64 else { return false }
152-
return intBinding == 1
153-
}
154-
155-
private func setBoolPragma(_ key: String, _ newValue: Bool) {
156-
_ = try? run("PRAGMA \(key) = \(newValue ? "1" : "0")")
157-
}
158121
}

Sources/SQLite/Schema/SchemaChanger.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ import Foundation
2727
12. If foreign keys constraints were originally enabled, reenable them now.
2828
*/
2929
public class SchemaChanger: CustomStringConvertible {
30-
typealias SQLiteVersion = (Int, Int, Int)
31-
3230
enum SchemaChangeError: LocalizedError {
3331
case foreignKeyError([ForeignKeyError])
3432

@@ -52,9 +50,9 @@ public class SchemaChanger: CustomStringConvertible {
5250
switch self {
5351
case .add(let definition):
5452
return "ALTER TABLE \(table.quote()) ADD COLUMN \(definition.toSQL())"
55-
case .renameColumn(let from, let to) where version.0 >= 3 && version.1 >= 25:
53+
case .renameColumn(let from, let to) where version >= (3, 25, 0):
5654
return "ALTER TABLE \(table.quote()) RENAME COLUMN \(from.quote()) TO \(to.quote())"
57-
case .remove(let column) where version.0 >= 3 && version.1 >= 35:
55+
case .remove(let column) where version >= (3, 35, 0):
5856
return "ALTER TABLE \(table.quote()) DROP COLUMN \(column.quote())"
5957
default: return nil
6058
}
@@ -97,7 +95,7 @@ public class SchemaChanger: CustomStringConvertible {
9795

9896
public convenience init(connection: Connection) {
9997
self.init(connection: connection,
100-
version: connection.sqliteVersionTriple)
98+
version: connection.sqliteVersion)
10199
}
102100

103101
init(connection: Connection, version: SQLiteVersion) {

0 commit comments

Comments
 (0)