From 2fa5ca767f00c2c5e33729d82014e5a2bd575835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Rou=C3=A9?= Date: Mon, 20 Mar 2023 13:27:57 +0100 Subject: [PATCH 01/18] WALSnapshot is only available when the SQLite feature is Since #1350 we no longer need to expose it and check for failures at runtime. --- GRDB/Core/WALSnapshot.swift | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/GRDB/Core/WALSnapshot.swift b/GRDB/Core/WALSnapshot.swift index 36f21eb690..1256833bbf 100644 --- a/GRDB/Core/WALSnapshot.swift +++ b/GRDB/Core/WALSnapshot.swift @@ -1,3 +1,4 @@ +#if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER && (compiler(>=5.7.1) || !(os(macOS) || targetEnvironment(macCatalyst)))) /// An instance of WALSnapshot records the state of a WAL mode database for some /// specific point in history. /// @@ -20,13 +21,6 @@ /// /// See . final class WALSnapshot: Sendable { - // Xcode 14 (Swift 5.7) ships with a macOS SDK that misses snapshot support. - // Xcode 14.1 (Swift 5.7.1) ships with a macOS SDK that has snapshot support. - // This is the meaning of (compiler(>=5.7.1) || !(os(macOS) || targetEnvironment(macCatalyst))) - // swiftlint:disable:next line_length -#if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER && (compiler(>=5.7.1) || !(os(macOS) || targetEnvironment(macCatalyst)))) - static let available = true - let sqliteSnapshot: UnsafeMutablePointer init(_ db: Database) throws { @@ -67,15 +61,5 @@ final class WALSnapshot: Sendable { func compare(_ other: WALSnapshot) -> CInt { sqlite3_snapshot_cmp(sqliteSnapshot, other.sqliteSnapshot) } -#else - static let available = false - - init(_ db: Database) throws { - throw DatabaseError(resultCode: .SQLITE_MISUSE, message: "snapshots are not available") - } - - func compare(_ other: WALSnapshot) -> CInt { - preconditionFailure("snapshots are not available") - } -#endif } +#endif From 52aef76b636f90ab1b2f42ad0fa3ca75e456cd33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Wed, 22 Mar 2023 08:25:37 +0100 Subject: [PATCH 02/18] Fix Swiftlint warning --- GRDB/Core/WALSnapshot.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/GRDB/Core/WALSnapshot.swift b/GRDB/Core/WALSnapshot.swift index 1256833bbf..f88509cd60 100644 --- a/GRDB/Core/WALSnapshot.swift +++ b/GRDB/Core/WALSnapshot.swift @@ -1,3 +1,4 @@ +// swiftlint:disable:next line_length #if SQLITE_ENABLE_SNAPSHOT || (!GRDBCUSTOMSQLITE && !GRDBCIPHER && (compiler(>=5.7.1) || !(os(macOS) || targetEnvironment(macCatalyst)))) /// An instance of WALSnapshot records the state of a WAL mode database for some /// specific point in history. From 018ae03f8e5216c18e102f63ec4a7cb93b91c322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Wed, 22 Mar 2023 08:30:21 +0100 Subject: [PATCH 03/18] Improve DatabaseEventPredicate usage --- GRDB/Core/TransactionObserver.swift | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/GRDB/Core/TransactionObserver.swift b/GRDB/Core/TransactionObserver.swift index 7f2cf179c3..c930d7b319 100644 --- a/GRDB/Core/TransactionObserver.swift +++ b/GRDB/Core/TransactionObserver.swift @@ -479,7 +479,7 @@ class DatabaseObservationBroker { if savepointStack.isEmpty { // Notify now - for statementObservation in statementObservations where statementObservation.predicate.evaluate(event) { + for statementObservation in statementObservations where statementObservation.tracksEvent(event) { statementObservation.transactionObservation.databaseDidChange(with: event) } } else { @@ -639,7 +639,7 @@ class DatabaseObservationBroker { for (event, statementObservations) in eventsBuffer { assert(statementObservations.isEmpty || !database.isReadOnly, "Read-only transactions are not notified") - for statementObservation in statementObservations where statementObservation.predicate.evaluate(event) { + for statementObservation in statementObservations where statementObservation.tracksEvent(event) { event.send(to: statementObservation.transactionObservation) } } @@ -969,12 +969,18 @@ final class TransactionObservation { struct StatementObservation { var transactionObservation: TransactionObservation - /// Filters database events that should be notified. - var predicate: DatabaseEventPredicate + /// A predicate that filters database events that should be notified. + /// + /// Call this predicate as a method: + /// + /// ``` + /// if observation.tracksEvent(event) { ... } + /// ``` + var tracksEvent: DatabaseEventPredicate init(transactionObservation: TransactionObservation, trackingEvents predicate: DatabaseEventPredicate) { self.transactionObservation = transactionObservation - self.predicate = predicate + self.tracksEvent = predicate } } @@ -1447,7 +1453,7 @@ enum DatabaseEventPredicate { /// statement authorizer. case matching(observedEventKinds: [DatabaseEventKind], authorizerEventKinds: [DatabaseEventKind]) - func evaluate(_ event: some DatabaseEventProtocol) -> Bool { + func callAsFunction(_ event: some DatabaseEventProtocol) -> Bool { switch self { case .all: return true From 5facc24ebbea034c8b390579d3fa110b23b22a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Wed, 22 Mar 2023 18:40:37 +0100 Subject: [PATCH 04/18] Fix compiler warnings for Swift 5.8 --- Tests/GRDBTests/ValueObservationTests.swift | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Tests/GRDBTests/ValueObservationTests.swift b/Tests/GRDBTests/ValueObservationTests.swift index 798b389e47..51570a3c57 100644 --- a/Tests/GRDBTests/ValueObservationTests.swift +++ b/Tests/GRDBTests/ValueObservationTests.swift @@ -782,7 +782,11 @@ class ValueObservationTests: GRDBTestCase { assertValueObservationRecordingMatch(recorded: counts, expected: [0, 1, 2]) // Observation was ended +#if compiler(>=5.8) + await fulfillment(of: [cancellationExpectation], timeout: 2) +#else wait(for: [cancellationExpectation], timeout: 2) +#endif } try await AsyncTest(test).run { try DatabaseQueue() } @@ -816,7 +820,11 @@ class ValueObservationTests: GRDBTestCase { assertValueObservationRecordingMatch(recorded: counts, expected: [0, 1, 2]) // Observation was ended +#if compiler(>=5.8) + await fulfillment(of: [cancellationExpectation], timeout: 2) +#else wait(for: [cancellationExpectation], timeout: 2) +#endif } try await AsyncTest(test).run { try DatabaseQueue() } @@ -854,7 +862,11 @@ class ValueObservationTests: GRDBTestCase { assertValueObservationRecordingMatch(recorded: counts, expected: [0, 1, 2]) // Observation was ended +#if compiler(>=5.8) + await fulfillment(of: [cancellationExpectation], timeout: 2) +#else wait(for: [cancellationExpectation], timeout: 2) +#endif } try await AsyncTest(test).run { try DatabaseQueue() } @@ -889,7 +901,11 @@ class ValueObservationTests: GRDBTestCase { assertValueObservationRecordingMatch(recorded: counts, expected: [0]) // Observation was ended +#if compiler(>=5.8) + await fulfillment(of: [cancellationExpectation], timeout: 2) +#else wait(for: [cancellationExpectation], timeout: 2) +#endif } try await AsyncTest(test).run { try DatabaseQueue() } @@ -936,7 +952,11 @@ class ValueObservationTests: GRDBTestCase { XCTAssertEqual(cancelledValue, "cancelled loop") // Make sure observation was cancelled as well +#if compiler(>=5.8) + await fulfillment(of: [cancellationExpectation], timeout: 2) +#else wait(for: [cancellationExpectation], timeout: 2) +#endif } try await AsyncTest(test).run { try DatabaseQueue() } From 6b311941b1fe945fa091eed1da699019ded234f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Wed, 22 Mar 2023 18:40:48 +0100 Subject: [PATCH 05/18] Remove WWDCCompanion from the release process --- Documentation/ReleaseProcess.md | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/ReleaseProcess.md b/Documentation/ReleaseProcess.md index e8aa77fb79..7d42c67607 100644 --- a/Documentation/ReleaseProcess.md +++ b/Documentation/ReleaseProcess.md @@ -21,7 +21,6 @@ To release a new GRDB version: - Check tag authors: `git for-each-ref --format '%(refname) %(authorname)' refs/tags` - Push to the master & development branch - `pod trunk push --allow-warnings GRDB.swift.podspec` -- Update https://github.com/groue/WWDCCompanion - Update [performance comparison](https://github.com/groue/GRDB.swift/wiki/Performance): `make test_performance | Tests/parsePerformanceTests.rb | Tests/generatePerformanceReport.rb` From 7e6f71912c4083d0dabb45bf43d54f11d4723124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Rou=C3=A9?= Date: Wed, 29 Mar 2023 13:02:31 +0200 Subject: [PATCH 06/18] Enhance DatabaseQueue read-only transactions --- GRDB/Core/DatabaseQueue.swift | 40 +++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/GRDB/Core/DatabaseQueue.swift b/GRDB/Core/DatabaseQueue.swift index ed5d1bcced..3721263911 100644 --- a/GRDB/Core/DatabaseQueue.swift +++ b/GRDB/Core/DatabaseQueue.swift @@ -225,21 +225,22 @@ extension DatabaseQueue: DatabaseReader { public func asyncRead(_ value: @escaping (Result) -> Void) { writer.async { db in + defer { + // Ignore error because we can not notify it. + try? db.commit() + try? db.endReadOnly() + } + do { - // The transaction guarantees snapshot isolation against eventual - // external connection. - try db.beginTransaction(.deferred) + // Enter read-only mode before starting a transaction, so that the + // transaction commit does not trigger database observation. + // See . try db.beginReadOnly() + try db.beginTransaction(.deferred) + value(.success(db)) } catch { value(.failure(error)) - return } - - value(.success(db)) - - // Ignore error because we can not notify it. - try? db.endReadOnly() - try? db.commit() } } @@ -273,20 +274,23 @@ extension DatabaseQueue: DatabaseReader { writer.execute { db in // ... and that no transaction is opened. GRDBPrecondition(!db.isInsideTransaction, "must not be called from inside a transaction.") + + defer { + // Ignore error because we can not notify it. + try? db.commit() + try? db.endReadOnly() + } do { - try db.beginTransaction(.deferred) + // Enter read-only mode before starting a transaction, so that the + // transaction commit does not trigger database observation. + // See . try db.beginReadOnly() + try db.beginTransaction(.deferred) + value(.success(db)) } catch { value(.failure(error)) - return } - - value(.success(db)) - - // Ignore error because we can not notify it. - try? db.endReadOnly() - try? db.commit() } } From 4762f8bb36bf4e0dd8930c2df051a1f6c1bc3bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Rou=C3=A9?= Date: Wed, 29 Mar 2023 13:02:49 +0200 Subject: [PATCH 07/18] Fix spawnConcurrentRead documentation --- GRDB/Core/DatabaseWriter.swift | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/GRDB/Core/DatabaseWriter.swift b/GRDB/Core/DatabaseWriter.swift index 1861d1505e..16956c6f1a 100644 --- a/GRDB/Core/DatabaseWriter.swift +++ b/GRDB/Core/DatabaseWriter.swift @@ -289,14 +289,13 @@ public protocol DatabaseWriter: DatabaseReader { /// ``` /// /// - note: Usage of this method is discouraged, because waiting on the - /// returned ``DatabaseFuture`` blocks a thread. You may prefer the - /// asynchronous version of this method: ``spawnConcurrentRead(_:)``. + /// returned ``DatabaseFuture`` blocks a thread. You may prefer + /// ``spawnConcurrentRead(_:)`` instead. /// - parameter value: A closure which accesses the database. func concurrentRead(_ value: @escaping (Database) throws -> T) -> DatabaseFuture // Exposed for RxGRDB and GRBCombine. Naming is not stabilized. - /// Schedules read-only database operations for execution, and - /// returns immediately. + /// Schedules read-only database operations for execution. /// /// - note: [**🔥 EXPERIMENTAL**](https://github.com/groue/GRDB.swift/blob/master/README.md#what-are-experimental-features) /// @@ -311,7 +310,7 @@ public protocol DatabaseWriter: DatabaseReader { /// by the database writer. /// /// In the example below, the number of players is fetched concurrently with - /// the player insertion. Yet the future is guaranteed to return zero: + /// the player insertion. Yet it is guaranteed to return zero: /// /// ```swift /// try writer.writeWithoutTransaction { db in @@ -334,6 +333,10 @@ public protocol DatabaseWriter: DatabaseReader { /// } /// ``` /// + /// - important: The database operations are executed immediately, + /// or asynchronously, depending on the actual class + /// of `DatabaseWriter`. + /// /// - parameter value: A closure which accesses the database. Its argument /// is a `Result` that provides the database connection, or the failure /// that would prevent establishing the read access to the database. From 4c0cc84c2dfb4c26620a1fc8fcbd3e6ce71d3c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Fri, 31 Mar 2023 08:02:04 +0200 Subject: [PATCH 08/18] Improve DatabaseEventPredicate usage with SQLITE_ENABLE_PREUPDATE_HOOK --- GRDB/Core/TransactionObserver.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GRDB/Core/TransactionObserver.swift b/GRDB/Core/TransactionObserver.swift index c930d7b319..e0d18226ac 100644 --- a/GRDB/Core/TransactionObserver.swift +++ b/GRDB/Core/TransactionObserver.swift @@ -454,7 +454,7 @@ class DatabaseObservationBroker { if savepointStack.isEmpty { // Notify now - for statementObservation in statementObservations where statementObservation.predicate.evaluate(event) { + for statementObservation in statementObservations where statementObservation.tracksEvent(event) { statementObservation.transactionObservation.databaseWillChange(with: event) } } else { From 99ddc5e13c42f01b99af452241a0c116ab4225f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 12:56:44 +0200 Subject: [PATCH 09/18] Makefile: add explicit macOS destinations --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 0dc02d847d..53b2d59cf0 100644 --- a/Makefile +++ b/Makefile @@ -128,6 +128,7 @@ test_framework_GRDBCustomSQLiteOSX: SQLiteCustom $(XCODEBUILD) \ -project GRDBCustom.xcodeproj \ -scheme GRDBCustom \ + -destination "platform=macOS" \ $(TEST_ACTIONS) \ $(XCPRETTY) @@ -249,6 +250,7 @@ test_install_SPM_Project: $(XCODEBUILD) \ -project Tests/SPM/PlainProject/Plain.xcodeproj \ -scheme Plain \ + -destination "platform=macOS" \ -configuration Release \ clean build \ $(XCPRETTY) @@ -266,6 +268,7 @@ test_install_SPM_macos_release: $(XCODEBUILD) \ -project Tests/SPM/macos/macos.xcodeproj \ -scheme macos \ + -destination "platform=macOS" \ -configuration Release \ clean build \ $(XCPRETTY) @@ -283,6 +286,7 @@ test_install_customSQLite: SQLiteCustom $(XCODEBUILD) \ -project Tests/CustomSQLite/CustomSQLite.xcodeproj \ -scheme CustomSQLite \ + -destination "platform=macOS" \ -configuration Release \ clean build \ $(XCPRETTY) @@ -357,6 +361,7 @@ test_performance: $(XCODEBUILD) \ -project Tests/Performance/GRDBPerformance/GRDBPerformance.xcodeproj \ -scheme GRDBOSXPerformanceComparisonTests \ + -destination "platform=macOS" \ build-for-testing test-without-building # Target that setups SQLite custom builds with extra compilation options. From e408bd17d8ddd3bc82b35e01fedee5a959987150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 13:04:52 +0200 Subject: [PATCH 10/18] Fix Swiftlint warning --- GRDB/Fixits.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GRDB/Fixits.swift b/GRDB/Fixits.swift index 5ae7ad85c6..7bd1e3f169 100644 --- a/GRDB/Fixits.swift +++ b/GRDB/Fixits.swift @@ -167,3 +167,5 @@ extension ValueObservation { where Reducer == ValueReducers.Fetch { preconditionFailure() } } + +// swiftlint:enable all From 89330daa527e5eeca06839a7e0b14a02e3b86a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 13:05:43 +0200 Subject: [PATCH 11/18] Use xcbeautify when available --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 53b2d59cf0..ad2767fafe 100644 --- a/Makefile +++ b/Makefile @@ -52,10 +52,13 @@ MAX_IOS_DESTINATION := $(shell xcrun simctl list -j devices available | Scripts/ MIN_TVOS_DESTINATION := $(shell xcrun simctl list -j devices available | Scripts/destination.rb | grep tvOS | sort -n | head -1 | cut -wf 3 | sed 's/\(.*\)/"platform=tvOS Simulator,id=\1"/') MAX_TVOS_DESTINATION := $(shell xcrun simctl list -j devices available | Scripts/destination.rb | grep tvOS | sort -rn | head -1 | cut -wf 3 | sed 's/\(.*\)/"platform=tvOS Simulator,id=\1"/') -# If xcpretty is available, use it for xcodebuild output +# If xcbeautify or xcpretty is available, use it for xcodebuild output XCPRETTY = +XCBEAUTIFY_PATH := $(shell command -v xcbeautify 2> /dev/null) XCPRETTY_PATH := $(shell command -v xcpretty 2> /dev/null) -ifdef XCPRETTY_PATH +ifdef XCBEAUTIFY_PATH + XCPRETTY = | xcbeautify +else ifdef XCPRETTY_PATH XCPRETTY = | xcpretty -c endif From c7ee12eff7074d53b9ea9d3c167bbcf93cff1499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 13:14:45 +0200 Subject: [PATCH 12/18] Remove deprecated swiftlint rule --- Scripts/swiftlint.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/Scripts/swiftlint.yml b/Scripts/swiftlint.yml index 00f9d3c474..c933e32ea0 100644 --- a/Scripts/swiftlint.yml +++ b/Scripts/swiftlint.yml @@ -62,7 +62,6 @@ opt_in_rules: - sorted_first_last - sorted_imports - toggle_bool - - unused_capture_list - vertical_parameter_alignment_on_call - yoda_condition From 81eb6b128f6d393648f4028aeef86c30439d902a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 14:05:14 +0200 Subject: [PATCH 13/18] Failing test for #1357 --- Tests/GRDBTests/QueryInterfaceRequestTests.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Tests/GRDBTests/QueryInterfaceRequestTests.swift b/Tests/GRDBTests/QueryInterfaceRequestTests.swift index 5a86db88fb..d3450c6a2b 100644 --- a/Tests/GRDBTests/QueryInterfaceRequestTests.swift +++ b/Tests/GRDBTests/QueryInterfaceRequestTests.swift @@ -136,6 +136,21 @@ class QueryInterfaceRequestTests: GRDBTestCase { } } + // Regression test for + func testIssue1357() throws { + let dbQueue = try makeDatabaseQueue() + try dbQueue.inDatabase { db in + let request = tableRequest + .annotated(with: Column("name").forKey("alt")) + .filter(Column("alt").detached) + + XCTAssertEqual(try request.fetchCount(db), 0) + XCTAssertEqual(lastSQLQuery, """ + SELECT COUNT(*) FROM (SELECT *, "name" AS "alt" FROM "readers" WHERE "alt") + """) + } + } + // MARK: - Select From 373fe467d6c9b6f9762fcf43e0c7f06b85e961b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 14:06:00 +0200 Subject: [PATCH 14/18] Fix failing test for #1357 --- GRDB/QueryInterface/SQL/SQLRelation.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/GRDB/QueryInterface/SQL/SQLRelation.swift b/GRDB/QueryInterface/SQL/SQLRelation.swift index c94c43ed62..332ae2f81a 100644 --- a/GRDB/QueryInterface/SQL/SQLRelation.swift +++ b/GRDB/QueryInterface/SQL/SQLRelation.swift @@ -617,7 +617,13 @@ extension SQLRelation { // -> // SELECT COUNT(*) FROM tableName ... let countRelation = unordered().select(.countAll) - return try QueryInterfaceRequest(relation: countRelation).fetchOne(db)! + do { + return try QueryInterfaceRequest(relation: countRelation).fetchOne(db)! + } catch { + // + // TODO: can we inspect the request and avoid catching an error? + return try fetchTrivialCount(db) + } } } From 9df1cfd110a1911110143af3b026c45070931141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 14:12:50 +0200 Subject: [PATCH 15/18] CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67e289cf07..e7658f6722 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -108,6 +108,10 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception: --- +## Next Release + +- **Fixed**: [#1357](https://github.com/groue/GRDB.swift/pull/1357) `QueryInterfaceRequest.fetchCount` no longer executes invalid SQL queries for some requests. + ## 6.10.0 Released March 20, 2023 • [diff](https://github.com/groue/GRDB.swift/compare/v6.9.2...v6.10.0) From 82f300e534e1a04f17d698471621ae44978f5690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 14:30:25 +0200 Subject: [PATCH 16/18] GitHub actions: Xcode 14.2 --- .github/workflows/CI.yml | 44 +++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d0a4e0bac4..cbb4b18145 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -38,18 +38,26 @@ jobs: fail-fast: false matrix: include: - - xcode: "Xcode_14.1.app" + - xcode: "Xcode_14.2.app" runsOn: macOS-12 destination: "platform=macOS" name: "macOS" - - xcode: "Xcode_14.1.app" + - xcode: "Xcode_14.2.app" runsOn: macOS-12 - destination: "OS=16.1,name=iPhone 14" + destination: "OS=16.2,name=iPhone 14" name: "iOS" - - xcode: "Xcode_14.1.app" + - xcode: "Xcode_14.2.app" runsOn: macOS-12 destination: "OS=16.1,name=Apple TV" name: "tvOS" + - xcode: "Xcode_14.1.app" + runsOn: macOS-12 + destination: "platform=macOS" + name: "macOS" + - xcode: "Xcode_14.1.app" + runsOn: macOS-12 + destination: "OS=16.1,name=iPhone 14" + name: "iOS" - xcode: "Xcode_14.0.1.app" runsOn: macOS-12 destination: "platform=macOS" @@ -72,6 +80,9 @@ jobs: fail-fast: false matrix: include: + - xcode: "Xcode_14.2.app" + runsOn: macOS-12 + name: "Xcode 14.2" - xcode: "Xcode_14.1.app" runsOn: macOS-12 name: "Xcode 14.1" @@ -92,9 +103,9 @@ jobs: fail-fast: false matrix: include: - - xcode: "Xcode_14.1.app" + - xcode: "Xcode_14.2.app" runsOn: macOS-12 - name: "Xcode 14.1" + name: "Xcode 14.2" steps: - uses: actions/checkout@v3 - name: ${{ matrix.name }} @@ -109,9 +120,12 @@ jobs: fail-fast: false matrix: include: - - xcode: "Xcode_14.1.app" + - xcode: "Xcode_14.2.app" runsOn: macOS-12 - name: "Xcode 14.1" + name: "Xcode 14.2" + - xcode: "Xcode_14.0.1.app" + runsOn: macOS-12 + name: "Xcode 14.0.1" steps: - uses: actions/checkout@v3 - name: ${{ matrix.name }} @@ -126,9 +140,12 @@ jobs: fail-fast: false matrix: include: - - xcode: "Xcode_14.1.app" + - xcode: "Xcode_14.2.app" runsOn: macOS-12 - name: "Xcode 14.1" + name: "Xcode 14.2" + - xcode: "Xcode_14.0.1.app" + runsOn: macOS-12 + name: "Xcode 14.0.1" steps: - uses: actions/checkout@v3 - name: ${{ matrix.name }} @@ -143,9 +160,12 @@ jobs: fail-fast: false matrix: include: - - xcode: "Xcode_14.1.app" + - xcode: "Xcode_14.2.app" runsOn: macOS-12 - name: "Xcode 14.1" + name: "Xcode 14.2" + - xcode: "Xcode_14.0.1.app" + runsOn: macOS-12 + name: "Xcode 14.0.1" steps: - uses: actions/checkout@v3 - name: ${{ matrix.name }} From b81e858ca0a19e57f6dfcba82024839e8c36398d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 14:59:42 +0200 Subject: [PATCH 17/18] Better fix for #1357 Previous fix would not correctly address #1357 when invalid double-quoted identifiers are interpreted as string literals (Configuration.acceptsDoubleQuotedStringLiterals = true, or SQLCipher 3) --- GRDB/QueryInterface/SQL/SQLRelation.swift | 15 +++++++-------- GRDB/QueryInterface/SQL/SQLSelection.swift | 12 ++++++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/GRDB/QueryInterface/SQL/SQLRelation.swift b/GRDB/QueryInterface/SQL/SQLRelation.swift index 332ae2f81a..c47b83a45c 100644 --- a/GRDB/QueryInterface/SQL/SQLRelation.swift +++ b/GRDB/QueryInterface/SQL/SQLRelation.swift @@ -612,18 +612,17 @@ extension SQLRelation { guard !isDistinct else { return try fetchTrivialCount(db) } - + + // + guard selection.allSatisfy(\.isTriviallyCountable) else { + return try fetchTrivialCount(db) + } + // SELECT expr1, expr2, ... FROM tableName ... // -> // SELECT COUNT(*) FROM tableName ... let countRelation = unordered().select(.countAll) - do { - return try QueryInterfaceRequest(relation: countRelation).fetchOne(db)! - } catch { - // - // TODO: can we inspect the request and avoid catching an error? - return try fetchTrivialCount(db) - } + return try QueryInterfaceRequest(relation: countRelation).fetchOne(db)! } } diff --git a/GRDB/QueryInterface/SQL/SQLSelection.swift b/GRDB/QueryInterface/SQL/SQLSelection.swift index aec58de09a..351b483775 100644 --- a/GRDB/QueryInterface/SQL/SQLSelection.swift +++ b/GRDB/QueryInterface/SQL/SQLSelection.swift @@ -244,6 +244,18 @@ extension SQLSelection { return .literal(sqlLiteral.qualified(with: alias)) } } + + /// Supports SQLRelation.fetchCount. + /// + /// See + var isTriviallyCountable: Bool { + switch impl { + case .aliasedExpression, .literal: + return false + case .allColumns, .qualifiedAllColumns, .expression: + return true + } + } } extension [SQLSelection] { From 12e3923af1091062f6aa0c6ddf93ab3a292717cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwendal=20Roue=CC=81?= Date: Sat, 1 Apr 2023 14:14:29 +0200 Subject: [PATCH 18/18] v6.10.1 --- CHANGELOG.md | 6 ++++-- GRDB.swift.podspec | 2 +- README.md | 4 ++-- Support/Info.plist | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7658f6722..4c6297bc91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception: #### 6.x Releases -- `6.10.x` Releases - [6.10.0](#6100) +- `6.10.x` Releases - [6.10.0](#6100) - [6.10.1](#6101) - `6.9.x` Releases - [6.9.0](#690) - [6.9.1](#691) - [6.9.2](#692) - `6.8.x` Releases - [6.8.0](#680) - `6.7.x` Releases - [6.7.0](#670) @@ -108,7 +108,9 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception: --- -## Next Release +## 6.10.1 + +Released April 1, 2023 • [diff](https://github.com/groue/GRDB.swift/compare/v6.10.0...v6.10.1) - **Fixed**: [#1357](https://github.com/groue/GRDB.swift/pull/1357) `QueryInterfaceRequest.fetchCount` no longer executes invalid SQL queries for some requests. diff --git a/GRDB.swift.podspec b/GRDB.swift.podspec index 11410cacab..d842649f58 100644 --- a/GRDB.swift.podspec +++ b/GRDB.swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'GRDB.swift' - s.version = '6.10.0' + s.version = '6.10.1' s.license = { :type => 'MIT', :file => 'LICENSE' } s.summary = 'A toolkit for SQLite databases, with a focus on application development.' diff --git a/README.md b/README.md index bd61b26e5b..eec0f79936 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,13 @@ --- -**Latest release**: March 20, 2023 • [version 6.10.0](https://github.com/groue/GRDB.swift/tree/v6.10.0) • [CHANGELOG](CHANGELOG.md) • [Migrating From GRDB 5 to GRDB 6](Documentation/GRDB6MigrationGuide.md) +**Latest release**: April 1, 2023 • [version 6.10.1](https://github.com/groue/GRDB.swift/tree/v6.10.1) • [CHANGELOG](CHANGELOG.md) • [Migrating From GRDB 5 to GRDB 6](Documentation/GRDB6MigrationGuide.md) **Requirements**: iOS 11.0+ / macOS 10.13+ / tvOS 11.0+ / watchOS 4.0+ • SQLite 3.19.3+ • Swift 5.7+ / Xcode 14+ | Swift version | GRDB version | | -------------- | ----------------------------------------------------------- | -| **Swift 5.7+** | **v6.10.0** | +| **Swift 5.7+** | **v6.10.1** | | Swift 5.3 | [v5.26.1](https://github.com/groue/GRDB.swift/tree/v5.26.1) | | Swift 5.2 | [v5.12.0](https://github.com/groue/GRDB.swift/tree/v5.12.0) | | Swift 5.1 | [v4.14.0](https://github.com/groue/GRDB.swift/tree/v4.14.0) | diff --git a/Support/Info.plist b/Support/Info.plist index 3bb5a6faae..8b6e8ec357 100644 --- a/Support/Info.plist +++ b/Support/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 6.10.0 + 6.10.1 CFBundleSignature ???? CFBundleVersion