From ff93ebc831c01daa0117be6c19e0960347e001a6 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Sat, 27 May 2023 23:09:08 +0200 Subject: [PATCH 01/84] Handle FK definitions w/o key references Closes #1199 --- SQLite.xcodeproj/project.pbxproj | 8 ++++ Sources/SQLite/Schema/SchemaDefinitions.swift | 4 +- Sources/SQLite/Schema/SchemaReader.swift | 2 +- .../Schema/SchemaReaderTests.swift | 38 +++++++++++++++++++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index def32855..e6bb4fc9 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -211,6 +211,9 @@ DB7C5DA728D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA828D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA928D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; + DBB93D5A2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; + DBB93D5B2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; + DBB93D5C2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; }; EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; @@ -340,6 +343,7 @@ DB58B21028FB864300F8EEA4 /* SchemaReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReader.swift; sourceTree = ""; }; DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteFeature.swift; sourceTree = ""; }; DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteVersion.swift; sourceTree = ""; }; + DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReaderTests.swift; sourceTree = ""; }; EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = ""; }; EE247AD81C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -483,6 +487,7 @@ 19A17B56FBA20E7245BC8AC0 /* Schema */ = { isa = PBXGroup; children = ( + DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */, 19A176174862D0F0139B3987 /* SchemaDefinitionsTests.swift */, 19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */, 19A17CA1DF7D0F7C9A94C51C /* Connection+SchemaTests.swift */, @@ -998,6 +1003,7 @@ 19A17FACE8E4D54A50BA934E /* FTS5Tests.swift in Sources */, 19A177909023B7B940C5805E /* FTSIntegrationTests.swift in Sources */, 19A17E1DD976D5CE80018749 /* FTS4Tests.swift in Sources */, + DBB93D5C2A22A373009BB96E /* SchemaReaderTests.swift in Sources */, 19A17411403D60640467209E /* ExpressionTests.swift in Sources */, 19A17CA4D7B63D845428A9C5 /* StatementTests.swift in Sources */, 19A17885B646CB0201BE4BD5 /* QueryTests.swift in Sources */, @@ -1119,6 +1125,7 @@ 19A178DA2BB5970778CCAF13 /* FTS5Tests.swift in Sources */, 19A1755C49154C87304C9146 /* FTSIntegrationTests.swift in Sources */, 19A17444861E1443143DEB44 /* FTS4Tests.swift in Sources */, + DBB93D5A2A22A373009BB96E /* SchemaReaderTests.swift in Sources */, 19A17DD33C2E43DD6EE05A60 /* ExpressionTests.swift in Sources */, 19A17D6EC40BC35A5DC81BA8 /* StatementTests.swift in Sources */, 19A17E3F47DA087E2B76D087 /* QueryTests.swift in Sources */, @@ -1199,6 +1206,7 @@ 19A1776BD5127DFDF847FF1F /* FTS5Tests.swift in Sources */, 19A173088B85A7E18E8582A7 /* FTSIntegrationTests.swift in Sources */, 19A178767223229E61C5066F /* FTS4Tests.swift in Sources */, + DBB93D5B2A22A373009BB96E /* SchemaReaderTests.swift in Sources */, 19A1781CBA8968ABD3E00877 /* ExpressionTests.swift in Sources */, 19A17923494236793893BF72 /* StatementTests.swift in Sources */, 19A17A52BF29D27C9AA229E7 /* QueryTests.swift in Sources */, diff --git a/Sources/SQLite/Schema/SchemaDefinitions.swift b/Sources/SQLite/Schema/SchemaDefinitions.swift index 2d38e1fb..9f4c126f 100644 --- a/Sources/SQLite/Schema/SchemaDefinitions.swift +++ b/Sources/SQLite/Schema/SchemaDefinitions.swift @@ -107,7 +107,7 @@ public struct ColumnDefinition: Equatable { public struct ForeignKey: Equatable { let table: String let column: String - let primaryKey: String + let primaryKey: String? let onUpdate: String? let onDelete: String? } @@ -365,7 +365,7 @@ extension ColumnDefinition.ForeignKey { ([ "REFERENCES", table.quote(), - "(\(primaryKey.quote()))", + primaryKey.map { "(\($0.quote()))" }, onUpdate.map { "ON UPDATE \($0)" }, onDelete.map { "ON DELETE \($0)" } ] as [String?]).compactMap { $0 } diff --git a/Sources/SQLite/Schema/SchemaReader.swift b/Sources/SQLite/Schema/SchemaReader.swift index 58a9b1bd..eb31888b 100644 --- a/Sources/SQLite/Schema/SchemaReader.swift +++ b/Sources/SQLite/Schema/SchemaReader.swift @@ -187,7 +187,7 @@ private enum ForeignKeyListTable { static let seqColumn = Expression("seq") static let tableColumn = Expression("table") static let fromColumn = Expression("from") - static let toColumn = Expression("to") + static let toColumn = Expression("to") // when null, use primary key static let onUpdateColumn = Expression("on_update") static let onDeleteColumn = Expression("on_delete") static let matchColumn = Expression("match") diff --git a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift index dd5ae103..e90578e7 100644 --- a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift @@ -135,6 +135,44 @@ class SchemaReaderTests: SQLiteTestCase { ]) } + func test_foreignKeys_references_column() throws { + let sql = """ + CREATE TABLE artist( + artistid INTEGER PRIMARY KEY, + artistname TEXT + ); + CREATE TABLE track( + trackid INTEGER, + trackname TEXT, + trackartist INTEGER REFERENCES artist(artistid) + ); + """ + try db.execute(sql) + let trackColumns = try db.schema.foreignKeys(table: "track") + XCTAssertEqual(trackColumns.map { $0.toSQL() }.joined(separator: "\n"), """ + REFERENCES "artist" ("artistid") + """) + } + + func test_foreignKeys_references_null_column() throws { + let sql = """ + CREATE TABLE artist( + artistid INTEGER PRIMARY KEY, + artistname TEXT + ); + CREATE TABLE track( + trackid INTEGER, + trackname TEXT, + trackartist INTEGER REFERENCES artist + ); + """ + try db.execute(sql) + let trackColumns = try db.schema.foreignKeys(table: "track") + XCTAssertEqual(trackColumns.map { $0.toSQL() }.joined(separator: "\n"), """ + REFERENCES "artist" + """) + } + func test_tableDefinitions() throws { let tables = try schemaReader.tableDefinitions() XCTAssertEqual(tables.count, 1) From 656ca871e357df8ef45b7344c777102cdbf7dfc6 Mon Sep 17 00:00:00 2001 From: Stefan Saasen Date: Tue, 30 May 2023 16:20:29 +0200 Subject: [PATCH 02/84] Fix column affinity parsing to match how SQLite determines affinity See https://www.sqlite.org/datatype3.html#determination_of_column_affinity for how SQLite determines column affinity. --- Sources/SQLite/Schema/SchemaDefinitions.swift | 14 +++- .../Schema/SchemaDefinitionsTests.swift | 64 ++++++++++++++++++- .../Schema/SchemaReaderTests.swift | 4 +- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/Sources/SQLite/Schema/SchemaDefinitions.swift b/Sources/SQLite/Schema/SchemaDefinitions.swift index 2d38e1fb..3c6b0523 100644 --- a/Sources/SQLite/Schema/SchemaDefinitions.swift +++ b/Sources/SQLite/Schema/SchemaDefinitions.swift @@ -57,7 +57,19 @@ public struct ColumnDefinition: Equatable { } init(_ string: String) { - self = Affinity.allCases.first { $0.rawValue.lowercased() == string.lowercased() } ?? .TEXT + let test = string.uppercased() + // https://sqlite.org/datatype3.html#determination_of_column_affinity + if test.contains("INT") { // Rule 1 + self = .INTEGER + } else if ["CHAR", "CLOB", "TEXT"].first(where: {test.contains($0)}) != nil { // Rule 2 + self = .TEXT + } else if string.contains("BLOB") { // Rule 3 + self = .BLOB + } else if ["REAL", "FLOA", "DOUB"].first(where: {test.contains($0)}) != nil { // Rule 4 + self = .REAL + } else { // Rule 5 + self = .NUMERIC + } } } diff --git a/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift b/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift index ef97b981..8b7e27e3 100644 --- a/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift @@ -71,8 +71,68 @@ class AffinityTests: XCTestCase { XCTAssertEqual(ColumnDefinition.Affinity("NUMERIC"), .NUMERIC) } - func test_returns_TEXT_for_unknown_type() { - XCTAssertEqual(ColumnDefinition.Affinity("baz"), .TEXT) + // [Determination Of Column Affinity](https://sqlite.org/datatype3.html#determination_of_column_affinity) + // Rule 1 + func testIntegerAffinity() { + let declared = [ + "INT", + "INTEGER", + "TINYINT", + "SMALLINT", + "MEDIUMINT", + "BIGINT", + "UNSIGNED BIG INT", + "INT2", + "INT8" + ] + XCTAssertTrue(declared.allSatisfy({ColumnDefinition.Affinity($0) == .INTEGER})) + } + + // Rule 2 + func testTextAffinity() { + let declared = [ + "CHARACTER(20)", + "VARCHAR(255)", + "VARYING CHARACTER(255)", + "NCHAR(55)", + "NATIVE CHARACTER(70)", + "NVARCHAR(100)", + "TEXT", + "CLOB" + ] + XCTAssertTrue(declared.allSatisfy({ColumnDefinition.Affinity($0) == .TEXT})) + } + + // Rule 3 + func testBlobAffinity() { + XCTAssertEqual(ColumnDefinition.Affinity("BLOB"), .BLOB) + } + + // Rule 4 + func testRealAffinity() { + let declared = [ + "REAL", + "DOUBLE", + "DOUBLE PRECISION", + "FLOAT" + ] + XCTAssertTrue(declared.allSatisfy({ColumnDefinition.Affinity($0) == .REAL})) + } + + // Rule 5 + func testNumericAffinity() { + let declared = [ + "NUMERIC", + "DECIMAL(10,5)", + "BOOLEAN", + "DATE", + "DATETIME" + ] + XCTAssertTrue(declared.allSatisfy({ColumnDefinition.Affinity($0) == .NUMERIC})) + } + + func test_returns_NUMERIC_for_unknown_type() { + XCTAssertEqual(ColumnDefinition.Affinity("baz"), .NUMERIC) } } diff --git a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift index dd5ae103..b03045de 100644 --- a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift @@ -40,7 +40,7 @@ class SchemaReaderTests: SQLiteTestCase { references: nil), ColumnDefinition(name: "admin", primaryKey: nil, - type: .TEXT, + type: .NUMERIC, nullable: false, defaultValue: .numericLiteral("0"), references: nil), @@ -51,7 +51,7 @@ class SchemaReaderTests: SQLiteTestCase { references: .init(table: "users", column: "manager_id", primaryKey: "id", onUpdate: nil, onDelete: nil)), ColumnDefinition(name: "created_at", primaryKey: nil, - type: .TEXT, + type: .NUMERIC, nullable: true, defaultValue: .NULL, references: nil) From 3023a1f63336f70c1470bdef59ac2dfded258206 Mon Sep 17 00:00:00 2001 From: Jacob Hearst Date: Mon, 16 Oct 2023 07:33:54 -0500 Subject: [PATCH 03/84] Add optional support for decoding --- Sources/SQLite/Typed/Coding.swift | 48 +++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Sources/SQLite/Typed/Coding.swift b/Sources/SQLite/Typed/Coding.swift index e7db03fb..8c7755c3 100644 --- a/Sources/SQLite/Typed/Coding.swift +++ b/Sources/SQLite/Typed/Coding.swift @@ -471,6 +471,54 @@ private class SQLiteDecoder: Decoder { } } + func decodeIfPresent(_ type: Bool.Type, forKey key: Key) throws -> Bool? { + try? row.get(Expression(key.stringValue)) + } + + func decodeIfPresent(_ type: Int.Type, forKey key: Key) throws -> Int? { + try? row.get(Expression(key.stringValue)) + } + + func decodeIfPresent(_ type: Int64.Type, forKey key: Key) throws -> Int64? { + try? row.get(Expression(key.stringValue)) + } + + func decodeIfPresent(_ type: Float.Type, forKey key: Key) throws -> Float? { + try? Float(row.get(Expression(key.stringValue))) + } + + func decodeIfPresent(_ type: Double.Type, forKey key: Key) throws -> Double? { + try? row.get(Expression(key.stringValue)) + } + + func decodeIfPresent(_ type: String.Type, forKey key: Key) throws -> String? { + try? row.get(Expression(key.stringValue)) + } + + func decode(_ type: T.Type, forKey key: Key) throws -> T? where T: Swift.Decodable { + switch type { + case is Data.Type: + let data = try row.get(Expression(key.stringValue)) + return data as? T + case is Date.Type: + let date = try row.get(Expression(key.stringValue)) + return date as? T + case is UUID.Type: + let uuid = try row.get(Expression(key.stringValue)) + return uuid as? T + default: + guard let JSONString = try row.get(Expression(key.stringValue)) else { + throw DecodingError.typeMismatch(type, DecodingError.Context(codingPath: codingPath, + debugDescription: "an unsupported type was found")) + } + guard let data = JSONString.data(using: .utf8) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, + debugDescription: "invalid utf8 data found")) + } + return try JSONDecoder().decode(type, from: data) + } + } + func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer where NestedKey: CodingKey { throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, From e7c259226373e9469d9166b842e5395dae302b6e Mon Sep 17 00:00:00 2001 From: Jacob Hearst Date: Thu, 19 Oct 2023 07:13:41 -0500 Subject: [PATCH 04/84] Fix copypasta --- Sources/SQLite/Typed/Coding.swift | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Sources/SQLite/Typed/Coding.swift b/Sources/SQLite/Typed/Coding.swift index 8c7755c3..f62f5b6b 100644 --- a/Sources/SQLite/Typed/Coding.swift +++ b/Sources/SQLite/Typed/Coding.swift @@ -495,19 +495,22 @@ private class SQLiteDecoder: Decoder { try? row.get(Expression(key.stringValue)) } - func decode(_ type: T.Type, forKey key: Key) throws -> T? where T: Swift.Decodable { + func decodeIfPresent(_ type: T.Type, forKey key: Key) throws -> T? where T: Swift.Decodable { switch type { case is Data.Type: - let data = try row.get(Expression(key.stringValue)) - return data as? T + if let data = try? row.get(Expression(key.stringValue)) { + return data as? T + } case is Date.Type: - let date = try row.get(Expression(key.stringValue)) - return date as? T + if let date = try? row.get(Expression(key.stringValue)) { + return date as? T + } case is UUID.Type: - let uuid = try row.get(Expression(key.stringValue)) - return uuid as? T + if let uuid = try? row.get(Expression(key.stringValue)) { + return uuid as? T + } default: - guard let JSONString = try row.get(Expression(key.stringValue)) else { + guard let JSONString = try? row.get(Expression(key.stringValue)) else { throw DecodingError.typeMismatch(type, DecodingError.Context(codingPath: codingPath, debugDescription: "an unsupported type was found")) } From 128246f30a396ef864318e3a7ca851e90b3e84a1 Mon Sep 17 00:00:00 2001 From: Jacob Hearst Date: Thu, 19 Oct 2023 11:04:58 -0500 Subject: [PATCH 05/84] Fix missing return --- Sources/SQLite/Typed/Coding.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/SQLite/Typed/Coding.swift b/Sources/SQLite/Typed/Coding.swift index f62f5b6b..52612063 100644 --- a/Sources/SQLite/Typed/Coding.swift +++ b/Sources/SQLite/Typed/Coding.swift @@ -520,6 +520,8 @@ private class SQLiteDecoder: Decoder { } return try JSONDecoder().decode(type, from: data) } + + return nil } func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws From 1c6bf76948de5b6ab1ef7a45629788e3c5c70d0a Mon Sep 17 00:00:00 2001 From: Jacob Hearst Date: Fri, 20 Oct 2023 07:20:58 -0500 Subject: [PATCH 06/84] Fix smoothbrain --- Sources/SQLite/Typed/Coding.swift | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/Sources/SQLite/Typed/Coding.swift b/Sources/SQLite/Typed/Coding.swift index 52612063..bfddc5ee 100644 --- a/Sources/SQLite/Typed/Coding.swift +++ b/Sources/SQLite/Typed/Coding.swift @@ -498,17 +498,11 @@ private class SQLiteDecoder: Decoder { func decodeIfPresent(_ type: T.Type, forKey key: Key) throws -> T? where T: Swift.Decodable { switch type { case is Data.Type: - if let data = try? row.get(Expression(key.stringValue)) { - return data as? T - } + return try? row.get(Expression(key.stringValue)) as? T case is Date.Type: - if let date = try? row.get(Expression(key.stringValue)) { - return date as? T - } + return try? row.get(Expression(key.stringValue)) as? T case is UUID.Type: - if let uuid = try? row.get(Expression(key.stringValue)) { - return uuid as? T - } + return try? row.get(Expression(key.stringValue)) as? T default: guard let JSONString = try? row.get(Expression(key.stringValue)) else { throw DecodingError.typeMismatch(type, DecodingError.Context(codingPath: codingPath, @@ -520,8 +514,6 @@ private class SQLiteDecoder: Decoder { } return try JSONDecoder().decode(type, from: data) } - - return nil } func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws From fc96d30b72db986b7f930d951eca14c16e32b9b5 Mon Sep 17 00:00:00 2001 From: Geoff MacDonald Date: Sat, 18 Nov 2023 18:30:28 -0800 Subject: [PATCH 07/84] Implements built-in window functions --- SQLite.xcodeproj/project.pbxproj | 18 +++ Sources/SQLite/Typed/AggregateFunctions.swift | 6 +- Sources/SQLite/Typed/WindowFunctions.swift | 145 ++++++++++++++++++ .../Typed/QueryIntegrationTests.swift | 95 ++++++++++++ .../Typed/WindowFunctionsTests.swift | 58 +++++++ 5 files changed, 319 insertions(+), 3 deletions(-) create mode 100644 Sources/SQLite/Typed/WindowFunctions.swift create mode 100644 Tests/SQLiteTests/Typed/WindowFunctionsTests.swift diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index def32855..95ed6806 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -195,6 +195,13 @@ 49EB68C51F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; }; 49EB68C61F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; }; 49EB68C71F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; }; + 64A8EE432B095FBB00F583F7 /* WindowFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */; }; + 64A8EE442B095FBB00F583F7 /* WindowFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */; }; + 64A8EE452B095FBB00F583F7 /* WindowFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */; }; + 64A8EE462B095FBB00F583F7 /* WindowFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */; }; + 64B8E1702B09748000545AFB /* WindowFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64B8E16F2B09748000545AFB /* WindowFunctionsTests.swift */; }; + 64B8E1712B09748000545AFB /* WindowFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64B8E16F2B09748000545AFB /* WindowFunctionsTests.swift */; }; + 64B8E1722B09748000545AFB /* WindowFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64B8E16F2B09748000545AFB /* WindowFunctionsTests.swift */; }; 997DF2AE287FC06D00F8DF95 /* Query+with.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DF2AD287FC06D00F8DF95 /* Query+with.swift */; }; 997DF2AF287FC06D00F8DF95 /* Query+with.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DF2AD287FC06D00F8DF95 /* Query+with.swift */; }; 997DF2B0287FC06D00F8DF95 /* Query+with.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DF2AD287FC06D00F8DF95 /* Query+with.swift */; }; @@ -335,6 +342,8 @@ 3DF7B79B2884C901005DD8CA /* Planning.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Planning.md; sourceTree = ""; }; 3DFC0B862886C239001C8FC9 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 49EB68C31F7B3CB400D89D40 /* Coding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coding.swift; sourceTree = ""; }; + 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowFunctions.swift; sourceTree = ""; }; + 64B8E16F2B09748000545AFB /* WindowFunctionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowFunctionsTests.swift; sourceTree = ""; }; 997DF2AD287FC06D00F8DF95 /* Query+with.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Query+with.swift"; sourceTree = ""; }; A121AC451CA35C79005A31D1 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DB58B21028FB864300F8EEA4 /* SchemaReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReader.swift; sourceTree = ""; }; @@ -476,6 +485,7 @@ 19A177EF5E2D91BA86DA4480 /* CustomAggregationTests.swift */, 19A1709D5BDD2691BA160012 /* SetterTests.swift */, 19A174FE5B47A97937A27276 /* RowTests.swift */, + 64B8E16F2B09748000545AFB /* WindowFunctionsTests.swift */, ); path = Typed; sourceTree = ""; @@ -607,6 +617,7 @@ isa = PBXGroup; children = ( EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */, + 64A8EE422B095FBB00F583F7 /* WindowFunctions.swift */, EE247AFB1C3F06E900AE3E12 /* Collation.swift */, EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */, EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */, @@ -960,6 +971,7 @@ 3DF7B78A28842972005DD8CA /* Connection+Attach.swift in Sources */, 03A65E811C6BB2FB0062603F /* CustomFunctions.swift in Sources */, 03A65E7A1C6BB2F70062603F /* Statement.swift in Sources */, + 64A8EE452B095FBB00F583F7 /* WindowFunctions.swift in Sources */, 03A65E741C6BB2DA0062603F /* Helpers.swift in Sources */, 03A65E831C6BB2FB0062603F /* Operators.swift in Sources */, 03A65E851C6BB2FB0062603F /* Schema.swift in Sources */, @@ -1014,6 +1026,7 @@ 19A17746150A815944A6820B /* SelectTests.swift in Sources */, 19A1766135CE9786B1878603 /* ValueTests.swift in Sources */, 19A177D5C6542E2D572162E5 /* QueryIntegrationTests.swift in Sources */, + 64B8E1722B09748000545AFB /* WindowFunctionsTests.swift in Sources */, 19A178DF5A96CFEFF1E271F6 /* AggregateFunctionsTests.swift in Sources */, 19A17437659BD7FD787D94A6 /* CustomAggregationTests.swift in Sources */, 19A17F907258E524B3CA2FAE /* SetterTests.swift in Sources */, @@ -1057,6 +1070,7 @@ 19A17DC282E36C4F41AA440B /* Errors.swift in Sources */, 19A173668D948AD4DF1F5352 /* DateAndTimeFunctions.swift in Sources */, 19A17DF8D4F13A20F5D2269E /* Result.swift in Sources */, + 64A8EE462B095FBB00F583F7 /* WindowFunctions.swift in Sources */, 19A17DFE05ED8B1F7C45F7EE /* SchemaChanger.swift in Sources */, 19A17D1BEABA610ABF003D67 /* SchemaDefinitions.swift in Sources */, 19A17A33EA026C2E2CEBAF36 /* Connection+Schema.swift in Sources */, @@ -1081,6 +1095,7 @@ EE247B151C3F06E900AE3E12 /* Setter.swift in Sources */, 3DF7B78828842972005DD8CA /* Connection+Attach.swift in Sources */, EE247B101C3F06E900AE3E12 /* CustomFunctions.swift in Sources */, + 64A8EE432B095FBB00F583F7 /* WindowFunctions.swift in Sources */, EE247B091C3F06E900AE3E12 /* FTS4.swift in Sources */, EE247B081C3F06E900AE3E12 /* Value.swift in Sources */, EE247B121C3F06E900AE3E12 /* Operators.swift in Sources */, @@ -1135,6 +1150,7 @@ 19A17F7977364EC8CD33C3C3 /* SelectTests.swift in Sources */, 19A17FD22EF43DF428DD93BA /* ValueTests.swift in Sources */, 19A177AA5922527BBDC77CF9 /* QueryIntegrationTests.swift in Sources */, + 64B8E1702B09748000545AFB /* WindowFunctionsTests.swift in Sources */, 19A179786A6826D58A70F8BC /* AggregateFunctionsTests.swift in Sources */, 19A1793972BDDDB027C113BB /* CustomAggregationTests.swift in Sources */, 19A1773155AC2BF2CA86A473 /* SetterTests.swift in Sources */, @@ -1161,6 +1177,7 @@ 3DF7B78928842972005DD8CA /* Connection+Attach.swift in Sources */, EE247B701C3F3FEC00AE3E12 /* CustomFunctions.swift in Sources */, EE247B691C3F3FEC00AE3E12 /* Statement.swift in Sources */, + 64A8EE442B095FBB00F583F7 /* WindowFunctions.swift in Sources */, EE247B641C3F3FDB00AE3E12 /* Helpers.swift in Sources */, EE247B721C3F3FEC00AE3E12 /* Operators.swift in Sources */, EE247B741C3F3FEC00AE3E12 /* Schema.swift in Sources */, @@ -1215,6 +1232,7 @@ 19A17DE1FCDB5695702AD24D /* SelectTests.swift in Sources */, 19A1726002D24C14F876C8FE /* ValueTests.swift in Sources */, 19A173389E53CB24DFA8CEDD /* QueryIntegrationTests.swift in Sources */, + 64B8E1712B09748000545AFB /* WindowFunctionsTests.swift in Sources */, 19A170C56745F9D722A73D77 /* AggregateFunctionsTests.swift in Sources */, 19A1772EBE65173EDFB1AFCA /* CustomAggregationTests.swift in Sources */, 19A17E0ABA6C415F014CD51C /* SetterTests.swift in Sources */, diff --git a/Sources/SQLite/Typed/AggregateFunctions.swift b/Sources/SQLite/Typed/AggregateFunctions.swift index bf4fb8fc..17fc4a20 100644 --- a/Sources/SQLite/Typed/AggregateFunctions.swift +++ b/Sources/SQLite/Typed/AggregateFunctions.swift @@ -166,7 +166,7 @@ extension ExpressionType where UnderlyingType: Value, UnderlyingType.Datatype: N /// salary.average /// // avg("salary") /// - /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// - Returns: A copy of the expression wrapped with the `avg` aggregate /// function. public var average: Expression { Function.avg.wrap(self) @@ -179,7 +179,7 @@ extension ExpressionType where UnderlyingType: Value, UnderlyingType.Datatype: N /// salary.sum /// // sum("salary") /// - /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// - Returns: A copy of the expression wrapped with the `sum` aggregate /// function. public var sum: Expression { Function.sum.wrap(self) @@ -192,7 +192,7 @@ extension ExpressionType where UnderlyingType: Value, UnderlyingType.Datatype: N /// salary.total /// // total("salary") /// - /// - Returns: A copy of the expression wrapped with the `min` aggregate + /// - Returns: A copy of the expression wrapped with the `total` aggregate /// function. public var total: Expression { Function.total.wrap(self) diff --git a/Sources/SQLite/Typed/WindowFunctions.swift b/Sources/SQLite/Typed/WindowFunctions.swift new file mode 100644 index 00000000..e71e1ada --- /dev/null +++ b/Sources/SQLite/Typed/WindowFunctions.swift @@ -0,0 +1,145 @@ +import Foundation + +// see https://www.sqlite.org/windowfunctions.html#builtins +private enum WindowFunction: String { + // swiftlint:disable identifier_name + case ntile + case row_number + case rank + case dense_rank + case percent_rank + case cume_dist + case lag + case lead + case first_value + case last_value + case nth_value + // swiftlint:enable identifier_name + + func wrap(_ value: Int? = nil) -> Expression { + if let value { + return self.rawValue.wrap(Expression(value: value)) + } + return Expression(literal: "\(rawValue)()") + } + + func over(value: Int? = nil, _ orderBy: Expressible) -> Expression { + return Expression(" ".join([ + self.wrap(value), + Expression("OVER (ORDER BY \(orderBy.expression.template))", orderBy.expression.bindings) + ]).expression) + } + + func over(valueExpr: Expressible, _ orderBy: Expressible) -> Expression { + return Expression(" ".join([ + self.rawValue.wrap(valueExpr), + Expression("OVER (ORDER BY \(orderBy.expression.template))", orderBy.expression.bindings) + ]).expression) + } +} + +extension ExpressionType where UnderlyingType: Value { + /// Builds a copy of the expression with `lag(self, offset, default) OVER (ORDER BY {orderBy})` window function + /// + /// - Parameter orderBy: Expression to evaluate window order + /// - Returns: An expression returning `lag(self, offset, default) OVER (ORDER BY {orderBy})` window function + public func lag(offset: Int = 0, default: Expressible? = nil, _ orderBy: Expressible) -> Expression { + if let defaultExpression = `default` { + return Expression( + "lag(\(template), \(offset), \(defaultExpression.asSQL())) OVER (ORDER BY \(orderBy.expression.template))", + bindings + orderBy.expression.bindings + ) + + } + return Expression("lag(\(template), \(offset)) OVER (ORDER BY \(orderBy.expression.template))", bindings + orderBy.expression.bindings) + } + + /// Builds a copy of the expression with `lead(self, offset, default) OVER (ORDER BY {orderBy})` window function + /// + /// - Parameter orderBy: Expression to evaluate window order + /// - Returns: An expression returning `lead(self, offset, default) OVER (ORDER BY {orderBy})` window function + public func lead(offset: Int = 0, default: Expressible? = nil, _ orderBy: Expressible) -> Expression { + if let defaultExpression = `default` { + return Expression( + "lead(\(template), \(offset), \(defaultExpression.asSQL())) OVER (ORDER BY \(orderBy.expression.template))", + bindings + orderBy.expression.bindings) + + } + return Expression("lead(\(template), \(offset)) OVER (ORDER BY \(orderBy.expression.template))", bindings + orderBy.expression.bindings) + } + + /// Builds a copy of the expression with `first_value(self) OVER (ORDER BY {orderBy})` window function + /// + /// - Parameter orderBy: Expression to evaluate window order + /// - Returns: An expression returning `first_value(self) OVER (ORDER BY {orderBy})` window function + public func firstValue(_ orderBy: Expressible) -> Expression { + WindowFunction.first_value.over(valueExpr: self, orderBy) + } + + /// Builds a copy of the expression with `last_value(self) OVER (ORDER BY {orderBy})` window function + /// + /// - Parameter orderBy: Expression to evaluate window order + /// - Returns: An expression returning `last_value(self) OVER (ORDER BY {orderBy})` window function + public func lastValue(_ orderBy: Expressible) -> Expression { + WindowFunction.last_value.over(valueExpr: self, orderBy) + } + + /// Builds a copy of the expression with `nth_value(self) OVER (ORDER BY {orderBy})` window function + /// + /// - Parameter index: Row N of the window frame to return + /// - Parameter orderBy: Expression to evaluate window order + /// - Returns: An expression returning `nth_value(self) OVER (ORDER BY {orderBy})` window function + public func value(_ index: Int, _ orderBy: Expressible) -> Expression { + Expression("nth_value(\(template), \(index)) OVER (ORDER BY \(orderBy.expression.template))", bindings + orderBy.expression.bindings) + } +} + +/// Builds an expression representing `ntile(size) OVER (ORDER BY {orderBy})` +/// +/// - Parameter orderBy: Expression to evaluate window order +/// - Returns: An expression returning `ntile(size) OVER (ORDER BY {orderBy})` +public func ntile(_ size: Int, _ orderBy: Expressible) -> Expression { +// Expression.ntile(size, orderBy) + + WindowFunction.ntile.over(value: size, orderBy) +} + +/// Builds an expression representing `row_count() OVER (ORDER BY {orderBy})` +/// +/// - Parameter orderBy: Expression to evaluate window order +/// - Returns: An expression returning `row_count() OVER (ORDER BY {orderBy})` +public func rowNumber(_ orderBy: Expressible) -> Expression { + WindowFunction.row_number.over(orderBy) +} + +/// Builds an expression representing `rank() OVER (ORDER BY {orderBy})` +/// +/// - Parameter orderBy: Expression to evaluate window order +/// - Returns: An expression returning `rank() OVER (ORDER BY {orderBy})` +public func rank(_ orderBy: Expressible) -> Expression { + WindowFunction.rank.over(orderBy) +} + +/// Builds an expression representing `dense_rank() OVER (ORDER BY {orderBy})` +/// +/// - Parameter orderBy: Expression to evaluate window order +/// - Returns: An expression returning `dense_rank() OVER ('over')` +public func denseRank(_ orderBy: Expressible) -> Expression { + WindowFunction.dense_rank.over(orderBy) +} + +/// Builds an expression representing `percent_rank() OVER (ORDER BY {orderBy})` +/// +/// - Parameter orderBy: Expression to evaluate window order +/// - Returns: An expression returning `percent_rank() OVER (ORDER BY {orderBy})` +public func percentRank(_ orderBy: Expressible) -> Expression { + WindowFunction.percent_rank.over(orderBy) +} + +/// Builds an expression representing `cume_dist() OVER (ORDER BY {orderBy})` +/// +/// - Parameter orderBy: Expression to evaluate window order +/// - Returns: An expression returning `cume_dist() OVER (ORDER BY {orderBy})` +public func cumeDist(_ orderBy: Expressible) -> Expression { + WindowFunction.cume_dist.over(orderBy) +} diff --git a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift index d8d31a79..aa45cafe 100644 --- a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift +++ b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift @@ -322,6 +322,101 @@ class QueryIntegrationTests: SQLiteTestCase { XCTAssertNotNil(row[name]) XCTAssertNotNil(row[email]) } + + func test_select_ntile_function() throws { + let users = Table("users") + + try insertUser("Joey") + try insertUser("Timmy") + try insertUser("Jimmy") + try insertUser("Billy") + + let bucket = ntile(1, id.asc) + try db.prepare(users.select(id, bucket)).forEach { + XCTAssertEqual($0[bucket], 1) // only 1 window + } + } + + func test_select_cume_dist_function() throws { + let users = Table("users") + + try insertUser("Joey") + try insertUser("Timmy") + try insertUser("Jimmy") + try insertUser("Billy") + + let cumeDist = cumeDist(email) + let results = try db.prepare(users.select(id, cumeDist)).map { + $0[cumeDist] + } + XCTAssertEqual([0.25, 0.5, 0.75, 1], results) + } + + func test_select_window_row_number() throws { + let users = Table("users") + + try insertUser("Billy") + try insertUser("Jimmy") + try insertUser("Joey") + try insertUser("Timmy") + + let rowNumber = rowNumber(email.asc) + var expectedRowNum = 1 + try db.prepare(users.select(id, rowNumber)).forEach { + // should retrieve row numbers in order of INSERT above + XCTAssertEqual($0[rowNumber], expectedRowNum) + expectedRowNum += 1 + } + } + + func test_select_window_ranking() throws { + let users = Table("users") + + try insertUser("Billy") + try insertUser("Jimmy") + try insertUser("Joey") + try insertUser("Timmy") + + let percentRank = percentRank(email) + let actualPercentRank: [Int] = try db.prepare(users.select(id, percentRank)).map { + Int($0[percentRank] * 100) + } + XCTAssertEqual([0, 33, 66, 100], actualPercentRank) + + let rank = rank(email) + let actualRank: [Int] = try db.prepare(users.select(id, rank)).map { + $0[rank] + } + XCTAssertEqual([1, 2, 3, 4], actualRank) + + let denseRank = denseRank(email) + let actualDenseRank: [Int] = try db.prepare(users.select(id, denseRank)).map { + $0[denseRank] + } + XCTAssertEqual([1, 2, 3, 4], actualDenseRank) + } + + func test_select_window_values() throws { + let users = Table("users") + + try insertUser("Billy") + try insertUser("Jimmy") + try insertUser("Joey") + try insertUser("Timmy") + + let firstValue = email.firstValue(email.desc) + try db.prepare(users.select(id, firstValue)).forEach { + XCTAssertEqual($0[firstValue], "Timmy@example.com") // should grab last email alphabetically + } + + let lastValue = email.lastValue(email.asc) + var row = try db.pluck(users.select(id, lastValue))! + XCTAssertEqual(row[lastValue], "Billy@example.com") + + let nthValue = email.value(1, email.asc) + row = try db.pluck(users.select(id, nthValue))! + XCTAssertEqual(row[nthValue], "Billy@example.com") + } } extension Connection { diff --git a/Tests/SQLiteTests/Typed/WindowFunctionsTests.swift b/Tests/SQLiteTests/Typed/WindowFunctionsTests.swift new file mode 100644 index 00000000..6ded152b --- /dev/null +++ b/Tests/SQLiteTests/Typed/WindowFunctionsTests.swift @@ -0,0 +1,58 @@ +import XCTest +import SQLite + +class WindowFunctionsTests: XCTestCase { + + func test_ntile_wrapsExpressionWithOverClause() { + assertSQL("ntile(1) OVER (ORDER BY \"int\" DESC)", ntile(1, int.desc)) + assertSQL("ntile(20) OVER (ORDER BY \"intOptional\" ASC)", ntile(20, intOptional.asc)) + assertSQL("ntile(20) OVER (ORDER BY \"double\" ASC)", ntile(20, double.asc)) + assertSQL("ntile(1) OVER (ORDER BY \"doubleOptional\" ASC)", ntile(1, doubleOptional.asc)) + assertSQL("ntile(1) OVER (ORDER BY \"int\" DESC)", ntile(1, int.desc)) + } + + func test_row_number_wrapsExpressionWithOverClause() { + assertSQL("row_number() OVER (ORDER BY \"int\" DESC)", rowNumber(int.desc)) + } + + func test_rank_wrapsExpressionWithOverClause() { + assertSQL("rank() OVER (ORDER BY \"int\" DESC)", rank(int.desc)) + } + + func test_dense_rank_wrapsExpressionWithOverClause() { + assertSQL("dense_rank() OVER (ORDER BY \"int\" DESC)", denseRank(int.desc)) + } + + func test_percent_rank_wrapsExpressionWithOverClause() { + assertSQL("percent_rank() OVER (ORDER BY \"int\" DESC)", percentRank(int.desc)) + } + + func test_cume_dist_wrapsExpressionWithOverClause() { + assertSQL("cume_dist() OVER (ORDER BY \"int\" DESC)", cumeDist(int.desc)) + } + + func test_lag_wrapsExpressionWithOverClause() { + assertSQL("lag(\"int\", 0) OVER (ORDER BY \"int\" DESC)", int.lag(int.desc)) + assertSQL("lag(\"int\", 7) OVER (ORDER BY \"int\" DESC)", int.lag(offset: 7, int.desc)) + assertSQL("lag(\"int\", 1, 3) OVER (ORDER BY \"int\" DESC)", int.lag(offset: 1, default: Expression(value: 3), int.desc)) + } + + func test_lead_wrapsExpressionWithOverClause() { + assertSQL("lead(\"int\", 0) OVER (ORDER BY \"int\" DESC)", int.lead(int.desc)) + assertSQL("lead(\"int\", 7) OVER (ORDER BY \"int\" DESC)", int.lead(offset: 7, int.desc)) + assertSQL("lead(\"int\", 1, 3) OVER (ORDER BY \"int\" DESC)", int.lead(offset: 1, default: Expression(value: 3), int.desc)) + } + + func test_firstValue_wrapsExpressionWithOverClause() { + assertSQL("first_value(\"int\") OVER (ORDER BY \"int\" DESC)", int.firstValue(int.desc)) + assertSQL("first_value(\"double\") OVER (ORDER BY \"int\" DESC)", double.firstValue(int.desc)) + } + + func test_lastValue_wrapsExpressionWithOverClause() { + assertSQL("last_value(\"int\") OVER (ORDER BY \"int\" DESC)", int.lastValue(int.desc)) + } + + func test_nth_value_wrapsExpressionWithOverClause() { + assertSQL("nth_value(\"int\", 3) OVER (ORDER BY \"int\" DESC)", int.value(3, int.desc)) + } +} From 2fc62a96f03112f77604285cd0ad24b60558c22a Mon Sep 17 00:00:00 2001 From: Geoff MacDonald Date: Sat, 18 Nov 2023 18:42:41 -0800 Subject: [PATCH 08/84] update docs --- Documentation/Index.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/Index.md b/Documentation/Index.md index 5d72aa4b..a03c26a3 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -64,6 +64,7 @@ - [Other Operators](#other-operators) - [Core SQLite Functions](#core-sqlite-functions) - [Aggregate SQLite Functions](#aggregate-sqlite-functions) + - [Window SQLite Functions](#window-sqlite-functions) - [Date and Time Functions](#date-and-time-functions) - [Custom SQL Functions](#custom-sql-functions) - [Custom Collations](#custom-collations) @@ -1871,6 +1872,11 @@ Most of SQLite’s [aggregate functions](https://www.sqlite.org/lang_aggfunc.html) have been surfaced in and type-audited for SQLite.swift. +## Window SQLite Functions + +Most of SQLite's [window functions](https://www.sqlite.org/windowfunctions.html) have been +surfaced in and type-audited for SQLite.swift. Currently only `OVER (ORDER BY ...)` windowing is possible. + ## Date and Time functions SQLite's [date and time](https://www.sqlite.org/lang_datefunc.html) From dedef242d9253e5d6169dfe91d9e67ba4597291b Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 4 Jan 2024 11:22:10 -0800 Subject: [PATCH 09/84] Add privacy manifest --- SQLite.xcodeproj/project.pbxproj | 16 ++++++++++++++++ Sources/SQLite/PrivacyInfo.xcprivacy | 14 ++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 Sources/SQLite/PrivacyInfo.xcprivacy diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index def32855..8eb1df66 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -211,6 +211,13 @@ DB7C5DA728D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA828D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA928D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; + EAE1E1542B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; + EAE1E1552B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; + EAE1E1562B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; + EAE1E1572B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; + EAE1E1582B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; + EAE1E1592B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; + EAE1E15A2B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; }; EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; @@ -340,6 +347,7 @@ DB58B21028FB864300F8EEA4 /* SchemaReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReader.swift; sourceTree = ""; }; DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteFeature.swift; sourceTree = ""; }; DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteVersion.swift; sourceTree = ""; }; + EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = ""; }; EE247AD81C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -546,6 +554,7 @@ EE247AF71C3F06E900AE3E12 /* Foundation.swift */, EE247AF81C3F06E900AE3E12 /* Helpers.swift */, EE247AD81C3F04ED00AE3E12 /* Info.plist */, + EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */, EE247AED1C3F06E900AE3E12 /* Core */, EE247AF41C3F06E900AE3E12 /* Extensions */, EE247AF91C3F06E900AE3E12 /* Typed */, @@ -892,6 +901,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE1E1582B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -899,6 +909,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE1E1592B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, 3DF7B79828846FED005DD8CA /* Resources in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -907,6 +918,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE1E15A2B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -914,6 +926,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE1E1542B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -921,6 +934,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE1E1552B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, 3DF7B79628846FCC005DD8CA /* Resources in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -929,6 +943,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE1E1562B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -936,6 +951,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE1E1572B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, 3DF7B79928847055005DD8CA /* Resources in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/SQLite/PrivacyInfo.xcprivacy b/Sources/SQLite/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..987771fa --- /dev/null +++ b/Sources/SQLite/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + NSPrivacyTracking + + + From e7c4212a213f8dec5d68ec6e7acadeed8f4fb912 Mon Sep 17 00:00:00 2001 From: Anthony Miller Date: Wed, 24 Jan 2024 15:18:34 -0800 Subject: [PATCH 10/84] Add visionOS support to Package.swift --- Package.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 70bde7ef..238661ae 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.7 +// swift-tools-version:5.9 import PackageDescription let package = Package( @@ -7,7 +7,8 @@ let package = Package( .iOS(.v11), .macOS(.v10_13), .watchOS(.v4), - .tvOS(.v11) + .tvOS(.v11), + .visionOS(.v1) ], products: [ .library( From 240f0802792cce82ebd0c27300cd1748b322e200 Mon Sep 17 00:00:00 2001 From: Anthony Miller Date: Wed, 24 Jan 2024 15:18:43 -0800 Subject: [PATCH 11/84] Create visionOS target and test plan --- SQLite.xcodeproj/project.pbxproj | 344 +++++++++++++++++- .../xcschemes/SQLite visionOS.xcscheme | 71 ++++ Tests/SQLite visionOS.xctestplan | 24 ++ 3 files changed, 435 insertions(+), 4 deletions(-) create mode 100644 SQLite.xcodeproj/xcshareddata/xcschemes/SQLite visionOS.xcscheme create mode 100644 Tests/SQLite visionOS.xctestplan diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index def32855..857c6fd9 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -211,6 +211,76 @@ DB7C5DA728D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA828D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA928D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; + DEB306BA2B61CEF500F9D46B /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DEB306BC2B61CEF500F9D46B /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; }; + DEB306BD2B61CEF500F9D46B /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; }; + DEB306BE2B61CEF500F9D46B /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF61C3F06E900AE3E12 /* RTree.swift */; }; + DEB306BF2B61CEF500F9D46B /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; + DEB306C02B61CEF500F9D46B /* URIQueryParameter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B790288449BA005DD8CA /* URIQueryParameter.swift */; }; + DEB306C12B61CEF500F9D46B /* Foundation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF71C3F06E900AE3E12 /* Foundation.swift */; }; + DEB306C22B61CEF500F9D46B /* Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEF1C3F06E900AE3E12 /* Connection.swift */; }; + DEB306C32B61CEF500F9D46B /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFE1C3F06E900AE3E12 /* Expression.swift */; }; + DEB306C42B61CEF500F9D46B /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF81C3F06E900AE3E12 /* Helpers.swift */; }; + DEB306C52B61CEF500F9D46B /* Collation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFB1C3F06E900AE3E12 /* Collation.swift */; }; + DEB306C62B61CEF500F9D46B /* Setter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B021C3F06E900AE3E12 /* Setter.swift */; }; + DEB306C72B61CEF500F9D46B /* Connection+Attach.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DF7B78728842972005DD8CA /* Connection+Attach.swift */; }; + DEB306C82B61CEF500F9D46B /* CustomFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */; }; + DEB306C92B61CEF500F9D46B /* FTS4.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF51C3F06E900AE3E12 /* FTS4.swift */; }; + DEB306CA2B61CEF500F9D46B /* Value.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF31C3F06E900AE3E12 /* Value.swift */; }; + DEB306CB2B61CEF500F9D46B /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFF1C3F06E900AE3E12 /* Operators.swift */; }; + DEB306CC2B61CEF500F9D46B /* Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B011C3F06E900AE3E12 /* Schema.swift */; }; + DEB306CD2B61CEF500F9D46B /* Query.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B001C3F06E900AE3E12 /* Query.swift */; }; + DEB306CE2B61CEF500F9D46B /* Statement.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AF21C3F06E900AE3E12 /* Statement.swift */; }; + DEB306CF2B61CEF500F9D46B /* AggregateFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */; }; + DEB306D02B61CEF500F9D46B /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; }; + DEB306D12B61CEF500F9D46B /* Cipher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178A39ACA9667A62663CC /* Cipher.swift */; }; + DEB306D22B61CEF500F9D46B /* Backup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02A43A9722738CF100FEC494 /* Backup.swift */; }; + DEB306D32B61CEF500F9D46B /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1710E73A46D5AC721CDA9 /* Errors.swift */; }; + DEB306D42B61CEF500F9D46B /* DateAndTimeFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BA55DABB480F9020C8A /* DateAndTimeFunctions.swift */; }; + DEB306D52B61CEF500F9D46B /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; + DEB306D62B61CEF500F9D46B /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17E723300E5ED3771DCB5 /* Result.swift */; }; + DEB306D72B61CEF500F9D46B /* Query+with.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997DF2AD287FC06D00F8DF95 /* Query+with.swift */; }; + DEB306D82B61CEF500F9D46B /* Connection+Aggregation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A175A9CB446640AE6F2200 /* Connection+Aggregation.swift */; }; + DEB306D92B61CEF500F9D46B /* SQLiteFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */; }; + DEB306DA2B61CEF500F9D46B /* SchemaChanger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171B262DDE8718513CFDA /* SchemaChanger.swift */; }; + DEB306DB2B61CEF500F9D46B /* SchemaDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17268AE67B746B96AC125 /* SchemaDefinitions.swift */; }; + DEB306DC2B61CEF500F9D46B /* Connection+Schema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170A97B51DC5EE365F3C5 /* Connection+Schema.swift */; }; + DEB306DD2B61CEF500F9D46B /* Connection+Pragmas.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F285B767BFACD96714B /* Connection+Pragmas.swift */; }; + DEB306DE2B61CEF500F9D46B /* SchemaReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB58B21028FB864300F8EEA4 /* SchemaReader.swift */; }; + DEB306E02B61CEF500F9D46B /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EE9180931C46EA210038162A /* libsqlite3.tbd */; }; + DEB306EB2B61CF9500F9D46B /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; }; + DEB306EC2B61CF9500F9D46B /* FoundationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1794CC4D7827E997E32A7 /* FoundationTests.swift */; }; + DEB306ED2B61CF9500F9D46B /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B93B48B5560E6E51791 /* Fixtures.swift */; }; + DEB306EE2B61CF9500F9D46B /* SchemaDefinitionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A176174862D0F0139B3987 /* SchemaDefinitionsTests.swift */; }; + DEB306EF2B61CF9500F9D46B /* SchemaChangerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17FDB0B0CFB8987906FD0 /* SchemaChangerTests.swift */; }; + DEB306F02B61CF9500F9D46B /* Connection+SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CA1DF7D0F7C9A94C51C /* Connection+SchemaTests.swift */; }; + DEB306F12B61CF9500F9D46B /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B96EBD42C878E609CDC /* FTS5Tests.swift */; }; + DEB306F22B61CF9500F9D46B /* FTSIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17BE1CC4AD4036BAB8EE0 /* FTSIntegrationTests.swift */; }; + DEB306F32B61CF9500F9D46B /* FTS4Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1715904F7B6851FCB5EF6 /* FTS4Tests.swift */; }; + DEB306F42B61CF9500F9D46B /* ExpressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170F141BF21946D159083 /* ExpressionTests.swift */; }; + DEB306F52B61CF9500F9D46B /* StatementTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1756EB81E9F7F45B12A78 /* StatementTests.swift */; }; + DEB306F62B61CF9500F9D46B /* QueryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171ED017645C8B04DF9F2 /* QueryTests.swift */; }; + DEB306F72B61CF9500F9D46B /* CipherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1787E16C8562C09C076F5 /* CipherTests.swift */; }; + DEB306F82B61CF9500F9D46B /* BlobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A2ED4E2640F197F48C /* BlobTests.swift */; }; + DEB306F92B61CF9500F9D46B /* ConnectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17855BD524FF888265B3C /* ConnectionTests.swift */; }; + DEB306FA2B61CF9500F9D46B /* CoreFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17B55F2409B7031443495 /* CoreFunctionsTests.swift */; }; + DEB306FB2B61CF9500F9D46B /* DateAndTimeFunctionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A178AEF32ABC8BF2993FB5 /* DateAndTimeFunctionTests.swift */; }; + DEB306FC2B61CF9500F9D46B /* CustomFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17F2B5959B212A33C383F /* CustomFunctionsTests.swift */; }; + DEB306FD2B61CF9500F9D46B /* OperatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17475DCA068453F787613 /* OperatorsTests.swift */; }; + DEB306FE2B61CF9500F9D46B /* ResultTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1745BE8623D8C6808DB3C /* ResultTests.swift */; }; + DEB306FF2B61CF9500F9D46B /* RTreeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17162C9861E5C4900455D /* RTreeTests.swift */; }; + DEB307002B61CF9500F9D46B /* SchemaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A171A7714C6524093255C5 /* SchemaTests.swift */; }; + DEB307012B61CF9500F9D46B /* SelectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17EC0C43015063945D32E /* SelectTests.swift */; }; + DEB307022B61CF9500F9D46B /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17AE284BB1DF31D1B753E /* ValueTests.swift */; }; + DEB307032B61CF9500F9D46B /* QueryIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17CAE60446607E99C22A6 /* QueryIntegrationTests.swift */; }; + DEB307042B61CF9500F9D46B /* AggregateFunctionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17613F00A3F4D4A257A04 /* AggregateFunctionsTests.swift */; }; + DEB307052B61CF9500F9D46B /* CustomAggregationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A177EF5E2D91BA86DA4480 /* CustomAggregationTests.swift */; }; + DEB307062B61CF9500F9D46B /* SetterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1709D5BDD2691BA160012 /* SetterTests.swift */; }; + DEB307072B61CF9500F9D46B /* RowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A174FE5B47A97937A27276 /* RowTests.swift */; }; + DEB307082B61CF9500F9D46B /* Connection+PragmaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A17C60D3464461057E4D63 /* Connection+PragmaTests.swift */; }; + DEB307092B61CF9500F9D46B /* Connection+AttachTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170C08525D3D27CB5F83C /* Connection+AttachTests.swift */; }; + DEB3070B2B61CF9500F9D46B /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E5A1C6BB0F50062603F /* SQLite.framework */; }; + DEB3070D2B61CF9500F9D46B /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 3DF7B79528846FCC005DD8CA /* Resources */; }; EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; }; EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; @@ -263,6 +333,13 @@ remoteGlobalIDString = 03A65E591C6BB0F50062603F; remoteInfo = "SQLite tvOS"; }; + DEB307142B61D07F00F9D46B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = EE247ACA1C3F04ED00AE3E12 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DEB306B82B61CEF500F9D46B; + remoteInfo = "SQLite visionOS"; + }; EE247ADF1C3F04ED00AE3E12 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = EE247ACA1C3F04ED00AE3E12 /* Project object */; @@ -340,6 +417,9 @@ DB58B21028FB864300F8EEA4 /* SchemaReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReader.swift; sourceTree = ""; }; DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteFeature.swift; sourceTree = ""; }; DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteVersion.swift; sourceTree = ""; }; + DEB306E52B61CEF500F9D46B /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DEB307112B61CF9500F9D46B /* SQLiteTests visionOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests visionOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + DEB307132B61D04500F9D46B /* SQLite visionOS.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = "SQLite visionOS.xctestplan"; path = "Tests/SQLite visionOS.xctestplan"; sourceTree = ""; }; EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = ""; }; EE247AD81C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -401,6 +481,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DEB306DF2B61CEF500F9D46B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DEB306E02B61CEF500F9D46B /* libsqlite3.tbd in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DEB3070A2B61CF9500F9D46B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DEB3070B2B61CF9500F9D46B /* SQLite.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EE247ACF1C3F04ED00AE3E12 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -517,6 +613,7 @@ 3D3C3CCB26E5568800759140 /* SQLite.playground */, EE247AD51C3F04ED00AE3E12 /* SQLite */, EE247AE11C3F04ED00AE3E12 /* SQLiteTests */, + DEB307132B61D04500F9D46B /* SQLite visionOS.xctestplan */, EE247B8A1C3F81D000AE3E12 /* Metadata */, EE247AD41C3F04ED00AE3E12 /* Products */, 3D67B3E41DB2469200A4F4C6 /* Frameworks */, @@ -535,6 +632,8 @@ 03A65E5A1C6BB0F50062603F /* SQLite.framework */, 03A65E631C6BB0F60062603F /* SQLiteTests tvOS.xctest */, A121AC451CA35C79005A31D1 /* SQLite.framework */, + DEB306E52B61CEF500F9D46B /* SQLite.framework */, + DEB307112B61CF9500F9D46B /* SQLiteTests visionOS.xctest */, ); name = Products; sourceTree = ""; @@ -679,6 +778,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DEB306B92B61CEF500F9D46B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DEB306BA2B61CEF500F9D46B /* SQLite.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EE247AD01C3F04ED00AE3E12 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -752,6 +859,42 @@ productReference = A121AC451CA35C79005A31D1 /* SQLite.framework */; productType = "com.apple.product-type.framework"; }; + DEB306B82B61CEF500F9D46B /* SQLite visionOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = DEB306E22B61CEF500F9D46B /* Build configuration list for PBXNativeTarget "SQLite visionOS" */; + buildPhases = ( + DEB306B92B61CEF500F9D46B /* Headers */, + DEB306BB2B61CEF500F9D46B /* Sources */, + DEB306DF2B61CEF500F9D46B /* Frameworks */, + DEB306E12B61CEF500F9D46B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "SQLite visionOS"; + productName = SQLite; + productReference = DEB306E52B61CEF500F9D46B /* SQLite.framework */; + productType = "com.apple.product-type.framework"; + }; + DEB306E72B61CF9500F9D46B /* SQLiteTests visionOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = DEB3070E2B61CF9500F9D46B /* Build configuration list for PBXNativeTarget "SQLiteTests visionOS" */; + buildPhases = ( + DEB306EA2B61CF9500F9D46B /* Sources */, + DEB3070A2B61CF9500F9D46B /* Frameworks */, + DEB3070C2B61CF9500F9D46B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DEB307152B61D07F00F9D46B /* PBXTargetDependency */, + ); + name = "SQLiteTests visionOS"; + productName = "SQLite tvOSTests"; + productReference = DEB307112B61CF9500F9D46B /* SQLiteTests visionOS.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; EE247AD21C3F04ED00AE3E12 /* SQLite iOS */ = { isa = PBXNativeTarget; buildConfigurationList = EE247AE71C3F04ED00AE3E12 /* Build configuration list for PBXNativeTarget "SQLite iOS" */; @@ -883,6 +1026,8 @@ 03A65E591C6BB0F50062603F /* SQLite tvOS */, 03A65E621C6BB0F60062603F /* SQLiteTests tvOS */, A121AC441CA35C79005A31D1 /* SQLite watchOS */, + DEB306B82B61CEF500F9D46B /* SQLite visionOS */, + DEB306E72B61CF9500F9D46B /* SQLiteTests visionOS */, ); }; /* End PBXProject section */ @@ -910,6 +1055,21 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DEB306E12B61CEF500F9D46B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DEB3070C2B61CF9500F9D46B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DEB3070D2B61CF9500F9D46B /* Resources in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EE247AD11C3F04ED00AE3E12 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1064,6 +1224,86 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DEB306BB2B61CEF500F9D46B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DEB306BC2B61CEF500F9D46B /* CoreFunctions.swift in Sources */, + DEB306BD2B61CEF500F9D46B /* Coding.swift in Sources */, + DEB306BE2B61CEF500F9D46B /* RTree.swift in Sources */, + DEB306BF2B61CEF500F9D46B /* Blob.swift in Sources */, + DEB306C02B61CEF500F9D46B /* URIQueryParameter.swift in Sources */, + DEB306C12B61CEF500F9D46B /* Foundation.swift in Sources */, + DEB306C22B61CEF500F9D46B /* Connection.swift in Sources */, + DEB306C32B61CEF500F9D46B /* Expression.swift in Sources */, + DEB306C42B61CEF500F9D46B /* Helpers.swift in Sources */, + DEB306C52B61CEF500F9D46B /* Collation.swift in Sources */, + DEB306C62B61CEF500F9D46B /* Setter.swift in Sources */, + DEB306C72B61CEF500F9D46B /* Connection+Attach.swift in Sources */, + DEB306C82B61CEF500F9D46B /* CustomFunctions.swift in Sources */, + DEB306C92B61CEF500F9D46B /* FTS4.swift in Sources */, + DEB306CA2B61CEF500F9D46B /* Value.swift in Sources */, + DEB306CB2B61CEF500F9D46B /* Operators.swift in Sources */, + DEB306CC2B61CEF500F9D46B /* Schema.swift in Sources */, + DEB306CD2B61CEF500F9D46B /* Query.swift in Sources */, + DEB306CE2B61CEF500F9D46B /* Statement.swift in Sources */, + DEB306CF2B61CEF500F9D46B /* AggregateFunctions.swift in Sources */, + DEB306D02B61CEF500F9D46B /* FTS5.swift in Sources */, + DEB306D12B61CEF500F9D46B /* Cipher.swift in Sources */, + DEB306D22B61CEF500F9D46B /* Backup.swift in Sources */, + DEB306D32B61CEF500F9D46B /* Errors.swift in Sources */, + DEB306D42B61CEF500F9D46B /* DateAndTimeFunctions.swift in Sources */, + DEB306D52B61CEF500F9D46B /* SQLiteVersion.swift in Sources */, + DEB306D62B61CEF500F9D46B /* Result.swift in Sources */, + DEB306D72B61CEF500F9D46B /* Query+with.swift in Sources */, + DEB306D82B61CEF500F9D46B /* Connection+Aggregation.swift in Sources */, + DEB306D92B61CEF500F9D46B /* SQLiteFeature.swift in Sources */, + DEB306DA2B61CEF500F9D46B /* SchemaChanger.swift in Sources */, + DEB306DB2B61CEF500F9D46B /* SchemaDefinitions.swift in Sources */, + DEB306DC2B61CEF500F9D46B /* Connection+Schema.swift in Sources */, + DEB306DD2B61CEF500F9D46B /* Connection+Pragmas.swift in Sources */, + DEB306DE2B61CEF500F9D46B /* SchemaReader.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DEB306EA2B61CF9500F9D46B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DEB306EB2B61CF9500F9D46B /* TestHelpers.swift in Sources */, + DEB306EC2B61CF9500F9D46B /* FoundationTests.swift in Sources */, + DEB306ED2B61CF9500F9D46B /* Fixtures.swift in Sources */, + DEB306EE2B61CF9500F9D46B /* SchemaDefinitionsTests.swift in Sources */, + DEB306EF2B61CF9500F9D46B /* SchemaChangerTests.swift in Sources */, + DEB306F02B61CF9500F9D46B /* Connection+SchemaTests.swift in Sources */, + DEB306F12B61CF9500F9D46B /* FTS5Tests.swift in Sources */, + DEB306F22B61CF9500F9D46B /* FTSIntegrationTests.swift in Sources */, + DEB306F32B61CF9500F9D46B /* FTS4Tests.swift in Sources */, + DEB306F42B61CF9500F9D46B /* ExpressionTests.swift in Sources */, + DEB306F52B61CF9500F9D46B /* StatementTests.swift in Sources */, + DEB306F62B61CF9500F9D46B /* QueryTests.swift in Sources */, + DEB306F72B61CF9500F9D46B /* CipherTests.swift in Sources */, + DEB306F82B61CF9500F9D46B /* BlobTests.swift in Sources */, + DEB306F92B61CF9500F9D46B /* ConnectionTests.swift in Sources */, + DEB306FA2B61CF9500F9D46B /* CoreFunctionsTests.swift in Sources */, + DEB306FB2B61CF9500F9D46B /* DateAndTimeFunctionTests.swift in Sources */, + DEB306FC2B61CF9500F9D46B /* CustomFunctionsTests.swift in Sources */, + DEB306FD2B61CF9500F9D46B /* OperatorsTests.swift in Sources */, + DEB306FE2B61CF9500F9D46B /* ResultTests.swift in Sources */, + DEB306FF2B61CF9500F9D46B /* RTreeTests.swift in Sources */, + DEB307002B61CF9500F9D46B /* SchemaTests.swift in Sources */, + DEB307012B61CF9500F9D46B /* SelectTests.swift in Sources */, + DEB307022B61CF9500F9D46B /* ValueTests.swift in Sources */, + DEB307032B61CF9500F9D46B /* QueryIntegrationTests.swift in Sources */, + DEB307042B61CF9500F9D46B /* AggregateFunctionsTests.swift in Sources */, + DEB307052B61CF9500F9D46B /* CustomAggregationTests.swift in Sources */, + DEB307062B61CF9500F9D46B /* SetterTests.swift in Sources */, + DEB307072B61CF9500F9D46B /* RowTests.swift in Sources */, + DEB307082B61CF9500F9D46B /* Connection+PragmaTests.swift in Sources */, + DEB307092B61CF9500F9D46B /* Connection+AttachTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EE247ACE1C3F04ED00AE3E12 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1232,6 +1472,11 @@ target = 03A65E591C6BB0F50062603F /* SQLite tvOS */; targetProxy = 03A65E651C6BB0F60062603F /* PBXContainerItemProxy */; }; + DEB307152B61D07F00F9D46B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DEB306B82B61CEF500F9D46B /* SQLite visionOS */; + targetProxy = DEB307142B61D07F00F9D46B /* PBXContainerItemProxy */; + }; EE247AE01C3F04ED00AE3E12 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EE247AD21C3F04ED00AE3E12 /* SQLite iOS */; @@ -1365,6 +1610,83 @@ }; name = Release; }; + DEB306E32B61CEF500F9D46B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MARKETING_VERSION = 0.14.0; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SDKROOT = xros; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; + TARGETED_DEVICE_FAMILY = 7; + }; + name = Debug; + }; + DEB306E42B61CEF500F9D46B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MARKETING_VERSION = 0.14.0; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; + PRODUCT_NAME = SQLite; + SDKROOT = xros; + SKIP_INSTALL = YES; + SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; + TARGETED_DEVICE_FAMILY = 7; + }; + name = Release; + }; + DEB3070F2B61CF9500F9D46B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; + TARGETED_DEVICE_FAMILY = 7; + }; + name = Debug; + }; + DEB307102B61CF9500F9D46B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = xros; + SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; + TARGETED_DEVICE_FAMILY = 7; + }; + name = Release; + }; EE247AE51C3F04ED00AE3E12 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1502,7 +1824,6 @@ GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MARKETING_VERSION = 0.14.0; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; @@ -1526,7 +1847,6 @@ GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MARKETING_VERSION = 0.14.0; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; @@ -1541,7 +1861,6 @@ buildSettings = { GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1554,7 +1873,6 @@ buildSettings = { GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1674,6 +1992,24 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DEB306E22B61CEF500F9D46B /* Build configuration list for PBXNativeTarget "SQLite visionOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DEB306E32B61CEF500F9D46B /* Debug */, + DEB306E42B61CEF500F9D46B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DEB3070E2B61CF9500F9D46B /* Build configuration list for PBXNativeTarget "SQLiteTests visionOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DEB3070F2B61CF9500F9D46B /* Debug */, + DEB307102B61CF9500F9D46B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; EE247ACD1C3F04ED00AE3E12 /* Build configuration list for PBXProject "SQLite" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite visionOS.xcscheme b/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite visionOS.xcscheme new file mode 100644 index 00000000..58783573 --- /dev/null +++ b/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite visionOS.xcscheme @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/SQLite visionOS.xctestplan b/Tests/SQLite visionOS.xctestplan new file mode 100644 index 00000000..9b4e90ed --- /dev/null +++ b/Tests/SQLite visionOS.xctestplan @@ -0,0 +1,24 @@ +{ + "configurations" : [ + { + "id" : "72B91FD4-441C-4C06-9E92-CAEDCB7325AB", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:SQLite.xcodeproj", + "identifier" : "DEB306E72B61CF9500F9D46B", + "name" : "SQLiteTests visionOS" + } + } + ], + "version" : 1 +} From 9043277c83fcddf18d325192616ec5214c3a50df Mon Sep 17 00:00:00 2001 From: Nathan Fallet Date: Tue, 6 Feb 2024 18:54:57 +0100 Subject: [PATCH 12/84] Using macOS 14 to build --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9cc2f56e..d4fc87d8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ env: IOS_VERSION: "16.2" jobs: build: - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v2 - name: "Select Xcode" From 623ac53da9a23e6e8d53acdcc07291b8496580c5 Mon Sep 17 00:00:00 2001 From: Nathan Fallet Date: Tue, 6 Feb 2024 18:56:12 +0100 Subject: [PATCH 13/84] Xcode 15? --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d4fc87d8..ec25e7bf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: # https://github.com/CocoaPods/CocoaPods/issues/11839 run: | xcode-select -p - sudo xcode-select -s /Applications/Xcode_14.2.app/Contents/Developer + sudo xcode-select -s /Applications/Xcode_15.0.1.app/Contents/Developer - name: "Lint" run: make lint - name: "Run tests (PACKAGE_MANAGER_COMMAND: test)" From 0c68b99da0e8378a0d43c7ad6911b98e437dd8c1 Mon Sep 17 00:00:00 2001 From: Nathan Fallet Date: Tue, 6 Feb 2024 19:00:02 +0100 Subject: [PATCH 14/84] Testing using iOS 17 --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec25e7bf..7be89270 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,8 +1,8 @@ name: Build and test on: [push, pull_request] env: - IOS_SIMULATOR: "iPhone 14" - IOS_VERSION: "16.2" + IOS_SIMULATOR: "iPhone 15" + IOS_VERSION: "17.2" jobs: build: runs-on: macos-14 From 03724bf3d28a16ac0197027d47956b8039c42e69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elfred=20Pag=C3=A1n?= Date: Tue, 20 Feb 2024 20:06:37 -0600 Subject: [PATCH 15/84] make fromDatatypeValue throw When using custom types, sometimes decoding can fail, say due to changes in the type structure. In this case decoding would fail and the only way to handle it is forcing a crash. This change allows you to use `try row.get()` instead. Givng you the chance to handle the mismatch. --- Sources/SQLite/Core/Value.swift | 2 +- Sources/SQLite/Helpers.swift | 4 ++-- Sources/SQLite/Typed/Query.swift | 12 +++++------ Tests/SQLiteTests/Typed/RowTests.swift | 30 ++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Sources/SQLite/Core/Value.swift b/Sources/SQLite/Core/Value.swift index 9c463f0c..249a7728 100644 --- a/Sources/SQLite/Core/Value.swift +++ b/Sources/SQLite/Core/Value.swift @@ -39,7 +39,7 @@ public protocol Value: Expressible { // extensions cannot have inheritance claus static var declaredDatatype: String { get } - static func fromDatatypeValue(_ datatypeValue: Datatype) -> ValueType + static func fromDatatypeValue(_ datatypeValue: Datatype) throws -> ValueType var datatypeValue: Datatype { get } diff --git a/Sources/SQLite/Helpers.swift b/Sources/SQLite/Helpers.swift index adfadc8a..c27ccf05 100644 --- a/Sources/SQLite/Helpers.swift +++ b/Sources/SQLite/Helpers.swift @@ -121,9 +121,9 @@ func transcode(_ literal: Binding?) -> String { } } -// swiftlint:disable force_cast +// swiftlint:disable force_cast force_try func value(_ binding: Binding) -> A { - A.fromDatatypeValue(binding as! A.Datatype) as! A + try! A.fromDatatypeValue(binding as! A.Datatype) as! A } func value(_ binding: Binding?) -> A { diff --git a/Sources/SQLite/Typed/Query.swift b/Sources/SQLite/Typed/Query.swift index c59b728f..2a83665c 100644 --- a/Sources/SQLite/Typed/Query.swift +++ b/Sources/SQLite/Typed/Query.swift @@ -1097,7 +1097,7 @@ extension Connection { public func scalar(_ query: ScalarQuery) throws -> V.ValueType? { let expression = query.expression guard let value = try scalar(expression.template, expression.bindings) as? V.Datatype else { return nil } - return V.fromDatatypeValue(value) + return try V.fromDatatypeValue(value) } public func scalar(_ query: Select) throws -> V { @@ -1108,7 +1108,7 @@ extension Connection { public func scalar(_ query: Select) throws -> V.ValueType? { let expression = query.expression guard let value = try scalar(expression.template, expression.bindings) as? V.Datatype else { return nil } - return V.fromDatatypeValue(value) + return try V.fromDatatypeValue(value) } public func pluck(_ query: QueryType) throws -> Row? { @@ -1200,9 +1200,9 @@ public struct Row { } public func get(_ column: Expression) throws -> V? { - func valueAtIndex(_ idx: Int) -> V? { + func valueAtIndex(_ idx: Int) throws -> V? { guard let value = values[idx] as? V.Datatype else { return nil } - return V.fromDatatypeValue(value) as? V + return try V.fromDatatypeValue(value) as? V } guard let idx = columnNames[column.template] else { @@ -1224,10 +1224,10 @@ public struct Row { similar: columnNames.keys.filter(similar).sorted() ) } - return valueAtIndex(columnNames[firstIndex].value) + return try valueAtIndex(columnNames[firstIndex].value) } - return valueAtIndex(idx) + return try valueAtIndex(idx) } public subscript(column: Expression) -> T { diff --git a/Tests/SQLiteTests/Typed/RowTests.swift b/Tests/SQLiteTests/Typed/RowTests.swift index 506f6b10..14fa373b 100644 --- a/Tests/SQLiteTests/Typed/RowTests.swift +++ b/Tests/SQLiteTests/Typed/RowTests.swift @@ -85,4 +85,34 @@ class RowTests: XCTestCase { } } } + + public func test_get_datatype_throws() { + // swiftlint:disable nesting + struct MyType: Value { + enum MyError: Error { + case failed + } + + public static var declaredDatatype: String { + Blob.declaredDatatype + } + + public static func fromDatatypeValue(_ dataValue: Blob) throws -> Data { + throw MyError.failed + } + + public var datatypeValue: Blob { + return Blob(bytes: []) + } + } + + let row = Row(["\"foo\"": 0], [Blob(bytes: [])]) + XCTAssertThrowsError(try row.get(Expression("foo"))) { error in + if case MyType.MyError.failed = error { + XCTAssertTrue(true) + } else { + XCTFail("unexpected error: \(error)") + } + } + } } From 5bfaddf455a152a276e534b24c98ff08c67d3f63 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Fri, 23 Feb 2024 13:50:42 +0100 Subject: [PATCH 16/84] fix: json tests (due to a swift upgrade) --- Tests/SQLiteTests/TestHelpers.swift | 10 ++++++++++ Tests/SQLiteTests/Typed/QueryTests.swift | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Tests/SQLiteTests/TestHelpers.swift b/Tests/SQLiteTests/TestHelpers.swift index 65cff8bb..e2da5927 100644 --- a/Tests/SQLiteTests/TestHelpers.swift +++ b/Tests/SQLiteTests/TestHelpers.swift @@ -105,6 +105,16 @@ func assertSQL(_ expression1: @autoclosure () -> String, _ expression2: @autoclo XCTAssertEqual(expression1(), expression2().asSQL(), file: file, line: line) } +func extractAndReplace(_ value: String, regex: String, with replacement: String) -> (String, String) { + // We cannot use `Regex` because it is not available before iOS 16 :( + let regex = try! NSRegularExpression(pattern: regex) + let valueRange = NSRange(location: 0, length: value.utf16.count) + let match = regex.firstMatch(in: value, options: [], range: valueRange)!.range + let range = Range(match, in: value)! + let extractedValue = String(value[range]) + return (value.replacingCharacters(in: range, with: replacement), extractedValue) +} + let table = Table("table") let qualifiedTable = Table("table", database: "main") let virtualTable = VirtualTable("virtual_table") diff --git a/Tests/SQLiteTests/Typed/QueryTests.swift b/Tests/SQLiteTests/Typed/QueryTests.swift index 82a33808..f698c621 100644 --- a/Tests/SQLiteTests/Typed/QueryTests.swift +++ b/Tests/SQLiteTests/Typed/QueryTests.swift @@ -364,13 +364,22 @@ class QueryTests: XCTestCase { let insert = try emails.insert(value) let encodedJSON = try JSONEncoder().encode(value1) let encodedJSONString = String(data: encodedJSON, encoding: .utf8)! - assertSQL( + + let expectedSQL = """ INSERT INTO \"emails\" (\"int\", \"string\", \"bool\", \"float\", \"double\", \"date\", \"uuid\", \"optional\", \"sub\") VALUES (1, '2', 1, 3.0, 4.0, '1970-01-01T00:00:00.000', 'E621E1F8-C36C-495A-93FC-0C247A3E6E5F', 'optional', '\(encodedJSONString)') - """.replacingOccurrences(of: "\n", with: ""), - insert + """.replacingOccurrences(of: "\n", with: "") + + // As JSON serialization gives a different result each time, we extract JSON and compare it by deserializing it + // and keep comparing the query but with the json replaced by the `JSON` string + let (expectedQuery, expectedJSON) = extractAndReplace(expectedSQL, regex: "\\{.*\\}", with: "JSON") + let (actualQuery, actualJSON) = extractAndReplace(insert.asSQL(), regex: "\\{.*\\}", with: "JSON") + XCTAssertEqual(expectedQuery, actualQuery) + XCTAssertEqual( + try JSONDecoder().decode(TestCodable.self, from: expectedJSON.data(using: .utf8)!), + try JSONDecoder().decode(TestCodable.self, from: actualJSON.data(using: .utf8)!) ) } #endif From 485b677b8991287bf9b91de2b7d18f3eff21c38e Mon Sep 17 00:00:00 2001 From: Nathan Fallet Date: Fri, 23 Feb 2024 14:26:22 +0100 Subject: [PATCH 17/84] Revert "Add privacy manifest" --- SQLite.xcodeproj/project.pbxproj | 16 ---------------- Sources/SQLite/PrivacyInfo.xcprivacy | 14 -------------- 2 files changed, 30 deletions(-) delete mode 100644 Sources/SQLite/PrivacyInfo.xcprivacy diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index 8eb1df66..def32855 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -211,13 +211,6 @@ DB7C5DA728D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA828D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA928D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; - EAE1E1542B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; - EAE1E1552B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; - EAE1E1562B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; - EAE1E1572B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; - EAE1E1582B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; - EAE1E1592B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; - EAE1E15A2B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */; }; EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; }; EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; @@ -347,7 +340,6 @@ DB58B21028FB864300F8EEA4 /* SchemaReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReader.swift; sourceTree = ""; }; DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteFeature.swift; sourceTree = ""; }; DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteVersion.swift; sourceTree = ""; }; - EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = ""; }; EE247AD81C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -554,7 +546,6 @@ EE247AF71C3F06E900AE3E12 /* Foundation.swift */, EE247AF81C3F06E900AE3E12 /* Helpers.swift */, EE247AD81C3F04ED00AE3E12 /* Info.plist */, - EAE1E1532B473B0C0048B157 /* PrivacyInfo.xcprivacy */, EE247AED1C3F06E900AE3E12 /* Core */, EE247AF41C3F06E900AE3E12 /* Extensions */, EE247AF91C3F06E900AE3E12 /* Typed */, @@ -901,7 +892,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - EAE1E1582B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -909,7 +899,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - EAE1E1592B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, 3DF7B79828846FED005DD8CA /* Resources in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -918,7 +907,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - EAE1E15A2B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -926,7 +914,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - EAE1E1542B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -934,7 +921,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - EAE1E1552B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, 3DF7B79628846FCC005DD8CA /* Resources in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -943,7 +929,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - EAE1E1562B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -951,7 +936,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - EAE1E1572B473B0C0048B157 /* PrivacyInfo.xcprivacy in Resources */, 3DF7B79928847055005DD8CA /* Resources in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/SQLite/PrivacyInfo.xcprivacy b/Sources/SQLite/PrivacyInfo.xcprivacy deleted file mode 100644 index 987771fa..00000000 --- a/Sources/SQLite/PrivacyInfo.xcprivacy +++ /dev/null @@ -1,14 +0,0 @@ - - - - - NSPrivacyTrackingDomains - - NSPrivacyCollectedDataTypes - - NSPrivacyAccessedAPITypes - - NSPrivacyTracking - - - From fec58b90b7a340377d16dfcce89027a6b6f81e26 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Fri, 23 Feb 2024 14:47:00 +0100 Subject: [PATCH 18/84] fix: ios deployment target --- SQLite.swift.podspec | 2 +- SQLite.xcodeproj/project.pbxproj | 4 ++-- .../xcshareddata/xcschemes/SQLite visionOS.xcscheme | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index 4edddd67..b8aaaa8f 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -18,7 +18,7 @@ Pod::Spec.new do |s| s.default_subspec = 'standard' s.swift_versions = ['5'] - ios_deployment_target = '11.0' + ios_deployment_target = '17.0' tvos_deployment_target = '11.0' osx_deployment_target = '10.13' watchos_deployment_target = '4.0' diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index 857c6fd9..d23b6d64 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -1736,7 +1736,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -1795,7 +1795,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = ""; diff --git a/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite visionOS.xcscheme b/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite visionOS.xcscheme index 58783573..c1536b66 100644 --- a/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite visionOS.xcscheme +++ b/SQLite.xcodeproj/xcshareddata/xcschemes/SQLite visionOS.xcscheme @@ -15,7 +15,7 @@ @@ -55,7 +55,7 @@ From ce125ce64c03e9fcd142f18aca254637c223be8c Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Fri, 23 Feb 2024 15:37:04 +0100 Subject: [PATCH 19/84] fix: deployment targets? --- SQLite.swift.podspec | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index b8aaaa8f..2a75f169 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -19,9 +19,9 @@ Pod::Spec.new do |s| s.swift_versions = ['5'] ios_deployment_target = '17.0' - tvos_deployment_target = '11.0' - osx_deployment_target = '10.13' - watchos_deployment_target = '4.0' + tvos_deployment_target = '17.0' + osx_deployment_target = '14.0' + watchos_deployment_target = '10.0' s.ios.deployment_target = ios_deployment_target s.tvos.deployment_target = tvos_deployment_target @@ -32,6 +32,11 @@ Pod::Spec.new do |s| ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}' ss.exclude_files = 'Sources/**/Cipher.swift' ss.library = 'sqlite3' + + ss.ios.deployment_target = ios_deployment_target + ss.tvos.deployment_target = tvos_deployment_target + ss.osx.deployment_target = osx_deployment_target + ss.watchos.deployment_target = watchos_deployment_target ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' @@ -51,6 +56,11 @@ Pod::Spec.new do |s| 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SQLITE_SWIFT_STANDALONE=1' } ss.dependency 'sqlite3' + + ss.ios.deployment_target = ios_deployment_target + ss.tvos.deployment_target = tvos_deployment_target + ss.osx.deployment_target = osx_deployment_target + ss.watchos.deployment_target = watchos_deployment_target ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' @@ -68,6 +78,11 @@ Pod::Spec.new do |s| 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SQLITE_HAS_CODEC=1 SQLITE_SWIFT_SQLCIPHER=1' } ss.dependency 'SQLCipher', '>= 4.0.0' + + ss.ios.deployment_target = ios_deployment_target + ss.tvos.deployment_target = tvos_deployment_target + ss.osx.deployment_target = osx_deployment_target + ss.watchos.deployment_target = watchos_deployment_target ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' From e7813517c80c5bd79d4e7029ec8a89121f5afe60 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 23 Feb 2024 12:51:28 -0800 Subject: [PATCH 20/84] Add privacy manifest - fixes build issue https://github.com/stephencelis/SQLite.swift/actions/runs/8019552944/job/21907598856 --- SQLite.xcodeproj/project.pbxproj | 10 ++++++++++ Sources/SQLite/PrivacyInfo.xcprivacy | 14 ++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 Sources/SQLite/PrivacyInfo.xcprivacy diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index 37c8a802..0b246a00 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -221,6 +221,10 @@ DBB93D5A2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; DBB93D5B2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; DBB93D5C2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; + EAE5A0372B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; }; + EAE5A0382B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; }; + EAE5A0392B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; }; + EAE5A03A2B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; }; EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; }; EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; }; @@ -353,6 +357,7 @@ DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteFeature.swift; sourceTree = ""; }; DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteVersion.swift; sourceTree = ""; }; DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReaderTests.swift; sourceTree = ""; }; + EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = ""; }; EE247AD81C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -560,6 +565,7 @@ EE247AD61C3F04ED00AE3E12 /* SQLite.h */, EE247AF71C3F06E900AE3E12 /* Foundation.swift */, EE247AF81C3F06E900AE3E12 /* Helpers.swift */, + EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */, EE247AD81C3F04ED00AE3E12 /* Info.plist */, EE247AED1C3F06E900AE3E12 /* Core */, EE247AF41C3F06E900AE3E12 /* Extensions */, @@ -908,6 +914,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE5A0392B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -923,6 +930,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE5A03A2B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -930,6 +938,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE5A0372B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -945,6 +954,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + EAE5A0382B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/SQLite/PrivacyInfo.xcprivacy b/Sources/SQLite/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..987771fa --- /dev/null +++ b/Sources/SQLite/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTrackingDomains + + NSPrivacyCollectedDataTypes + + NSPrivacyAccessedAPITypes + + NSPrivacyTracking + + + From e78ae0220e17525a15ac68c697a155eb7a672a8e Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Sat, 24 Feb 2024 11:51:41 +0100 Subject: [PATCH 21/84] changelogs --- CHANGELOG.md | 33 ++++++++++++++++++++++++++++++-- Documentation/Index.md | 42 ++++++++++++++++++++++++++++++----------- README.md | 4 ++-- SQLite.swift.podspec | 2 +- Tests/SPM/Package.swift | 2 +- 5 files changed, 66 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 970b4ca1..4c5c1fba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ -0.15.0 (unreleased) +0.15.0 (24-02-2024), [diff][diff-0.15.0] ======================================== +* Fix incorrect behavior when preparing `SELECT *` preceded by a `WITH` ([#1179][]) +* Adds support for returning extended error codes ([#1178][]) +* Fix typos ([#1182][]) +* fix Xcode build error ([#1192][]) +* Make the IndexDefinition properties public ([#1196][]) +* Fix GitHub Actions build badge ([#1200][]) +* Run CI on macOS 13 ([#1206][]) +* SchemaReader: return the correct column definition for a composite primary key ([#1217][]) +* Add optional support for decoding ([#1224][]) +* make fromDatatypeValue throw ([#1242][]) +* Implements built-in window functions ([#1228][]) +* Fix column affinity parsing to match how SQLite determines affinity ([#1218][]) +* Handle FK definitions w/o key references ([#1210][]) +* Add privacy manifest ([#1245][]) * New minimum deployment targets: iOS/tvOS 11.0, watchOS 4.0 0.14.1 (01-11-2022), [diff][diff-0.14.1] @@ -14,7 +28,7 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). * Support more complex schema changes and queries ([#1073][], [#1146][] [#1148][]) * Support `ATTACH`/`DETACH` ([#30][], [#1142][]) -* Expose connection flags (via `URIQueryParameter`) to open db ([#1074][])) +* Expose connection flags (via `URIQueryParameter`) to open db ([#1074][]) * Support `WITH` clause ([#1139][]) * Add `Value` conformance for `NSURL` ([#1110][], [#1141][]) * Add decoding for `UUID` ([#1137][]) @@ -140,6 +154,7 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). [diff-0.13.3]: https://github.com/stephencelis/SQLite.swift/compare/0.13.2...0.13.3 [diff-0.14.0]: https://github.com/stephencelis/SQLite.swift/compare/0.13.3...0.14.0 [diff-0.14.1]: https://github.com/stephencelis/SQLite.swift/compare/0.14.0...0.14.1 +[diff-0.15.0]: https://github.com/stephencelis/SQLite.swift/compare/0.14.0...0.15.0 [#30]: https://github.com/stephencelis/SQLite.swift/issues/30 [#142]: https://github.com/stephencelis/SQLite.swift/issues/142 @@ -206,3 +221,17 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). [#1146]: https://github.com/stephencelis/SQLite.swift/pull/1146 [#1148]: https://github.com/stephencelis/SQLite.swift/pull/1148 [#1167]: https://github.com/stephencelis/SQLite.swift/pull/1167 +[#1179]: https://github.com/stephencelis/SQLite.swift/pull/1179 +[#1178]: https://github.com/stephencelis/SQLite.swift/pull/1178 +[#1182]: https://github.com/stephencelis/SQLite.swift/pull/1182 +[#1192]: https://github.com/stephencelis/SQLite.swift/pull/1192 +[#1196]: https://github.com/stephencelis/SQLite.swift/pull/1196 +[#1200]: https://github.com/stephencelis/SQLite.swift/pull/1200 +[#1206]: https://github.com/stephencelis/SQLite.swift/pull/1206 +[#1217]: https://github.com/stephencelis/SQLite.swift/pull/1217 +[#1224]: https://github.com/stephencelis/SQLite.swift/pull/1224 +[#1242]: https://github.com/stephencelis/SQLite.swift/pull/1242 +[#1228]: https://github.com/stephencelis/SQLite.swift/pull/1228 +[#1218]: https://github.com/stephencelis/SQLite.swift/pull/1218 +[#1210]: https://github.com/stephencelis/SQLite.swift/pull/1210 +[#1245]: https://github.com/stephencelis/SQLite.swift/pull/1245 diff --git a/Documentation/Index.md b/Documentation/Index.md index a03c26a3..7f900bc5 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -1,21 +1,24 @@ # SQLite.swift Documentation +- [SQLite.swift Documentation](#sqliteswift-documentation) - [Installation](#installation) - [Swift Package Manager](#swift-package-manager) - [Carthage](#carthage) - [CocoaPods](#cocoapods) + - [Requiring a specific version of SQLite](#requiring-a-specific-version-of-sqlite) + - [Using SQLite.swift with SQLCipher](#using-sqliteswift-with-sqlcipher) - [Manual](#manual) - [Getting Started](#getting-started) - [Connecting to a Database](#connecting-to-a-database) - [Read-Write Databases](#read-write-databases) - [Read-Only Databases](#read-only-databases) - - [In a Shared Group Container](#in-a-shared-group-container) + - [In a shared group container](#in-a-shared-group-container) - [In-Memory Databases](#in-memory-databases) - [URI parameters](#uri-parameters) - [Thread-Safety](#thread-safety) - [Building Type-Safe SQL](#building-type-safe-sql) - [Expressions](#expressions) - - [Compound Expressions](#compound-expressions) + - [Compound Expressions](#compound-expressions) - [Queries](#queries) - [Creating a Table](#creating-a-table) - [Create Table Options](#create-table-options) @@ -24,8 +27,11 @@ - [Inserting Rows](#inserting-rows) - [Handling SQLite errors](#handling-sqlite-errors) - [Setters](#setters) + - [Infix Setters](#infix-setters) + - [Postfix Setters](#postfix-setters) - [Selecting Rows](#selecting-rows) - [Iterating and Accessing Values](#iterating-and-accessing-values) + - [Failable iteration](#failable-iteration) - [Plucking Rows](#plucking-rows) - [Building Complex Queries](#building-complex-queries) - [Selecting Columns](#selecting-columns) @@ -34,6 +40,9 @@ - [Table Aliasing](#table-aliasing) - [Filtering Rows](#filtering-rows) - [Filter Operators and Functions](#filter-operators-and-functions) + - [Infix Filter Operators](#infix-filter-operators) + - [Prefix Filter Operators](#prefix-filter-operators) + - [Filtering Functions](#filtering-functions) - [Sorting Rows](#sorting-rows) - [Limiting and Paging Results](#limiting-and-paging-results) - [Recursive and Hierarchical Queries](#recursive-and-hierarchical-queries) @@ -43,13 +52,14 @@ - [Deleting Rows](#deleting-rows) - [Transactions and Savepoints](#transactions-and-savepoints) - [Querying the Schema](#querying-the-schema) + - [Indexes and Columns](#indexes-and-columns) - [Altering the Schema](#altering-the-schema) - [Renaming Tables](#renaming-tables) - [Dropping Tables](#dropping-tables) - [Adding Columns](#adding-columns) - [Added Column Constraints](#added-column-constraints) - - [Schema Changer](#schemachanger) - - [Adding Columns](#adding-columns) + - [SchemaChanger](#schemachanger) + - [Adding Columns](#adding-columns-1) - [Renaming Columns](#renaming-columns) - [Dropping Columns](#dropping-columns) - [Renaming/Dropping Tables](#renamingdropping-tables) @@ -61,17 +71,27 @@ - [Date-Time Values](#date-time-values) - [Binary Data](#binary-data) - [Codable Types](#codable-types) + - [Inserting Codable Types](#inserting-codable-types) + - [Updating Codable Types](#updating-codable-types) + - [Retrieving Codable Types](#retrieving-codable-types) + - [Restrictions](#restrictions) - [Other Operators](#other-operators) + - [Other Infix Operators](#other-infix-operators) + - [Other Prefix Operators](#other-prefix-operators) - [Core SQLite Functions](#core-sqlite-functions) - [Aggregate SQLite Functions](#aggregate-sqlite-functions) - [Window SQLite Functions](#window-sqlite-functions) - - [Date and Time Functions](#date-and-time-functions) + - [Date and Time functions](#date-and-time-functions) - [Custom SQL Functions](#custom-sql-functions) + - [Custom Aggregations](#custom-aggregations) - [Custom Collations](#custom-collations) - [Full-text Search](#full-text-search) + - [FTS5](#fts5) - [Executing Arbitrary SQL](#executing-arbitrary-sql) + - [Online Database Backup](#online-database-backup) - [Attaching and detaching databases](#attaching-and-detaching-databases) - [Logging](#logging) + - [Vacuum](#vacuum) [↩]: #sqliteswift-documentation @@ -88,7 +108,7 @@ process of downloading, compiling, and linking dependencies. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.0") ] ``` @@ -109,7 +129,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.14.1 + github "stephencelis/SQLite.swift" ~> 0.15.0 ``` 3. Run `carthage update` and [add the appropriate framework][Carthage Usage]. @@ -139,7 +159,7 @@ install SQLite.swift with Carthage: use_frameworks! target 'YourAppTargetName' do - pod 'SQLite.swift', '~> 0.14.1' + pod 'SQLite.swift', '~> 0.15.0' end ``` @@ -153,7 +173,7 @@ with the OS you can require the `standalone` subspec: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.14.1' + pod 'SQLite.swift/standalone', '~> 0.15.0' end ``` @@ -163,7 +183,7 @@ dependency to sqlite3 or one of its subspecs: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.14.1' + pod 'SQLite.swift/standalone', '~> 0.15.0' pod 'sqlite3/fts5', '= 3.15.0' # SQLite 3.15.0 with FTS5 enabled end ``` @@ -179,7 +199,7 @@ If you want to use [SQLCipher][] with SQLite.swift you can require the target 'YourAppTargetName' do # Make sure you only require the subspec, otherwise you app might link against # the system SQLite, which means the SQLCipher-specific methods won't work. - pod 'SQLite.swift/SQLCipher', '~> 0.14.1' + pod 'SQLite.swift/SQLCipher', '~> 0.15.0' end ``` diff --git a/README.md b/README.md index e6e5a894..117edb5a 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Swift code. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.0") ] ``` @@ -152,7 +152,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.14.1 + github "stephencelis/SQLite.swift" ~> 0.15.0 ``` 3. Run `carthage update` and diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index 4edddd67..b691aeab 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SQLite.swift" - s.version = "0.14.1" + s.version = "0.15.0" s.summary = "A type-safe, Swift-language layer over SQLite3." s.description = <<-DESC diff --git a/Tests/SPM/Package.swift b/Tests/SPM/Package.swift index 3c446ae6..c82b3b9e 100644 --- a/Tests/SPM/Package.swift +++ b/Tests/SPM/Package.swift @@ -15,7 +15,7 @@ let package = Package( // for testing from same repository .package(path: "../..") // normally this would be: - // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.14.1") + // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.0") ], targets: [ .executableTarget(name: "test", dependencies: [.product(name: "SQLite", package: "SQLite.swift")]) From 20ebe9b334ff557c1166e26ca6c89e94a77a7f2d Mon Sep 17 00:00:00 2001 From: Chris Stockbridge Date: Mon, 4 Mar 2024 20:07:22 -0500 Subject: [PATCH 22/84] Adding failing test that includes an optional struct This test passes with release 0.14.1, but fails starting with 0.15 --- .../Typed/QueryIntegrationTests.swift | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift index aa45cafe..7ac72d0c 100644 --- a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift +++ b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift @@ -152,6 +152,33 @@ class QueryIntegrationTests: SQLiteTestCase { XCTAssertEqual(values.count, 2) } + func test_insert_custom_encodable_type() throws { + struct TestTypeWithOptionalArray: Codable { + var myInt: Int + var myString: String + var myOptionalArray: [Int]? + } + + let table = Table("custom_codable") + try db.run(table.create { builder in + builder.column(Expression("myInt")) + builder.column(Expression("myString")) + builder.column(Expression("myOptionalArray")) + }) + + let customType = TestTypeWithOptionalArray(myInt: 13, myString: "foo", myOptionalArray: [1, 2, 3]) + try db.run(table.insert(customType)) + let rows = try db.prepare(table) + let values: [TestTypeWithOptionalArray] = try rows.map({ try $0.decode() }) + XCTAssertEqual(values.count, 1, "return one optional custom type") + + let customTypeWithNil = TestTypeWithOptionalArray(myInt: 123, myString: "String", myOptionalArray: nil) + try db.run(table.insert(customTypeWithNil)) + let rowsNil = try db.prepare(table) + let valuesNil: [TestTypeWithOptionalArray] = try rowsNil.map({ try $0.decode() }) + XCTAssertEqual(valuesNil.count, 2, "return two custom objects, including one that contains a nil optional") + } + func test_upsert() throws { try XCTSkipUnless(db.satisfiesMinimumVersion(minor: 24)) let fetchAge = { () throws -> Int? in From bad16cb5d1a09e93bbdb40f50df5f222920a10e3 Mon Sep 17 00:00:00 2001 From: Chris Stockbridge Date: Tue, 5 Mar 2024 11:11:50 -0500 Subject: [PATCH 23/84] Bugfix: returning nil when decoding an optional should not throw an error --- Sources/SQLite/Typed/Coding.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Sources/SQLite/Typed/Coding.swift b/Sources/SQLite/Typed/Coding.swift index bfddc5ee..d0061851 100644 --- a/Sources/SQLite/Typed/Coding.swift +++ b/Sources/SQLite/Typed/Coding.swift @@ -504,9 +504,8 @@ private class SQLiteDecoder: Decoder { case is UUID.Type: return try? row.get(Expression(key.stringValue)) as? T default: - guard let JSONString = try? row.get(Expression(key.stringValue)) else { - throw DecodingError.typeMismatch(type, DecodingError.Context(codingPath: codingPath, - debugDescription: "an unsupported type was found")) + guard let JSONString = try row.get(Expression(key.stringValue)) else { + return nil } guard let data = JSONString.data(using: .utf8) else { throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, From cda8a1274a5c426c043bea6d381fddab630dad95 Mon Sep 17 00:00:00 2001 From: Steven Date: Sun, 17 Mar 2024 01:10:17 +0800 Subject: [PATCH 24/84] Update CoreFunctions.swift fix typo fix lower to upper --- Sources/SQLite/Typed/CoreFunctions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SQLite/Typed/CoreFunctions.swift b/Sources/SQLite/Typed/CoreFunctions.swift index 4429bb5f..c4359d8b 100644 --- a/Sources/SQLite/Typed/CoreFunctions.swift +++ b/Sources/SQLite/Typed/CoreFunctions.swift @@ -224,7 +224,7 @@ extension ExpressionType where UnderlyingType == String { /// /// let name = Expression("name") /// name.uppercaseString - /// // lower("name") + /// // upper("name") /// /// - Returns: A copy of the expression wrapped with the `upper` function. public var uppercaseString: Expression { From 6d821f83499500cb7bb7f258655fe83ac6f890ed Mon Sep 17 00:00:00 2001 From: Sagar Dagdu Date: Sat, 13 Apr 2024 08:23:49 +0530 Subject: [PATCH 25/84] Add dependency on custom cocoapods fork --- Gemfile | 1 + Gemfile.lock | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 Gemfile create mode 100644 Gemfile.lock diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..2f97c391 --- /dev/null +++ b/Gemfile @@ -0,0 +1 @@ +gem 'cocoapods', :git => 'https://github.com/SagarSDagdu/CocoaPods.git', tag: '1.15.2.1-sagard' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..75374a30 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,116 @@ +GIT + remote: https://github.com/SagarSDagdu/CocoaPods.git + revision: d96f491f79abd2804d1359c5228cce404dd365b7 + tag: 1.15.2.1-sagard + specs: + cocoapods (1.15.2.1.pre.sagard) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.15.2) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 2.1, < 3.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) + nap (~> 1.0) + ruby-macho (>= 2.3.0, < 3.0) + xcodeproj (>= 1.23.0, < 2.0) + +GEM + specs: + CFPropertyList (3.0.7) + base64 + nkf + rexml + activesupport (7.1.3.2) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + minitest (>= 5.1) + mutex_m + tzinfo (~> 2.0) + addressable (2.8.6) + public_suffix (>= 2.0.2, < 6.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + base64 (0.2.0) + bigdecimal (3.1.5) + claide (1.1.0) + cocoapods-core (1.15.2) + activesupport (>= 5.0, < 8) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (2.1) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) + colored2 (3.1.2) + concurrent-ruby (1.2.3) + connection_pool (2.4.1) + drb (2.2.0) + ruby2_keywords + escape (0.0.4) + ethon (0.16.0) + ffi (>= 1.15.0) + ffi (1.16.3) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + httpclient (2.8.3) + i18n (1.14.4) + concurrent-ruby (~> 1.0) + json (2.7.1) + minitest (5.22.0) + molinillo (0.8.0) + mutex_m (0.2.0) + nanaimo (0.3.0) + nap (1.1.0) + netrc (0.11.0) + nkf (0.1.3) + public_suffix (4.0.7) + rexml (3.2.6) + ruby-macho (2.5.1) + ruby2_keywords (0.0.5) + typhoeus (1.4.1) + ethon (>= 0.9.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + xcodeproj (1.24.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + rexml (~> 3.2.4) + +PLATFORMS + arm64-darwin-23 + ruby + +DEPENDENCIES + cocoapods! + +BUNDLED WITH + 2.5.4 From 6491e381d7f827ced234e6aa7edca0a92f25eff6 Mon Sep 17 00:00:00 2001 From: Sagar Dagdu Date: Sat, 13 Apr 2024 08:24:03 +0530 Subject: [PATCH 26/84] Update deployment targets for Xcode 15 --- SQLite.swift.podspec | 4 ++-- SQLite.xcodeproj/project.pbxproj | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index b691aeab..4a7a390c 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -18,8 +18,8 @@ Pod::Spec.new do |s| s.default_subspec = 'standard' s.swift_versions = ['5'] - ios_deployment_target = '11.0' - tvos_deployment_target = '11.0' + ios_deployment_target = '12.0' + tvos_deployment_target = '12.0' osx_deployment_target = '10.13' watchos_deployment_target = '4.0' diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index 0b246a00..c5215807 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -1299,7 +1299,7 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Debug; }; @@ -1321,7 +1321,7 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Release; }; @@ -1335,7 +1335,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Debug; }; @@ -1349,7 +1349,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_TREAT_WARNINGS_AS_ERRORS = YES; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; }; name = Release; }; @@ -1450,7 +1450,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -1459,7 +1459,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3"; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; WATCHOS_DEPLOYMENT_TARGET = 4.0; @@ -1509,7 +1509,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = ""; @@ -1517,7 +1517,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3"; - TVOS_DEPLOYMENT_TARGET = 11.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1538,7 +1538,7 @@ GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MARKETING_VERSION = 0.14.0; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; @@ -1562,7 +1562,7 @@ GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MARKETING_VERSION = 0.14.0; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; @@ -1577,7 +1577,7 @@ buildSettings = { GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1590,7 +1590,7 @@ buildSettings = { GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Tests/SQLiteTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLiteTests; PRODUCT_NAME = "$(TARGET_NAME)"; From c4ec236be4b089984c8239869309bd4c637642b6 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Sat, 13 Apr 2024 15:17:15 +0200 Subject: [PATCH 27/84] using temp cocoapods (fix xcode 15 build, to be reverted later) --- run-tests.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/run-tests.sh b/run-tests.sh index 49330c12..1bf8de96 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -7,10 +7,11 @@ if [ -n "$BUILD_SCHEME" ]; then make test BUILD_SCHEME="$BUILD_SCHEME" fi elif [ -n "$VALIDATOR_SUBSPEC" ]; then + bundle install if [ "$VALIDATOR_SUBSPEC" == "none" ]; then - pod lib lint --no-subspecs --fail-fast + bundle exec pod lib lint --no-subspecs --fail-fast else - pod lib lint --subspec="${VALIDATOR_SUBSPEC}" --fail-fast + bundle exec pod lib lint --subspec="${VALIDATOR_SUBSPEC}" --fail-fast fi elif [ -n "$CARTHAGE_PLATFORM" ]; then cd Tests/Carthage && make test CARTHAGE_PLATFORM="$CARTHAGE_PLATFORM" From a6e7697bac187dd6ee5ee8026e7fca91235e5b73 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Sat, 13 Apr 2024 15:31:08 +0200 Subject: [PATCH 28/84] fixing bundle versions? --- Gemfile.lock | 2 +- run-tests.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 75374a30..159cbf9c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -82,7 +82,7 @@ GEM i18n (1.14.4) concurrent-ruby (~> 1.0) json (2.7.1) - minitest (5.22.0) + minitest (5.22.3) molinillo (0.8.0) mutex_m (0.2.0) nanaimo (0.3.0) diff --git a/run-tests.sh b/run-tests.sh index 1bf8de96..13975f0e 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -7,7 +7,7 @@ if [ -n "$BUILD_SCHEME" ]; then make test BUILD_SCHEME="$BUILD_SCHEME" fi elif [ -n "$VALIDATOR_SUBSPEC" ]; then - bundle install + bundle install --deployment if [ "$VALIDATOR_SUBSPEC" == "none" ]; then bundle exec pod lib lint --no-subspecs --fail-fast else From 9bed2450cbd38352a5a3316b2817bec8baf4f5d3 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Sat, 13 Apr 2024 15:38:17 +0200 Subject: [PATCH 29/84] adding source for gems as otherwise it does not resolve correctly in CI --- Gemfile | 2 ++ Gemfile.lock | 11 +++++------ run-tests.sh | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Gemfile b/Gemfile index 2f97c391..eb6036cd 100644 --- a/Gemfile +++ b/Gemfile @@ -1 +1,3 @@ +source "https://rubygems.org" + gem 'cocoapods', :git => 'https://github.com/SagarSDagdu/CocoaPods.git', tag: '1.15.2.1-sagard' diff --git a/Gemfile.lock b/Gemfile.lock index 159cbf9c..a58783ea 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,6 +23,7 @@ GIT xcodeproj (>= 1.23.0, < 2.0) GEM + remote: https://rubygems.org/ specs: CFPropertyList (3.0.7) base64 @@ -45,7 +46,7 @@ GEM json (>= 1.5.1) atomos (0.1.3) base64 (0.2.0) - bigdecimal (3.1.5) + bigdecimal (3.1.7) claide (1.1.0) cocoapods-core (1.15.2) activesupport (>= 5.0, < 8) @@ -69,8 +70,7 @@ GEM colored2 (3.1.2) concurrent-ruby (1.2.3) connection_pool (2.4.1) - drb (2.2.0) - ruby2_keywords + drb (2.2.1) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) @@ -81,18 +81,17 @@ GEM httpclient (2.8.3) i18n (1.14.4) concurrent-ruby (~> 1.0) - json (2.7.1) + json (2.7.2) minitest (5.22.3) molinillo (0.8.0) mutex_m (0.2.0) nanaimo (0.3.0) nap (1.1.0) netrc (0.11.0) - nkf (0.1.3) + nkf (0.2.0) public_suffix (4.0.7) rexml (3.2.6) ruby-macho (2.5.1) - ruby2_keywords (0.0.5) typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) diff --git a/run-tests.sh b/run-tests.sh index 13975f0e..1bf8de96 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -7,7 +7,7 @@ if [ -n "$BUILD_SCHEME" ]; then make test BUILD_SCHEME="$BUILD_SCHEME" fi elif [ -n "$VALIDATOR_SUBSPEC" ]; then - bundle install --deployment + bundle install if [ "$VALIDATOR_SUBSPEC" == "none" ]; then bundle exec pod lib lint --no-subspecs --fail-fast else From 6be8ca943138e3b3d77bb14b74c1b498d75b0cf4 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Sat, 13 Apr 2024 16:30:09 +0200 Subject: [PATCH 30/84] fix carthage location? --- Tests/Carthage/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Carthage/Makefile b/Tests/Carthage/Makefile index b44d85b9..fe708ab0 100644 --- a/Tests/Carthage/Makefile +++ b/Tests/Carthage/Makefile @@ -1,4 +1,4 @@ -CARTHAGE := /usr/local/bin/carthage +CARTHAGE := $(shell which carthage) CARTHAGE_PLATFORM := iOS CARTHAGE_CONFIGURATION := Release CARTHAGE_DIR := Carthage From a2a550e6266e80ebe4d896d1360cff4ef9ad202a Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Sat, 13 Apr 2024 17:18:49 +0200 Subject: [PATCH 31/84] bump xcode version + carthage visionOS tests --- .github/workflows/build.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7be89270..9fbba1c5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,7 +13,7 @@ jobs: # https://github.com/CocoaPods/CocoaPods/issues/11839 run: | xcode-select -p - sudo xcode-select -s /Applications/Xcode_15.0.1.app/Contents/Developer + sudo xcode-select -s /Applications/Xcode_15.3.app/Contents/Developer - name: "Lint" run: make lint - name: "Run tests (PACKAGE_MANAGER_COMMAND: test)" @@ -64,6 +64,10 @@ jobs: env: CARTHAGE_PLATFORM: tvOS run: ./run-tests.sh + - name: "Run tests (CARTHAGE_PLATFORM: visionOS)" + env: + CARTHAGE_PLATFORM: visionOS + run: ./run-tests.sh build-linux: runs-on: ubuntu-latest steps: From f0af5e0a2b6917ae38e3019e3456fd0fa9365864 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Sat, 13 Apr 2024 18:55:58 +0200 Subject: [PATCH 32/84] Changelogs v0.15.1 --- CHANGELOG.md | 13 +++++++++++++ Documentation/Index.md | 12 ++++++------ README.md | 4 ++-- SQLite.swift.podspec | 2 +- Tests/SPM/Package.swift | 2 +- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c5c1fba..79085ce3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +0.15.1 (14-04-2024), [diff][diff-0.15.1] +======================================== + +* Update CoreFunctions.swift fix typo ([#1249][]) +* Fix #1247 support nil case when decoding optionals ([#1248][]) +* Change deployment targets for Xcode 15 and add dependency on custom Cocoapods fork ([#1255][]) +* Add VisionOS support ([#1237][]) + 0.15.0 (24-02-2024), [diff][diff-0.15.0] ======================================== @@ -155,6 +163,7 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). [diff-0.14.0]: https://github.com/stephencelis/SQLite.swift/compare/0.13.3...0.14.0 [diff-0.14.1]: https://github.com/stephencelis/SQLite.swift/compare/0.14.0...0.14.1 [diff-0.15.0]: https://github.com/stephencelis/SQLite.swift/compare/0.14.0...0.15.0 +[diff-0.15.1]: https://github.com/stephencelis/SQLite.swift/compare/0.15.0...0.15.1 [#30]: https://github.com/stephencelis/SQLite.swift/issues/30 [#142]: https://github.com/stephencelis/SQLite.swift/issues/142 @@ -235,3 +244,7 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). [#1218]: https://github.com/stephencelis/SQLite.swift/pull/1218 [#1210]: https://github.com/stephencelis/SQLite.swift/pull/1210 [#1245]: https://github.com/stephencelis/SQLite.swift/pull/1245 +[#1249]: https://github.com/stephencelis/SQLite.swift/pull/1249 +[#1248]: https://github.com/stephencelis/SQLite.swift/pull/1248 +[#1255]: https://github.com/stephencelis/SQLite.swift/pull/1255 +[#1237]: https://github.com/stephencelis/SQLite.swift/pull/1237 diff --git a/Documentation/Index.md b/Documentation/Index.md index 7f900bc5..edb9dab3 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -108,7 +108,7 @@ process of downloading, compiling, and linking dependencies. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.0") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.1") ] ``` @@ -129,7 +129,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.15.0 + github "stephencelis/SQLite.swift" ~> 0.15.1 ``` 3. Run `carthage update` and [add the appropriate framework][Carthage Usage]. @@ -159,7 +159,7 @@ install SQLite.swift with Carthage: use_frameworks! target 'YourAppTargetName' do - pod 'SQLite.swift', '~> 0.15.0' + pod 'SQLite.swift', '~> 0.15.1' end ``` @@ -173,7 +173,7 @@ with the OS you can require the `standalone` subspec: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.15.0' + pod 'SQLite.swift/standalone', '~> 0.15.1' end ``` @@ -183,7 +183,7 @@ dependency to sqlite3 or one of its subspecs: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.15.0' + pod 'SQLite.swift/standalone', '~> 0.15.1' pod 'sqlite3/fts5', '= 3.15.0' # SQLite 3.15.0 with FTS5 enabled end ``` @@ -199,7 +199,7 @@ If you want to use [SQLCipher][] with SQLite.swift you can require the target 'YourAppTargetName' do # Make sure you only require the subspec, otherwise you app might link against # the system SQLite, which means the SQLCipher-specific methods won't work. - pod 'SQLite.swift/SQLCipher', '~> 0.15.0' + pod 'SQLite.swift/SQLCipher', '~> 0.15.1' end ``` diff --git a/README.md b/README.md index 117edb5a..51090e5d 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Swift code. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.0") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.1") ] ``` @@ -152,7 +152,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.15.0 + github "stephencelis/SQLite.swift" ~> 0.15.1 ``` 3. Run `carthage update` and diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index 860fe3d4..035fffb0 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SQLite.swift" - s.version = "0.15.0" + s.version = "0.15.1" s.summary = "A type-safe, Swift-language layer over SQLite3." s.description = <<-DESC diff --git a/Tests/SPM/Package.swift b/Tests/SPM/Package.swift index c82b3b9e..5a96daff 100644 --- a/Tests/SPM/Package.swift +++ b/Tests/SPM/Package.swift @@ -15,7 +15,7 @@ let package = Package( // for testing from same repository .package(path: "../..") // normally this would be: - // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.0") + // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.1") ], targets: [ .executableTarget(name: "test", dependencies: [.product(name: "SQLite", package: "SQLite.swift")]) From fc236997c8e1b21be4ecaaa547496857483dcf6b Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Tue, 16 Apr 2024 05:40:47 +0200 Subject: [PATCH 33/84] fix: visionos to cocoapods --- CHANGELOG.md | 6 ++++++ Documentation/Index.md | 12 ++++++------ README.md | 4 ++-- SQLite.swift.podspec | 7 ++++++- Tests/SPM/Package.swift | 2 +- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79085ce3..376c19d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +0.15.2 (16-04-2024), [diff][diff-0.15.2] +======================================== +* fix: visionos to cocoapods ([#1260][]) + 0.15.1 (14-04-2024), [diff][diff-0.15.1] ======================================== @@ -164,6 +168,7 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). [diff-0.14.1]: https://github.com/stephencelis/SQLite.swift/compare/0.14.0...0.14.1 [diff-0.15.0]: https://github.com/stephencelis/SQLite.swift/compare/0.14.0...0.15.0 [diff-0.15.1]: https://github.com/stephencelis/SQLite.swift/compare/0.15.0...0.15.1 +[diff-0.15.2]: https://github.com/stephencelis/SQLite.swift/compare/0.15.1...0.15.2 [#30]: https://github.com/stephencelis/SQLite.swift/issues/30 [#142]: https://github.com/stephencelis/SQLite.swift/issues/142 @@ -248,3 +253,4 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). [#1248]: https://github.com/stephencelis/SQLite.swift/pull/1248 [#1255]: https://github.com/stephencelis/SQLite.swift/pull/1255 [#1237]: https://github.com/stephencelis/SQLite.swift/pull/1237 +[#1260]: https://github.com/stephencelis/SQLite.swift/pull/1260 diff --git a/Documentation/Index.md b/Documentation/Index.md index edb9dab3..adbbff8b 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -108,7 +108,7 @@ process of downloading, compiling, and linking dependencies. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.1") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.2") ] ``` @@ -129,7 +129,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.15.1 + github "stephencelis/SQLite.swift" ~> 0.15.2 ``` 3. Run `carthage update` and [add the appropriate framework][Carthage Usage]. @@ -159,7 +159,7 @@ install SQLite.swift with Carthage: use_frameworks! target 'YourAppTargetName' do - pod 'SQLite.swift', '~> 0.15.1' + pod 'SQLite.swift', '~> 0.15.2' end ``` @@ -173,7 +173,7 @@ with the OS you can require the `standalone` subspec: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.15.1' + pod 'SQLite.swift/standalone', '~> 0.15.2' end ``` @@ -183,7 +183,7 @@ dependency to sqlite3 or one of its subspecs: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.15.1' + pod 'SQLite.swift/standalone', '~> 0.15.2' pod 'sqlite3/fts5', '= 3.15.0' # SQLite 3.15.0 with FTS5 enabled end ``` @@ -199,7 +199,7 @@ If you want to use [SQLCipher][] with SQLite.swift you can require the target 'YourAppTargetName' do # Make sure you only require the subspec, otherwise you app might link against # the system SQLite, which means the SQLCipher-specific methods won't work. - pod 'SQLite.swift/SQLCipher', '~> 0.15.1' + pod 'SQLite.swift/SQLCipher', '~> 0.15.2' end ``` diff --git a/README.md b/README.md index 51090e5d..a87ab937 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Swift code. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.1") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.2") ] ``` @@ -152,7 +152,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.15.1 + github "stephencelis/SQLite.swift" ~> 0.15.2 ``` 3. Run `carthage update` and diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index 035fffb0..efed67c1 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SQLite.swift" - s.version = "0.15.1" + s.version = "0.15.2" s.summary = "A type-safe, Swift-language layer over SQLite3." s.description = <<-DESC @@ -22,11 +22,13 @@ Pod::Spec.new do |s| tvos_deployment_target = '12.0' osx_deployment_target = '10.13' watchos_deployment_target = '4.0' + visionos_deployment_target = '1.0' s.ios.deployment_target = ios_deployment_target s.tvos.deployment_target = tvos_deployment_target s.osx.deployment_target = osx_deployment_target s.watchos.deployment_target = watchos_deployment_target + s.visionos.deployment_target = visionos_deployment_target s.subspec 'standard' do |ss| ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}' @@ -37,6 +39,7 @@ Pod::Spec.new do |s| ss.tvos.deployment_target = tvos_deployment_target ss.osx.deployment_target = osx_deployment_target ss.watchos.deployment_target = watchos_deployment_target + ss.visionos.deployment_target = visionos_deployment_target ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' @@ -61,6 +64,7 @@ Pod::Spec.new do |s| ss.tvos.deployment_target = tvos_deployment_target ss.osx.deployment_target = osx_deployment_target ss.watchos.deployment_target = watchos_deployment_target + ss.visionos.deployment_target = visionos_deployment_target ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' @@ -83,6 +87,7 @@ Pod::Spec.new do |s| ss.tvos.deployment_target = tvos_deployment_target ss.osx.deployment_target = osx_deployment_target ss.watchos.deployment_target = watchos_deployment_target + ss.visionos.deployment_target = visionos_deployment_target ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' diff --git a/Tests/SPM/Package.swift b/Tests/SPM/Package.swift index 5a96daff..b73ecd83 100644 --- a/Tests/SPM/Package.swift +++ b/Tests/SPM/Package.swift @@ -15,7 +15,7 @@ let package = Package( // for testing from same repository .package(path: "../..") // normally this would be: - // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.1") + // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.2") ], targets: [ .executableTarget(name: "test", dependencies: [.product(name: "SQLite", package: "SQLite.swift")]) From 8f75f4609221c55901cf60b1438b7a8441af145e Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Tue, 16 Apr 2024 06:06:25 +0200 Subject: [PATCH 34/84] gonna fix that later --- SQLite.swift.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index efed67c1..88713c9e 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -87,7 +87,7 @@ Pod::Spec.new do |s| ss.tvos.deployment_target = tvos_deployment_target ss.osx.deployment_target = osx_deployment_target ss.watchos.deployment_target = watchos_deployment_target - ss.visionos.deployment_target = visionos_deployment_target + #ss.visionos.deployment_target = visionos_deployment_target # Not supported by SQLCipher for now ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' From 15fe07e3d5d0555a7f03966114ce5a9390823af7 Mon Sep 17 00:00:00 2001 From: Sagar Dagdu Date: Thu, 18 Apr 2024 18:57:43 +0530 Subject: [PATCH 35/84] Update the marketing version to the version we will be releasing next For recent releases, the `Info.plist` shipped inside the `xcframeworks` do not match the release version. Fixing that to reflect the marketing version we will be releasing next. --- SQLite.xcodeproj/project.pbxproj | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index 79de22e7..a2d7edbe 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -218,6 +218,9 @@ DB7C5DA728D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA828D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; DB7C5DA928D7C9B6006395CF /* SQLiteVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */; }; + DBB93D5A2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; + DBB93D5B2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; + DBB93D5C2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; DEB306BA2B61CEF500F9D46B /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; }; DEB306BC2B61CEF500F9D46B /* CoreFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */; }; DEB306BD2B61CEF500F9D46B /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; }; @@ -288,9 +291,6 @@ DEB307092B61CF9500F9D46B /* Connection+AttachTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A170C08525D3D27CB5F83C /* Connection+AttachTests.swift */; }; DEB3070B2B61CF9500F9D46B /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E5A1C6BB0F50062603F /* SQLite.framework */; }; DEB3070D2B61CF9500F9D46B /* Resources in Resources */ = {isa = PBXBuildFile; fileRef = 3DF7B79528846FCC005DD8CA /* Resources */; }; - DBB93D5A2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; - DBB93D5B2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; - DBB93D5C2A22A373009BB96E /* SchemaReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */; }; EAE5A0372B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; }; EAE5A0382B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; }; EAE5A0392B893C43007C7EA4 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */; }; @@ -433,10 +433,10 @@ DB58B21028FB864300F8EEA4 /* SchemaReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReader.swift; sourceTree = ""; }; DB58B21528FC7C4600F8EEA4 /* SQLiteFeature.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteFeature.swift; sourceTree = ""; }; DB7C5DA528D7C9B6006395CF /* SQLiteVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteVersion.swift; sourceTree = ""; }; + DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReaderTests.swift; sourceTree = ""; }; DEB306E52B61CEF500F9D46B /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DEB307112B61CF9500F9D46B /* SQLiteTests visionOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests visionOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; DEB307132B61D04500F9D46B /* SQLite visionOS.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = "SQLite visionOS.xctestplan"; path = "Tests/SQLite visionOS.xctestplan"; sourceTree = ""; }; - DBB93D592A22A373009BB96E /* SchemaReaderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaReaderTests.swift; sourceTree = ""; }; EAE5A0362B893C43007C7EA4 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = ""; }; @@ -1539,6 +1539,7 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = appletvos; @@ -1561,6 +1562,7 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = appletvos; @@ -1612,6 +1614,7 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = watchos; @@ -1636,6 +1639,7 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = watchos; @@ -1660,7 +1664,7 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.14.0; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = xros; @@ -1685,7 +1689,7 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.14.0; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = xros; @@ -1862,7 +1866,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.14.0; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SKIP_INSTALL = YES; @@ -1886,7 +1890,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.14.0; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SKIP_INSTALL = YES; @@ -1936,6 +1940,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.13; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = macosx; @@ -1961,6 +1966,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.13; + MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = macosx; From 5d3db22d9b1e979a3436d199f10bc7dddd4d3a39 Mon Sep 17 00:00:00 2001 From: Sagar Dagdu Date: Thu, 18 Apr 2024 21:26:22 +0530 Subject: [PATCH 36/84] Update `podspec` to include privacy manifest Update `podspec` to include privacy manifest --- SQLite.swift.podspec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index 88713c9e..e6aa2c6a 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -34,6 +34,7 @@ Pod::Spec.new do |s| ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}' ss.exclude_files = 'Sources/**/Cipher.swift' ss.library = 'sqlite3' + ss.resource_bundle = { 'SQLite.swift' => 'Sources/SQLite/PrivacyInfo.xcprivacy' } ss.ios.deployment_target = ios_deployment_target ss.tvos.deployment_target = tvos_deployment_target @@ -53,6 +54,7 @@ Pod::Spec.new do |s| s.subspec 'standalone' do |ss| ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}' ss.exclude_files = 'Sources/**/Cipher.swift' + ss.resource_bundle = { 'SQLite.swift' => 'Sources/SQLite/PrivacyInfo.xcprivacy' } ss.xcconfig = { 'OTHER_SWIFT_FLAGS' => '$(inherited) -DSQLITE_SWIFT_STANDALONE', @@ -77,6 +79,8 @@ Pod::Spec.new do |s| s.subspec 'SQLCipher' do |ss| ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}' + ss.resource_bundle = { 'SQLite.swift' => 'Sources/SQLite/PrivacyInfo.xcprivacy' } + ss.xcconfig = { 'OTHER_SWIFT_FLAGS' => '$(inherited) -DSQLITE_SWIFT_SQLCIPHER', 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SQLITE_HAS_CODEC=1 SQLITE_SWIFT_SQLCIPHER=1' From a95fc6df17d108bd99210db5e8a9bac90fe984b8 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Fri, 19 Apr 2024 02:50:43 +0200 Subject: [PATCH 37/84] v0.15.3 (oups) --- CHANGELOG.md | 5 +++++ Documentation/Index.md | 12 ++++++------ README.md | 4 ++-- SQLite.swift.podspec | 2 +- Tests/SPM/Package.swift | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 376c19d8..c96724fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +0.15.3 (19-04-2024), [diff][diff-0.15.3] +======================================== +* Update `podspec` to include privacy manifest ([#1265][]) + 0.15.2 (16-04-2024), [diff][diff-0.15.2] ======================================== * fix: visionos to cocoapods ([#1260][]) @@ -254,3 +258,4 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). [#1255]: https://github.com/stephencelis/SQLite.swift/pull/1255 [#1237]: https://github.com/stephencelis/SQLite.swift/pull/1237 [#1260]: https://github.com/stephencelis/SQLite.swift/pull/1260 +[#1265]: https://github.com/stephencelis/SQLite.swift/pull/1265 diff --git a/Documentation/Index.md b/Documentation/Index.md index adbbff8b..fcd2d642 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -108,7 +108,7 @@ process of downloading, compiling, and linking dependencies. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.2") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.3") ] ``` @@ -129,7 +129,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.15.2 + github "stephencelis/SQLite.swift" ~> 0.15.3 ``` 3. Run `carthage update` and [add the appropriate framework][Carthage Usage]. @@ -159,7 +159,7 @@ install SQLite.swift with Carthage: use_frameworks! target 'YourAppTargetName' do - pod 'SQLite.swift', '~> 0.15.2' + pod 'SQLite.swift', '~> 0.15.3' end ``` @@ -173,7 +173,7 @@ with the OS you can require the `standalone` subspec: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.15.2' + pod 'SQLite.swift/standalone', '~> 0.15.3' end ``` @@ -183,7 +183,7 @@ dependency to sqlite3 or one of its subspecs: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.15.2' + pod 'SQLite.swift/standalone', '~> 0.15.3' pod 'sqlite3/fts5', '= 3.15.0' # SQLite 3.15.0 with FTS5 enabled end ``` @@ -199,7 +199,7 @@ If you want to use [SQLCipher][] with SQLite.swift you can require the target 'YourAppTargetName' do # Make sure you only require the subspec, otherwise you app might link against # the system SQLite, which means the SQLCipher-specific methods won't work. - pod 'SQLite.swift/SQLCipher', '~> 0.15.2' + pod 'SQLite.swift/SQLCipher', '~> 0.15.3' end ``` diff --git a/README.md b/README.md index a87ab937..a4d713b6 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Swift code. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.2") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.3") ] ``` @@ -152,7 +152,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.15.2 + github "stephencelis/SQLite.swift" ~> 0.15.3 ``` 3. Run `carthage update` and diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index e6aa2c6a..184ce23e 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SQLite.swift" - s.version = "0.15.2" + s.version = "0.15.3" s.summary = "A type-safe, Swift-language layer over SQLite3." s.description = <<-DESC diff --git a/Tests/SPM/Package.swift b/Tests/SPM/Package.swift index b73ecd83..6521211a 100644 --- a/Tests/SPM/Package.swift +++ b/Tests/SPM/Package.swift @@ -15,7 +15,7 @@ let package = Package( // for testing from same repository .package(path: "../..") // normally this would be: - // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.2") + // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.3") ], targets: [ .executableTarget(name: "test", dependencies: [.product(name: "SQLite", package: "SQLite.swift")]) From 363141ac6c070799239593cf6dcad63fe33edd17 Mon Sep 17 00:00:00 2001 From: YiKai Deng Date: Thu, 26 Sep 2024 17:33:15 +0800 Subject: [PATCH 38/84] Add `CustomStringConvertible` for Setter --- Documentation/Upgrading.md | 4 +- Sources/SQLite/Typed/Setter.swift | 6 ++ .../Core/Connection+AttachTests.swift | 4 +- .../SQLiteTests/Core/CoreFunctionsTests.swift | 16 ++--- Tests/SQLiteTests/Core/StatementTests.swift | 4 +- Tests/SQLiteTests/Extensions/FTS4Tests.swift | 6 +- .../Extensions/FTSIntegrationTests.swift | 2 +- .../Schema/SchemaChangerTests.swift | 2 +- .../Schema/SchemaReaderTests.swift | 4 +- Tests/SQLiteTests/TestHelpers.swift | 32 ++++----- .../Typed/CustomFunctionsTests.swift | 28 ++++---- Tests/SQLiteTests/Typed/ExpressionTests.swift | 10 +-- Tests/SQLiteTests/Typed/OperatorsTests.swift | 2 +- .../Typed/QueryIntegrationTests.swift | 70 +++++++++---------- Tests/SQLiteTests/Typed/QueryTests.swift | 22 +++--- Tests/SQLiteTests/Typed/RowTests.swift | 22 +++--- Tests/SQLiteTests/Typed/SelectTests.swift | 8 +-- Tests/SQLiteTests/Typed/SetterTests.swift | 3 + .../Typed/WindowFunctionsTests.swift | 4 +- 19 files changed, 130 insertions(+), 119 deletions(-) diff --git a/Documentation/Upgrading.md b/Documentation/Upgrading.md index f2cc2ecb..0e12aacf 100644 --- a/Documentation/Upgrading.md +++ b/Documentation/Upgrading.md @@ -4,6 +4,8 @@ - `Expression.asSQL()` is no longer available. Expressions now implement `CustomStringConvertible`, where `description` returns the SQL. -- `Statement.prepareRowIterator()` is now longer available. Instead, use the methods +- `Statement.prepareRowIterator()` is no longer available. Instead, use the methods of the same name on `Connection`. - `Connection.registerTokenizer` is no longer available to register custom FTS4 tokenizers. +- `Setter.asSQL()` is no longer available. Instead, Setter now implement `CustomStringConvertible`, + where `description` returns the SQL. diff --git a/Sources/SQLite/Typed/Setter.swift b/Sources/SQLite/Typed/Setter.swift index 7910cab8..8dc8a0e0 100644 --- a/Sources/SQLite/Typed/Setter.swift +++ b/Sources/SQLite/Typed/Setter.swift @@ -75,6 +75,12 @@ extension Setter: Expressible { } +extension Setter: CustomStringConvertible { + public var description: String { + asSQL() + } +} + public func <-(column: Expression, value: Expression) -> Setter { Setter(column: column, value: value) } diff --git a/Tests/SQLiteTests/Core/Connection+AttachTests.swift b/Tests/SQLiteTests/Core/Connection+AttachTests.swift index 940a30ca..f37300ca 100644 --- a/Tests/SQLiteTests/Core/Connection+AttachTests.swift +++ b/Tests/SQLiteTests/Core/Connection+AttachTests.swift @@ -19,7 +19,7 @@ class ConnectionAttachTests: SQLiteTestCase { try db.attach(.inMemory, as: schemaName) let table = Table("attached_users", database: schemaName) - let name = Expression("string") + let name = SQLite.Expression("string") // create a table, insert some data try db.run(table.create { builder in @@ -41,7 +41,7 @@ class ConnectionAttachTests: SQLiteTestCase { try db.attach(.uri(testDb, parameters: [.mode(.readOnly)]), as: schemaName) let table = Table("tests", database: schemaName) - let email = Expression("email") + let email = SQLite.Expression("email") let rows = try db.prepare(table.select(email)).map { $0[email] } XCTAssertEqual(["foo@bar.com"], rows) diff --git a/Tests/SQLiteTests/Core/CoreFunctionsTests.swift b/Tests/SQLiteTests/Core/CoreFunctionsTests.swift index e03e3769..b866c4e9 100644 --- a/Tests/SQLiteTests/Core/CoreFunctionsTests.swift +++ b/Tests/SQLiteTests/Core/CoreFunctionsTests.swift @@ -12,8 +12,8 @@ class CoreFunctionsTests: XCTestCase { } func test_random_generatesExpressionWithRandomFunction() { - assertSQL("random()", Expression.random()) - assertSQL("random()", Expression.random()) + assertSQL("random()", SQLite.Expression.random()) + assertSQL("random()", SQLite.Expression.random()) } func test_length_wrapsStringExpressionWithLengthFunction() { @@ -38,14 +38,14 @@ class CoreFunctionsTests: XCTestCase { assertSQL("(\"string\" LIKE '%\\%' ESCAPE '\\')", string.like("%\\%", escape: "\\")) assertSQL("(\"stringOptional\" LIKE '_\\_' ESCAPE '\\')", stringOptional.like("_\\_", escape: "\\")) - assertSQL("(\"string\" LIKE \"a\")", string.like(Expression("a"))) - assertSQL("(\"stringOptional\" LIKE \"a\")", stringOptional.like(Expression("a"))) + assertSQL("(\"string\" LIKE \"a\")", string.like(SQLite.Expression("a"))) + assertSQL("(\"stringOptional\" LIKE \"a\")", stringOptional.like(SQLite.Expression("a"))) - assertSQL("(\"string\" LIKE \"a\" ESCAPE '\\')", string.like(Expression("a"), escape: "\\")) - assertSQL("(\"stringOptional\" LIKE \"a\" ESCAPE '\\')", stringOptional.like(Expression("a"), escape: "\\")) + assertSQL("(\"string\" LIKE \"a\" ESCAPE '\\')", string.like(SQLite.Expression("a"), escape: "\\")) + assertSQL("(\"stringOptional\" LIKE \"a\" ESCAPE '\\')", stringOptional.like(SQLite.Expression("a"), escape: "\\")) - assertSQL("('string' LIKE \"a\")", "string".like(Expression("a"))) - assertSQL("('string' LIKE \"a\" ESCAPE '\\')", "string".like(Expression("a"), escape: "\\")) + assertSQL("('string' LIKE \"a\")", "string".like(SQLite.Expression("a"))) + assertSQL("('string' LIKE \"a\" ESCAPE '\\')", "string".like(SQLite.Expression("a"), escape: "\\")) } func test_glob_buildsExpressionWithGlobOperator() { diff --git a/Tests/SQLiteTests/Core/StatementTests.swift b/Tests/SQLiteTests/Core/StatementTests.swift index 5f212505..dbf99d7c 100644 --- a/Tests/SQLiteTests/Core/StatementTests.swift +++ b/Tests/SQLiteTests/Core/StatementTests.swift @@ -27,7 +27,7 @@ class StatementTests: SQLiteTestCase { func test_zero_sized_blob_returns_null() throws { let blobs = Table("blobs") - let blobColumn = Expression("blob_column") + let blobColumn = SQLite.Expression("blob_column") try db.run(blobs.create { $0.column(blobColumn) }) try db.run(blobs.insert(blobColumn <- Blob(bytes: []))) let blobValue = try db.scalar(blobs.select(blobColumn).limit(1, offset: 0)) @@ -38,7 +38,7 @@ class StatementTests: SQLiteTestCase { let names = ["a", "b", "c"] try insertUsers(names) - let emailColumn = Expression("email") + let emailColumn = SQLite.Expression("email") let statement = try db.prepare("SELECT email FROM users") let emails = try statement.prepareRowIterator().map { $0[emailColumn] } diff --git a/Tests/SQLiteTests/Extensions/FTS4Tests.swift b/Tests/SQLiteTests/Extensions/FTS4Tests.swift index 5e595007..f7258fb5 100644 --- a/Tests/SQLiteTests/Extensions/FTS4Tests.swift +++ b/Tests/SQLiteTests/Extensions/FTS4Tests.swift @@ -35,9 +35,9 @@ class FTS4Tests: XCTestCase { } func test_match_onVirtualTableAsExpression_compilesMatchExpression() { - assertSQL("(\"virtual_table\" MATCH 'string')", virtualTable.match("string") as Expression) - assertSQL("(\"virtual_table\" MATCH \"string\")", virtualTable.match(string) as Expression) - assertSQL("(\"virtual_table\" MATCH \"stringOptional\")", virtualTable.match(stringOptional) as Expression) + assertSQL("(\"virtual_table\" MATCH 'string')", virtualTable.match("string") as SQLite.Expression) + assertSQL("(\"virtual_table\" MATCH \"string\")", virtualTable.match(string) as SQLite.Expression) + assertSQL("(\"virtual_table\" MATCH \"stringOptional\")", virtualTable.match(stringOptional) as SQLite.Expression) } func test_match_onVirtualTableAsQueryType_compilesMatchExpression() { diff --git a/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift b/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift index da9ba8dc..1129ae08 100644 --- a/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift +++ b/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift @@ -11,7 +11,7 @@ import SQLite3 @testable import SQLite class FTSIntegrationTests: SQLiteTestCase { - let email = Expression("email") + let email = SQLite.Expression("email") let index = VirtualTable("index") private func createIndex() throws { diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index 9f8e21f4..2bec6a06 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -92,7 +92,7 @@ class SchemaChangerTests: SQLiteTestCase { } func test_add_column() throws { - let column = Expression("new_column") + let column = SQLite.Expression("new_column") let newColumn = ColumnDefinition(name: "new_column", type: .TEXT, nullable: true, diff --git a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift index d57ebff7..8c033e41 100644 --- a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift @@ -163,7 +163,7 @@ class SchemaReaderTests: SQLiteTestCase { try db.run(linkTable.create(block: { definition in definition.column(idColumn, primaryKey: .autoincrement) - definition.column(testIdColumn, unique: false, check: nil, references: users, Expression("id")) + definition.column(testIdColumn, unique: false, check: nil, references: users, SQLite.Expression("id")) })) let foreignKeys = try schemaReader.foreignKeys(table: "test_links") @@ -238,7 +238,7 @@ class SchemaReaderTests: SQLiteTestCase { } func test_objectDefinitions_indexes() throws { - let emailIndex = users.createIndex(Expression("email"), unique: false, ifNotExists: true) + let emailIndex = users.createIndex(SQLite.Expression("email"), unique: false, ifNotExists: true) try db.run(emailIndex) let indexes = try schemaReader.objectDefinitions(type: .index) diff --git a/Tests/SQLiteTests/TestHelpers.swift b/Tests/SQLiteTests/TestHelpers.swift index e2da5927..56415a59 100644 --- a/Tests/SQLiteTests/TestHelpers.swift +++ b/Tests/SQLiteTests/TestHelpers.swift @@ -74,29 +74,29 @@ class SQLiteTestCase: XCTestCase { } -let bool = Expression("bool") -let boolOptional = Expression("boolOptional") +let bool = SQLite.Expression("bool") +let boolOptional = SQLite.Expression("boolOptional") -let data = Expression("blob") -let dataOptional = Expression("blobOptional") +let data = SQLite.Expression("blob") +let dataOptional = SQLite.Expression("blobOptional") -let date = Expression("date") -let dateOptional = Expression("dateOptional") +let date = SQLite.Expression("date") +let dateOptional = SQLite.Expression("dateOptional") -let double = Expression("double") -let doubleOptional = Expression("doubleOptional") +let double = SQLite.Expression("double") +let doubleOptional = SQLite.Expression("doubleOptional") -let int = Expression("int") -let intOptional = Expression("intOptional") +let int = SQLite.Expression("int") +let intOptional = SQLite.Expression("intOptional") -let int64 = Expression("int64") -let int64Optional = Expression("int64Optional") +let int64 = SQLite.Expression("int64") +let int64Optional = SQLite.Expression("int64Optional") -let string = Expression("string") -let stringOptional = Expression("stringOptional") +let string = SQLite.Expression("string") +let stringOptional = SQLite.Expression("stringOptional") -let uuid = Expression("uuid") -let uuidOptional = Expression("uuidOptional") +let uuid = SQLite.Expression("uuid") +let uuidOptional = SQLite.Expression("uuidOptional") let testUUIDValue = UUID(uuidString: "E621E1F8-C36C-495A-93FC-0C247A3E6E5F")! diff --git a/Tests/SQLiteTests/Typed/CustomFunctionsTests.swift b/Tests/SQLiteTests/Typed/CustomFunctionsTests.swift index 0f46b380..8598b6fb 100644 --- a/Tests/SQLiteTests/Typed/CustomFunctionsTests.swift +++ b/Tests/SQLiteTests/Typed/CustomFunctionsTests.swift @@ -5,8 +5,8 @@ import SQLite #if !os(Linux) class CustomFunctionNoArgsTests: SQLiteTestCase { - typealias FunctionNoOptional = () -> Expression - typealias FunctionResultOptional = () -> Expression + typealias FunctionNoOptional = () -> SQLite.Expression + typealias FunctionResultOptional = () -> SQLite.Expression func testFunctionNoOptional() throws { let _: FunctionNoOptional = try db.createFunction("test", deterministic: true) { @@ -26,10 +26,10 @@ class CustomFunctionNoArgsTests: SQLiteTestCase { } class CustomFunctionWithOneArgTests: SQLiteTestCase { - typealias FunctionNoOptional = (Expression) -> Expression - typealias FunctionLeftOptional = (Expression) -> Expression - typealias FunctionResultOptional = (Expression) -> Expression - typealias FunctionLeftResultOptional = (Expression) -> Expression + typealias FunctionNoOptional = (SQLite.Expression) -> SQLite.Expression + typealias FunctionLeftOptional = (SQLite.Expression) -> SQLite.Expression + typealias FunctionResultOptional = (SQLite.Expression) -> SQLite.Expression + typealias FunctionLeftResultOptional = (SQLite.Expression) -> SQLite.Expression func testFunctionNoOptional() throws { let _: FunctionNoOptional = try db.createFunction("test", deterministic: true) { a in @@ -65,14 +65,14 @@ class CustomFunctionWithOneArgTests: SQLiteTestCase { } class CustomFunctionWithTwoArgsTests: SQLiteTestCase { - typealias FunctionNoOptional = (Expression, Expression) -> Expression - typealias FunctionLeftOptional = (Expression, Expression) -> Expression - typealias FunctionRightOptional = (Expression, Expression) -> Expression - typealias FunctionResultOptional = (Expression, Expression) -> Expression - typealias FunctionLeftRightOptional = (Expression, Expression) -> Expression - typealias FunctionLeftResultOptional = (Expression, Expression) -> Expression - typealias FunctionRightResultOptional = (Expression, Expression) -> Expression - typealias FunctionLeftRightResultOptional = (Expression, Expression) -> Expression + typealias FunctionNoOptional = (SQLite.Expression, SQLite.Expression) -> SQLite.Expression + typealias FunctionLeftOptional = (SQLite.Expression, SQLite.Expression) -> SQLite.Expression + typealias FunctionRightOptional = (SQLite.Expression, SQLite.Expression) -> SQLite.Expression + typealias FunctionResultOptional = (SQLite.Expression, SQLite.Expression) -> SQLite.Expression + typealias FunctionLeftRightOptional = (SQLite.Expression, SQLite.Expression) -> SQLite.Expression + typealias FunctionLeftResultOptional = (SQLite.Expression, SQLite.Expression) -> SQLite.Expression + typealias FunctionRightResultOptional = (SQLite.Expression, SQLite.Expression) -> SQLite.Expression + typealias FunctionLeftRightResultOptional = (SQLite.Expression, SQLite.Expression) -> SQLite.Expression func testNoOptional() throws { let _: FunctionNoOptional = try db.createFunction("test", deterministic: true) { a, b in diff --git a/Tests/SQLiteTests/Typed/ExpressionTests.swift b/Tests/SQLiteTests/Typed/ExpressionTests.swift index 147d62e9..1b97fe94 100644 --- a/Tests/SQLiteTests/Typed/ExpressionTests.swift +++ b/Tests/SQLiteTests/Typed/ExpressionTests.swift @@ -4,17 +4,17 @@ import XCTest class ExpressionTests: XCTestCase { func test_asSQL_expression_bindings() { - let expression = Expression("foo ? bar", ["baz"]) + let expression = SQLite.Expression("foo ? bar", ["baz"]) XCTAssertEqual(expression.asSQL(), "foo 'baz' bar") } func test_asSQL_expression_bindings_quoting() { - let expression = Expression("foo ? bar", ["'baz'"]) + let expression = SQLite.Expression("foo ? bar", ["'baz'"]) XCTAssertEqual(expression.asSQL(), "foo '''baz''' bar") } func test_expression_custom_string_convertible() { - let expression = Expression("foo ? bar", ["baz"]) + let expression = SQLite.Expression("foo ? bar", ["baz"]) XCTAssertEqual(expression.asSQL(), expression.description) } @@ -24,12 +24,12 @@ class ExpressionTests: XCTestCase { } func test_init_literal() { - let expression = Expression(literal: "literal") + let expression = SQLite.Expression(literal: "literal") XCTAssertEqual(expression.template, "literal") } func test_init_identifier() { - let expression = Expression("identifier") + let expression = SQLite.Expression("identifier") XCTAssertEqual(expression.template, "\"identifier\"") } } diff --git a/Tests/SQLiteTests/Typed/OperatorsTests.swift b/Tests/SQLiteTests/Typed/OperatorsTests.swift index 370b910b..7a5d83da 100644 --- a/Tests/SQLiteTests/Typed/OperatorsTests.swift +++ b/Tests/SQLiteTests/Typed/OperatorsTests.swift @@ -356,7 +356,7 @@ class OperatorsTests: XCTestCase { } func test_precedencePreserved() { - let n = Expression(value: 1) + let n = SQLite.Expression(value: 1) assertSQL("(((1 = 1) AND (1 = 1)) OR (1 = 1))", (n == n && n == n) || n == n) assertSQL("((1 = 1) AND ((1 = 1) OR (1 = 1)))", n == n && (n == n || n == n)) } diff --git a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift index 7ac72d0c..6be98ca0 100644 --- a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift +++ b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift @@ -12,9 +12,9 @@ import SQLite3 class QueryIntegrationTests: SQLiteTestCase { - let id = Expression("id") - let email = Expression("email") - let age = Expression("age") + let id = SQLite.Expression("id") + let email = SQLite.Expression("email") + let age = SQLite.Expression("age") override func setUpWithError() throws { try super.setUpWithError() @@ -24,7 +24,7 @@ class QueryIntegrationTests: SQLiteTestCase { // MARK: - func test_select() throws { - let managerId = Expression("manager_id") + let managerId = SQLite.Expression("manager_id") let managers = users.alias("managers") let alice = try db.run(users.insert(email <- "alice@example.com")) @@ -39,7 +39,7 @@ class QueryIntegrationTests: SQLiteTestCase { let names = ["a", "b", "c"] try insertUsers(names) - let emailColumn = Expression("email") + let emailColumn = SQLite.Expression("email") let emails = try db.prepareRowIterator(users).map { $0[emailColumn] } XCTAssertEqual(names.map({ "\($0)@example.com" }), emails.sorted()) @@ -55,7 +55,7 @@ class QueryIntegrationTests: SQLiteTestCase { } func test_select_optional() throws { - let managerId = Expression("manager_id") + let managerId = SQLite.Expression("manager_id") let managers = users.alias("managers") let alice = try db.run(users.insert(email <- "alice@example.com")) @@ -69,15 +69,15 @@ class QueryIntegrationTests: SQLiteTestCase { func test_select_codable() throws { let table = Table("codable") try db.run(table.create { builder in - builder.column(Expression("int")) - builder.column(Expression("string")) - builder.column(Expression("bool")) - builder.column(Expression("float")) - builder.column(Expression("double")) - builder.column(Expression("date")) - builder.column(Expression("uuid")) - builder.column(Expression("optional")) - builder.column(Expression("sub")) + builder.column(SQLite.Expression("int")) + builder.column(SQLite.Expression("string")) + builder.column(SQLite.Expression("bool")) + builder.column(SQLite.Expression("float")) + builder.column(SQLite.Expression("double")) + builder.column(SQLite.Expression("date")) + builder.column(SQLite.Expression("uuid")) + builder.column(SQLite.Expression("optional")) + builder.column(SQLite.Expression("sub")) }) let value1 = TestCodable(int: 1, string: "2", bool: true, float: 3, double: 4, @@ -133,13 +133,13 @@ class QueryIntegrationTests: SQLiteTestCase { func test_insert_many_encodables() throws { let table = Table("codable") try db.run(table.create { builder in - builder.column(Expression("int")) - builder.column(Expression("string")) - builder.column(Expression("bool")) - builder.column(Expression("float")) - builder.column(Expression("double")) - builder.column(Expression("date")) - builder.column(Expression("uuid")) + builder.column(SQLite.Expression("int")) + builder.column(SQLite.Expression("string")) + builder.column(SQLite.Expression("bool")) + builder.column(SQLite.Expression("float")) + builder.column(SQLite.Expression("double")) + builder.column(SQLite.Expression("date")) + builder.column(SQLite.Expression("uuid")) }) let value1 = TestOptionalCodable(int: 5, string: "6", bool: true, float: 7, double: 8, @@ -161,9 +161,9 @@ class QueryIntegrationTests: SQLiteTestCase { let table = Table("custom_codable") try db.run(table.create { builder in - builder.column(Expression("myInt")) - builder.column(Expression("myString")) - builder.column(Expression("myOptionalArray")) + builder.column(SQLite.Expression("myInt")) + builder.column(SQLite.Expression("myString")) + builder.column(SQLite.Expression("myOptionalArray")) }) let customType = TestTypeWithOptionalArray(myInt: 13, myString: "foo", myOptionalArray: [1, 2, 3]) @@ -216,22 +216,22 @@ class QueryIntegrationTests: SQLiteTestCase { let actualIDs = try db.prepare(query1.union(query2)).map { $0[id] } XCTAssertEqual(expectedIDs, actualIDs) - let query3 = users.select(users[*], Expression(literal: "1 AS weight")).filter(email == "sally@example.com") - let query4 = users.select(users[*], Expression(literal: "2 AS weight")).filter(email == "alice@example.com") + let query3 = users.select(users[*], SQLite.Expression(literal: "1 AS weight")).filter(email == "sally@example.com") + let query4 = users.select(users[*], SQLite.Expression(literal: "2 AS weight")).filter(email == "alice@example.com") - let sql = query3.union(query4).order(Expression(literal: "weight")).asSQL() + let sql = query3.union(query4).order(SQLite.Expression(literal: "weight")).asSQL() XCTAssertEqual(sql, """ SELECT "users".*, 1 AS weight FROM "users" WHERE ("email" = 'sally@example.com') UNION \ SELECT "users".*, 2 AS weight FROM "users" WHERE ("email" = 'alice@example.com') ORDER BY weight """) - let orderedIDs = try db.prepare(query3.union(query4).order(Expression(literal: "weight"), email)).map { $0[id] } + let orderedIDs = try db.prepare(query3.union(query4).order(SQLite.Expression(literal: "weight"), email)).map { $0[id] } XCTAssertEqual(Array(expectedIDs.reversed()), orderedIDs) } func test_no_such_column() throws { - let doesNotExist = Expression("doesNotExist") + let doesNotExist = SQLite.Expression("doesNotExist") try insertUser("alice") let row = try db.pluck(users.filter(email == "alice@example.com"))! @@ -272,15 +272,15 @@ class QueryIntegrationTests: SQLiteTestCase { // https://github.com/stephencelis/SQLite.swift/issues/285 func test_order_by_random() throws { try insertUsers(["a", "b", "c'"]) - let result = Array(try db.prepare(users.select(email).order(Expression.random()).limit(1))) + let result = Array(try db.prepare(users.select(email).order(SQLite.Expression.random()).limit(1))) XCTAssertEqual(1, result.count) } func test_with_recursive() throws { let nodes = Table("nodes") - let id = Expression("id") - let parent = Expression("parent") - let value = Expression("value") + let id = SQLite.Expression("id") + let parent = SQLite.Expression("parent") + let value = SQLite.Expression("value") try db.run(nodes.create { builder in builder.column(id) @@ -320,7 +320,7 @@ class QueryIntegrationTests: SQLiteTestCase { /// Verify that `*` is properly expanded in a SELECT statement following a WITH clause. func test_with_glob_expansion() throws { let names = Table("names") - let name = Expression("name") + let name = SQLite.Expression("name") try db.run(names.create { builder in builder.column(email) builder.column(name) diff --git a/Tests/SQLiteTests/Typed/QueryTests.swift b/Tests/SQLiteTests/Typed/QueryTests.swift index f698c621..f018f097 100644 --- a/Tests/SQLiteTests/Typed/QueryTests.swift +++ b/Tests/SQLiteTests/Typed/QueryTests.swift @@ -13,19 +13,19 @@ import SQLite3 class QueryTests: XCTestCase { let users = Table("users") - let id = Expression("id") - let email = Expression("email") - let age = Expression("age") - let admin = Expression("admin") - let optionalAdmin = Expression("admin") + let id = SQLite.Expression("id") + let email = SQLite.Expression("email") + let age = SQLite.Expression("age") + let admin = SQLite.Expression("admin") + let optionalAdmin = SQLite.Expression("admin") let posts = Table("posts") - let userId = Expression("user_id") - let categoryId = Expression("category_id") - let published = Expression("published") + let userId = SQLite.Expression("user_id") + let categoryId = SQLite.Expression("category_id") + let published = SQLite.Expression("published") let categories = Table("categories") - let tag = Expression("tag") + let tag = SQLite.Expression("tag") func test_select_withExpression_compilesSelectClause() { assertSQL("SELECT \"email\" FROM \"users\"", users.select(email)) @@ -217,7 +217,7 @@ class QueryTests: XCTestCase { } func test_alias_aliasesTable() { - let managerId = Expression("manager_id") + let managerId = SQLite.Expression("manager_id") let managers = users.alias("managers") @@ -422,7 +422,7 @@ class QueryTests: XCTestCase { func test_upsert_encodable() throws { let emails = Table("emails") - let string = Expression("string") + let string = SQLite.Expression("string") let value = TestCodable(int: 1, string: "2", bool: true, float: 3, double: 4, date: Date(timeIntervalSince1970: 0), uuid: testUUIDValue, optional: nil, sub: nil) let insert = try emails.upsert(value, onConflictOf: string) diff --git a/Tests/SQLiteTests/Typed/RowTests.swift b/Tests/SQLiteTests/Typed/RowTests.swift index 14fa373b..1aed00a7 100644 --- a/Tests/SQLiteTests/Typed/RowTests.swift +++ b/Tests/SQLiteTests/Typed/RowTests.swift @@ -5,49 +5,49 @@ class RowTests: XCTestCase { public func test_get_value() throws { let row = Row(["\"foo\"": 0], ["value"]) - let result = try row.get(Expression("foo")) + let result = try row.get(SQLite.Expression("foo")) XCTAssertEqual("value", result) } public func test_get_value_subscript() { let row = Row(["\"foo\"": 0], ["value"]) - let result = row[Expression("foo")] + let result = row[SQLite.Expression("foo")] XCTAssertEqual("value", result) } public func test_get_value_optional() throws { let row = Row(["\"foo\"": 0], ["value"]) - let result = try row.get(Expression("foo")) + let result = try row.get(SQLite.Expression("foo")) XCTAssertEqual("value", result) } public func test_get_value_optional_subscript() { let row = Row(["\"foo\"": 0], ["value"]) - let result = row[Expression("foo")] + let result = row[SQLite.Expression("foo")] XCTAssertEqual("value", result) } public func test_get_value_optional_nil() throws { let row = Row(["\"foo\"": 0], [nil]) - let result = try row.get(Expression("foo")) + let result = try row.get(SQLite.Expression("foo")) XCTAssertNil(result) } public func test_get_value_optional_nil_subscript() { let row = Row(["\"foo\"": 0], [nil]) - let result = row[Expression("foo")] + let result = row[SQLite.Expression("foo")] XCTAssertNil(result) } public func test_get_type_mismatch_throws_unexpected_null_value() { let row = Row(["\"foo\"": 0], ["value"]) - XCTAssertThrowsError(try row.get(Expression("foo"))) { error in + XCTAssertThrowsError(try row.get(SQLite.Expression("foo"))) { error in if case QueryError.unexpectedNullValue(let name) = error { XCTAssertEqual("\"foo\"", name) } else { @@ -58,13 +58,13 @@ class RowTests: XCTestCase { public func test_get_type_mismatch_optional_returns_nil() throws { let row = Row(["\"foo\"": 0], ["value"]) - let result = try row.get(Expression("foo")) + let result = try row.get(SQLite.Expression("foo")) XCTAssertNil(result) } public func test_get_non_existent_column_throws_no_such_column() { let row = Row(["\"foo\"": 0], ["value"]) - XCTAssertThrowsError(try row.get(Expression("bar"))) { error in + XCTAssertThrowsError(try row.get(SQLite.Expression("bar"))) { error in if case QueryError.noSuchColumn(let name, let columns) = error { XCTAssertEqual("\"bar\"", name) XCTAssertEqual(["\"foo\""], columns) @@ -76,7 +76,7 @@ class RowTests: XCTestCase { public func test_get_ambiguous_column_throws() { let row = Row(["table1.\"foo\"": 0, "table2.\"foo\"": 1], ["value"]) - XCTAssertThrowsError(try row.get(Expression("foo"))) { error in + XCTAssertThrowsError(try row.get(SQLite.Expression("foo"))) { error in if case QueryError.ambiguousColumn(let name, let columns) = error { XCTAssertEqual("\"foo\"", name) XCTAssertEqual(["table1.\"foo\"", "table2.\"foo\""], columns.sorted()) @@ -107,7 +107,7 @@ class RowTests: XCTestCase { } let row = Row(["\"foo\"": 0], [Blob(bytes: [])]) - XCTAssertThrowsError(try row.get(Expression("foo"))) { error in + XCTAssertThrowsError(try row.get(SQLite.Expression("foo"))) { error in if case MyType.MyError.failed = error { XCTAssertTrue(true) } else { diff --git a/Tests/SQLiteTests/Typed/SelectTests.swift b/Tests/SQLiteTests/Typed/SelectTests.swift index 52d5bb6b..5fa3cd30 100644 --- a/Tests/SQLiteTests/Typed/SelectTests.swift +++ b/Tests/SQLiteTests/Typed/SelectTests.swift @@ -24,10 +24,10 @@ class SelectTests: SQLiteTestCase { let usersData = Table("users_name") let users = Table("users") - let name = Expression("name") - let id = Expression("id") - let userID = Expression("user_id") - let email = Expression("email") + let name = SQLite.Expression("name") + let id = SQLite.Expression("id") + let userID = SQLite.Expression("user_id") + let email = SQLite.Expression("email") try insertUser("Joey") try db.run(usersData.insert( diff --git a/Tests/SQLiteTests/Typed/SetterTests.swift b/Tests/SQLiteTests/Typed/SetterTests.swift index 938dd013..05da57a4 100644 --- a/Tests/SQLiteTests/Typed/SetterTests.swift +++ b/Tests/SQLiteTests/Typed/SetterTests.swift @@ -134,4 +134,7 @@ class SetterTests: XCTestCase { assertSQL("\"intOptional\" = (\"intOptional\" - 1)", intOptional--) } + func test_setter_custom_string_convertible() { + XCTAssertEqual("\"int\" = \"int\"", (int <- int).description) + } } diff --git a/Tests/SQLiteTests/Typed/WindowFunctionsTests.swift b/Tests/SQLiteTests/Typed/WindowFunctionsTests.swift index 6ded152b..01e88297 100644 --- a/Tests/SQLiteTests/Typed/WindowFunctionsTests.swift +++ b/Tests/SQLiteTests/Typed/WindowFunctionsTests.swift @@ -34,13 +34,13 @@ class WindowFunctionsTests: XCTestCase { func test_lag_wrapsExpressionWithOverClause() { assertSQL("lag(\"int\", 0) OVER (ORDER BY \"int\" DESC)", int.lag(int.desc)) assertSQL("lag(\"int\", 7) OVER (ORDER BY \"int\" DESC)", int.lag(offset: 7, int.desc)) - assertSQL("lag(\"int\", 1, 3) OVER (ORDER BY \"int\" DESC)", int.lag(offset: 1, default: Expression(value: 3), int.desc)) + assertSQL("lag(\"int\", 1, 3) OVER (ORDER BY \"int\" DESC)", int.lag(offset: 1, default: SQLite.Expression(value: 3), int.desc)) } func test_lead_wrapsExpressionWithOverClause() { assertSQL("lead(\"int\", 0) OVER (ORDER BY \"int\" DESC)", int.lead(int.desc)) assertSQL("lead(\"int\", 7) OVER (ORDER BY \"int\" DESC)", int.lead(offset: 7, int.desc)) - assertSQL("lead(\"int\", 1, 3) OVER (ORDER BY \"int\" DESC)", int.lead(offset: 1, default: Expression(value: 3), int.desc)) + assertSQL("lead(\"int\", 1, 3) OVER (ORDER BY \"int\" DESC)", int.lead(offset: 1, default: SQLite.Expression(value: 3), int.desc)) } func test_firstValue_wrapsExpressionWithOverClause() { From 4a5eda39a5aa63b4151b54e13ac9cd6ff3390a7e Mon Sep 17 00:00:00 2001 From: Cary Clark Date: Fri, 4 Oct 2024 15:54:10 -0700 Subject: [PATCH 39/84] Update oldest supported platform versions --- Package.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Package.swift b/Package.swift index 238661ae..12a2f11c 100644 --- a/Package.swift +++ b/Package.swift @@ -4,10 +4,10 @@ import PackageDescription let package = Package( name: "SQLite.swift", platforms: [ - .iOS(.v11), + .iOS(.v12), .macOS(.v10_13), .watchOS(.v4), - .tvOS(.v11), + .tvOS(.v12), .visionOS(.v1) ], products: [ From 748dcba3312485151fa91b551a4564238f2b69b9 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 20 May 2025 18:35:08 +0200 Subject: [PATCH 40/84] Support creating tables in schema changer --- Makefile | 2 +- Sources/SQLite/Schema/SchemaChanger.swift | 49 +++++++++++++++++++ Sources/SQLite/Schema/SchemaDefinitions.swift | 5 +- .../Schema/SchemaChangerTests.swift | 46 +++++++++++++++++ 4 files changed, 100 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 73b33f97..52a25a12 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ lint: $(SWIFTLINT) $< --strict lint-fix: $(SWIFTLINT) - $< lint fix + $< --fix clean: $(XCODEBUILD) $(BUILD_ARGUMENTS) clean diff --git a/Sources/SQLite/Schema/SchemaChanger.swift b/Sources/SQLite/Schema/SchemaChanger.swift index af7b5e27..b6ed7312 100644 --- a/Sources/SQLite/Schema/SchemaChanger.swift +++ b/Sources/SQLite/Schema/SchemaChanger.swift @@ -43,19 +43,31 @@ public class SchemaChanger: CustomStringConvertible { public enum Operation { case addColumn(ColumnDefinition) + case addIndex(IndexDefinition) case dropColumn(String) case renameColumn(String, String) case renameTable(String) + case createTable(columns: [ColumnDefinition]) /// Returns non-nil if the operation can be executed with a simple SQL statement func toSQL(_ table: String, version: SQLiteVersion) -> String? { switch self { case .addColumn(let definition): return "ALTER TABLE \(table.quote()) ADD COLUMN \(definition.toSQL())" + case .addIndex(let definition): + let unique = definition.unique ? "UNIQUE" : "" + let columns = definition.columns.joined(separator: ", ") + let `where` = definition.where.map { " WHERE " + $0 } ?? "" + + return "CREATE \(unique) INDEX \(definition.name) ON \(definition.table) (\(columns)) \(`where`)" case .renameColumn(let from, let to) where SQLiteFeature.renameColumn.isSupported(by: version): return "ALTER TABLE \(table.quote()) RENAME COLUMN \(from.quote()) TO \(to.quote())" case .dropColumn(let column) where SQLiteFeature.dropColumn.isSupported(by: version): return "ALTER TABLE \(table.quote()) DROP COLUMN \(column.quote())" + case .createTable(let columns): + return "CREATE TABLE \(table.quote()) (" + + columns.map { $0.toSQL() }.joined(separator: ", ") + + ")" default: return nil } } @@ -108,12 +120,39 @@ public class SchemaChanger: CustomStringConvertible { } } + public class CreateTableDefinition { + fileprivate var columnDefinitions: [ColumnDefinition] = [] + fileprivate var indexDefinitions: [IndexDefinition] = [] + + let name: String + + init(name: String) { + self.name = name + } + + public func add(column: ColumnDefinition) { + columnDefinitions.append(column) + } + + public func add(index: IndexDefinition) { + indexDefinitions.append(index) + } + + var operations: [Operation] { + precondition(!columnDefinitions.isEmpty) + return [ + .createTable(columns: columnDefinitions) + ] + indexDefinitions.map { .addIndex($0) } + } + } + private let connection: Connection private let schemaReader: SchemaReader private let version: SQLiteVersion static let tempPrefix = "tmp_" typealias Block = () throws -> Void public typealias AlterTableDefinitionBlock = (AlterTableDefinition) -> Void + public typealias CreateTableDefinitionBlock = (CreateTableDefinition) -> Void struct Options: OptionSet { let rawValue: Int @@ -141,6 +180,15 @@ public class SchemaChanger: CustomStringConvertible { } } + public func create(table: String, ifNotExists: Bool = false, block: CreateTableDefinitionBlock) throws { + let createTableDefinition = CreateTableDefinition(name: table) + block(createTableDefinition) + + for operation in createTableDefinition.operations { + try run(table: table, operation: operation) + } + } + public func drop(table: String, ifExists: Bool = true) throws { try dropTable(table, ifExists: ifExists) } @@ -263,6 +311,7 @@ extension TableDefinition { func apply(_ operation: SchemaChanger.Operation?) -> TableDefinition { switch operation { case .none: return self + case .createTable, .addIndex: fatalError() case .addColumn: fatalError("Use 'ALTER TABLE ADD COLUMN (...)'") case .dropColumn(let column): return TableDefinition(name: name, diff --git a/Sources/SQLite/Schema/SchemaDefinitions.swift b/Sources/SQLite/Schema/SchemaDefinitions.swift index 80f9e199..60837244 100644 --- a/Sources/SQLite/Schema/SchemaDefinitions.swift +++ b/Sources/SQLite/Schema/SchemaDefinitions.swift @@ -270,12 +270,15 @@ public struct IndexDefinition: Equatable { return memo2 } } + + let orders = indexSQL.flatMap(orders) + self.init(table: table, name: name, unique: unique, columns: columns, where: indexSQL.flatMap(wherePart), - orders: indexSQL.flatMap(orders)) + orders: (orders?.isEmpty ?? false) ? nil : orders) } public let table: String diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index 2bec6a06..125ef09e 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -154,4 +154,50 @@ class SchemaChangerTests: SQLiteTestCase { let users_new = Table("users_new") XCTAssertEqual((try db.scalar(users_new.count)) as Int, 1) } + + func test_create_table() throws { + try schemaChanger.create(table: "foo") { table in + table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) + table.add(column: .init(name: "name", type: .TEXT, nullable: false)) + table.add(column: .init(name: "age", type: .INTEGER)) + + table.add(index: .init(table: table.name, + name: "nameIndex", + unique: true, + columns: ["name"], + where: nil, + orders: nil)) + } + + // make sure new table can be queried + let foo = Table("foo") + XCTAssertEqual((try db.scalar(foo.count)) as Int, 0) + + let columns = try schema.columnDefinitions(table: "foo") + XCTAssertEqual(columns, [ + ColumnDefinition(name: "id", + primaryKey: .init(autoIncrement: true, onConflict: nil), + type: .INTEGER, + nullable: true, + defaultValue: .NULL, + references: nil), + ColumnDefinition(name: "name", + primaryKey: nil, + type: .TEXT, + nullable: false, + defaultValue: .NULL, + references: nil), + ColumnDefinition(name: "age", + primaryKey: nil, + type: .INTEGER, + nullable: true, + defaultValue: .NULL, + references: nil) + ]) + + let indexes = try schema.indexDefinitions(table: "foo") + XCTAssertEqual(indexes, [ + IndexDefinition(table: "foo", name: "nameIndex", unique: true, columns: ["name"], where: nil, orders: nil) + ]) + } } From 261f98ae268f986ec6e54822d45d9bda263bdd50 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 20 May 2025 22:17:45 +0200 Subject: [PATCH 41/84] Update docs --- Documentation/Index.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Documentation/Index.md b/Documentation/Index.md index fcd2d642..bc62c791 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -63,6 +63,7 @@ - [Renaming Columns](#renaming-columns) - [Dropping Columns](#dropping-columns) - [Renaming/Dropping Tables](#renamingdropping-tables) + - [Creating Tables](#creating-tables) - [Indexes](#indexes) - [Creating Indexes](#creating-indexes) - [Dropping Indexes](#dropping-indexes) @@ -1583,6 +1584,16 @@ try schemaChanger.rename(table: "users", to: "users_new") try schemaChanger.drop(table: "emails", ifExists: false) ``` +#### Creating Tables + +```swift +let schemaChanger = SchemaChanger(connection: db) + +try schemaChanger.create(table: "users") { table in + table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) + table.add(column: .init(name: "name", type: .TEXT, nullable: false)) +} + ### Indexes From e21fde28f0f96cc452151aaa17413b198f3718a9 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 20 May 2025 22:18:37 +0200 Subject: [PATCH 42/84] Revert to standard cocoapods --- Gemfile | 2 +- Gemfile.lock | 93 ++++++++++++++++++++++++++-------------------------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/Gemfile b/Gemfile index eb6036cd..1f2ebb87 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem 'cocoapods', :git => 'https://github.com/SagarSDagdu/CocoaPods.git', tag: '1.15.2.1-sagard' +gem 'cocoapods' diff --git a/Gemfile.lock b/Gemfile.lock index a58783ea..464ef06b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,27 +1,3 @@ -GIT - remote: https://github.com/SagarSDagdu/CocoaPods.git - revision: d96f491f79abd2804d1359c5228cce404dd365b7 - tag: 1.15.2.1-sagard - specs: - cocoapods (1.15.2.1.pre.sagard) - addressable (~> 2.8) - claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.15.2) - cocoapods-deintegrate (>= 1.0.3, < 2.0) - cocoapods-downloader (>= 2.1, < 3.0) - cocoapods-plugins (>= 1.0.0, < 2.0) - cocoapods-search (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.6.0, < 2.0) - cocoapods-try (>= 1.1.0, < 2.0) - colored2 (~> 3.1) - escape (~> 0.0.4) - fourflusher (>= 2.3.0, < 3.0) - gh_inspector (~> 1.0) - molinillo (~> 0.8.0) - nap (~> 1.0) - ruby-macho (>= 2.3.0, < 3.0) - xcodeproj (>= 1.23.0, < 2.0) - GEM remote: https://rubygems.org/ specs: @@ -29,26 +5,47 @@ GEM base64 nkf rexml - activesupport (7.1.3.2) + activesupport (7.2.2.1) base64 + benchmark (>= 0.3) bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) algoliasearch (1.27.5) httpclient (~> 2.8, >= 2.8.3) json (>= 1.5.1) atomos (0.1.3) base64 (0.2.0) - bigdecimal (3.1.7) + benchmark (0.4.0) + bigdecimal (3.1.9) claide (1.1.0) - cocoapods-core (1.15.2) + cocoapods (1.16.2) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.16.2) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 2.1, < 3.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) + nap (~> 1.0) + ruby-macho (>= 2.3.0, < 3.0) + xcodeproj (>= 1.27.0, < 2.0) + cocoapods-core (1.16.2) activesupport (>= 5.0, < 8) addressable (~> 2.8) algoliasearch (~> 1.0) @@ -68,48 +65,52 @@ GEM netrc (~> 0.11) cocoapods-try (1.2.0) colored2 (3.1.2) - concurrent-ruby (1.2.3) - connection_pool (2.4.1) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) drb (2.2.1) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) - ffi (1.16.3) + ffi (1.17.2) + ffi (1.17.2-arm64-darwin) fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - httpclient (2.8.3) - i18n (1.14.4) + httpclient (2.9.0) + mutex_m + i18n (1.14.7) concurrent-ruby (~> 1.0) - json (2.7.2) - minitest (5.22.3) + json (2.12.0) + logger (1.7.0) + minitest (5.25.5) molinillo (0.8.0) - mutex_m (0.2.0) - nanaimo (0.3.0) + mutex_m (0.3.0) + nanaimo (0.4.0) nap (1.1.0) netrc (0.11.0) nkf (0.2.0) public_suffix (4.0.7) - rexml (3.2.6) + rexml (3.4.1) ruby-macho (2.5.1) + securerandom (0.4.1) typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - xcodeproj (1.24.0) + xcodeproj (1.27.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) colored2 (~> 3.1) - nanaimo (~> 0.3.0) - rexml (~> 3.2.4) + nanaimo (~> 0.4.0) + rexml (>= 3.3.6, < 4.0) PLATFORMS arm64-darwin-23 ruby DEPENDENCIES - cocoapods! + cocoapods BUNDLED WITH 2.5.4 From 5ef20d1887e4b8763df890c4f1ffc256b3f79b99 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 20 May 2025 22:39:15 +0200 Subject: [PATCH 43/84] Don't lint against visionOS --- run-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-tests.sh b/run-tests.sh index 1bf8de96..cb68a022 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -11,7 +11,7 @@ elif [ -n "$VALIDATOR_SUBSPEC" ]; then if [ "$VALIDATOR_SUBSPEC" == "none" ]; then bundle exec pod lib lint --no-subspecs --fail-fast else - bundle exec pod lib lint --subspec="${VALIDATOR_SUBSPEC}" --fail-fast + bundle exec pod lib lint --subspec="${VALIDATOR_SUBSPEC}" --fail-fast --platforms=macos,ios,tvos,watchos fi elif [ -n "$CARTHAGE_PLATFORM" ]; then cd Tests/Carthage && make test CARTHAGE_PLATFORM="$CARTHAGE_PLATFORM" From 017929080c146c2085b21adcce95ff67b9e82d2e Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 20 May 2025 23:14:13 +0200 Subject: [PATCH 44/84] Disable visionos just for standalone --- run-tests.sh | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/run-tests.sh b/run-tests.sh index cb68a022..94f643e4 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -8,15 +8,21 @@ if [ -n "$BUILD_SCHEME" ]; then fi elif [ -n "$VALIDATOR_SUBSPEC" ]; then bundle install - if [ "$VALIDATOR_SUBSPEC" == "none" ]; then - bundle exec pod lib lint --no-subspecs --fail-fast - else - bundle exec pod lib lint --subspec="${VALIDATOR_SUBSPEC}" --fail-fast --platforms=macos,ios,tvos,watchos - fi + case "$VALIDATOR_SUBSPEC" in + none) + bundle exec pod lib lint --no-subspecs --fail-fast + ;; + standalone) + bundle exec pod lib lint --subspec="${VALIDATOR_SUBSPEC}" --fail-fast --platforms=macos,ios,tvos,watchos + ;; + *) + bundle exec pod lib lint --subspec="${VALIDATOR_SUBSPEC}" --fail-fast + ;; + esac elif [ -n "$CARTHAGE_PLATFORM" ]; then cd Tests/Carthage && make test CARTHAGE_PLATFORM="$CARTHAGE_PLATFORM" elif [ -n "$SPM" ]; then - cd Tests/SPM && swift ${SPM} + cd Tests/SPM && swift "${SPM}" elif [ -n "${PACKAGE_MANAGER_COMMAND}" ]; then - swift ${PACKAGE_MANAGER_COMMAND} + swift "${PACKAGE_MANAGER_COMMAND}" fi From 023c5039780b1c086f1d4bbea1c6d5a683e3041f Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 20 May 2025 23:18:21 +0200 Subject: [PATCH 45/84] Enable word splitting --- run-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-tests.sh b/run-tests.sh index 94f643e4..7d5c26d2 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -24,5 +24,5 @@ elif [ -n "$CARTHAGE_PLATFORM" ]; then elif [ -n "$SPM" ]; then cd Tests/SPM && swift "${SPM}" elif [ -n "${PACKAGE_MANAGER_COMMAND}" ]; then - swift "${PACKAGE_MANAGER_COMMAND}" + swift ${PACKAGE_MANAGER_COMMAND} fi From 673367b772b04a8df0be64e757b2979da8798939 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Tue, 20 May 2025 23:36:41 +0200 Subject: [PATCH 46/84] Public init --- Sources/SQLite/Schema/SchemaDefinitions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SQLite/Schema/SchemaDefinitions.swift b/Sources/SQLite/Schema/SchemaDefinitions.swift index 60837244..897f8557 100644 --- a/Sources/SQLite/Schema/SchemaDefinitions.swift +++ b/Sources/SQLite/Schema/SchemaDefinitions.swift @@ -93,7 +93,7 @@ public struct ColumnDefinition: Equatable { // swiftlint:disable:next force_try static let pattern = try! NSRegularExpression(pattern: "PRIMARY KEY\\s*(?:ASC|DESC)?\\s*(?:ON CONFLICT (\\w+)?)?\\s*(AUTOINCREMENT)?") - init(autoIncrement: Bool = true, onConflict: OnConflict? = nil) { + public init(autoIncrement: Bool = true, onConflict: OnConflict? = nil) { self.autoIncrement = autoIncrement self.onConflict = onConflict } From 5de1420d58a87e082bb3659da9b59a19687cb867 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 21 May 2025 14:23:31 +0200 Subject: [PATCH 47/84] Support ifNotExists --- Sources/SQLite/Schema/SchemaChanger.swift | 14 +++++++----- .../Schema/SchemaChangerTests.swift | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/Sources/SQLite/Schema/SchemaChanger.swift b/Sources/SQLite/Schema/SchemaChanger.swift index b6ed7312..e2e3d5fa 100644 --- a/Sources/SQLite/Schema/SchemaChanger.swift +++ b/Sources/SQLite/Schema/SchemaChanger.swift @@ -47,7 +47,7 @@ public class SchemaChanger: CustomStringConvertible { case dropColumn(String) case renameColumn(String, String) case renameTable(String) - case createTable(columns: [ColumnDefinition]) + case createTable(columns: [ColumnDefinition], ifNotExists: Bool) /// Returns non-nil if the operation can be executed with a simple SQL statement func toSQL(_ table: String, version: SQLiteVersion) -> String? { @@ -64,8 +64,8 @@ public class SchemaChanger: CustomStringConvertible { return "ALTER TABLE \(table.quote()) RENAME COLUMN \(from.quote()) TO \(to.quote())" case .dropColumn(let column) where SQLiteFeature.dropColumn.isSupported(by: version): return "ALTER TABLE \(table.quote()) DROP COLUMN \(column.quote())" - case .createTable(let columns): - return "CREATE TABLE \(table.quote()) (" + + case .createTable(let columns, let ifNotExists): + return "CREATE TABLE \(ifNotExists ? " IF NOT EXISTS " : "") \(table.quote()) (" + columns.map { $0.toSQL() }.joined(separator: ", ") + ")" default: return nil @@ -125,9 +125,11 @@ public class SchemaChanger: CustomStringConvertible { fileprivate var indexDefinitions: [IndexDefinition] = [] let name: String + let ifNotExists: Bool - init(name: String) { + init(name: String, ifNotExists: Bool) { self.name = name + self.ifNotExists = ifNotExists } public func add(column: ColumnDefinition) { @@ -141,7 +143,7 @@ public class SchemaChanger: CustomStringConvertible { var operations: [Operation] { precondition(!columnDefinitions.isEmpty) return [ - .createTable(columns: columnDefinitions) + .createTable(columns: columnDefinitions, ifNotExists: ifNotExists) ] + indexDefinitions.map { .addIndex($0) } } } @@ -181,7 +183,7 @@ public class SchemaChanger: CustomStringConvertible { } public func create(table: String, ifNotExists: Bool = false, block: CreateTableDefinitionBlock) throws { - let createTableDefinition = CreateTableDefinition(name: table) + let createTableDefinition = CreateTableDefinition(name: table, ifNotExists: ifNotExists) block(createTableDefinition) for operation in createTableDefinition.operations { diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index 125ef09e..bba16e08 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -200,4 +200,26 @@ class SchemaChangerTests: SQLiteTestCase { IndexDefinition(table: "foo", name: "nameIndex", unique: true, columns: ["name"], where: nil, orders: nil) ]) } + + func test_create_table_if_not_exists() throws { + try schemaChanger.create(table: "foo") { table in + table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) + } + + try schemaChanger.create(table: "foo", ifNotExists: true) { table in + table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) + } + + XCTAssertThrowsError( + try schemaChanger.create(table: "foo", ifNotExists: false) { table in + table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) + } + ) { error in + if case Result.error(_, let code, _) = error { + XCTAssertEqual(code, 1) + } else { + XCTFail("unexpected error: \(error)") + } + } + } } From f2a86841f527f756610797d56b6c49a46c947f41 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 21 May 2025 17:24:57 +0200 Subject: [PATCH 48/84] Add columns via Expressions --- Sources/SQLite/Schema/SchemaChanger.swift | 25 ++++++++++++++++ .../Schema/SchemaChangerTests.swift | 30 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/Sources/SQLite/Schema/SchemaChanger.swift b/Sources/SQLite/Schema/SchemaChanger.swift index e2e3d5fa..d3342032 100644 --- a/Sources/SQLite/Schema/SchemaChanger.swift +++ b/Sources/SQLite/Schema/SchemaChanger.swift @@ -136,6 +136,14 @@ public class SchemaChanger: CustomStringConvertible { columnDefinitions.append(column) } + public func add(expression: Expression) where T: Value { + add(column: .init(name: columnName(for: expression), type: .init(expression: expression), nullable: false)) + } + + public func add(expression: Expression) where T: Value { + add(column: .init(name: columnName(for: expression), type: .init(expression: expression), nullable: true)) + } + public func add(index: IndexDefinition) { indexDefinitions.append(index) } @@ -146,6 +154,13 @@ public class SchemaChanger: CustomStringConvertible { .createTable(columns: columnDefinitions, ifNotExists: ifNotExists) ] + indexDefinitions.map { .addIndex($0) } } + + private func columnName(for expression: Expression) -> String { + switch LiteralValue(expression.template) { + case .stringLiteral(let string): return string + default: fatalError("expression is not a literal string value") + } + } } private let connection: Connection @@ -331,3 +346,13 @@ extension TableDefinition { } } } + +extension ColumnDefinition.Affinity { + init(expression: Expression) where T: Value { + self.init(T.declaredDatatype) + } + + init(expression: Expression) where T: Value { + self.init(T.declaredDatatype) + } +} diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index bba16e08..6b53c9ce 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -201,6 +201,36 @@ class SchemaChangerTests: SQLiteTestCase { ]) } + func test_create_table_add_column_expression() throws { + try schemaChanger.create(table: "foo") { table in + table.add(expression: Expression("name")) + table.add(expression: Expression("age")) + table.add(expression: Expression("salary")) + } + + let columns = try schema.columnDefinitions(table: "foo") + XCTAssertEqual(columns, [ + ColumnDefinition(name: "name", + primaryKey: nil, + type: .TEXT, + nullable: false, + defaultValue: .NULL, + references: nil), + ColumnDefinition(name: "age", + primaryKey: nil, + type: .INTEGER, + nullable: false, + defaultValue: .NULL, + references: nil), + ColumnDefinition(name: "salary", + primaryKey: nil, + type: .REAL, + nullable: true, + defaultValue: .NULL, + references: nil) + ]) + } + func test_create_table_if_not_exists() throws { try schemaChanger.create(table: "foo") { table in table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) From cdaade15b93a43a5db8038da05da1c30c997ea3d Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 21 May 2025 18:45:26 +0200 Subject: [PATCH 49/84] Respect ifNotExists for index --- Sources/SQLite/Schema/SchemaChanger.swift | 12 ++++-------- Tests/SQLiteTests/Schema/SchemaChangerTests.swift | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Sources/SQLite/Schema/SchemaChanger.swift b/Sources/SQLite/Schema/SchemaChanger.swift index d3342032..13222dab 100644 --- a/Sources/SQLite/Schema/SchemaChanger.swift +++ b/Sources/SQLite/Schema/SchemaChanger.swift @@ -43,7 +43,7 @@ public class SchemaChanger: CustomStringConvertible { public enum Operation { case addColumn(ColumnDefinition) - case addIndex(IndexDefinition) + case addIndex(IndexDefinition, ifNotExists: Bool) case dropColumn(String) case renameColumn(String, String) case renameTable(String) @@ -54,12 +54,8 @@ public class SchemaChanger: CustomStringConvertible { switch self { case .addColumn(let definition): return "ALTER TABLE \(table.quote()) ADD COLUMN \(definition.toSQL())" - case .addIndex(let definition): - let unique = definition.unique ? "UNIQUE" : "" - let columns = definition.columns.joined(separator: ", ") - let `where` = definition.where.map { " WHERE " + $0 } ?? "" - - return "CREATE \(unique) INDEX \(definition.name) ON \(definition.table) (\(columns)) \(`where`)" + case .addIndex(let definition, let ifNotExists): + return definition.toSQL(ifNotExists: ifNotExists) case .renameColumn(let from, let to) where SQLiteFeature.renameColumn.isSupported(by: version): return "ALTER TABLE \(table.quote()) RENAME COLUMN \(from.quote()) TO \(to.quote())" case .dropColumn(let column) where SQLiteFeature.dropColumn.isSupported(by: version): @@ -152,7 +148,7 @@ public class SchemaChanger: CustomStringConvertible { precondition(!columnDefinitions.isEmpty) return [ .createTable(columns: columnDefinitions, ifNotExists: ifNotExists) - ] + indexDefinitions.map { .addIndex($0) } + ] + indexDefinitions.map { .addIndex($0, ifNotExists: ifNotExists) } } private func columnName(for expression: Expression) -> String { diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index 6b53c9ce..02a82267 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -252,4 +252,18 @@ class SchemaChangerTests: SQLiteTestCase { } } } + + func test_create_table_if_not_exists_with_index() throws { + try schemaChanger.create(table: "foo") { table in + table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) + table.add(column: .init(name: "name", type: .TEXT)) + table.add(index: .init(table: "foo", name: "name_index", unique: true, columns: ["name"], indexSQL: nil)) + } + + // ifNotExists needs to apply to index creation as well + try schemaChanger.create(table: "foo", ifNotExists: true) { table in + table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) + table.add(index: .init(table: "foo", name: "name_index", unique: true, columns: ["name"], indexSQL: nil)) + } + } } From a0136544e9627b941008d7c59836b61feaf1f142 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 21 May 2025 22:17:39 +0200 Subject: [PATCH 50/84] New visionOS0-compatible pod has been release --- run-tests.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/run-tests.sh b/run-tests.sh index 7d5c26d2..3ffba810 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -12,9 +12,6 @@ elif [ -n "$VALIDATOR_SUBSPEC" ]; then none) bundle exec pod lib lint --no-subspecs --fail-fast ;; - standalone) - bundle exec pod lib lint --subspec="${VALIDATOR_SUBSPEC}" --fail-fast --platforms=macos,ios,tvos,watchos - ;; *) bundle exec pod lib lint --subspec="${VALIDATOR_SUBSPEC}" --fail-fast ;; From 77b493e661cff1498892dbaa48aa2205b673ce46 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 21 May 2025 22:42:20 +0200 Subject: [PATCH 51/84] Use inheritance --- SQLite.swift.podspec | 43 +++++-------------------------------------- 1 file changed, 5 insertions(+), 38 deletions(-) diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index 184ce23e..4cbd91bb 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -18,17 +18,11 @@ Pod::Spec.new do |s| s.default_subspec = 'standard' s.swift_versions = ['5'] - ios_deployment_target = '12.0' - tvos_deployment_target = '12.0' - osx_deployment_target = '10.13' - watchos_deployment_target = '4.0' - visionos_deployment_target = '1.0' - - s.ios.deployment_target = ios_deployment_target - s.tvos.deployment_target = tvos_deployment_target - s.osx.deployment_target = osx_deployment_target - s.watchos.deployment_target = watchos_deployment_target - s.visionos.deployment_target = visionos_deployment_target + s.ios.deployment_target = '12.0' + s.tvos.deployment_target = '12.0' + s.osx.deployment_target = '10.13' + s.watchos.deployment_target = '4.0' + s.visionos.deployment_target = '1.0' s.subspec 'standard' do |ss| ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}' @@ -36,18 +30,9 @@ Pod::Spec.new do |s| ss.library = 'sqlite3' ss.resource_bundle = { 'SQLite.swift' => 'Sources/SQLite/PrivacyInfo.xcprivacy' } - ss.ios.deployment_target = ios_deployment_target - ss.tvos.deployment_target = tvos_deployment_target - ss.osx.deployment_target = osx_deployment_target - ss.watchos.deployment_target = watchos_deployment_target - ss.visionos.deployment_target = visionos_deployment_target - ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' test_spec.source_files = 'Tests/SQLiteTests/*.swift' - test_spec.ios.deployment_target = ios_deployment_target - test_spec.tvos.deployment_target = tvos_deployment_target - test_spec.osx.deployment_target = osx_deployment_target end end @@ -62,18 +47,9 @@ Pod::Spec.new do |s| } ss.dependency 'sqlite3' - ss.ios.deployment_target = ios_deployment_target - ss.tvos.deployment_target = tvos_deployment_target - ss.osx.deployment_target = osx_deployment_target - ss.watchos.deployment_target = watchos_deployment_target - ss.visionos.deployment_target = visionos_deployment_target - ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' test_spec.source_files = 'Tests/SQLiteTests/*.swift' - test_spec.ios.deployment_target = ios_deployment_target - test_spec.tvos.deployment_target = tvos_deployment_target - test_spec.osx.deployment_target = osx_deployment_target end end @@ -87,18 +63,9 @@ Pod::Spec.new do |s| } ss.dependency 'SQLCipher', '>= 4.0.0' - ss.ios.deployment_target = ios_deployment_target - ss.tvos.deployment_target = tvos_deployment_target - ss.osx.deployment_target = osx_deployment_target - ss.watchos.deployment_target = watchos_deployment_target - #ss.visionos.deployment_target = visionos_deployment_target # Not supported by SQLCipher for now - ss.test_spec 'tests' do |test_spec| test_spec.resources = 'Tests/SQLiteTests/Resources/*' test_spec.source_files = 'Tests/SQLiteTests/*.swift' - test_spec.ios.deployment_target = ios_deployment_target - test_spec.tvos.deployment_target = tvos_deployment_target - test_spec.osx.deployment_target = osx_deployment_target end end end From 7309b4337a0649d53d8ebd703f582117c1dc9e91 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 21 May 2025 23:04:30 +0200 Subject: [PATCH 52/84] Use newer Xcode --- .github/workflows/build.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9fbba1c5..5b6b74a6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,15 +5,9 @@ env: IOS_VERSION: "17.2" jobs: build: - runs-on: macos-14 + runs-on: macos-15 steps: - uses: actions/checkout@v2 - - name: "Select Xcode" - # Currently only works with Xcode 14.2: - # https://github.com/CocoaPods/CocoaPods/issues/11839 - run: | - xcode-select -p - sudo xcode-select -s /Applications/Xcode_15.3.app/Contents/Developer - name: "Lint" run: make lint - name: "Run tests (PACKAGE_MANAGER_COMMAND: test)" From 4166f86e844f5d1e87e25264eb9a5194dbaf3b08 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 21 May 2025 23:10:36 +0200 Subject: [PATCH 53/84] iOS 17.5 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5b6b74a6..a0274321 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build and test on: [push, pull_request] env: IOS_SIMULATOR: "iPhone 15" - IOS_VERSION: "17.2" + IOS_VERSION: "17.5" jobs: build: runs-on: macos-15 From f312ab4d12b344f7e541df5cb0363070a0f964ba Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Wed, 21 May 2025 23:29:27 +0200 Subject: [PATCH 54/84] Update bundler --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 464ef06b..9f71603b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -67,7 +67,7 @@ GEM colored2 (3.1.2) concurrent-ruby (1.3.5) connection_pool (2.5.3) - drb (2.2.1) + drb (2.2.3) escape (0.0.4) ethon (0.16.0) ffi (>= 1.15.0) @@ -113,4 +113,4 @@ DEPENDENCIES cocoapods BUNDLED WITH - 2.5.4 + 2.6.9 From 9dc478c9f1f6eaae43f1aa4286e3bf574bb5976d Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 22 May 2025 10:02:48 +0200 Subject: [PATCH 55/84] SchemaReader: parse and create unique constraints --- Sources/SQLite/Schema/SchemaDefinitions.swift | 27 ++++++++-- Sources/SQLite/Schema/SchemaReader.swift | 52 ++++++++++++++----- .../Schema/SchemaChangerTests.swift | 9 ++-- .../Schema/SchemaReaderTests.swift | 32 ++++++++++-- 4 files changed, 98 insertions(+), 22 deletions(-) diff --git a/Sources/SQLite/Schema/SchemaDefinitions.swift b/Sources/SQLite/Schema/SchemaDefinitions.swift index 897f8557..bb4ce82b 100644 --- a/Sources/SQLite/Schema/SchemaDefinitions.swift +++ b/Sources/SQLite/Schema/SchemaDefinitions.swift @@ -128,6 +128,7 @@ public struct ColumnDefinition: Equatable { public let primaryKey: PrimaryKey? public let type: Affinity public let nullable: Bool + public let unique: Bool public let defaultValue: LiteralValue public let references: ForeignKey? @@ -135,12 +136,14 @@ public struct ColumnDefinition: Equatable { primaryKey: PrimaryKey? = nil, type: Affinity, nullable: Bool = true, + unique: Bool = false, defaultValue: LiteralValue = .NULL, references: ForeignKey? = nil) { self.name = name self.primaryKey = primaryKey self.type = type self.nullable = nullable + self.unique = unique self.defaultValue = defaultValue self.references = references } @@ -244,16 +247,18 @@ public struct IndexDefinition: Equatable { public enum Order: String { case ASC, DESC } - public init(table: String, name: String, unique: Bool = false, columns: [String], `where`: String? = nil, orders: [String: Order]? = nil) { + public init(table: String, name: String, unique: Bool = false, columns: [String], `where`: String? = nil, + orders: [String: Order]? = nil, origin: Origin? = nil) { self.table = table self.name = name self.unique = unique self.columns = columns self.where = `where` self.orders = orders + self.origin = origin } - init (table: String, name: String, unique: Bool, columns: [String], indexSQL: String?) { + init (table: String, name: String, unique: Bool, columns: [String], indexSQL: String?, origin: Origin? = nil) { func wherePart(sql: String) -> String? { IndexDefinition.whereRe.firstMatch(in: sql, options: [], range: NSRange(location: 0, length: sql.count)).map { (sql as NSString).substring(with: $0.range(at: 1)) @@ -278,7 +283,8 @@ public struct IndexDefinition: Equatable { unique: unique, columns: columns, where: indexSQL.flatMap(wherePart), - orders: (orders?.isEmpty ?? false) ? nil : orders) + orders: (orders?.isEmpty ?? false) ? nil : orders, + origin: origin) } public let table: String @@ -287,6 +293,13 @@ public struct IndexDefinition: Equatable { public let columns: [String] public let `where`: String? public let orders: [String: Order]? + public let origin: Origin? + + public enum Origin: String { + case uniqueConstraint = "u" // index created from a "CREATE TABLE (... UNIQUE)" column constraint + case createIndex = "c" // index created explicitly via "CREATE INDEX ..." + case primaryKey = "pk" // index created from a "CREATE TABLE PRIMARY KEY" column constraint + } enum IndexError: LocalizedError { case tooLong(String, String) @@ -300,6 +313,13 @@ public struct IndexDefinition: Equatable { } } + // Indices with names of the form "sqlite_autoindex_TABLE_N" that are used to implement UNIQUE and PRIMARY KEY + // constraints on ordinary tables. + // https://sqlite.org/fileformat2.html#intschema + var isInternal: Bool { + name.starts(with: "sqlite_autoindex_") + } + func validate() throws { if name.count > IndexDefinition.maxIndexLength { throw IndexError.tooLong(name, table) @@ -348,6 +368,7 @@ extension ColumnDefinition { defaultValue.map { "DEFAULT \($0)" }, primaryKey.map { $0.toSQL() }, nullable ? nil : "NOT NULL", + unique ? "UNIQUE" : nil, references.map { $0.toSQL() } ].compactMap { $0 } .joined(separator: " ") diff --git a/Sources/SQLite/Schema/SchemaReader.swift b/Sources/SQLite/Schema/SchemaReader.swift index 1989ad6f..a67fb94f 100644 --- a/Sources/SQLite/Schema/SchemaReader.swift +++ b/Sources/SQLite/Schema/SchemaReader.swift @@ -21,7 +21,7 @@ public class SchemaReader { let foreignKeys: [String: [ColumnDefinition.ForeignKey]] = Dictionary(grouping: try foreignKeys(table: table), by: { $0.column }) - return try connection.prepareRowIterator("PRAGMA table_info(\(table.quote()))") + let columnDefinitions = try connection.prepareRowIterator("PRAGMA table_info(\(table.quote()))") .map { (row: Row) -> ColumnDefinition in ColumnDefinition( name: row[TableInfoTable.nameColumn], @@ -29,10 +29,27 @@ public class SchemaReader { try parsePrimaryKey(column: row[TableInfoTable.nameColumn]) : nil, type: ColumnDefinition.Affinity(row[TableInfoTable.typeColumn]), nullable: row[TableInfoTable.notNullColumn] == 0, + unique: false, defaultValue: LiteralValue(row[TableInfoTable.defaultValueColumn]), references: foreignKeys[row[TableInfoTable.nameColumn]]?.first ) } + + let internalIndexes = try indexDefinitions(table: table).filter { $0.isInternal } + return columnDefinitions.map { definition in + if let index = internalIndexes.first(where: { $0.columns.contains(definition.name) }), index.origin == .uniqueConstraint { + + ColumnDefinition(name: definition.name, + primaryKey: definition.primaryKey, + type: definition.type, + nullable: definition.nullable, + unique: true, + defaultValue: definition.defaultValue, + references: definition.references) + } else { + definition + } + } } public func objectDefinitions(name: String? = nil, @@ -66,27 +83,26 @@ public class SchemaReader { .first } - func columns(name: String) throws -> [String] { + func indexInfos(name: String) throws -> [IndexInfo] { try connection.prepareRowIterator("PRAGMA index_info(\(name.quote()))") .compactMap { row in - row[IndexInfoTable.nameColumn] + IndexInfo(name: row[IndexInfoTable.nameColumn], + columnRank: row[IndexInfoTable.seqnoColumn], + columnRankWithinTable: row[IndexInfoTable.cidColumn]) + } } return try connection.prepareRowIterator("PRAGMA index_list(\(table.quote()))") .compactMap { row -> IndexDefinition? in let name = row[IndexListTable.nameColumn] - guard !name.starts(with: "sqlite_") else { - // Indexes SQLite creates implicitly for internal use start with "sqlite_". - // See https://www.sqlite.org/fileformat2.html#intschema - return nil - } return IndexDefinition( table: table, name: name, unique: row[IndexListTable.uniqueColumn] == 1, - columns: try columns(name: name), - indexSQL: try indexSQL(name: name) + columns: try indexInfos(name: name).compactMap { $0.name }, + indexSQL: try indexSQL(name: name), + origin: IndexDefinition.Origin(rawValue: row[IndexListTable.originColumn]) ) } } @@ -123,6 +139,15 @@ public class SchemaReader { objectDefinitions(name: name, type: .table, temp: true) ).compactMap(\.sql).first } + + struct IndexInfo { + let name: String? + // The rank of the column within the index. (0 means left-most.) + let columnRank: Int + // The rank of the column within the table being indexed. + // A value of -1 means rowid and a value of -2 means that an expression is being used + let columnRankWithinTable: Int + } } private enum SchemaTable { @@ -159,11 +184,12 @@ private enum TableInfoTable { private enum IndexInfoTable { // The rank of the column within the index. (0 means left-most.) - static let seqnoColumn = Expression("seqno") + static let seqnoColumn = Expression("seqno") // The rank of the column within the table being indexed. // A value of -1 means rowid and a value of -2 means that an expression is being used. - static let cidColumn = Expression("cid") - // The name of the column being indexed. This columns is NULL if the column is the rowid or an expression. + static let cidColumn = Expression("cid") + // The name of the column being indexed. + // This columns is NULL if the column is the rowid or an expression. static let nameColumn = Expression("name") } diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index 02a82267..724c2d0c 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -158,7 +158,7 @@ class SchemaChangerTests: SQLiteTestCase { func test_create_table() throws { try schemaChanger.create(table: "foo") { table in table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) - table.add(column: .init(name: "name", type: .TEXT, nullable: false)) + table.add(column: .init(name: "name", type: .TEXT, nullable: false, unique: true)) table.add(column: .init(name: "age", type: .INTEGER)) table.add(index: .init(table: table.name, @@ -179,25 +179,28 @@ class SchemaChangerTests: SQLiteTestCase { primaryKey: .init(autoIncrement: true, onConflict: nil), type: .INTEGER, nullable: true, + unique: false, defaultValue: .NULL, references: nil), ColumnDefinition(name: "name", primaryKey: nil, type: .TEXT, nullable: false, + unique: true, defaultValue: .NULL, references: nil), ColumnDefinition(name: "age", primaryKey: nil, type: .INTEGER, nullable: true, + unique: false, defaultValue: .NULL, references: nil) ]) - let indexes = try schema.indexDefinitions(table: "foo") + let indexes = try schema.indexDefinitions(table: "foo").filter { !$0.isInternal } XCTAssertEqual(indexes, [ - IndexDefinition(table: "foo", name: "nameIndex", unique: true, columns: ["name"], where: nil, orders: nil) + IndexDefinition(table: "foo", name: "nameIndex", unique: true, columns: ["name"], where: nil, orders: nil, origin: .createIndex) ]) } diff --git a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift index 8c033e41..01047c9c 100644 --- a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift @@ -18,41 +18,48 @@ class SchemaReaderTests: SQLiteTestCase { primaryKey: .init(autoIncrement: false, onConflict: nil), type: .INTEGER, nullable: true, + unique: false, defaultValue: .NULL, references: nil), ColumnDefinition(name: "email", primaryKey: nil, type: .TEXT, nullable: false, + unique: true, defaultValue: .NULL, references: nil), ColumnDefinition(name: "age", primaryKey: nil, type: .INTEGER, nullable: true, + unique: false, defaultValue: .NULL, references: nil), ColumnDefinition(name: "salary", primaryKey: nil, type: .REAL, nullable: true, + unique: false, defaultValue: .NULL, references: nil), ColumnDefinition(name: "admin", primaryKey: nil, type: .NUMERIC, nullable: false, + unique: false, defaultValue: .numericLiteral("0"), references: nil), ColumnDefinition(name: "manager_id", primaryKey: nil, type: .INTEGER, nullable: true, + unique: false, defaultValue: .NULL, references: .init(table: "users", column: "manager_id", primaryKey: "id", onUpdate: nil, onDelete: nil)), ColumnDefinition(name: "created_at", primaryKey: nil, type: .NUMERIC, nullable: true, + unique: false, defaultValue: .NULL, references: nil) ]) @@ -68,6 +75,24 @@ class SchemaReaderTests: SQLiteTestCase { primaryKey: .init(autoIncrement: true, onConflict: .IGNORE), type: .INTEGER, nullable: true, + unique: false, + defaultValue: .NULL, + references: nil) + ] + ) + } + + func test_columnDefinitions_parses_unique() throws { + try db.run("CREATE TABLE t (name TEXT UNIQUE)") + + let columns = try schemaReader.columnDefinitions(table: "t") + XCTAssertEqual(columns, [ + ColumnDefinition( + name: "name", + primaryKey: nil, + type: .TEXT, + nullable: true, + unique: true, defaultValue: .NULL, references: nil) ] @@ -128,13 +153,13 @@ class SchemaReaderTests: SQLiteTestCase { } func test_indexDefinitions_no_index() throws { - let indexes = try schemaReader.indexDefinitions(table: "users") + let indexes = try schemaReader.indexDefinitions(table: "users").filter { !$0.isInternal } XCTAssertTrue(indexes.isEmpty) } func test_indexDefinitions_with_index() throws { try db.run("CREATE UNIQUE INDEX index_users ON users (age DESC) WHERE age IS NOT NULL") - let indexes = try schemaReader.indexDefinitions(table: "users") + let indexes = try schemaReader.indexDefinitions(table: "users").filter { !$0.isInternal } XCTAssertEqual(indexes, [ IndexDefinition( @@ -143,7 +168,8 @@ class SchemaReaderTests: SQLiteTestCase { unique: true, columns: ["age"], where: "age IS NOT NULL", - orders: ["age": .DESC] + orders: ["age": .DESC], + origin: .createIndex ) ]) } From 374d99da2107656adf12670feea4f167853321d9 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 22 May 2025 10:53:36 +0200 Subject: [PATCH 56/84] Use cocoapods with watchOS fix --- Gemfile | 2 +- Gemfile.lock | 46 ++++++++++++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/Gemfile b/Gemfile index 1f2ebb87..2bb803ca 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem 'cocoapods' +gem 'cocoapods', :git => 'https://github.com/jberkel/CocoaPods.git', branch: 'watchos-fourflusher' diff --git a/Gemfile.lock b/Gemfile.lock index 9f71603b..20ed2aad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,27 @@ +GIT + remote: https://github.com/jberkel/CocoaPods.git + revision: 899f273f298ea20de2378687ea55331004b39371 + branch: watchos-fourflusher + specs: + cocoapods (1.16.2) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.16.2) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 2.1, < 3.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.6.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) + nap (~> 1.0) + ruby-macho (~> 4.1.0) + xcodeproj (>= 1.27.0, < 2.0) + GEM remote: https://rubygems.org/ specs: @@ -27,24 +51,6 @@ GEM benchmark (0.4.0) bigdecimal (3.1.9) claide (1.1.0) - cocoapods (1.16.2) - addressable (~> 2.8) - claide (>= 1.0.2, < 2.0) - cocoapods-core (= 1.16.2) - cocoapods-deintegrate (>= 1.0.3, < 2.0) - cocoapods-downloader (>= 2.1, < 3.0) - cocoapods-plugins (>= 1.0.0, < 2.0) - cocoapods-search (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.6.0, < 2.0) - cocoapods-try (>= 1.1.0, < 2.0) - colored2 (~> 3.1) - escape (~> 0.0.4) - fourflusher (>= 2.3.0, < 3.0) - gh_inspector (~> 1.0) - molinillo (~> 0.8.0) - nap (~> 1.0) - ruby-macho (>= 2.3.0, < 3.0) - xcodeproj (>= 1.27.0, < 2.0) cocoapods-core (1.16.2) activesupport (>= 5.0, < 8) addressable (~> 2.8) @@ -91,7 +97,7 @@ GEM nkf (0.2.0) public_suffix (4.0.7) rexml (3.4.1) - ruby-macho (2.5.1) + ruby-macho (4.1.0) securerandom (0.4.1) typhoeus (1.4.1) ethon (>= 0.9.0) @@ -110,7 +116,7 @@ PLATFORMS ruby DEPENDENCIES - cocoapods + cocoapods! BUNDLED WITH 2.6.9 From 108431244de611050f25c20efd02bcfe68687b28 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 22 May 2025 11:52:52 +0200 Subject: [PATCH 57/84] Disable visionOS for SQLCipher --- SQLite.swift.podspec | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index 4cbd91bb..d0ccb136 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -54,6 +54,13 @@ Pod::Spec.new do |s| end s.subspec 'SQLCipher' do |ss| + # Disable unsupported visionOS + # https://github.com/sqlcipher/sqlcipher/issues/483 + ss.ios.deployment_target = s.deployment_target(:ios) + ss.tvos.deployment_target = s.deployment_target(:tvos) + ss.osx.deployment_target = s.deployment_target(:osx) + ss.watchos.deployment_target = s.deployment_target(:watchos) + ss.source_files = 'Sources/SQLite/**/*.{c,h,m,swift}' ss.resource_bundle = { 'SQLite.swift' => 'Sources/SQLite/PrivacyInfo.xcprivacy' } From 718c7988780f803ede87c03ef2cdce58ea762656 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 22 May 2025 12:21:19 +0200 Subject: [PATCH 58/84] Add comment --- Gemfile | 1 + Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 2bb803ca..2770e85d 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,4 @@ source "https://rubygems.org" +# https://github.com/CocoaPods/CocoaPods/pull/12816 gem 'cocoapods', :git => 'https://github.com/jberkel/CocoaPods.git', branch: 'watchos-fourflusher' diff --git a/Gemfile.lock b/Gemfile.lock index 20ed2aad..7dac2c18 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/jberkel/CocoaPods.git - revision: 899f273f298ea20de2378687ea55331004b39371 + revision: 32a90c184bc5dc9ec8b7b9b8ad08e98b7253dec2 branch: watchos-fourflusher specs: cocoapods (1.16.2) From c812caf9c432bc196f87648b56551dff2c0017e3 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 22 May 2025 13:30:36 +0200 Subject: [PATCH 59/84] Make ForeignKey public, rename fields for clarity --- Sources/SQLite/Schema/SchemaDefinitions.swift | 23 ++++++++++--- Sources/SQLite/Schema/SchemaReader.swift | 8 ++--- .../Schema/SchemaChangerTests.swift | 34 +++++++++++++++++++ .../Schema/SchemaDefinitionsTests.swift | 8 ++--- .../Schema/SchemaReaderTests.swift | 4 +-- 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/Sources/SQLite/Schema/SchemaDefinitions.swift b/Sources/SQLite/Schema/SchemaDefinitions.swift index bb4ce82b..d7803999 100644 --- a/Sources/SQLite/Schema/SchemaDefinitions.swift +++ b/Sources/SQLite/Schema/SchemaDefinitions.swift @@ -117,11 +117,24 @@ public struct ColumnDefinition: Equatable { } public struct ForeignKey: Equatable { - let table: String - let column: String - let primaryKey: String? + let fromColumn: String + let toTable: String + // when null, use primary key of "toTable" + let toColumn: String? let onUpdate: String? let onDelete: String? + + public init(toTable: String, toColumn: String? = nil, onUpdate: String? = nil, onDelete: String? = nil) { + self.init(fromColumn: "", toTable: toTable, toColumn: toColumn, onUpdate: onUpdate, onDelete: onDelete) + } + + public init(fromColumn: String, toTable: String, toColumn: String? = nil, onUpdate: String? = nil, onDelete: String? = nil) { + self.fromColumn = fromColumn + self.toTable = toTable + self.toColumn = toColumn + self.onUpdate = onUpdate + self.onDelete = onDelete + } } public let name: String @@ -400,8 +413,8 @@ extension ColumnDefinition.ForeignKey { func toSQL() -> String { ([ "REFERENCES", - table.quote(), - primaryKey.map { "(\($0.quote()))" }, + toTable.quote(), + toColumn.map { "(\($0.quote()))" }, onUpdate.map { "ON UPDATE \($0)" }, onDelete.map { "ON DELETE \($0)" } ] as [String?]).compactMap { $0 } diff --git a/Sources/SQLite/Schema/SchemaReader.swift b/Sources/SQLite/Schema/SchemaReader.swift index a67fb94f..995cd4d7 100644 --- a/Sources/SQLite/Schema/SchemaReader.swift +++ b/Sources/SQLite/Schema/SchemaReader.swift @@ -19,7 +19,7 @@ public class SchemaReader { } let foreignKeys: [String: [ColumnDefinition.ForeignKey]] = - Dictionary(grouping: try foreignKeys(table: table), by: { $0.column }) + Dictionary(grouping: try foreignKeys(table: table), by: { $0.fromColumn }) let columnDefinitions = try connection.prepareRowIterator("PRAGMA table_info(\(table.quote()))") .map { (row: Row) -> ColumnDefinition in @@ -111,9 +111,9 @@ public class SchemaReader { try connection.prepareRowIterator("PRAGMA foreign_key_list(\(table.quote()))") .map { row in ColumnDefinition.ForeignKey( - table: row[ForeignKeyListTable.tableColumn], - column: row[ForeignKeyListTable.fromColumn], - primaryKey: row[ForeignKeyListTable.toColumn], + fromColumn: row[ForeignKeyListTable.fromColumn], + toTable: row[ForeignKeyListTable.tableColumn], + toColumn: row[ForeignKeyListTable.toColumn], onUpdate: row[ForeignKeyListTable.onUpdateColumn] == TableBuilder.Dependency.noAction.rawValue ? nil : row[ForeignKeyListTable.onUpdateColumn], onDelete: row[ForeignKeyListTable.onDeleteColumn] == TableBuilder.Dependency.noAction.rawValue diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index 724c2d0c..b08344fc 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -269,4 +269,38 @@ class SchemaChangerTests: SQLiteTestCase { table.add(index: .init(table: "foo", name: "name_index", unique: true, columns: ["name"], indexSQL: nil)) } } + + func test_create_table_with_foreign_key_reference() throws { + try schemaChanger.create(table: "foo") { table in + table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) + } + + try schemaChanger.create(table: "bars") { table in + table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) + table.add(column: .init(name: "foo_id", + type: .INTEGER, + nullable: false, + references: .init(toTable: "foo", toColumn: "id"))) + } + + let barColumns = try schema.columnDefinitions(table: "bars") + + XCTAssertEqual([ + ColumnDefinition(name: "id", + primaryKey: .init(autoIncrement: true, onConflict: nil), + type: .INTEGER, + nullable: true, + unique: false, + defaultValue: .NULL, + references: nil), + + ColumnDefinition(name: "foo_id", + primaryKey: nil, + type: .INTEGER, + nullable: false, + unique: false, + defaultValue: .NULL, + references: .init(fromColumn: "foo_id", toTable: "foo", toColumn: "id", onUpdate: nil, onDelete: nil)) + ], barColumns) + } } diff --git a/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift b/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift index 8b7e27e3..1c648bd8 100644 --- a/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift @@ -11,7 +11,7 @@ class ColumnDefinitionTests: XCTestCase { ("\"other_id\" INTEGER NOT NULL REFERENCES \"other_table\" (\"some_id\")", ColumnDefinition(name: "other_id", primaryKey: nil, type: .INTEGER, nullable: false, defaultValue: .NULL, - references: .init(table: "other_table", column: "", primaryKey: "some_id", onUpdate: nil, onDelete: nil))), + references: .init(fromColumn: "", toTable: "other_table", toColumn: "some_id", onUpdate: nil, onDelete: nil))), ("\"text\" TEXT", ColumnDefinition(name: "text", primaryKey: nil, type: .TEXT, nullable: true, defaultValue: .NULL, references: nil)), @@ -245,9 +245,9 @@ class ForeignKeyDefinitionTests: XCTestCase { func test_toSQL() { XCTAssertEqual( ColumnDefinition.ForeignKey( - table: "foo", - column: "bar", - primaryKey: "bar_id", + fromColumn: "bar", + toTable: "foo", + toColumn: "bar_id", onUpdate: nil, onDelete: "SET NULL" ).toSQL(), """ diff --git a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift index 01047c9c..8963070f 100644 --- a/Tests/SQLiteTests/Schema/SchemaReaderTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaReaderTests.swift @@ -54,7 +54,7 @@ class SchemaReaderTests: SQLiteTestCase { nullable: true, unique: false, defaultValue: .NULL, - references: .init(table: "users", column: "manager_id", primaryKey: "id", onUpdate: nil, onDelete: nil)), + references: .init(fromColumn: "manager_id", toTable: "users", toColumn: "id", onUpdate: nil, onDelete: nil)), ColumnDefinition(name: "created_at", primaryKey: nil, type: .NUMERIC, @@ -194,7 +194,7 @@ class SchemaReaderTests: SQLiteTestCase { let foreignKeys = try schemaReader.foreignKeys(table: "test_links") XCTAssertEqual(foreignKeys, [ - .init(table: "users", column: "test_id", primaryKey: "id", onUpdate: nil, onDelete: nil) + .init(fromColumn: "test_id", toTable: "users", toColumn: "id", onUpdate: nil, onDelete: nil) ]) } From 1c440766b22019190a9c78731f0c69b78f5d177b Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 22 May 2025 17:06:41 +0200 Subject: [PATCH 60/84] Add drop(index:) --- Sources/SQLite/Schema/SchemaChanger.swift | 10 ++++- .../Schema/SchemaChangerTests.swift | 38 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Sources/SQLite/Schema/SchemaChanger.swift b/Sources/SQLite/Schema/SchemaChanger.swift index 13222dab..7ba458c1 100644 --- a/Sources/SQLite/Schema/SchemaChanger.swift +++ b/Sources/SQLite/Schema/SchemaChanger.swift @@ -45,6 +45,7 @@ public class SchemaChanger: CustomStringConvertible { case addColumn(ColumnDefinition) case addIndex(IndexDefinition, ifNotExists: Bool) case dropColumn(String) + case dropIndex(String, ifExists: Bool) case renameColumn(String, String) case renameTable(String) case createTable(columns: [ColumnDefinition], ifNotExists: Bool) @@ -60,6 +61,8 @@ public class SchemaChanger: CustomStringConvertible { return "ALTER TABLE \(table.quote()) RENAME COLUMN \(from.quote()) TO \(to.quote())" case .dropColumn(let column) where SQLiteFeature.dropColumn.isSupported(by: version): return "ALTER TABLE \(table.quote()) DROP COLUMN \(column.quote())" + case .dropIndex(let name, let ifExists): + return "DROP INDEX \(ifExists ? " IF EXISTS " : "") \(name.quote())" case .createTable(let columns, let ifNotExists): return "CREATE TABLE \(ifNotExists ? " IF NOT EXISTS " : "") \(table.quote()) (" + columns.map { $0.toSQL() }.joined(separator: ", ") + @@ -111,6 +114,10 @@ public class SchemaChanger: CustomStringConvertible { operations.append(.dropColumn(column)) } + public func drop(index: String, ifExists: Bool = false) { + operations.append(.dropIndex(index, ifExists: ifExists)) + } + public func rename(column: String, to: String) { operations.append(.renameColumn(column, to)) } @@ -324,8 +331,9 @@ extension TableDefinition { func apply(_ operation: SchemaChanger.Operation?) -> TableDefinition { switch operation { case .none: return self - case .createTable, .addIndex: fatalError() + case .createTable, .addIndex, .dropIndex: fatalError() case .addColumn: fatalError("Use 'ALTER TABLE ADD COLUMN (...)'") + case .dropColumn(let column): return TableDefinition(name: name, columns: columns.filter { $0.name != column }, diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index b08344fc..75331a97 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -124,6 +124,44 @@ class SchemaChangerTests: SQLiteTestCase { } } + func test_drop_index() throws { + try db.execute(""" + CREATE INDEX age_index ON users(age) + """) + + try schemaChanger.alter(table: "users") { table in + table.drop(index: "age_index") + } + let indexes = try schema.indexDefinitions(table: "users").filter { !$0.isInternal } + XCTAssertEqual(0, indexes.count) + } + + func test_drop_index_if_exists() throws { + try db.execute(""" + CREATE INDEX age_index ON users(age) + """) + + try schemaChanger.alter(table: "users") { table in + table.drop(index: "age_index") + } + + try schemaChanger.alter(table: "users") { table in + table.drop(index: "age_index", ifExists: true) + } + + XCTAssertThrowsError( + try schemaChanger.alter(table: "users") { table in + table.drop(index: "age_index", ifExists: false) + } + ) { error in + if case Result.error(let message, _, _) = error { + XCTAssertEqual(message, "no such index: age_index") + } else { + XCTFail("unexpected error \(error)") + } + } + } + func test_drop_table() throws { try schemaChanger.drop(table: "users") XCTAssertThrowsError(try db.scalar(users.count)) { error in From 08bed022dc12289d64278cc5ad2e9a63868fb12f Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 22 May 2025 17:23:02 +0200 Subject: [PATCH 61/84] Implement add(index:) --- Sources/SQLite/Schema/SchemaChanger.swift | 4 +++ .../Schema/SchemaChangerTests.swift | 34 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Sources/SQLite/Schema/SchemaChanger.swift b/Sources/SQLite/Schema/SchemaChanger.swift index 7ba458c1..3badb8d8 100644 --- a/Sources/SQLite/Schema/SchemaChanger.swift +++ b/Sources/SQLite/Schema/SchemaChanger.swift @@ -110,6 +110,10 @@ public class SchemaChanger: CustomStringConvertible { operations.append(.addColumn(column)) } + public func add(index: IndexDefinition, ifNotExists: Bool = false) { + operations.append(.addIndex(index, ifNotExists: ifNotExists)) + } + public func drop(column: String) { operations.append(.dropColumn(column)) } diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index 75331a97..dafdea54 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -124,6 +124,40 @@ class SchemaChangerTests: SQLiteTestCase { } } + func test_add_index() throws { + try schemaChanger.alter(table: "users") { table in + table.add(index: .init(table: table.name, name: "age_index", unique: false, columns: ["age"], indexSQL: nil)) + } + + let indexes = try schema.indexDefinitions(table: "users").filter { !$0.isInternal } + XCTAssertEqual([ + IndexDefinition(table: "users", + name: "age_index", + unique: false, + columns: ["age"], + where: nil, + orders: nil, + origin: .createIndex) + ], indexes) + } + + func test_add_index_if_not_exists() throws { + let index = IndexDefinition(table: "users", name: "age_index", unique: false, columns: ["age"], indexSQL: nil) + try schemaChanger.alter(table: "users") { table in + table.add(index: index) + } + + try schemaChanger.alter(table: "users") { table in + table.add(index: index, ifNotExists: true) + } + + XCTAssertThrowsError( + try schemaChanger.alter(table: "users") { table in + table.add(index: index, ifNotExists: false) + } + ) + } + func test_drop_index() throws { try db.execute(""" CREATE INDEX age_index ON users(age) From 3def7d60f70b109e0f74f6d42bac61d631de56dd Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 22 May 2025 17:45:33 +0200 Subject: [PATCH 62/84] Make name public, expose plain SQL run --- Sources/SQLite/Schema/SchemaChanger.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/SQLite/Schema/SchemaChanger.swift b/Sources/SQLite/Schema/SchemaChanger.swift index 3badb8d8..3e146df7 100644 --- a/Sources/SQLite/Schema/SchemaChanger.swift +++ b/Sources/SQLite/Schema/SchemaChanger.swift @@ -100,7 +100,7 @@ public class SchemaChanger: CustomStringConvertible { public class AlterTableDefinition { fileprivate var operations: [Operation] = [] - let name: String + public let name: String init(name: String) { self.name = name @@ -223,6 +223,11 @@ public class SchemaChanger: CustomStringConvertible { try connection.run("ALTER TABLE \(table.quote()) RENAME TO \(to.quote())") } + // Runs arbitrary SQL. Should only be used if no predefined operations exist. + public func run(sql: String) throws { + try connection.run(sql) + } + private func run(table: String, operation: Operation) throws { try operation.validate() From 25bd06392f65d7ca75ffc481471de05905ec1c79 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 22 May 2025 17:53:46 +0200 Subject: [PATCH 63/84] Better API, test --- Sources/SQLite/Schema/SchemaChanger.swift | 5 +++-- Tests/SQLiteTests/Schema/SchemaChangerTests.swift | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Sources/SQLite/Schema/SchemaChanger.swift b/Sources/SQLite/Schema/SchemaChanger.swift index 3e146df7..6fae532a 100644 --- a/Sources/SQLite/Schema/SchemaChanger.swift +++ b/Sources/SQLite/Schema/SchemaChanger.swift @@ -224,8 +224,9 @@ public class SchemaChanger: CustomStringConvertible { } // Runs arbitrary SQL. Should only be used if no predefined operations exist. - public func run(sql: String) throws { - try connection.run(sql) + @discardableResult + public func run(_ sql: String, _ bindings: Binding?...) throws -> Statement { + return try connection.run(sql, bindings) } private func run(table: String, operation: Operation) throws { diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index dafdea54..d942fba4 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -375,4 +375,9 @@ class SchemaChangerTests: SQLiteTestCase { references: .init(fromColumn: "foo_id", toTable: "foo", toColumn: "id", onUpdate: nil, onDelete: nil)) ], barColumns) } + + func test_run_arbitrary_sql() throws { + try schemaChanger.run("DROP TABLE users") + XCTAssertEqual(0, try schema.objectDefinitions(name: "users", type: .table).count) + } } From 8938697549dccc21803c5cbef9f2e5fec7ee274a Mon Sep 17 00:00:00 2001 From: ha100 Date: Sun, 8 Jun 2025 05:38:36 +0200 Subject: [PATCH 64/84] change CSQLite dep to SwiftToolchainCSQLite to allow swift sdk cross compilation --- Package.swift | 69 +++++++++++-------- Sources/SQLite/Core/Backup.swift | 2 +- .../SQLite/Core/Connection+Aggregation.swift | 2 +- Sources/SQLite/Core/Connection+Attach.swift | 2 +- Sources/SQLite/Core/Connection.swift | 2 +- Sources/SQLite/Core/Result.swift | 2 +- Sources/SQLite/Core/Statement.swift | 2 +- Sources/SQLite/Helpers.swift | 2 +- .../Core/Connection+AttachTests.swift | 2 +- .../Core/Connection+PragmaTests.swift | 2 +- Tests/SQLiteTests/Core/ConnectionTests.swift | 2 +- Tests/SQLiteTests/Core/ResultTests.swift | 2 +- Tests/SQLiteTests/Core/StatementTests.swift | 2 +- .../Extensions/FTSIntegrationTests.swift | 2 +- .../Typed/CustomAggregationTests.swift | 2 +- .../Typed/QueryIntegrationTests.swift | 2 +- Tests/SQLiteTests/Typed/QueryTests.swift | 2 +- 17 files changed, 56 insertions(+), 45 deletions(-) diff --git a/Package.swift b/Package.swift index 238661ae..690d41e2 100644 --- a/Package.swift +++ b/Package.swift @@ -1,6 +1,38 @@ // swift-tools-version:5.9 import PackageDescription +let deps: [Package.Dependency] = [ + .github("swiftlang/swift-toolchain-sqlite", exact: "1.0.4") +] + +let targets: [Target] = [ + .target( + name: "SQLite", + dependencies: [ + .product(name: "SwiftToolchainCSQLite", package: "swift-toolchain-sqlite") + ], + exclude: [ + "Info.plist" + ] + ) +] + +let testTargets: [Target] = [ + .testTarget( + name: "SQLiteTests", + dependencies: [ + "SQLite" + ], + path: "Tests/SQLiteTests", + exclude: [ + "Info.plist" + ], + resources: [ + .copy("Resources") + ] + ) +] + let package = Package( name: "SQLite.swift", platforms: [ @@ -16,34 +48,13 @@ let package = Package( targets: ["SQLite"] ) ], - targets: [ - .target( - name: "SQLite", - exclude: [ - "Info.plist" - ] - ), - .testTarget( - name: "SQLiteTests", - dependencies: [ - "SQLite" - ], - path: "Tests/SQLiteTests", - exclude: [ - "Info.plist" - ], - resources: [ - .copy("Resources") - ] - ) - ] + dependencies: deps, + targets: targets + testTargets ) -#if os(Linux) -package.dependencies = [ - .package(url: "https://github.com/stephencelis/CSQLite.git", from: "0.0.3") -] -package.targets.first?.dependencies += [ - .product(name: "CSQLite", package: "CSQLite") -] -#endif +extension Package.Dependency { + + static func github(_ repo: String, exact ver: Version) -> Package.Dependency { + .package(url: "https://github.com/\(repo)", exact: ver) + } +} diff --git a/Sources/SQLite/Core/Backup.swift b/Sources/SQLite/Core/Backup.swift index 0eebbdd5..5e741ecd 100644 --- a/Sources/SQLite/Core/Backup.swift +++ b/Sources/SQLite/Core/Backup.swift @@ -29,7 +29,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Core/Connection+Aggregation.swift b/Sources/SQLite/Core/Connection+Aggregation.swift index 4eea76c3..bfe253a7 100644 --- a/Sources/SQLite/Core/Connection+Aggregation.swift +++ b/Sources/SQLite/Core/Connection+Aggregation.swift @@ -4,7 +4,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Core/Connection+Attach.swift b/Sources/SQLite/Core/Connection+Attach.swift index 8a25e51d..32461468 100644 --- a/Sources/SQLite/Core/Connection+Attach.swift +++ b/Sources/SQLite/Core/Connection+Attach.swift @@ -4,7 +4,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Core/Connection.swift b/Sources/SQLite/Core/Connection.swift index f2c3b781..188ff80b 100644 --- a/Sources/SQLite/Core/Connection.swift +++ b/Sources/SQLite/Core/Connection.swift @@ -29,7 +29,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Core/Result.swift b/Sources/SQLite/Core/Result.swift index ee59e5d1..2659ad21 100644 --- a/Sources/SQLite/Core/Result.swift +++ b/Sources/SQLite/Core/Result.swift @@ -3,7 +3,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Core/Statement.swift b/Sources/SQLite/Core/Statement.swift index 6cb2e5d3..458e3d9c 100644 --- a/Sources/SQLite/Core/Statement.swift +++ b/Sources/SQLite/Core/Statement.swift @@ -27,7 +27,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Sources/SQLite/Helpers.swift b/Sources/SQLite/Helpers.swift index c27ccf05..00493f21 100644 --- a/Sources/SQLite/Helpers.swift +++ b/Sources/SQLite/Helpers.swift @@ -27,7 +27,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Tests/SQLiteTests/Core/Connection+AttachTests.swift b/Tests/SQLiteTests/Core/Connection+AttachTests.swift index f37300ca..68618596 100644 --- a/Tests/SQLiteTests/Core/Connection+AttachTests.swift +++ b/Tests/SQLiteTests/Core/Connection+AttachTests.swift @@ -7,7 +7,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Tests/SQLiteTests/Core/Connection+PragmaTests.swift b/Tests/SQLiteTests/Core/Connection+PragmaTests.swift index 2bcdb6af..bd29bd98 100644 --- a/Tests/SQLiteTests/Core/Connection+PragmaTests.swift +++ b/Tests/SQLiteTests/Core/Connection+PragmaTests.swift @@ -7,7 +7,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Tests/SQLiteTests/Core/ConnectionTests.swift b/Tests/SQLiteTests/Core/ConnectionTests.swift index 6a1d94ae..61083453 100644 --- a/Tests/SQLiteTests/Core/ConnectionTests.swift +++ b/Tests/SQLiteTests/Core/ConnectionTests.swift @@ -8,7 +8,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Tests/SQLiteTests/Core/ResultTests.swift b/Tests/SQLiteTests/Core/ResultTests.swift index d3c8bb1f..b6a373f7 100644 --- a/Tests/SQLiteTests/Core/ResultTests.swift +++ b/Tests/SQLiteTests/Core/ResultTests.swift @@ -7,7 +7,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Tests/SQLiteTests/Core/StatementTests.swift b/Tests/SQLiteTests/Core/StatementTests.swift index dbf99d7c..ceaa8813 100644 --- a/Tests/SQLiteTests/Core/StatementTests.swift +++ b/Tests/SQLiteTests/Core/StatementTests.swift @@ -6,7 +6,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift b/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift index 1129ae08..8a34e93b 100644 --- a/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift +++ b/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift @@ -4,7 +4,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Tests/SQLiteTests/Typed/CustomAggregationTests.swift b/Tests/SQLiteTests/Typed/CustomAggregationTests.swift index 71cbba9c..8b7ec09a 100644 --- a/Tests/SQLiteTests/Typed/CustomAggregationTests.swift +++ b/Tests/SQLiteTests/Typed/CustomAggregationTests.swift @@ -8,7 +8,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift index 6be98ca0..899bf354 100644 --- a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift +++ b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift @@ -4,7 +4,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif diff --git a/Tests/SQLiteTests/Typed/QueryTests.swift b/Tests/SQLiteTests/Typed/QueryTests.swift index f018f097..7fc3dcf5 100644 --- a/Tests/SQLiteTests/Typed/QueryTests.swift +++ b/Tests/SQLiteTests/Typed/QueryTests.swift @@ -4,7 +4,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher #elseif os(Linux) -import CSQLite +import SwiftToolchainCSQLite #else import SQLite3 #endif From fc774a2585965a90f60aa034001e6d69aee42382 Mon Sep 17 00:00:00 2001 From: ha100 Date: Sun, 8 Jun 2025 07:08:47 +0200 Subject: [PATCH 65/84] fix macOS build via platform condition --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 690d41e2..48085178 100644 --- a/Package.swift +++ b/Package.swift @@ -9,7 +9,7 @@ let targets: [Target] = [ .target( name: "SQLite", dependencies: [ - .product(name: "SwiftToolchainCSQLite", package: "swift-toolchain-sqlite") + .product(name: "SwiftToolchainCSQLite", package: "swift-toolchain-sqlite", condition: .when(platforms: [.linux, .windows])) ], exclude: [ "Info.plist" From f3cb9105a80d566575c02bb77ac50e74e5895ccc Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 12 Jun 2025 12:15:34 +0200 Subject: [PATCH 66/84] Fully qualify Expression --- Tests/SQLiteTests/Schema/SchemaChangerTests.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift index d942fba4..f5a6de42 100644 --- a/Tests/SQLiteTests/Schema/SchemaChangerTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaChangerTests.swift @@ -278,9 +278,9 @@ class SchemaChangerTests: SQLiteTestCase { func test_create_table_add_column_expression() throws { try schemaChanger.create(table: "foo") { table in - table.add(expression: Expression("name")) - table.add(expression: Expression("age")) - table.add(expression: Expression("salary")) + table.add(expression: SQLite.Expression("name")) + table.add(expression: SQLite.Expression("age")) + table.add(expression: SQLite.Expression("salary")) } let columns = try schema.columnDefinitions(table: "foo") From a7d7e8c0b7529f851fd8927071003095f1e87522 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 12 Jun 2025 12:27:28 +0200 Subject: [PATCH 67/84] 17.5 no longer available --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a0274321..33c4dba6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,7 @@ name: Build and test on: [push, pull_request] env: IOS_SIMULATOR: "iPhone 15" - IOS_VERSION: "17.5" + IOS_VERSION: "18.0" jobs: build: runs-on: macos-15 From 716394d091618047dfe86b7da5106fb21ede412f Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 12 Jun 2025 12:34:42 +0200 Subject: [PATCH 68/84] iPhone 16 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 33c4dba6..37f75476 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,7 @@ name: Build and test on: [push, pull_request] env: - IOS_SIMULATOR: "iPhone 15" + IOS_SIMULATOR: "iPhone 16" IOS_VERSION: "18.0" jobs: build: From 9831a45edb84d492cd5b68ba6f8d53300808499f Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Thu, 12 Jun 2025 13:17:56 +0200 Subject: [PATCH 69/84] Update Index.md --- Documentation/Index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/Index.md b/Documentation/Index.md index bc62c791..bd2a7a77 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -1592,7 +1592,8 @@ let schemaChanger = SchemaChanger(connection: db) try schemaChanger.create(table: "users") { table in table.add(column: .init(name: "id", primaryKey: .init(autoIncrement: true), type: .INTEGER)) table.add(column: .init(name: "name", type: .TEXT, nullable: false)) -} +} +``` ### Indexes From e3a916637162ece77b0ffd89b9e758669adc62f0 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 13 Jun 2025 22:49:43 +0200 Subject: [PATCH 70/84] Update CHANGELOG for release --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c96724fd..b77a8b07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +0.15.4 (13-06-2025), [diff][diff-0.15.4] +======================================== +* Fix cross compilation for linux on macOS fails ([#1317][]) +* Support creating tables in schema changer ([#1315][]) +* Update oldest supported platform versions ([#1280][]) +* Add CustomStringConvertible for Setter ([#1279][]) + 0.15.3 (19-04-2024), [diff][diff-0.15.3] ======================================== * Update `podspec` to include privacy manifest ([#1265][]) @@ -173,6 +180,8 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). [diff-0.15.0]: https://github.com/stephencelis/SQLite.swift/compare/0.14.0...0.15.0 [diff-0.15.1]: https://github.com/stephencelis/SQLite.swift/compare/0.15.0...0.15.1 [diff-0.15.2]: https://github.com/stephencelis/SQLite.swift/compare/0.15.1...0.15.2 +[diff-0.15.3]: https://github.com/stephencelis/SQLite.swift/compare/0.15.2...0.15.3 +[diff-0.15.4]: https://github.com/stephencelis/SQLite.swift/compare/0.15.3...0.15.4 [#30]: https://github.com/stephencelis/SQLite.swift/issues/30 [#142]: https://github.com/stephencelis/SQLite.swift/issues/142 @@ -259,3 +268,7 @@ For breaking changes, see [Upgrading.md](Documentation/Upgrading.md). [#1237]: https://github.com/stephencelis/SQLite.swift/pull/1237 [#1260]: https://github.com/stephencelis/SQLite.swift/pull/1260 [#1265]: https://github.com/stephencelis/SQLite.swift/pull/1265 +[#1279]: https://github.com/stephencelis/SQLite.swift/pull/1279 +[#1280]: https://github.com/stephencelis/SQLite.swift/pull/1280 +[#1315]: https://github.com/stephencelis/SQLite.swift/pull/1315 +[#1317]: https://github.com/stephencelis/SQLite.swift/pull/1317 \ No newline at end of file From 02e055c99c4fa19604a95fea4e82fd085391fdf0 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 13 Jun 2025 22:51:53 +0200 Subject: [PATCH 71/84] Update README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a4d713b6..3e782f86 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Swift code. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.3") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.4") ] ``` @@ -152,7 +152,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.15.3 + github "stephencelis/SQLite.swift" ~> 0.15.4 ``` 3. Run `carthage update` and @@ -183,7 +183,7 @@ SQLite.swift with CocoaPods: use_frameworks! target 'YourAppTargetName' do - pod 'SQLite.swift', '~> 0.14.0' + pod 'SQLite.swift', '~> 0.15.0' end ``` From bbc5212c2ae9905d17ae581927c06e2cbad61ff7 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 13 Jun 2025 22:53:36 +0200 Subject: [PATCH 72/84] Project looks dead --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 3e782f86..db80fd3a 100644 --- a/README.md +++ b/README.md @@ -266,7 +266,6 @@ Looking for something else? Try another Swift wrapper (or [FMDB][]): - [GRDB](https://github.com/groue/GRDB.swift) - [SQLiteDB](https://github.com/FahimF/SQLiteDB) - - [Squeal](https://github.com/nerdyc/Squeal) [Swift]: https://swift.org/ [SQLite3]: https://www.sqlite.org From 4e289bed6f1ed6737ffa963570beae3359a849e8 Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 13 Jun 2025 23:00:44 +0200 Subject: [PATCH 73/84] No longer maintained --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index db80fd3a..0e83504f 100644 --- a/README.md +++ b/README.md @@ -226,8 +226,6 @@ device: ## Communication -[See the planning document] for a roadmap and existing feature requests. - [Read the contributing guidelines][]. The _TL;DR_ (but please; _R_): - Need **help** or have a **general question**? [Ask on Stack @@ -235,7 +233,6 @@ device: - Found a **bug** or have a **feature request**? [Open an issue][]. - Want to **contribute**? [Submit a pull request][]. -[See the planning document]: /Documentation/Planning.md [Read the contributing guidelines]: ./CONTRIBUTING.md#contributing [Ask on Stack Overflow]: https://stackoverflow.com/questions/tagged/sqlite.swift [Open an issue]: https://github.com/stephencelis/SQLite.swift/issues/new From 0f4f2c85c5beddeb70f02e1db36785b5f6e2dccf Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Fri, 13 Jun 2025 23:12:38 +0200 Subject: [PATCH 74/84] Bump version to 0.15.4 --- Documentation/Index.md | 12 ++++++------ SQLite.swift.podspec | 2 +- SQLite.xcodeproj/project.pbxproj | 12 ++---------- Tests/SPM/Package.swift | 2 +- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Documentation/Index.md b/Documentation/Index.md index bd2a7a77..0e8261f2 100644 --- a/Documentation/Index.md +++ b/Documentation/Index.md @@ -109,7 +109,7 @@ process of downloading, compiling, and linking dependencies. ```swift dependencies: [ - .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.3") + .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.4") ] ``` @@ -130,7 +130,7 @@ install SQLite.swift with Carthage: 2. Update your Cartfile to include the following: ```ruby - github "stephencelis/SQLite.swift" ~> 0.15.3 + github "stephencelis/SQLite.swift" ~> 0.15.4 ``` 3. Run `carthage update` and [add the appropriate framework][Carthage Usage]. @@ -160,7 +160,7 @@ install SQLite.swift with Carthage: use_frameworks! target 'YourAppTargetName' do - pod 'SQLite.swift', '~> 0.15.3' + pod 'SQLite.swift', '~> 0.15.4' end ``` @@ -174,7 +174,7 @@ with the OS you can require the `standalone` subspec: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.15.3' + pod 'SQLite.swift/standalone', '~> 0.15.4' end ``` @@ -184,7 +184,7 @@ dependency to sqlite3 or one of its subspecs: ```ruby target 'YourAppTargetName' do - pod 'SQLite.swift/standalone', '~> 0.15.3' + pod 'SQLite.swift/standalone', '~> 0.15.4' pod 'sqlite3/fts5', '= 3.15.0' # SQLite 3.15.0 with FTS5 enabled end ``` @@ -200,7 +200,7 @@ If you want to use [SQLCipher][] with SQLite.swift you can require the target 'YourAppTargetName' do # Make sure you only require the subspec, otherwise you app might link against # the system SQLite, which means the SQLCipher-specific methods won't work. - pod 'SQLite.swift/SQLCipher', '~> 0.15.3' + pod 'SQLite.swift/SQLCipher', '~> 0.15.4' end ``` diff --git a/SQLite.swift.podspec b/SQLite.swift.podspec index d0ccb136..73c6f705 100644 --- a/SQLite.swift.podspec +++ b/SQLite.swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SQLite.swift" - s.version = "0.15.3" + s.version = "0.15.4" s.summary = "A type-safe, Swift-language layer over SQLite3." s.description = <<-DESC diff --git a/SQLite.xcodeproj/project.pbxproj b/SQLite.xcodeproj/project.pbxproj index a2d7edbe..ec0423e9 100644 --- a/SQLite.xcodeproj/project.pbxproj +++ b/SQLite.xcodeproj/project.pbxproj @@ -1539,7 +1539,6 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = appletvos; @@ -1562,7 +1561,6 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = appletvos; @@ -1614,7 +1612,6 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = watchos; @@ -1639,7 +1636,6 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = watchos; @@ -1664,7 +1660,6 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = xros; @@ -1689,7 +1684,6 @@ INFOPLIST_FILE = "$(SRCROOT)/Sources/SQLite/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = xros; @@ -1778,6 +1772,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 10.13; + MARKETING_VERSION = 0.15.4; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = ""; @@ -1837,6 +1832,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 13.0; MACOSX_DEPLOYMENT_TARGET = 10.13; + MARKETING_VERSION = 0.15.4; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = ""; SDKROOT = iphoneos; @@ -1866,7 +1862,6 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SKIP_INSTALL = YES; @@ -1890,7 +1885,6 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SKIP_INSTALL = YES; @@ -1940,7 +1934,6 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = macosx; @@ -1966,7 +1959,6 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.13; - MARKETING_VERSION = 0.15.3; PRODUCT_BUNDLE_IDENTIFIER = com.stephencelis.SQLite; PRODUCT_NAME = SQLite; SDKROOT = macosx; diff --git a/Tests/SPM/Package.swift b/Tests/SPM/Package.swift index 6521211a..a5a4afc4 100644 --- a/Tests/SPM/Package.swift +++ b/Tests/SPM/Package.swift @@ -15,7 +15,7 @@ let package = Package( // for testing from same repository .package(path: "../..") // normally this would be: - // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.3") + // .package(url: "https://github.com/stephencelis/SQLite.swift.git", from: "0.15.4") ], targets: [ .executableTarget(name: "test", dependencies: [.product(name: "SQLite", package: "SQLite.swift")]) From 496a086e5a4d03fb6b0338f63b600dc153be6fa3 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Mon, 14 Jul 2025 15:14:14 -0400 Subject: [PATCH 75/84] Build `SwiftToolchainCSQLite` for Android --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index cf3a0b60..56925d18 100644 --- a/Package.swift +++ b/Package.swift @@ -9,7 +9,7 @@ let targets: [Target] = [ .target( name: "SQLite", dependencies: [ - .product(name: "SwiftToolchainCSQLite", package: "swift-toolchain-sqlite", condition: .when(platforms: [.linux, .windows])) + .product(name: "SwiftToolchainCSQLite", package: "swift-toolchain-sqlite", condition: .when(platforms: [.linux, .windows, .android])) ], exclude: [ "Info.plist" From e8cfef658cbdbdd297ed7f549d197ec481b6b7a9 Mon Sep 17 00:00:00 2001 From: Alsey Coleman Miller Date: Mon, 14 Jul 2025 15:14:34 -0400 Subject: [PATCH 76/84] Fix Android build --- Sources/SQLite/Core/Backup.swift | 2 +- Sources/SQLite/Core/Connection+Aggregation.swift | 2 +- Sources/SQLite/Core/Connection+Attach.swift | 2 +- Sources/SQLite/Core/Connection.swift | 2 +- Sources/SQLite/Core/Result.swift | 2 +- Sources/SQLite/Core/Statement.swift | 2 +- Sources/SQLite/Helpers.swift | 2 +- Tests/SQLiteTests/Core/Connection+AttachTests.swift | 2 +- Tests/SQLiteTests/Core/Connection+PragmaTests.swift | 2 +- Tests/SQLiteTests/Core/ConnectionTests.swift | 2 +- Tests/SQLiteTests/Core/ResultTests.swift | 2 +- Tests/SQLiteTests/Core/StatementTests.swift | 2 +- Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift | 2 +- Tests/SQLiteTests/Typed/CustomAggregationTests.swift | 2 +- Tests/SQLiteTests/Typed/QueryIntegrationTests.swift | 2 +- Tests/SQLiteTests/Typed/QueryTests.swift | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Sources/SQLite/Core/Backup.swift b/Sources/SQLite/Core/Backup.swift index 5e741ecd..023acc08 100644 --- a/Sources/SQLite/Core/Backup.swift +++ b/Sources/SQLite/Core/Backup.swift @@ -28,7 +28,7 @@ import Dispatch import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Sources/SQLite/Core/Connection+Aggregation.swift b/Sources/SQLite/Core/Connection+Aggregation.swift index bfe253a7..a1abb74a 100644 --- a/Sources/SQLite/Core/Connection+Aggregation.swift +++ b/Sources/SQLite/Core/Connection+Aggregation.swift @@ -3,7 +3,7 @@ import Foundation import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Sources/SQLite/Core/Connection+Attach.swift b/Sources/SQLite/Core/Connection+Attach.swift index 32461468..0c674ee6 100644 --- a/Sources/SQLite/Core/Connection+Attach.swift +++ b/Sources/SQLite/Core/Connection+Attach.swift @@ -3,7 +3,7 @@ import Foundation import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Sources/SQLite/Core/Connection.swift b/Sources/SQLite/Core/Connection.swift index 188ff80b..57521f83 100644 --- a/Sources/SQLite/Core/Connection.swift +++ b/Sources/SQLite/Core/Connection.swift @@ -28,7 +28,7 @@ import Dispatch import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Sources/SQLite/Core/Result.swift b/Sources/SQLite/Core/Result.swift index 2659ad21..9a72e4c5 100644 --- a/Sources/SQLite/Core/Result.swift +++ b/Sources/SQLite/Core/Result.swift @@ -2,7 +2,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Sources/SQLite/Core/Statement.swift b/Sources/SQLite/Core/Statement.swift index 458e3d9c..82d535b9 100644 --- a/Sources/SQLite/Core/Statement.swift +++ b/Sources/SQLite/Core/Statement.swift @@ -26,7 +26,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Sources/SQLite/Helpers.swift b/Sources/SQLite/Helpers.swift index 00493f21..e3c84589 100644 --- a/Sources/SQLite/Helpers.swift +++ b/Sources/SQLite/Helpers.swift @@ -26,7 +26,7 @@ import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Tests/SQLiteTests/Core/Connection+AttachTests.swift b/Tests/SQLiteTests/Core/Connection+AttachTests.swift index 68618596..0e185da5 100644 --- a/Tests/SQLiteTests/Core/Connection+AttachTests.swift +++ b/Tests/SQLiteTests/Core/Connection+AttachTests.swift @@ -6,7 +6,7 @@ import Foundation import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Tests/SQLiteTests/Core/Connection+PragmaTests.swift b/Tests/SQLiteTests/Core/Connection+PragmaTests.swift index bd29bd98..d1d4ab04 100644 --- a/Tests/SQLiteTests/Core/Connection+PragmaTests.swift +++ b/Tests/SQLiteTests/Core/Connection+PragmaTests.swift @@ -6,7 +6,7 @@ import Foundation import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Tests/SQLiteTests/Core/ConnectionTests.swift b/Tests/SQLiteTests/Core/ConnectionTests.swift index 61083453..da50974a 100644 --- a/Tests/SQLiteTests/Core/ConnectionTests.swift +++ b/Tests/SQLiteTests/Core/ConnectionTests.swift @@ -7,7 +7,7 @@ import Dispatch import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Tests/SQLiteTests/Core/ResultTests.swift b/Tests/SQLiteTests/Core/ResultTests.swift index b6a373f7..03415f3a 100644 --- a/Tests/SQLiteTests/Core/ResultTests.swift +++ b/Tests/SQLiteTests/Core/ResultTests.swift @@ -6,7 +6,7 @@ import Foundation import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Tests/SQLiteTests/Core/StatementTests.swift b/Tests/SQLiteTests/Core/StatementTests.swift index ceaa8813..3c90d941 100644 --- a/Tests/SQLiteTests/Core/StatementTests.swift +++ b/Tests/SQLiteTests/Core/StatementTests.swift @@ -5,7 +5,7 @@ import XCTest import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift b/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift index 8a34e93b..b3b9e617 100644 --- a/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift +++ b/Tests/SQLiteTests/Extensions/FTSIntegrationTests.swift @@ -3,7 +3,7 @@ import XCTest import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Tests/SQLiteTests/Typed/CustomAggregationTests.swift b/Tests/SQLiteTests/Typed/CustomAggregationTests.swift index 8b7ec09a..73a0767f 100644 --- a/Tests/SQLiteTests/Typed/CustomAggregationTests.swift +++ b/Tests/SQLiteTests/Typed/CustomAggregationTests.swift @@ -7,7 +7,7 @@ import Dispatch import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift index 899bf354..cde5a0c3 100644 --- a/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift +++ b/Tests/SQLiteTests/Typed/QueryIntegrationTests.swift @@ -3,7 +3,7 @@ import XCTest import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 diff --git a/Tests/SQLiteTests/Typed/QueryTests.swift b/Tests/SQLiteTests/Typed/QueryTests.swift index 7fc3dcf5..257b5245 100644 --- a/Tests/SQLiteTests/Typed/QueryTests.swift +++ b/Tests/SQLiteTests/Typed/QueryTests.swift @@ -3,7 +3,7 @@ import XCTest import sqlite3 #elseif SQLITE_SWIFT_SQLCIPHER import SQLCipher -#elseif os(Linux) +#elseif canImport(SwiftToolchainCSQLite) import SwiftToolchainCSQLite #else import SQLite3 From 91a30a3535e74767372ef605751569299696d8d1 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Tue, 15 Jul 2025 13:54:04 +0200 Subject: [PATCH 77/84] add android ci --- .github/workflows/build.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 37f75476..f82a9c59 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,3 +76,9 @@ jobs: env: SPM: run run: ./run-tests.sh + build-android: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Run tests + uses: skiptools/swift-android-action@v2 From 22d30c885f6ac1161ff5e88e32f054b4672963d2 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Wed, 16 Jul 2025 15:17:33 +0200 Subject: [PATCH 78/84] add SQLite. prefix for Expression in README --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0e83504f..a52b7ae5 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,9 @@ do { let db = try Connection("path/to/db.sqlite3") let users = Table("users") - let id = Expression("id") - let name = Expression("name") - let email = Expression("email") + let id = SQLite.Expression("id") + let name = SQLite.Expression("name") + let email = SQLite.Expression("email") try db.run(users.create { t in t.column(id, primaryKey: true) @@ -83,6 +83,9 @@ do { } ``` +Note that `Expression` should be written as `SQLite.Expression` to avoid +conflicts with the `SwiftUI.Expression` if you are using SwiftUI too. + SQLite.swift also works as a lightweight, Swift-friendly wrapper over the C API. From fee88af870ccf4f574607b1dc8f2835cb2aa0b36 Mon Sep 17 00:00:00 2001 From: hawk0620 Date: Thu, 17 Jul 2025 14:11:06 +0800 Subject: [PATCH 79/84] create index support array as parameters --- Sources/SQLite/Typed/Schema.swift | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Sources/SQLite/Typed/Schema.swift b/Sources/SQLite/Typed/Schema.swift index e162cf34..02f5b102 100644 --- a/Sources/SQLite/Typed/Schema.swift +++ b/Sources/SQLite/Typed/Schema.swift @@ -135,8 +135,8 @@ extension Table { } // MARK: - CREATE INDEX - - public func createIndex(_ columns: Expressible..., unique: Bool = false, ifNotExists: Bool = false) -> String { + + public func createIndex(_ columns: [Expressible], unique: Bool = false, ifNotExists: Bool = false) -> String { let clauses: [Expressible?] = [ create("INDEX", indexName(columns), unique ? .unique : nil, ifNotExists), Expression(literal: "ON"), @@ -146,12 +146,20 @@ extension Table { return " ".join(clauses.compactMap { $0 }).asSQL() } + + public func createIndex(_ columns: Expressible..., unique: Bool = false, ifNotExists: Bool = false) -> String { + return createIndex(Array(columns), unique: unique, ifNotExists: ifNotExists) + } // MARK: - DROP INDEX - - public func dropIndex(_ columns: Expressible..., ifExists: Bool = false) -> String { + + public func dropIndex(_ columns: [Expressible], ifExists: Bool = false) -> String { drop("INDEX", indexName(columns), ifExists) } + + public func dropIndex(_ columns: Expressible..., ifExists: Bool = false) -> String { + dropIndex(Array(columns), ifExists: ifExists) + } fileprivate func indexName(_ columns: [Expressible]) -> Expressible { let string = (["index", clauses.from.name, "on"] + columns.map { $0.expression.template }).joined(separator: " ").lowercased() From 98d83a223db0d1a51c2d575f108c66b1b770b725 Mon Sep 17 00:00:00 2001 From: NathanFallet Date: Thu, 17 Jul 2025 13:42:49 +0200 Subject: [PATCH 80/84] fix linting --- Sources/SQLite/Typed/Query.swift | 2 +- Sources/SQLite/Typed/Schema.swift | 8 ++++---- Tests/SQLiteTests/TestHelpers.swift | 10 ---------- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Sources/SQLite/Typed/Query.swift b/Sources/SQLite/Typed/Query.swift index 2a83665c..6162fcc7 100644 --- a/Sources/SQLite/Typed/Query.swift +++ b/Sources/SQLite/Typed/Query.swift @@ -1055,7 +1055,7 @@ extension Connection { } func expandGlob(_ namespace: Bool) -> (QueryType) throws -> Void { - { (queryType: QueryType) throws -> Void in + { (queryType: QueryType) throws in var query = type(of: queryType).init(queryType.clauses.from.name, database: queryType.clauses.from.database) query.clauses.select = queryType.clauses.select query.clauses.with = strip(queryType.clauses.with) diff --git a/Sources/SQLite/Typed/Schema.swift b/Sources/SQLite/Typed/Schema.swift index 02f5b102..919042ab 100644 --- a/Sources/SQLite/Typed/Schema.swift +++ b/Sources/SQLite/Typed/Schema.swift @@ -135,7 +135,7 @@ extension Table { } // MARK: - CREATE INDEX - + public func createIndex(_ columns: [Expressible], unique: Bool = false, ifNotExists: Bool = false) -> String { let clauses: [Expressible?] = [ create("INDEX", indexName(columns), unique ? .unique : nil, ifNotExists), @@ -146,17 +146,17 @@ extension Table { return " ".join(clauses.compactMap { $0 }).asSQL() } - + public func createIndex(_ columns: Expressible..., unique: Bool = false, ifNotExists: Bool = false) -> String { return createIndex(Array(columns), unique: unique, ifNotExists: ifNotExists) } // MARK: - DROP INDEX - + public func dropIndex(_ columns: [Expressible], ifExists: Bool = false) -> String { drop("INDEX", indexName(columns), ifExists) } - + public func dropIndex(_ columns: Expressible..., ifExists: Bool = false) -> String { dropIndex(Array(columns), ifExists: ifExists) } diff --git a/Tests/SQLiteTests/TestHelpers.swift b/Tests/SQLiteTests/TestHelpers.swift index 56415a59..e62b2a23 100644 --- a/Tests/SQLiteTests/TestHelpers.swift +++ b/Tests/SQLiteTests/TestHelpers.swift @@ -164,14 +164,4 @@ struct TestOptionalCodable: Codable, Equatable { let double: Double? let date: Date? let uuid: UUID? - - init(int: Int?, string: String?, bool: Bool?, float: Float?, double: Double?, date: Date?, uuid: UUID?) { - self.int = int - self.string = string - self.bool = bool - self.float = float - self.double = double - self.date = date - self.uuid = uuid - } } From 83c0c9828c0adb80b6ef08d3451fd8c2951398bd Mon Sep 17 00:00:00 2001 From: Nikolay Dzhulay Date: Wed, 13 Aug 2025 15:59:05 +0100 Subject: [PATCH 81/84] Attempt to fix tests build for android --- Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift b/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift index 1c648bd8..f3a0ba83 100644 --- a/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift +++ b/Tests/SQLiteTests/Schema/SchemaDefinitionsTests.swift @@ -32,7 +32,7 @@ class ColumnDefinitionTests: XCTestCase { defaultValue: .numericLiteral("123.123"), references: nil)) ] - #if !os(Linux) + #if !(os(Linux) || os(Android)) override class var defaultTestSuite: XCTestSuite { let suite = XCTestSuite(forTestCaseClass: ColumnDefinitionTests.self) @@ -183,7 +183,7 @@ class IndexDefinitionTests: XCTestCase { "CREATE INDEX IF NOT EXISTS \"index_tests\" ON \"tests\" (\"test_column\")") ] - #if !os(Linux) + #if !(os(Linux) || os(Android)) override class var defaultTestSuite: XCTestSuite { let suite = XCTestSuite(forTestCaseClass: IndexDefinitionTests.self) From b7b7923708c684d73d378c2a279268c72afae407 Mon Sep 17 00:00:00 2001 From: Nikolay Dzhulay Date: Sun, 17 Aug 2025 20:45:07 +0100 Subject: [PATCH 82/84] Disable for Android same tests, which disabled for Linux --- Tests/SQLiteTests/Core/ConnectionTests.swift | 2 +- Tests/SQLiteTests/Typed/CustomAggregationTests.swift | 2 +- Tests/SQLiteTests/Typed/CustomFunctionsTests.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/SQLiteTests/Core/ConnectionTests.swift b/Tests/SQLiteTests/Core/ConnectionTests.swift index da50974a..abdb3e1b 100644 --- a/Tests/SQLiteTests/Core/ConnectionTests.swift +++ b/Tests/SQLiteTests/Core/ConnectionTests.swift @@ -374,7 +374,7 @@ class ConnectionTests: SQLiteTestCase { } // https://github.com/stephencelis/SQLite.swift/issues/1071 - #if !os(Linux) + #if !(os(Linux) || os(Android)) func test_createFunction_withArrayArguments() throws { db.createFunction("hello") { $0[0].map { "Hello, \($0)!" } } diff --git a/Tests/SQLiteTests/Typed/CustomAggregationTests.swift b/Tests/SQLiteTests/Typed/CustomAggregationTests.swift index 73a0767f..b052d236 100644 --- a/Tests/SQLiteTests/Typed/CustomAggregationTests.swift +++ b/Tests/SQLiteTests/Typed/CustomAggregationTests.swift @@ -14,7 +14,7 @@ import SQLite3 #endif // https://github.com/stephencelis/SQLite.swift/issues/1071 -#if !os(Linux) +#if !(os(Linux) || os(Android)) class CustomAggregationTests: SQLiteTestCase { override func setUpWithError() throws { diff --git a/Tests/SQLiteTests/Typed/CustomFunctionsTests.swift b/Tests/SQLiteTests/Typed/CustomFunctionsTests.swift index 8598b6fb..fd9ae6b9 100644 --- a/Tests/SQLiteTests/Typed/CustomFunctionsTests.swift +++ b/Tests/SQLiteTests/Typed/CustomFunctionsTests.swift @@ -2,7 +2,7 @@ import XCTest import SQLite // https://github.com/stephencelis/SQLite.swift/issues/1071 -#if !os(Linux) +#if !(os(Linux) || os(Android)) class CustomFunctionNoArgsTests: SQLiteTestCase { typealias FunctionNoOptional = () -> SQLite.Expression From 4f2fdffc2a5924d807bded85e6fe58378eba3ae6 Mon Sep 17 00:00:00 2001 From: Nathan Fallet Date: Sat, 30 Aug 2025 15:10:47 +0200 Subject: [PATCH 83/84] Change iOS simulator device to Any iOS Simulator Device --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f82a9c59..d2ef6aa1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,7 @@ name: Build and test on: [push, pull_request] env: - IOS_SIMULATOR: "iPhone 16" + IOS_SIMULATOR: "Any iOS Simulator Device" IOS_VERSION: "18.0" jobs: build: From 9c14b66992517fe3c376b8af6ede3f68aabc3577 Mon Sep 17 00:00:00 2001 From: Nathan Fallet Date: Sat, 30 Aug 2025 15:20:21 +0200 Subject: [PATCH 84/84] Trying iPhone 16 with iOS 18.4 --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d2ef6aa1..3c6970f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,8 +1,8 @@ name: Build and test on: [push, pull_request] env: - IOS_SIMULATOR: "Any iOS Simulator Device" - IOS_VERSION: "18.0" + IOS_SIMULATOR: "iPhone 16" + IOS_VERSION: "18.4" jobs: build: runs-on: macos-15