diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 12d609314..8a996d4ba 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -674,13 +674,13 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, } public func fetchUnreadArticleIDs(_ callback: @escaping (Set) -> Void) { - return database.fetchUnreadArticleIDsAsync(webFeedIDs: flattenedWebFeeds().webFeedIDs(), callback: callback) + database.fetchUnreadArticleIDsAsync(webFeedIDs: flattenedWebFeeds().webFeedIDs(), callback: callback) } - public func fetchStarredArticleIDs() -> Set { - return database.fetchStarredArticleIDs() + public func fetchStarredArticleIDs(_ callback: @escaping (Set) -> Void) { + database.fetchStarredArticleIDsAsync(webFeedIDs: flattenedWebFeeds().webFeedIDs(), callback: callback) } - + public func fetchArticleIDsForStatusesWithoutArticles() -> Set { return database.fetchArticleIDsForStatusesWithoutArticles() } diff --git a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift index ed730e833..2d1473b48 100644 --- a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift @@ -1224,27 +1224,27 @@ private extension FeedbinAccountDelegate { } let feedbinStarredArticleIDs = Set(articleIDs.map { String($0) } ) - let currentStarredArticleIDs = account.fetchStarredArticleIDs() - - // Mark articles as starred - let deltaStarredArticleIDs = feedbinStarredArticleIDs.subtracting(currentStarredArticleIDs) - let markStarredArticles = account.fetchArticles(.articleIDs(deltaStarredArticleIDs)) - account.update(markStarredArticles, statusKey: .starred, flag: true) + account.fetchStarredArticleIDs { currentStarredArticleIDs in + // Mark articles as starred + let deltaStarredArticleIDs = feedbinStarredArticleIDs.subtracting(currentStarredArticleIDs) + let markStarredArticles = account.fetchArticles(.articleIDs(deltaStarredArticleIDs)) + account.update(markStarredArticles, statusKey: .starred, flag: true) - // Save any starred statuses for articles we haven't yet received - let markStarredArticleIDs = Set(markStarredArticles.map { $0.articleID }) - let missingStarredArticleIDs = deltaStarredArticleIDs.subtracting(markStarredArticleIDs) - account.ensureStatuses(missingStarredArticleIDs, true, .starred, true) + // Save any starred statuses for articles we haven't yet received + let markStarredArticleIDs = Set(markStarredArticles.map { $0.articleID }) + let missingStarredArticleIDs = deltaStarredArticleIDs.subtracting(markStarredArticleIDs) + account.ensureStatuses(missingStarredArticleIDs, true, .starred, true) - // Mark articles as unstarred - let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(feedbinStarredArticleIDs) - let markUnstarredArticles = account.fetchArticles(.articleIDs(deltaUnstarredArticleIDs)) - account.update(markUnstarredArticles, statusKey: .starred, flag: false) + // Mark articles as unstarred + let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(feedbinStarredArticleIDs) + let markUnstarredArticles = account.fetchArticles(.articleIDs(deltaUnstarredArticleIDs)) + account.update(markUnstarredArticles, statusKey: .starred, flag: false) - // Save any unstarred statuses for articles we haven't yet received - let markUnstarredArticleIDs = Set(markUnstarredArticles.map { $0.articleID }) - let missingUnstarredArticleIDs = deltaUnstarredArticleIDs.subtracting(markUnstarredArticleIDs) - account.ensureStatuses(missingUnstarredArticleIDs, true, .starred, false) + // Save any unstarred statuses for articles we haven't yet received + let markUnstarredArticleIDs = Set(markUnstarredArticles.map { $0.articleID }) + let missingUnstarredArticleIDs = deltaUnstarredArticleIDs.subtracting(markUnstarredArticleIDs) + account.ensureStatuses(missingUnstarredArticleIDs, true, .starred, false) + } } func deleteTagging(for account: Account, with feed: WebFeed, from container: Container?, completion: @escaping (Result) -> Void) { diff --git a/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift b/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift index ebd11bd87..f32824587 100644 --- a/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift +++ b/Frameworks/Account/Feedly/Operations/FeedlySetStarredArticlesOperation.swift @@ -35,36 +35,36 @@ final class FeedlySetStarredArticlesOperation: FeedlyOperation { let group = DispatchGroup() let remoteStarredArticleIds = allStarredEntryIdsProvider.entryIds - let localStarredArticleIDs = account.fetchStarredArticleIDs() - - // Mark articles as starred - let deltaStarredArticleIDs = remoteStarredArticleIds.subtracting(localStarredArticleIDs) - let markStarredArticles = account.fetchArticles(.articleIDs(deltaStarredArticleIDs)) - account.update(markStarredArticles, statusKey: .starred, flag: true) + account.fetchStarredArticleIDs { localStarredArticleIDs in + // Mark articles as starred + let deltaStarredArticleIDs = remoteStarredArticleIds.subtracting(localStarredArticleIDs) + let markStarredArticles = self.account.fetchArticles(.articleIDs(deltaStarredArticleIDs)) + self.account.update(markStarredArticles, statusKey: .starred, flag: true) - // Save any starred statuses for articles we haven't yet received - let markStarredArticleIDs = Set(markStarredArticles.map { $0.articleID }) - let missingStarredArticleIDs = deltaStarredArticleIDs.subtracting(markStarredArticleIDs) - group.enter() - account.ensureStatuses(missingStarredArticleIDs, true, .starred, true) { - group.leave() - } + // Save any starred statuses for articles we haven't yet received + let markStarredArticleIDs = Set(markStarredArticles.map { $0.articleID }) + let missingStarredArticleIDs = deltaStarredArticleIDs.subtracting(markStarredArticleIDs) + group.enter() + self.account.ensureStatuses(missingStarredArticleIDs, true, .starred, true) { + group.leave() + } - // Mark articles as unstarred - let deltaUnstarredArticleIDs = localStarredArticleIDs.subtracting(remoteStarredArticleIds) - let markUnstarredArticles = account.fetchArticles(.articleIDs(deltaUnstarredArticleIDs)) - account.update(markUnstarredArticles, statusKey: .starred, flag: false) + // Mark articles as unstarred + let deltaUnstarredArticleIDs = localStarredArticleIDs.subtracting(remoteStarredArticleIds) + let markUnstarredArticles = self.account.fetchArticles(.articleIDs(deltaUnstarredArticleIDs)) + self.account.update(markUnstarredArticles, statusKey: .starred, flag: false) - // Save any unstarred statuses for articles we haven't yet received - let markUnstarredArticleIDs = Set(markUnstarredArticles.map { $0.articleID }) - let missingUnstarredArticleIDs = deltaUnstarredArticleIDs.subtracting(markUnstarredArticleIDs) - group.enter() - account.ensureStatuses(missingUnstarredArticleIDs, true, .starred, false) { - group.leave() - } - - group.notify(queue: .main) { - self.didFinish() + // Save any unstarred statuses for articles we haven't yet received + let markUnstarredArticleIDs = Set(markUnstarredArticles.map { $0.articleID }) + let missingUnstarredArticleIDs = deltaUnstarredArticleIDs.subtracting(markUnstarredArticleIDs) + group.enter() + self.account.ensureStatuses(missingUnstarredArticleIDs, true, .starred, false) { + group.leave() + } + + group.notify(queue: .main) { + self.didFinish() + } } } } diff --git a/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 9d138750f..d30aec4eb 100644 --- a/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Frameworks/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -942,27 +942,27 @@ private extension ReaderAPIAccountDelegate { } let feedbinStarredArticleIDs = Set(articleIDs.map { String($0) } ) - let currentStarredArticleIDs = account.fetchStarredArticleIDs() - - // Mark articles as starred - let deltaStarredArticleIDs = feedbinStarredArticleIDs.subtracting(currentStarredArticleIDs) - let markStarredArticles = account.fetchArticles(.articleIDs(deltaStarredArticleIDs)) - account.update(markStarredArticles, statusKey: .starred, flag: true) + account.fetchStarredArticleIDs { currentStarredArticleIDs in + // Mark articles as starred + let deltaStarredArticleIDs = feedbinStarredArticleIDs.subtracting(currentStarredArticleIDs) + let markStarredArticles = account.fetchArticles(.articleIDs(deltaStarredArticleIDs)) + account.update(markStarredArticles, statusKey: .starred, flag: true) - // Save any starred statuses for articles we haven't yet received - let markStarredArticleIDs = Set(markStarredArticles.map { $0.articleID }) - let missingStarredArticleIDs = deltaStarredArticleIDs.subtracting(markStarredArticleIDs) - account.ensureStatuses(missingStarredArticleIDs, true, .starred, true) + // Save any starred statuses for articles we haven't yet received + let markStarredArticleIDs = Set(markStarredArticles.map { $0.articleID }) + let missingStarredArticleIDs = deltaStarredArticleIDs.subtracting(markStarredArticleIDs) + account.ensureStatuses(missingStarredArticleIDs, true, .starred, true) - // Mark articles as unstarred - let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(feedbinStarredArticleIDs) - let markUnstarredArticles = account.fetchArticles(.articleIDs(deltaUnstarredArticleIDs)) - account.update(markUnstarredArticles, statusKey: .starred, flag: false) + // Mark articles as unstarred + let deltaUnstarredArticleIDs = currentStarredArticleIDs.subtracting(feedbinStarredArticleIDs) + let markUnstarredArticles = account.fetchArticles(.articleIDs(deltaUnstarredArticleIDs)) + account.update(markUnstarredArticles, statusKey: .starred, flag: false) - // Save any unstarred statuses for articles we haven't yet received - let markUnstarredArticleIDs = Set(markUnstarredArticles.map { $0.articleID }) - let missingUnstarredArticleIDs = deltaUnstarredArticleIDs.subtracting(markUnstarredArticleIDs) - account.ensureStatuses(missingUnstarredArticleIDs, true, .starred, false) + // Save any unstarred statuses for articles we haven't yet received + let markUnstarredArticleIDs = Set(markUnstarredArticles.map { $0.articleID }) + let missingUnstarredArticleIDs = deltaUnstarredArticleIDs.subtracting(markUnstarredArticleIDs) + account.ensureStatuses(missingUnstarredArticleIDs, true, .starred, false) + } } diff --git a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift index 283fdbcfa..22f53ae1c 100644 --- a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift +++ b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift @@ -154,15 +154,16 @@ public final class ArticlesDatabase { // MARK: - Status - /// Fetch the articleIDs of unread articles for feeds specified by webFeedIDs. + /// Fetch the articleIDs of unread articles in feeds specified by webFeedIDs. public func fetchUnreadArticleIDsAsync(webFeedIDs: Set, callback: @escaping (Set) -> Void) { articlesTable.fetchUnreadArticleIDsAsync(webFeedIDs, callback) } - public func fetchStarredArticleIDs() -> Set { - return articlesTable.fetchStarredArticleIDs() + /// Fetch the articleIDs of starred articles in feeds specified by webFeedIDs. + public func fetchStarredArticleIDsAsync(webFeedIDs: Set, callback: @escaping (Set) -> Void) { + articlesTable.fetchStarredArticleIDsAsync(webFeedIDs, callback) } - + public func fetchArticleIDsForStatusesWithoutArticles() -> Set { return articlesTable.fetchArticleIDsForStatusesWithoutArticles() } diff --git a/Frameworks/ArticlesDatabase/ArticlesTable.swift b/Frameworks/ArticlesDatabase/ArticlesTable.swift index c81f4f318..bbdddfdac 100644 --- a/Frameworks/ArticlesDatabase/ArticlesTable.swift +++ b/Frameworks/ArticlesDatabase/ArticlesTable.swift @@ -401,28 +401,12 @@ final class ArticlesTable: DatabaseTable { // MARK: - Statuses - func fetchUnreadArticleIDs() -> Set{ - return statusesTable.fetchUnreadArticleIDs() + func fetchUnreadArticleIDsAsync(_ webFeedIDs: Set, _ callback: @escaping (Set) -> Void) { + fetchArticleIDsAsync(.read, false, webFeedIDs, callback) } - func fetchUnreadArticleIDsAsync(_ webFeedIDs: Set, _ callback: @escaping (Set) -> Void) { - queue.runInDatabase { database in - let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! - let sql = "select articleID from articles natural join statuses where feedID in \(placeholders) and read=0 and userDeleted=0;" - let parameters = Array(webFeedIDs) as [Any] - - guard let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) else { - DispatchQueue.main.async { - callback(Set()) - } - return - } - - let articleIDs = resultSet.mapToSet{ $0.string(forColumnIndex: 0) } - DispatchQueue.main.async { - callback(articleIDs) - } - } + func fetchStarredArticleIDsAsync(_ webFeedIDs: Set, _ callback: @escaping (Set) -> Void) { + fetchArticleIDsAsync(.starred, true, webFeedIDs, callback) } func fetchStarredArticleIDs() -> Set { @@ -668,6 +652,33 @@ private extension ArticlesTable { return articlesWithResultSet(resultSet, database) } + func fetchArticleIDsAsync(_ statusKey: ArticleStatus.Key, _ value: Bool, _ webFeedIDs: Set, _ callback: @escaping (Set) -> Void) { + queue.runInDatabase { database in + let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))! + var sql = "select articleID from articles natural join statuses where feedID in \(placeholders) and \(statusKey.rawValue)=" + sql += value ? "1" : "0" + if statusKey != .userDeleted { + sql += " and userDeleted=0" + } + sql += ";" + + let parameters = Array(webFeedIDs) as [Any] + + guard let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) else { + DispatchQueue.main.async { + callback(Set()) + } + return + } + + let articleIDs = resultSet.mapToSet{ $0.string(forColumnIndex: 0) } + DispatchQueue.main.async { + callback(articleIDs) + } + } + } + + // MARK: - Saving Parsed Items func callUpdateArticlesCompletionBlock(_ newArticles: Set
?, _ updatedArticles: Set
?, _ completion: @escaping UpdateArticlesCompletionBlock) {