Fetch all unread counts at startup. This is done with a single SQL call, and it’s done in the background, so performance hit should not be noticeable. Fix #138.

This commit is contained in:
Brent Simmons 2017-12-03 11:57:53 -08:00
parent c83e0ca68d
commit 0c176eccd0
4 changed files with 64 additions and 1 deletions

View File

@ -140,6 +140,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
DispatchQueue.main.async {
self.updateUnreadCount()
self.fetchAllUnreadCounts()
}
}
@ -622,6 +623,28 @@ private extension Account {
NotificationCenter.default.post(name: .StatusesDidChange, object: self, userInfo: [UserInfoKey.statuses: statuses, UserInfoKey.articles: articles, UserInfoKey.feeds: feeds])
}
func fetchAllUnreadCounts() {
database.fetchAllNonZeroUnreadCounts { (unreadCountDictionary) in
if unreadCountDictionary.isEmpty {
return
}
self.flattenedFeeds().forEach{ (feed) in
// When the unread count is zero, it wont appear in unreadCountDictionary.
if let unreadCount = unreadCountDictionary[feed] {
feed.unreadCount = unreadCount
}
else {
feed.unreadCount = 0
}
}
}
}
}
// MARK: - Container Overrides

View File

@ -174,6 +174,37 @@ final class ArticlesTable: DatabaseTable {
}
}
func fetchAllUnreadCounts(_ completion: @escaping UnreadCountCompletionBlock) {
// Returns only where unreadCount > 0.
let cutoffDate = articleCutoffDate
queue.fetch { (database) in
let sql = "select distinct feedID, count(*) from articles natural join statuses where read=0 and userDeleted=0 and (starred=1 or dateArrived>?) group by feedID;"
guard let resultSet = database.executeQuery(sql, withArgumentsIn: [cutoffDate]) else {
DispatchQueue.main.async() {
completion(UnreadCountDictionary())
}
return
}
var d = UnreadCountDictionary()
while resultSet.next() {
let unreadCount = resultSet.long(forColumnIndex: 1)
if let feedID = resultSet.string(forColumnIndex: 0) {
d[feedID] = unreadCount
}
}
DispatchQueue.main.async() {
completion(d)
}
}
}
func fetchStarredAndUnreadCount(_ feeds: Set<Feed>, _ callback: @escaping (Int) -> Void) {
if feeds.isEmpty {

View File

@ -57,7 +57,7 @@ public final class Database {
// MARK: - Unread Counts
public func fetchUnreadCounts(for feeds: Set<Feed>, _ completion: @escaping UnreadCountCompletionBlock) {
articlesTable.fetchUnreadCounts(feeds, completion)
}
@ -71,6 +71,11 @@ public final class Database {
articlesTable.fetchStarredAndUnreadCount(feeds, callback)
}
public func fetchAllNonZeroUnreadCounts(_ completion: @escaping UnreadCountCompletionBlock) {
articlesTable.fetchAllUnreadCounts(completion)
}
// MARK: - Saving and Updating Articles
public func update(feed: Feed, parsedFeed: ParsedFeed, completion: @escaping UpdateArticlesWithFeedCompletionBlock) {

View File

@ -12,6 +12,10 @@ import Data
public struct UnreadCountDictionary {
private var dictionary = [String: Int]()
public var isEmpty: Bool {
return dictionary.count < 1
}
subscript(_ feedID: String) -> Int? {
get {