diff --git a/DB/Sources/DB/Content/ContentDatabase+Migration.swift b/DB/Sources/DB/Content/ContentDatabase+Migration.swift index eed40ed..9b57f14 100644 --- a/DB/Sources/DB/Content/ContentDatabase+Migration.swift +++ b/DB/Sources/DB/Content/ContentDatabase+Migration.swift @@ -3,7 +3,7 @@ import GRDB extension ContentDatabase { - var migrator: DatabaseMigrator { + static var migrator: DatabaseMigrator { var migrator = DatabaseMigrator() migrator.registerMigration("0.1.0") { db in diff --git a/DB/Sources/DB/Content/ContentDatabase.swift b/DB/Sources/DB/Content/ContentDatabase.swift index ece76ce..0f58337 100644 --- a/DB/Sources/DB/Content/ContentDatabase.swift +++ b/DB/Sources/DB/Content/ContentDatabase.swift @@ -8,6 +8,8 @@ import Mastodon import Secrets public struct ContentDatabase { + public let activeFiltersPublisher: AnyPublisher<[Filter], Error> + private let databaseWriter: DatabaseWriter public init(identityID: UUID, inMemory: Bool, keychain: Keychain.Type) throws { @@ -24,8 +26,15 @@ public struct ContentDatabase { databaseWriter = try DatabasePool(path: path, configuration: configuration) } - try migrator.migrate(databaseWriter) - try clean() + try Self.migrator.migrate(databaseWriter) + try Self.clean(databaseWriter) + + activeFiltersPublisher = ValueObservation.tracking { + try Filter.filter(Filter.Columns.expiresAt == nil || Filter.Columns.expiresAt > Date()).fetchAll($0) + } + .removeDuplicates() + .publisher(in: databaseWriter) + .eraseToAnyPublisher() } } @@ -173,26 +182,23 @@ public extension ContentDatabase { } func observation(timeline: Timeline) -> AnyPublisher<[[Timeline.Item]], Error> { - ValueObservation.tracking { db -> (TimelineItemsInfo?, [Filter]) in - (try TimelineItemsInfo.request( - TimelineRecord.filter(TimelineRecord.Columns.id == timeline.id)).fetchOne(db), - try Filter.active.fetchAll(db)) - } - .map { $0?.items(filters: $1) ?? [] } - .removeDuplicates() - .publisher(in: databaseWriter) - .eraseToAnyPublisher() + ValueObservation.tracking( + TimelineItemsInfo.request(TimelineRecord.filter(TimelineRecord.Columns.id == timeline.id)).fetchOne) + .removeDuplicates() + .publisher(in: databaseWriter) + .combineLatest(activeFiltersPublisher) + .compactMap { $0?.items(filters: $1) } + .eraseToAnyPublisher() } func contextObservation(parentID: String) -> AnyPublisher<[[Timeline.Item]], Error> { - ValueObservation.tracking { db -> (ContextItemsInfo?, [Filter]) in - (try ContextItemsInfo.request(StatusRecord.filter(StatusRecord.Columns.id == parentID)).fetchOne(db), - try Filter.active.fetchAll(db)) - } - .map { $0?.items(filters: $1) ?? [] } - .removeDuplicates() - .publisher(in: databaseWriter) - .eraseToAnyPublisher() + ValueObservation.tracking( + ContextItemsInfo.request(StatusRecord.filter(StatusRecord.Columns.id == parentID)).fetchOne) + .removeDuplicates() + .publisher(in: databaseWriter) + .combineLatest(activeFiltersPublisher) + .compactMap { $0?.items(filters: $1) } + .eraseToAnyPublisher() } func listsObservation() -> AnyPublisher<[Timeline], Error> { @@ -205,16 +211,8 @@ public extension ContentDatabase { .eraseToAnyPublisher() } - func activeFiltersObservation(date: Date) -> AnyPublisher<[Filter], Error> { - ValueObservation.tracking( - Filter.filter(Filter.Columns.expiresAt == nil || Filter.Columns.expiresAt > date).fetchAll) - .removeDuplicates() - .publisher(in: databaseWriter) - .eraseToAnyPublisher() - } - - func expiredFiltersObservation(date: Date) -> AnyPublisher<[Filter], Error> { - ValueObservation.tracking(Filter.filter(Filter.Columns.expiresAt < date).fetchAll) + func expiredFiltersObservation() -> AnyPublisher<[Filter], Error> { + ValueObservation.tracking { try Filter.filter(Filter.Columns.expiresAt < Date()).fetchAll($0) } .removeDuplicates() .publisher(in: databaseWriter) .eraseToAnyPublisher() @@ -248,7 +246,7 @@ private extension ContentDatabase { try FileManager.default.databaseDirectoryURL(name: identityID.uuidString) } - func clean() throws { + static func clean(_ databaseWriter: DatabaseWriter) throws { try databaseWriter.write { try TimelineRecord.deleteAll($0) try StatusRecord.deleteAll($0) diff --git a/DB/Sources/DB/Extensions/Filter+Extensions.swift b/DB/Sources/DB/Extensions/Filter+Extensions.swift index 7eca9dd..b5fdb8d 100644 --- a/DB/Sources/DB/Extensions/Filter+Extensions.swift +++ b/DB/Sources/DB/Extensions/Filter+Extensions.swift @@ -23,10 +23,6 @@ extension Filter { case irreversible case wholeWord } - - static var active: QueryInterfaceRequest { - filter(Filter.Columns.expiresAt == nil || Filter.Columns.expiresAt > Date()) - } } extension Array where Element == StatusInfo { diff --git a/ServiceLayer/Sources/ServiceLayer/Services/IdentityService.swift b/ServiceLayer/Sources/ServiceLayer/Services/IdentityService.swift index 9b438e5..aa8adf7 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/IdentityService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/IdentityService.swift @@ -128,12 +128,12 @@ public extension IdentityService { .eraseToAnyPublisher() } - func activeFiltersObservation(date: Date) -> AnyPublisher<[Filter], Error> { - contentDatabase.activeFiltersObservation(date: date) + func activeFiltersObservation() -> AnyPublisher<[Filter], Error> { + contentDatabase.activeFiltersPublisher } - func expiredFiltersObservation(date: Date) -> AnyPublisher<[Filter], Error> { - contentDatabase.expiredFiltersObservation(date: date) + func expiredFiltersObservation() -> AnyPublisher<[Filter], Error> { + contentDatabase.expiredFiltersObservation() } func updatePreferences(_ preferences: Identity.Preferences) -> AnyPublisher { diff --git a/ViewModels/Sources/ViewModels/FiltersViewModel.swift b/ViewModels/Sources/ViewModels/FiltersViewModel.swift index cd1e255..be6d01c 100644 --- a/ViewModels/Sources/ViewModels/FiltersViewModel.swift +++ b/ViewModels/Sources/ViewModels/FiltersViewModel.swift @@ -16,13 +16,11 @@ public final class FiltersViewModel: ObservableObject { public init(identification: Identification) { self.identification = identification - let now = Date() - - identification.service.activeFiltersObservation(date: now) + identification.service.activeFiltersObservation() .assignErrorsToAlertItem(to: \.alertItem, on: self) .assign(to: &$activeFilters) - identification.service.expiredFiltersObservation(date: now) + identification.service.expiredFiltersObservation() .assignErrorsToAlertItem(to: \.alertItem, on: self) .assign(to: &$expiredFilters) }