Make progress on making ArticleStatus a reference type and on making article.status non-optional.
This commit is contained in:
parent
ab43db7761
commit
6db993075b
|
@ -131,19 +131,9 @@ final class ArticlesTable: DatabaseTable {
|
|||
|
||||
// MARK: Status
|
||||
|
||||
func status(for article: Article) -> ArticleStatus? {
|
||||
func mark(_ articles: Set<Article>, _ statusKey: String, _ flag: Bool) {
|
||||
|
||||
return statusesTable.cachedStatus(for: article.articleID)
|
||||
}
|
||||
|
||||
func statuses(for articles: Set<Article>) -> Set<ArticleStatus> {
|
||||
|
||||
return statusesTable.cachedStatuses(for: articles.articleIDs())
|
||||
}
|
||||
|
||||
func mark(_ statuses: Set<ArticleStatus>, _ statusKey: String, _ flag: Bool) {
|
||||
|
||||
statusesTable.mark(statuses, statusKey, flag)
|
||||
statusesTable.mark(articles.statuses(), statusKey, flag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,19 +70,9 @@ public final class Database {
|
|||
|
||||
// MARK: - Status
|
||||
|
||||
public func status(for article: Article) -> ArticleStatus? {
|
||||
public func mark(_ articles: Set<Article>, statusKey: String, flag: Bool) {
|
||||
|
||||
return articlesTable.status(for: article)
|
||||
}
|
||||
|
||||
public func statuses(for articles: Set<Article>) -> Set<ArticleStatus> {
|
||||
|
||||
return articlesTable.statuses(for: articles)
|
||||
}
|
||||
|
||||
public func mark(_ statuses: Set<ArticleStatus>, statusKey: String, flag: Bool) {
|
||||
|
||||
articlesTable.mark(statuses, statusKey, flag)
|
||||
articlesTable.mark(articles, statusKey, flag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,11 @@ extension Set where Element == Article {
|
|||
return Set<String>(map { $0.databaseID })
|
||||
}
|
||||
|
||||
func statuses() -> Set<ArticleStatus> {
|
||||
|
||||
return Set<ArticleStatus>(map { $0.status })
|
||||
}
|
||||
|
||||
func dictionary() -> [String: Article] {
|
||||
|
||||
var d = [String: Article]()
|
||||
|
|
|
@ -12,7 +12,7 @@ import Data
|
|||
|
||||
extension ArticleStatus {
|
||||
|
||||
init(articleID: String, dateArrived: Date, row: FMResultSet) {
|
||||
convenience init(articleID: String, dateArrived: Date, row: FMResultSet) {
|
||||
|
||||
let read = row.bool(forColumn: DatabaseKey.read)
|
||||
let starred = row.bool(forColumn: DatabaseKey.starred)
|
||||
|
|
|
@ -30,42 +30,27 @@ final class StatusesTable: DatabaseTable {
|
|||
|
||||
// MARK: Cache
|
||||
|
||||
func cachedStatus(for articleID: String) -> ArticleStatus? {
|
||||
// func cachedStatus(for articleID: String) -> ArticleStatus? {
|
||||
//
|
||||
// assert(Thread.isMainThread)
|
||||
// assert(cache[articleID] != nil)
|
||||
// return cache[articleID]
|
||||
// }
|
||||
//
|
||||
// func cachedStatuses(for articleIDs: Set<String>) -> Set<ArticleStatus> {
|
||||
//
|
||||
// assert(Thread.isMainThread)
|
||||
//
|
||||
// var statuses = Set<ArticleStatus>()
|
||||
// for articleID in articleIDs {
|
||||
// if let articleStatus = cache[articleID] {
|
||||
// statuses.insert(articleStatus)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return statuses
|
||||
// }
|
||||
|
||||
assert(Thread.isMainThread)
|
||||
assert(cache[articleID] != nil)
|
||||
return cache[articleID]
|
||||
}
|
||||
|
||||
func cachedStatuses(for articleIDs: Set<String>) -> Set<ArticleStatus> {
|
||||
|
||||
assert(Thread.isMainThread)
|
||||
|
||||
var statuses = Set<ArticleStatus>()
|
||||
for articleID in articleIDs {
|
||||
if let articleStatus = cache[articleID] {
|
||||
statuses.insert(articleStatus)
|
||||
}
|
||||
}
|
||||
|
||||
return statuses
|
||||
}
|
||||
|
||||
func addIfNotCached(_ statuses: Set<ArticleStatus>) {
|
||||
|
||||
if statuses.isEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
if Thread.isMainThread {
|
||||
self.cache.addIfNotCached(statuses)
|
||||
}
|
||||
else {
|
||||
DispatchQueue.main.async {
|
||||
self.cache.addIfNotCached(statuses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Creating/Updating
|
||||
|
||||
|
@ -108,15 +93,13 @@ final class StatusesTable: DatabaseTable {
|
|||
if status.boolStatus(forKey: statusKey) == flag {
|
||||
continue
|
||||
}
|
||||
var statusCopy = status
|
||||
statusCopy.setBoolStatus(flag, forKey: statusKey)
|
||||
updatedStatuses.insert(statusCopy)
|
||||
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)
|
||||
|
@ -183,6 +166,22 @@ private extension StatusesTable {
|
|||
}
|
||||
}
|
||||
|
||||
func addIfNotCached(_ statuses: Set<ArticleStatus>) {
|
||||
|
||||
if statuses.isEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
if Thread.isMainThread {
|
||||
self.cache.addIfNotCached(statuses)
|
||||
}
|
||||
else {
|
||||
DispatchQueue.main.async {
|
||||
self.cache.addIfNotCached(statuses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Creating
|
||||
|
||||
func saveStatuses(_ statuses: Set<ArticleStatus>) {
|
||||
|
@ -231,7 +230,7 @@ private extension StatusesTable {
|
|||
|
||||
private final class StatusCache {
|
||||
|
||||
// Main thread only.
|
||||
// Serial database queue only.
|
||||
|
||||
var dictionary = [String: ArticleStatus]()
|
||||
|
||||
|
@ -239,6 +238,8 @@ private final class StatusCache {
|
|||
|
||||
// Replaces any cached statuses.
|
||||
|
||||
assert(!Thread.isMainThread)
|
||||
|
||||
for status in statuses {
|
||||
self[status.articleID] = status
|
||||
}
|
||||
|
@ -248,6 +249,8 @@ private final class StatusCache {
|
|||
|
||||
// Does not replace already cached statuses.
|
||||
|
||||
assert(!Thread.isMainThread)
|
||||
|
||||
for status in statuses {
|
||||
let articleID = status.articleID
|
||||
if let _ = self[articleID] {
|
||||
|
@ -259,9 +262,11 @@ private final class StatusCache {
|
|||
|
||||
subscript(_ articleID: String) -> ArticleStatus? {
|
||||
get {
|
||||
assert(!Thread.isMainThread)
|
||||
return self[articleID]
|
||||
}
|
||||
set {
|
||||
assert(!Thread.isMainThread)
|
||||
self[articleID] = newValue
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue