Do things. I forget what, since it was yesterday or whatever. Progress, anyway.
This commit is contained in:
parent
c76d42b42f
commit
b756f39cbe
|
@ -36,6 +36,11 @@ public final class ArticleStatus: Hashable {
|
|||
self.hashValue = articleID.hashValue
|
||||
}
|
||||
|
||||
public convenience init(articleID: String, dateArrived: Date) {
|
||||
|
||||
init(articleID: articleID, read: false, starred: false, userDeleted: false, dateArrived: dateArrived, accountInfo: nil)
|
||||
}
|
||||
|
||||
public func boolStatus(forKey key: String) -> Bool {
|
||||
|
||||
if let articleStatusKey = ArticleStatusKey(rawValue: key) {
|
||||
|
|
|
@ -46,6 +46,10 @@ final class StatusesTable: DatabaseTable {
|
|||
|
||||
func ensureStatusesForParsedArticles(_ parsedArticles: [ParsedItem], _ callback: @escaping RSVoidCompletionBlock) {
|
||||
|
||||
// 1. Check cache for statuses
|
||||
// 2. Fetch statuses not found in cache
|
||||
// 3. Create, save, and cache statuses not found in database
|
||||
|
||||
var articleIDs = Set(parsedArticles.map { $0.articleID })
|
||||
articleIDs = articleIDsMissingStatuses(articleIDs)
|
||||
if articleIDs.isEmpty {
|
||||
|
@ -62,11 +66,17 @@ final class StatusesTable: DatabaseTable {
|
|||
self.cache.addObjectsNotCached(Array(statuses))
|
||||
|
||||
let newArticleIDs = self.articleIDsMissingStatuses(articleIDs)
|
||||
self.createStatusForNewArticleIDs(newArticleIDs)
|
||||
if !newArticleIDs.isEmpty {
|
||||
self.createAndSaveStatusesForArticleIDs(newArticleIDs)
|
||||
}
|
||||
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension StatusesTable {
|
||||
|
||||
func assertNoMissingStatuses(_ articles: Set<Article>) {
|
||||
|
||||
|
@ -77,30 +87,6 @@ final class StatusesTable: DatabaseTable {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension StatusesTable {
|
||||
|
||||
// MARK: Marking
|
||||
|
||||
func markArticleStatuses(_ statuses: Set<ArticleStatus>, statusKey: String, flag: Bool) {
|
||||
|
||||
// Ignore the statuses where status.[statusKey] == flag. Update the remainder and save in database.
|
||||
|
||||
var articleIDs = Set<String>()
|
||||
|
||||
statuses.forEach { (oneStatus) in
|
||||
|
||||
if oneStatus.boolStatus(forKey: statusKey) != flag {
|
||||
oneStatus.setBoolStatus(flag, forKey: statusKey)
|
||||
articleIDs.insert(oneStatus.articleID)
|
||||
}
|
||||
}
|
||||
|
||||
if !articleIDs.isEmpty {
|
||||
updateArticleStatusesInDatabase(articleIDs, statusKey: statusKey, flag: flag)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Fetching
|
||||
|
||||
|
@ -126,12 +112,27 @@ private extension StatusesTable {
|
|||
return statuses
|
||||
}
|
||||
|
||||
// MARK: Saving
|
||||
// MARK: Updating
|
||||
|
||||
func saveStatuses(_ statuses: Set<ArticleStatus>) {
|
||||
func markArticleStatuses(_ statuses: Set<ArticleStatus>, statusKey: String, flag: Bool) {
|
||||
|
||||
let statusArray = statuses.map { $0.databaseDictionary() }
|
||||
insertRows(statusArray, insertType: .orIgnore)
|
||||
// Ignore the statuses where status.[statusKey] == flag. Update the remainder and save in database.
|
||||
|
||||
var articleIDsToUpdate = Set<String>()
|
||||
|
||||
statuses.forEach { (oneStatus) in
|
||||
|
||||
if oneStatus.boolStatus(forKey: statusKey) == flag {
|
||||
return
|
||||
}
|
||||
|
||||
oneStatus.setBoolStatus(flag, forKey: statusKey)
|
||||
articleIDsToUpdate.insert(oneStatus.articleID)
|
||||
}
|
||||
|
||||
if !articleIDsToUpdate.isEmpty {
|
||||
updateArticleStatusesInDatabase(articleIDsToUpdate, statusKey: statusKey, flag: flag)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateArticleStatusesInDatabase(_ articleIDs: Set<String>, statusKey: String, flag: Bool) {
|
||||
|
@ -141,30 +142,26 @@ private extension StatusesTable {
|
|||
|
||||
// MARK: Creating
|
||||
|
||||
func createStatusForNewArticleIDs(_ articleIDs: Set<String>) {
|
||||
func saveStatuses(_ statuses: Set<ArticleStatus>) {
|
||||
|
||||
let statusArray = statuses.map { $0.databaseDictionary() }
|
||||
insertRows(statusArray, insertType: .orIgnore)
|
||||
}
|
||||
|
||||
func createAndSaveStatusesForArticleIDs(_ articleIDs: Set<String>) {
|
||||
|
||||
let now = Date()
|
||||
let statuses = articleIDs.map { (oneArticleID) -> ArticleStatus in
|
||||
return ArticleStatus(articleID: oneArticleID, read: false, starred: false, userDeleted: false, dateArrived: now)
|
||||
}
|
||||
let statuses = articleIDs.map { ArticleStatus(articleID: $0, dateArrived: now) }
|
||||
cache.addObjectsNotCached(statuses)
|
||||
|
||||
queue.update { (database: FMDatabase!) -> Void in
|
||||
|
||||
let falseValue = NSNumber(value: false)
|
||||
|
||||
articleIDs.forEach { (oneArticleID) in
|
||||
|
||||
let _ = database.executeUpdate("insert or ignore into statuses (read, articleID, starred, userDeleted, dateArrived) values (?, ?, ?, ?, ?)", withArgumentsIn:[falseValue, oneArticleID as NSString, falseValue, falseValue, now])
|
||||
}
|
||||
}
|
||||
saveStatuses(Set(statuses))
|
||||
}
|
||||
|
||||
// MARK: Utilities
|
||||
|
||||
func articleIDsMissingStatuses(_ articleIDs: Set<String>) -> Set<String> {
|
||||
|
||||
return Set(articleIDs.filter { cache[$0] == nil })
|
||||
return Set(articleIDs.filter { !objectWithIDIsCached[$0] })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
// Not thread-safe.
|
||||
|
||||
public final class ObjectCache<T> {
|
||||
|
||||
private let keyPathForID: KeyPath<T,String>
|
||||
|
@ -60,7 +62,7 @@ public final class ObjectCache<T> {
|
|||
// When an object is not already cached, cache it,
|
||||
// then consider that version the unique version.
|
||||
|
||||
return objects.map({ (object) -> T in
|
||||
return objects.map { (object) -> T in
|
||||
|
||||
let identifier = identifierForObject(object)
|
||||
if let cachedObject = self[identifier] {
|
||||
|
@ -68,7 +70,15 @@ public final class ObjectCache<T> {
|
|||
}
|
||||
add(object)
|
||||
return object
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public func objectWithIDIsCached(_ identifier: String) -> Bool {
|
||||
|
||||
if let _ = self[identifier] {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public subscript(_ identifier: String) -> T? {
|
||||
|
|
Loading…
Reference in New Issue