mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Continue converting ArticlesDatabase to async/await.
This commit is contained in:
@@ -668,8 +668,8 @@ public enum FetchType {
|
||||
structureDidChange()
|
||||
}
|
||||
|
||||
public func updateUnreadCounts(for feeds: Set<Feed>, completion: VoidCompletionBlock? = nil) {
|
||||
fetchUnreadCounts(for: feeds, completion: completion)
|
||||
public func updateUnreadCounts(for feeds: Set<Feed>) {
|
||||
fetchUnreadCounts(for: feeds)
|
||||
}
|
||||
|
||||
public func fetchUnreadArticlesBetween(limit: Int?, before: Date?, after: Date?) throws -> Set<Article> {
|
||||
@@ -1454,50 +1454,46 @@ private extension Account {
|
||||
/// Fetch unread counts for zero or more feeds.
|
||||
///
|
||||
/// Uses the most efficient method based on how many feeds were passed in.
|
||||
func fetchUnreadCounts(for feeds: Set<Feed>, completion: VoidCompletionBlock?) {
|
||||
func fetchUnreadCounts(for feeds: Set<Feed>) {
|
||||
if feeds.isEmpty {
|
||||
completion?()
|
||||
return
|
||||
}
|
||||
if feeds.count == 1, let feed = feeds.first {
|
||||
fetchUnreadCount(feed, completion)
|
||||
fetchUnreadCount(feed)
|
||||
}
|
||||
else if feeds.count < 10 {
|
||||
fetchUnreadCounts(feeds, completion)
|
||||
fetchUnreadCounts(feeds)
|
||||
}
|
||||
else {
|
||||
fetchAllUnreadCounts(completion)
|
||||
fetchAllUnreadCounts()
|
||||
}
|
||||
}
|
||||
|
||||
func fetchUnreadCount(_ feed: Feed, _ completion: VoidCompletionBlock?) {
|
||||
func fetchUnreadCount(_ feed: Feed) {
|
||||
Task { @MainActor in
|
||||
if let unreadCount = try? await database.unreadCountForFeed(feed.feedID) {
|
||||
feed.unreadCount = unreadCount
|
||||
}
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
func fetchUnreadCounts(_ feeds: Set<Feed>, _ completion: VoidCompletionBlock?) {
|
||||
let feedIDs = Set(feeds.map { $0.feedID })
|
||||
database.fetchUnreadCounts(for: feedIDs) { result in
|
||||
Task { @MainActor in
|
||||
if let unreadCountDictionary = try? result.get() {
|
||||
self.processUnreadCounts(unreadCountDictionary: unreadCountDictionary, feeds: feeds)
|
||||
}
|
||||
completion?()
|
||||
}
|
||||
func fetchUnreadCounts(_ feeds: Set<Feed>) {
|
||||
|
||||
Task { @MainActor in
|
||||
let feedIDs = Set(feeds.map { $0.feedID })
|
||||
|
||||
if let unreadCountDictionary = try? await database.unreadCountsForFeedIDs(feedIDs) {
|
||||
self.processUnreadCounts(unreadCountDictionary: unreadCountDictionary, feeds: feeds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fetchAllUnreadCounts(_ completion: VoidCompletionBlock? = nil) {
|
||||
func fetchAllUnreadCounts() {
|
||||
fetchingAllUnreadCounts = true
|
||||
database.fetchAllUnreadCounts { result in
|
||||
Task { @MainActor in
|
||||
guard let unreadCountDictionary = try? result.get() else {
|
||||
completion?()
|
||||
return
|
||||
return
|
||||
}
|
||||
self.processUnreadCounts(unreadCountDictionary: unreadCountDictionary, feeds: self.flattenedFeeds())
|
||||
|
||||
@@ -1508,7 +1504,6 @@ private extension Account {
|
||||
self.isUnreadCountsInitialized = true
|
||||
self.postUnreadCountDidInitializeNotification()
|
||||
}
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,14 +185,8 @@ public typealias ArticleStatusesResultBlock = (ArticleStatusesResult) -> Void
|
||||
try await articlesTable.unreadCountForFeedID(feedID)
|
||||
}
|
||||
|
||||
/// Fetch non-zero unread counts for given feedIDs.
|
||||
public func fetchUnreadCounts(for feedIDs: Set<String>, _ completion: @escaping UnreadCountDictionaryCompletionBlock) {
|
||||
let operation = FetchUnreadCountsForFeedsOperation(feedIDs: feedIDs, databaseQueue: queue)
|
||||
operation.completionBlock = { operation in
|
||||
let fetchOperation = operation as! FetchUnreadCountsForFeedsOperation
|
||||
completion(fetchOperation.result)
|
||||
}
|
||||
operationQueue.add(operation)
|
||||
public func unreadCountsForFeedIDs(_ feedIDs: Set<String>) async throws -> UnreadCountDictionary {
|
||||
try await articlesTable.unreadCountsForFeedIDs(feedIDs)
|
||||
}
|
||||
|
||||
public func fetchUnreadCountForToday(for feedIDs: Set<String>, completion: @escaping SingleUnreadCountCompletionBlock) {
|
||||
|
||||
@@ -420,6 +420,44 @@ final class ArticlesTable: DatabaseTable {
|
||||
}
|
||||
}
|
||||
|
||||
func unreadCountsForFeedIDs(_ feedIDs: Set<String>) async throws -> UnreadCountDictionary {
|
||||
|
||||
try await withCheckedThrowingContinuation { continuation in
|
||||
queue.runInDatabase { databaseResult in
|
||||
|
||||
func fetchUnreadCounts(_ database: FMDatabase) -> UnreadCountDictionary {
|
||||
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
|
||||
let sql = "select distinct feedID, count(*) from articles natural join statuses where feedID in \(placeholders) and read=0 group by feedID;"
|
||||
let parameters = Array(feedIDs) as [Any]
|
||||
|
||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) else {
|
||||
return UnreadCountDictionary()
|
||||
}
|
||||
|
||||
var unreadCountDictionary = UnreadCountDictionary()
|
||||
while resultSet.next() {
|
||||
let unreadCount = resultSet.long(forColumnIndex: 1)
|
||||
if let feedID = resultSet.string(forColumnIndex: 0) {
|
||||
unreadCountDictionary[feedID] = unreadCount
|
||||
}
|
||||
}
|
||||
resultSet.close()
|
||||
|
||||
return unreadCountDictionary
|
||||
}
|
||||
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
let unreadCountDictionary = fetchUnreadCounts(database)
|
||||
continuation.resume(returning: unreadCountDictionary)
|
||||
case .failure(let databaseError):
|
||||
continuation.resume(throwing: databaseError)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fetchUnreadCount(_ feedIDs: Set<String>, _ since: Date, _ completion: @escaping SingleUnreadCountCompletionBlock) {
|
||||
// Get unread count for today, for instance.
|
||||
if feedIDs.isEmpty {
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
//
|
||||
// FetchUnreadCountsForFeedsOperation.swift
|
||||
// ArticlesDatabase
|
||||
//
|
||||
// Created by Brent Simmons on 2/1/20.
|
||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import RSCore
|
||||
import RSDatabase
|
||||
import RSDatabaseObjC
|
||||
|
||||
/// Fetch the unread counts for a number of feeds.
|
||||
public final class FetchUnreadCountsForFeedsOperation: MainThreadOperation {
|
||||
|
||||
var result: UnreadCountDictionaryCompletionResult = .failure(.isSuspended)
|
||||
|
||||
// MainThreadOperation
|
||||
public var isCanceled = false
|
||||
public var id: Int?
|
||||
public weak var operationDelegate: MainThreadOperationDelegate?
|
||||
public var name: String? = "FetchUnreadCountsForFeedsOperation"
|
||||
public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock?
|
||||
|
||||
private let queue: DatabaseQueue
|
||||
private let feedIDs: Set<String>
|
||||
|
||||
init(feedIDs: Set<String>, databaseQueue: DatabaseQueue) {
|
||||
self.feedIDs = feedIDs
|
||||
self.queue = databaseQueue
|
||||
}
|
||||
|
||||
public func run() {
|
||||
queue.runInDatabase { databaseResult in
|
||||
if self.isCanceled {
|
||||
self.informOperationDelegateOfCompletion()
|
||||
return
|
||||
}
|
||||
|
||||
switch databaseResult {
|
||||
case .success(let database):
|
||||
self.fetchUnreadCounts(database)
|
||||
case .failure:
|
||||
self.informOperationDelegateOfCompletion()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension FetchUnreadCountsForFeedsOperation {
|
||||
|
||||
func fetchUnreadCounts(_ database: FMDatabase) {
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
|
||||
let sql = "select distinct feedID, count(*) from articles natural join statuses where feedID in \(placeholders) and read=0 group by feedID;"
|
||||
|
||||
let parameters = Array(feedIDs) as [Any]
|
||||
|
||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) else {
|
||||
informOperationDelegateOfCompletion()
|
||||
return
|
||||
}
|
||||
if isCanceled {
|
||||
resultSet.close()
|
||||
informOperationDelegateOfCompletion()
|
||||
return
|
||||
}
|
||||
|
||||
var unreadCountDictionary = UnreadCountDictionary()
|
||||
while resultSet.next() {
|
||||
if isCanceled {
|
||||
resultSet.close()
|
||||
informOperationDelegateOfCompletion()
|
||||
return
|
||||
}
|
||||
let unreadCount = resultSet.long(forColumnIndex: 1)
|
||||
if let feedID = resultSet.string(forColumnIndex: 0) {
|
||||
unreadCountDictionary[feedID] = unreadCount
|
||||
}
|
||||
}
|
||||
resultSet.close()
|
||||
|
||||
result = .success(unreadCountDictionary)
|
||||
informOperationDelegateOfCompletion()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user