diff --git a/Examples/CaseStudies/ObservableModelDemo.swift b/Examples/CaseStudies/ObservableModelDemo.swift index 374f331d..a8e4a107 100644 --- a/Examples/CaseStudies/ObservableModelDemo.swift +++ b/Examples/CaseStudies/ObservableModelDemo.swift @@ -3,7 +3,7 @@ import SwiftUI struct ObservableModelDemo: SwiftUICaseStudy { let readMe = """ - This demonstrates how to use the `@FetchAll` and `@FetchOne` tools in an @Observable model. \ + This demonstrates how to use the `@FetchAll` and `@FetchOne` tools in an `@Observable` model. \ In SwiftUI, the `@Query` macro only works when installed directly in a SwiftUI view, and \ cannot be used outside of views. diff --git a/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index ad5edcec..59d5cb99 100644 --- a/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -123,8 +123,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-structured-queries", "state" : { - "revision" : "603bcbf0bd5818437ff975e37cf5a1ea6867c41e", - "version" : "0.22.2" + "revision" : "9bbfc44d18f6fbbfc500676df55738db8800f5a3", + "version" : "0.22.3" } }, { diff --git a/Examples/Reminders/SearchReminders.swift b/Examples/Reminders/SearchReminders.swift index 3055a5d4..a84909ea 100644 --- a/Examples/Reminders/SearchReminders.swift +++ b/Examples/Reminders/SearchReminders.swift @@ -66,7 +66,11 @@ class SearchRemindersModel { withErrorReporting { try database.write { db in try Reminder - .where { $0.isCompleted && $0.id.in(baseQuery.select { $1.id }) } + .where { + $0.isCompleted && $0.id.in( + baseQuery(searchText: searchText, searchTokens: searchTokens).select { $1.id } + ) + } .where { if let monthsAgo { #sql("\($0.dueDate) < date('now', '-\(raw: monthsAgo) months')") @@ -78,29 +82,6 @@ class SearchRemindersModel { } } - private var baseQuery: SelectOf { - let searchText = searchText.quoted() - - return - ReminderText - .where { - if !searchText.isEmpty { - $0.match(searchText) - } - } - .where { - for token in searchTokens { - switch token.kind { - case .near: - $0.match("NEAR(\(token.rawValue.quoted()))") - case .tag: - $0.tags.match(token.rawValue) - } - } - } - .join(Reminder.all) { $0.rowid.eq($1.rowid) } - } - private func updateQuery(debounce: Bool = true) async throws { if debounce { try await clock.sleep(for: .seconds(0.3)) @@ -120,7 +101,8 @@ class SearchRemindersModel { } else { try await $searchResults.load( SearchRequest( - baseQuery: baseQuery, + searchText: searchText, + searchTokens: searchTokens, showCompletedInSearchResults: showCompletedInSearchResults ), animation: .default @@ -145,10 +127,12 @@ class SearchRemindersModel { var completedCount = 0 var rows: [Row] = [] } - let baseQuery: SelectOf + let searchText: String + let searchTokens: [Token] let showCompletedInSearchResults: Bool func fetch(_ db: Database) throws -> Value { - try Value( + let baseQuery = baseQuery(searchText: searchText, searchTokens: searchTokens) + return try Value( completedCount: baseQuery .where { $1.isCompleted } @@ -280,6 +264,32 @@ struct SearchRemindersView: View { } } +fileprivate func baseQuery( + searchText: String, + searchTokens: [SearchRemindersModel.Token] +) -> SelectOf { + let searchText = searchText.quoted() + + return + ReminderText + .where { + if !searchText.isEmpty { + $0.match(searchText) + } + } + .where { + for token in searchTokens { + switch token.kind { + case .near: + $0.match("NEAR(\(token.rawValue.quoted()))") + case .tag: + $0.tags.match(token.rawValue) + } + } + } + .join(Reminder.all) { $0.rowid.eq($1.rowid) } +} + extension String { fileprivate func quoted() -> String { split(separator: " ") diff --git a/Sources/SQLiteData/Internal/StatementKey.swift b/Sources/SQLiteData/Internal/StatementKey.swift index ff974ff8..ba65b826 100644 --- a/Sources/SQLiteData/Internal/StatementKey.swift +++ b/Sources/SQLiteData/Internal/StatementKey.swift @@ -5,19 +5,10 @@ protocol StatementKeyRequest: FetchKeyRequest { extension StatementKeyRequest { static func == (lhs: Self, rhs: Self) -> Bool { - // NB: A Swift 6.1 regression prevents this from compiling: - // https://github.com/swiftlang/swift/issues/79623 - // return AnyHashable(lhs.statement) == AnyHashable(rhs.statement) - let lhs = lhs.statement - let rhs = rhs.statement - return AnyHashable(lhs) == AnyHashable(rhs) + lhs.statement.query == rhs.statement.query } func hash(into hasher: inout Hasher) { - // NB: A Swift 6.1 regression prevents this from compiling: - // https://github.com/swiftlang/swift/issues/79623 - // hasher.combine(statement) - let statement = statement - hasher.combine(statement) + hasher.combine(statement.query) } }