From db757bcdb906baebae222865d394f4ac14b14148 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 16 Sep 2017 11:04:29 -0700 Subject: [PATCH] Implement marking statuses. --- Frameworks/Database/ArticlesTable.swift | 29 ++-------- Frameworks/Database/Database.swift | 4 +- .../Extensions/ArticleStatus+Database.swift | 9 +++- Frameworks/Database/StatusesTable.swift | 54 ++++++++++++++++--- 4 files changed, 61 insertions(+), 35 deletions(-) diff --git a/Frameworks/Database/ArticlesTable.swift b/Frameworks/Database/ArticlesTable.swift index 76b26898c..9cfe9b056 100644 --- a/Frameworks/Database/ArticlesTable.swift +++ b/Frameworks/Database/ArticlesTable.swift @@ -131,32 +131,9 @@ final class ArticlesTable: DatabaseTable { // MARK: Status - func mark(_ articles: Set
, _ statusKey: String, _ flag: Bool) { - - // Sets flag in both memory and in database. - -// let articleIDs = articles.flatMap { (article) -> String? in -// -// guard let status = article.status else { -// assertionFailure("Each article must have a status.") -// return nil -// } -// -// if status.boolStatus(forKey: statusKey) == flag { -// return nil -// } -// status.setBoolStatus(flag, forKey: statusKey) -// return article.articleID -// } -// -// if articleIDs.isEmpty { -// return -// } -// -// // TODO: statusesTable needs to cache status changes. -// queue.update { (database) in -// self.statusesTable.markArticleIDs(Set(articleIDs), statusKey, flag, database) -// } + func mark(_ statuses: Set, _ statusKey: String, _ flag: Bool) { + + statusesTable.mark(statuses, statusKey, flag) } } diff --git a/Frameworks/Database/Database.swift b/Frameworks/Database/Database.swift index 508b21009..4850f110a 100644 --- a/Frameworks/Database/Database.swift +++ b/Frameworks/Database/Database.swift @@ -70,9 +70,9 @@ public final class Database { // MARK: - Status - public func mark(_ articles: Set
, statusKey: String, flag: Bool) { + public func mark(_ statuses: Set, statusKey: String, flag: Bool) { - articlesTable.mark(articles, statusKey, flag) + articlesTable.mark(statuses, statusKey, flag) } } diff --git a/Frameworks/Database/Extensions/ArticleStatus+Database.swift b/Frameworks/Database/Extensions/ArticleStatus+Database.swift index f529c9894..fab48ccdc 100644 --- a/Frameworks/Database/Extensions/ArticleStatus+Database.swift +++ b/Frameworks/Database/Extensions/ArticleStatus+Database.swift @@ -49,5 +49,12 @@ extension ArticleStatus: DatabaseObject { return (d.copy() as! NSDictionary) } - +} + +extension Set where Element == ArticleStatus { + + func articleIDs() -> Set { + + return Set(map { $0.articleID }) + } } diff --git a/Frameworks/Database/StatusesTable.swift b/Frameworks/Database/StatusesTable.swift index b90edac3b..c7b1e4c30 100644 --- a/Frameworks/Database/StatusesTable.swift +++ b/Frameworks/Database/StatusesTable.swift @@ -82,12 +82,30 @@ final class StatusesTable: DatabaseTable { } // MARK: Marking - - func markArticleIDs(_ articleIDs: Set, _ statusKey: String, _ flag: Bool, _ database: FMDatabase) { - - // TODO: replace statuses in cache. - updateRowsWithValue(NSNumber(value: flag), valueKey: statusKey, whereKey: DatabaseKey.articleID, matches: Array(articleIDs), database: database) + func mark(_ statuses: Set, _ statusKey: String, _ flag: Bool) { + + // Sets flag in both memory and in database. + + var updatedStatuses = Set() + + for status in statuses { + + if status.boolStatus(forKey: statusKey) == flag { + continue + } + status.setBoolStatus(flag, forKey: statusKey) + updatedStatuses.insert(status) + } + + if updatedStatuses.isEmpty { + return + } + addToCache(updatedStatuses) + + queue.update { (database) in + self.markArticleIDs(updatedStatuses.articleIDs(), statusKey, flag, database) + } } // MARK: Fetching @@ -132,7 +150,24 @@ private extension StatusesTable { return d } - + + func addToCache(_ statuses: Set) { + + // Replacing any already cached statuses. + if statuses.isEmpty { + return + } + + if Thread.isMainThread { + self.cache.add(statuses) + } + else { + DispatchQueue.main.async { + self.cache.add(statuses) + } + } + } + // MARK: Creating func saveStatuses(_ statuses: Set) { @@ -170,6 +205,13 @@ private extension StatusesTable { } } } + + // MARK: Marking + + func markArticleIDs(_ articleIDs: Set, _ statusKey: String, _ flag: Bool, _ database: FMDatabase) { + + updateRowsWithValue(NSNumber(value: flag), valueKey: statusKey, whereKey: DatabaseKey.articleID, matches: Array(articleIDs), database: database) + } } private final class StatusCache {