Implement marking statuses.

This commit is contained in:
Brent Simmons 2017-09-16 11:04:29 -07:00
parent 90c11bb687
commit db757bcdb9
4 changed files with 61 additions and 35 deletions

View File

@ -131,32 +131,9 @@ final class ArticlesTable: DatabaseTable {
// MARK: Status
func mark(_ articles: Set<Article>, _ 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<ArticleStatus>, _ statusKey: String, _ flag: Bool) {
statusesTable.mark(statuses, statusKey, flag)
}
}

View File

@ -70,9 +70,9 @@ public final class Database {
// MARK: - Status
public func mark(_ articles: Set<Article>, statusKey: String, flag: Bool) {
public func mark(_ statuses: Set<ArticleStatus>, statusKey: String, flag: Bool) {
articlesTable.mark(articles, statusKey, flag)
articlesTable.mark(statuses, statusKey, flag)
}
}

View File

@ -49,5 +49,12 @@ extension ArticleStatus: DatabaseObject {
return (d.copy() as! NSDictionary)
}
}
extension Set where Element == ArticleStatus {
func articleIDs() -> Set<String> {
return Set<String>(map { $0.articleID })
}
}

View File

@ -82,12 +82,30 @@ final class StatusesTable: DatabaseTable {
}
// MARK: Marking
func markArticleIDs(_ articleIDs: Set<String>, _ 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<ArticleStatus>, _ statusKey: String, _ flag: Bool) {
// Sets flag in both memory and in database.
var updatedStatuses = Set<ArticleStatus>()
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<ArticleStatus>) {
// 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<ArticleStatus>) {
@ -170,6 +205,13 @@ private extension StatusesTable {
}
}
}
// MARK: Marking
func markArticleIDs(_ articleIDs: Set<String>, _ statusKey: String, _ flag: Bool, _ database: FMDatabase) {
updateRowsWithValue(NSNumber(value: flag), valueKey: statusKey, whereKey: DatabaseKey.articleID, matches: Array(articleIDs), database: database)
}
}
private final class StatusCache {