diff --git a/Frameworks/Data/Attachment.swift b/Frameworks/Data/Attachment.swift index 40ed4cb75..61008e313 100644 --- a/Frameworks/Data/Attachment.swift +++ b/Frameworks/Data/Attachment.swift @@ -10,8 +10,7 @@ import Foundation public struct Attachment: Hashable { - public let databaseID: String // Calculated - public let articleID: String // Article.databaseID + public let attachmentID: String // Calculated public let url: String public let mimeType: String? public let title: String? @@ -19,16 +18,15 @@ public struct Attachment: Hashable { public let durationInSeconds: Int? public let hashValue: Int - public init(databaseID: String?, articleID: String, url: String, mimeType: String?, title: String?, sizeInBytes: Int?, durationInSeconds: Int?) { + public init(attachmentID: String?, url: String, mimeType: String?, title: String?, sizeInBytes: Int?, durationInSeconds: Int?) { - self.articleID = articleID self.url = url self.mimeType = mimeType self.title = title self.sizeInBytes = sizeInBytes self.durationInSeconds = durationInSeconds - var s = articleID + url + var s = url s += mimeType ?? "" s += title ?? "" if let sizeInBytes = sizeInBytes { @@ -39,11 +37,11 @@ public struct Attachment: Hashable { } self.hashValue = s.hashValue - if let databaseID = databaseID { - self.databaseID = databaseID + if let attachmentID = attachmentID { + self.attachmentID = attachmentID } else { - self.databaseID = databaseIDWithString(s) + self.attachmentID = databaseIDWithString(s) } } diff --git a/Frameworks/Database/AccountInfo.swift b/Frameworks/Database/AccountInfo.swift index 985ecfd81..9dac39660 100644 --- a/Frameworks/Database/AccountInfo.swift +++ b/Frameworks/Database/AccountInfo.swift @@ -12,10 +12,11 @@ import RSDatabase // AccountInfo is a plist-compatible dictionary that’s stored as a binary plist in the database. -func accountInfoWithRow(_ row: FMResultSet) -> AccountInfo? { - - guard let rawAccountInfo = row.data(forColumn: DatabaseKey.accountInfo) else { - return nil - } - return propertyList(withData: rawAccountInfo) as? AccountInfo -} +//func accountInfoWithRow(_ row: FMResultSet) -> AccountInfo? { +// +// guard let rawAccountInfo = row.data(forColumn: DatabaseKey.accountInfo) else { +// return nil +// } +// return propertyList(withData: rawAccountInfo) as? AccountInfo +//} + diff --git a/Frameworks/Database/ArticlesTable.swift b/Frameworks/Database/ArticlesTable.swift index 78eaebbbc..cc5aa9f35 100644 --- a/Frameworks/Database/ArticlesTable.swift +++ b/Frameworks/Database/ArticlesTable.swift @@ -10,80 +10,80 @@ import Foundation import RSDatabase import Data -final class ArticlesTable: DatabaseTable { +//final class ArticlesTable: DatabaseTable { +// +// let name: String +// private let cachedArticles: NSMapTable = NSMapTable.weakToWeakObjects() +// +// init(name: String) { +// +// self.name = name +// } - let name: String - let queue: RSDatabaseQueue - private let cachedArticles: NSMapTable = NSMapTable.weakToWeakObjects() - init(name: String, queue: RSDatabaseQueue) { - self.name = name - self.queue = queue - } +// func uniquedArticles(_ fetchedArticles: Set
, statusesTable: StatusesTable) -> Set
{ +// +// var articles = Set
() +// +// for oneArticle in fetchedArticles { +// +// assert(oneArticle.status != nil) +// +// if let existingArticle = cachedArticle(oneArticle.databaseID) { +// articles.insert(existingArticle) +// } +// else { +// cacheArticle(oneArticle) +// articles.insert(oneArticle) +// } +// } +// +// statusesTable.attachCachedStatuses(articles) +// +// return articles +// } - func uniquedArticles(_ fetchedArticles: Set
, statusesTable: StatusesTable) -> Set
{ - - var articles = Set
() - - for oneArticle in fetchedArticles { - - assert(oneArticle.status != nil) - - if let existingArticle = cachedArticle(oneArticle.databaseID) { - articles.insert(existingArticle) - } - else { - cacheArticle(oneArticle) - articles.insert(oneArticle) - } - } - - statusesTable.attachCachedStatuses(articles) - - return articles - } +// typealias FeedCountCallback = (Int) -> Void +// +// func numberOfArticlesWithFeedID(_ feedID: String, callback: @escaping FeedCountCallback) { +// +// queue.fetch { (database: FMDatabase!) +// +// let sql = "select count(*) from articles where feedID = ?;" +// var numberOfArticles = -1 +// +// if let resultSet = database.executeQuery(sql, withArgumentsIn: [feedID]) { +// +// while (resultSet.next()) { +// numberOfArticles = resultSet.long(forColumnIndex: 0) +// break +// } +// } +// +// DispatchQueue.main.async() { +// callback(numberOfArticles) +// } +// } +// +// } +//} - typealias FeedCountCallback = (Int) -> Void +//private extension ArticlesTable { - func numberOfArticlesWithFeedID(_ feedID: String, callback: @escaping FeedCountCallback) { - - queue.fetch { (database: FMDatabase!) - - let sql = "select count(*) from articles where feedID = ?;" - var numberOfArticles = -1 - - if let resultSet = database.executeQuery(sql, withArgumentsIn: [feedID]) { - - while (resultSet.next()) { - numberOfArticles = resultSet.long(forColumnIndex: 0) - break - } - } - - DispatchQueue.main.async() { - callback(numberOfArticles) - } - } - - } -} - -private extension ArticlesTable { - - func cachedArticle(_ articleID: String) -> Article? { - - return cachedArticles.object(forKey: articleID as NSString) - } - - func cacheArticle(_ article: Article) { - - cachedArticles.setObject(article, forKey: article.databaseID as NSString) - } - - func cacheArticles(_ articles: Set
) { - - articles.forEach { cacheArticle($0) } - } -} +// func cachedArticle(_ articleID: String) -> Article? { +// +// return cachedArticles.object(forKey: articleID as NSString) +// } +// +// func cacheArticle(_ article: Article) { +// +// cachedArticles.setObject(article, forKey: article.databaseID as NSString) +// } +// +// func cacheArticles(_ articles: Set
) { +// +// articles.forEach { cacheArticle($0) } +// } +//} diff --git a/Frameworks/Database/AttachmentsTable.swift b/Frameworks/Database/AttachmentsTable.swift index 08149d152..fb1d0dac7 100644 --- a/Frameworks/Database/AttachmentsTable.swift +++ b/Frameworks/Database/AttachmentsTable.swift @@ -25,7 +25,14 @@ struct AttachmentsTable: DatabaseTable { func objectWithRow(_ row: FMResultSet) -> DatabaseObject? { - return attachmentWithRow(row) as DatabaseObject + if let attachment = attachmentWithRow(row) { + return attachment as DatabaseObject + } + return nil + } + + func save(_ objects: [DatabaseObject], in database: FMDatabase) { + // TODO } } @@ -33,11 +40,17 @@ private extension AttachmentsTable { func attachmentWithRow(_ row: FMResultSet) -> Attachment? { - let attachmentID = row.string(forColumn: DatabaseKey.attachmentID) - if let cachedAttachment = cache(attachmentID) { + guard let attachmentID = row.string(forColumn: DatabaseKey.attachmentID) else { + return nil + } + if let cachedAttachment = cache[attachmentID] as? Attachment { return cachedAttachment } - return Attachment(attachmentID: attachmentID, row: row) + guard let attachment = Attachment(attachmentID: attachmentID, row: row) else { + return nil + } + cache[attachmentID] = attachment as DatabaseObject + return attachment } } diff --git a/Frameworks/Database/AuthorsTable.swift b/Frameworks/Database/AuthorsTable.swift index ffac66c0d..e9dc6cbc6 100644 --- a/Frameworks/Database/AuthorsTable.swift +++ b/Frameworks/Database/AuthorsTable.swift @@ -31,9 +31,17 @@ struct AuthorsTable: DatabaseTable { // MARK: DatabaseTable Methods func objectWithRow(_ row: FMResultSet) -> DatabaseObject? { - - return authorWithRow(row) as DatabaseObject + + if let author = authorWithRow(row) { + return author as DatabaseObject + } + return nil } + + func save(_ objects: [DatabaseObject], in database: FMDatabase) { + // TODO + } + } private extension AuthorsTable { @@ -44,7 +52,7 @@ private extension AuthorsTable { return nil } - if let cachedAuthor = cache[authorID] { + if let cachedAuthor = cache[authorID] as? Author { return cachedAuthor } diff --git a/Frameworks/Database/Database.swift b/Frameworks/Database/Database.swift index a2fbf20c1..4385a3bbd 100644 --- a/Frameworks/Database/Database.swift +++ b/Frameworks/Database/Database.swift @@ -26,7 +26,7 @@ final class Database { private let queue: RSDatabaseQueue private let databaseFile: String - private let articlesTable: ArticlesTable +// private let articlesTable: ArticlesTable private let statusesTable: StatusesTable private let authorsLookupTable: DatabaseLookupTable private let attachmentsLookupTable: DatabaseLookupTable @@ -41,7 +41,7 @@ final class Database { self.databaseFile = databaseFile self.queue = RSDatabaseQueue(filepath: databaseFile, excludeFromBackup: false) - self.articlesTable = ArticlesTable(name: DatabaseTableName.articles, queue: queue) +// self.articlesTable = ArticlesTable(name: DatabaseTableName.articles, queue: queue) self.statusesTable = StatusesTable(name: DatabaseTableName.statuses) let authorsTable = AuthorsTable(name: DatabaseTableName.authors) diff --git a/Frameworks/Database/Database.xcodeproj/project.pbxproj b/Frameworks/Database/Database.xcodeproj/project.pbxproj index c2daa7101..01535452e 100644 --- a/Frameworks/Database/Database.xcodeproj/project.pbxproj +++ b/Frameworks/Database/Database.xcodeproj/project.pbxproj @@ -467,21 +467,21 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 84E156EA1F0AB80500F8CC05 /* Database.swift in Sources */, - 84E156EC1F0AB80E00F8CC05 /* ArticlesTable.swift in Sources */, - 84E156EE1F0AB81400F8CC05 /* StatusesTable.swift in Sources */, - 8455807C1F0C0DBD003CCFA1 /* Attachment+Database.swift in Sources */, - 84F20F8F1F180D8700D8E682 /* AuthorsTable.swift in Sources */, 845580671F0AEBCD003CCFA1 /* Constants.swift in Sources */, - 840405CF1F1A963700DF0296 /* AttachmentsTable.swift in Sources */, - 84D0DEA11F4A429800073503 /* String+Database.swift in Sources */, 846FB36B1F4A937B00EAB81D /* Feed+Database.swift in Sources */, + 84D0DEA11F4A429800073503 /* String+Database.swift in Sources */, 843CB9961F34174100EE6581 /* Author+Database.swift in Sources */, 845580781F0AF678003CCFA1 /* Folder+Database.swift in Sources */, 845580761F0AF670003CCFA1 /* Article+Database.swift in Sources */, - 845580721F0AEE49003CCFA1 /* AccountInfo.swift in Sources */, 8455807A1F0AF67D003CCFA1 /* ArticleStatus+Database.swift in Sources */, + 8455807C1F0C0DBD003CCFA1 /* Attachment+Database.swift in Sources */, 84BB4BA91F11A32800858766 /* TagsTable.swift in Sources */, + 840405CF1F1A963700DF0296 /* AttachmentsTable.swift in Sources */, + 84F20F8F1F180D8700D8E682 /* AuthorsTable.swift in Sources */, + 84E156EC1F0AB80E00F8CC05 /* ArticlesTable.swift in Sources */, + 84E156EE1F0AB81400F8CC05 /* StatusesTable.swift in Sources */, + 845580721F0AEE49003CCFA1 /* AccountInfo.swift in Sources */, + 84E156EA1F0AB80500F8CC05 /* Database.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Frameworks/Database/Extensions/Article+Database.swift b/Frameworks/Database/Extensions/Article+Database.swift index 00c87571c..c479de172 100644 --- a/Frameworks/Database/Extensions/Article+Database.swift +++ b/Frameworks/Database/Extensions/Article+Database.swift @@ -32,17 +32,17 @@ extension Article { let bannerImageURL = row.string(forColumn: DatabaseKey.bannerImageURL) let datePublished = row.date(forColumn: DatabaseKey.datePublished) let dateModified = row.date(forColumn: DatabaseKey.dateModified) - let authors = PropertyListTransformer.authorsWithRow(row) - let tags = PropertyListTransformer.tagsWithRow(row) - let attachments = PropertyListTransformer.attachmentsWithRow(row) - let accountInfo = accountInfoWithRow(row) +// let authors = PropertyListTransformer.authorsWithRow(row) +// let tags = PropertyListTransformer.tagsWithRow(row) +// let attachments = PropertyListTransformer.attachmentsWithRow(row) +// let accountInfo = accountInfoWithRow(row) - self.init(account: account, feedID: feed, uniqueID: uniqueID, title: title, contentHTML: contentHTML, contentText: contentText, url: url, externalURL: externalURL, summary: summary, imageURL: imageURL, bannerImageURL: bannerImageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, tags: tags, attachments: attachments, accountInfo: accountInfo) + self.init(account: account, feedID: feedID, uniqueID: uniqueID, title: title, contentHTML: contentHTML, contentText: contentText, url: url, externalURL: externalURL, summary: summary, imageURL: imageURL, bannerImageURL: bannerImageURL, datePublished: datePublished, dateModified: dateModified, authors: authors, tags: tags, attachments: attachments, accountInfo: accountInfo) } func databaseDictionary() -> NSDictionary { - var d = NSMutableDictionary() + let d = NSMutableDictionary() return d.copy() as! NSDictionary @@ -51,7 +51,7 @@ extension Article { extension Article: DatabaseObject { - var databaseID: String { + public var databaseID: String { get { return articleID } diff --git a/Frameworks/Database/Extensions/ArticleStatus+Database.swift b/Frameworks/Database/Extensions/ArticleStatus+Database.swift index 44235644e..24ad25b77 100644 --- a/Frameworks/Database/Extensions/ArticleStatus+Database.swift +++ b/Frameworks/Database/Extensions/ArticleStatus+Database.swift @@ -23,9 +23,9 @@ extension ArticleStatus { dateArrived = NSDate.distantPast } - let accountInfoPlist = accountInfoWithRow(row) +// let accountInfoPlist = accountInfoWithRow(row) - self.init(articleID: articleID, read: read, starred: starred, userDeleted: userDeleted, dateArrived: dateArrived!, accountInfo: accountInfoPlist) + self.init(articleID: articleID, read: read, starred: starred, userDeleted: userDeleted, dateArrived: dateArrived!, accountInfo: nil) } func databaseDictionary() -> NSDictionary { @@ -38,11 +38,19 @@ extension ArticleStatus { d[DatabaseKey.userDeleted] = userDeleted d[DatabaseKey.dateArrived] = dateArrived - if let accountInfo = accountInfo, let data = PropertyListTransformer.data(withPropertyList: accountInfo) { - d[DatabaseKey.accountInfo] = data - } +// if let accountInfo = accountInfo, let data = PropertyListTransformer.data(withPropertyList: accountInfo) { +// d[DatabaseKey.accountInfo] = data +// } return d.copy() as! NSDictionary } } +extension ArticleStatus: DatabaseObject { + + public var databaseID: String { + get { + return articleID + } + } +} diff --git a/Frameworks/Database/Extensions/Attachment+Database.swift b/Frameworks/Database/Extensions/Attachment+Database.swift index 5676a72cc..3ef5b0d4d 100644 --- a/Frameworks/Database/Extensions/Attachment+Database.swift +++ b/Frameworks/Database/Extensions/Attachment+Database.swift @@ -12,24 +12,36 @@ import RSDatabase extension Attachment { - init?(databaseID: String, row: FMResultSet) { + init?(attachmentID: String, row: FMResultSet) { + + guard let url = row.string(forColumn: DatabaseKey.url) else { + return nil + } - let articleID = row.string(forColumn: DatabaseKey.articleID) - let url = row.string(forColumn: DatabaseKey.url) let mimeType = row.string(forColumn: DatabaseKey.mimeType) let title = row.string(forColumn: DatabaseKey.title) let sizeInBytes = optionalIntForColumn(row, DatabaseKey.sizeInBytes) let durationInSeconds = optionalIntForColumn(row, DatabaseKey.durationInSeconds) - self.init(databaseID: databaseID, articleID: articleID, url: url, mimeType: mimeType, title: title, sizeInBytes: sizeInBytes, durationInSeconds: durationInSeconds) + self.init(attachmentID: attachmentID, url: url, mimeType: mimeType, title: title, sizeInBytes: sizeInBytes, durationInSeconds: durationInSeconds) } - private func optionalIntForColumn(_ row: FMResultSet, _ columnName: String) -> Int? { +} - let intValue = row.long(forColumn: columnName) - if intValue < 1 { - return nil +private func optionalIntForColumn(_ row: FMResultSet, _ columnName: String) -> Int? { + + let intValue = row.long(forColumn: columnName) + if intValue < 1 { + return nil + } + return intValue +} + +extension Attachment: DatabaseObject { + + public var databaseID: String { + get { + return attachmentID } - return intValue } } diff --git a/Frameworks/Database/Extensions/Author+Database.swift b/Frameworks/Database/Extensions/Author+Database.swift index 10d794800..51bc8eac9 100644 --- a/Frameworks/Database/Extensions/Author+Database.swift +++ b/Frameworks/Database/Extensions/Author+Database.swift @@ -23,9 +23,9 @@ extension Author { } } -public extension Author: DatabaseObject { +extension Author: DatabaseObject { - var databaseID: String { + public var databaseID: String { get { return authorID } diff --git a/Frameworks/Database/Extensions/Feed+Database.swift b/Frameworks/Database/Extensions/Feed+Database.swift index baf961f3b..581304278 100644 --- a/Frameworks/Database/Extensions/Feed+Database.swift +++ b/Frameworks/Database/Extensions/Feed+Database.swift @@ -13,6 +13,6 @@ extension Set where Element == Feed { func feedIDs() -> Set { - return Set(map { $0.feedID }) + return Set(map { $0.feedID }) } } diff --git a/Frameworks/Database/Extensions/String+Database.swift b/Frameworks/Database/Extensions/String+Database.swift index 13804d2ee..dcbf47493 100644 --- a/Frameworks/Database/Extensions/String+Database.swift +++ b/Frameworks/Database/Extensions/String+Database.swift @@ -14,7 +14,7 @@ import RSDatabase extension String: DatabaseObject { - var databaseID: String { + public var databaseID: String { get { return self } diff --git a/Frameworks/Database/StatusesTable.swift b/Frameworks/Database/StatusesTable.swift index 1c0aa970a..7dfbcfc82 100644 --- a/Frameworks/Database/StatusesTable.swift +++ b/Frameworks/Database/StatusesTable.swift @@ -18,6 +18,7 @@ import Data final class StatusesTable: DatabaseTable { let name: String + let databaseIDKey = DatabaseKey.articleID private let cache = DatabaseObjectCache() init(name: String) { @@ -25,40 +26,58 @@ final class StatusesTable: DatabaseTable { self.name = name } - func markArticles(_ articles: Set
, statusKey: String, flag: Bool) { - - // Main thread. - - assertNoMissingStatuses(articles) - let statuses = Set(articles.flatMap { $0.status }) - markArticleStatuses(statuses, statusKey: statusKey, flag: flag) + // Mark: DatabaseTable Methods + + func objectWithRow(_ row: FMResultSet) -> DatabaseObject? { + + if let status = statusWithRow(row) { + return status as DatabaseObject + } + return nil } - func attachStatuses(_ articles: Set
, _ database: FMDatabase) { - - // Look in cache first. - attachCachedStatuses(articles) - let articlesNeedingStatuses = articlesMissingStatuses(articles) - if articlesNeedingStatuses.isEmpty { - return - } - - // Fetch from database. - fetchAndCacheStatusesForArticles(articlesNeedingStatuses, database) - attachCachedStatuses(articlesNeedingStatuses) - - // Create new statuses, and cache and save them in the database. - // It shouldn’t happen that an Article in the database has no corresponding ArticleStatus, - // but the case should be handled anyway. - - let articlesNeedingStatusesCreated = articlesMissingStatuses(articlesNeedingStatuses) - if articlesNeedingStatusesCreated.isEmpty { - return - } - createAndSaveStatusesForArticles(articlesNeedingStatusesCreated, database) - - assertNoMissingStatuses(articles) + func save(_ objects: [DatabaseObject], in database: FMDatabase) { + + // TODO } + + + + +// func markArticles(_ articles: Set
, statusKey: String, flag: Bool) { +// +// // Main thread. +// +// assertNoMissingStatuses(articles) +// let statuses = Set(articles.flatMap { $0.status }) +// markArticleStatuses(statuses, statusKey: statusKey, flag: flag) +// } + +// func attachStatuses(_ articles: Set
, _ database: FMDatabase) { +// +// // Look in cache first. +// attachCachedStatuses(articles) +// let articlesNeedingStatuses = articlesMissingStatuses(articles) +// if articlesNeedingStatuses.isEmpty { +// return +// } +// +// // Fetch from database. +// fetchAndCacheStatusesForArticles(articlesNeedingStatuses, database) +// attachCachedStatuses(articlesNeedingStatuses) +// +// // Create new statuses, and cache and save them in the database. +// // It shouldn’t happen that an Article in the database has no corresponding ArticleStatus, +// // but the case should be handled anyway. +// +// let articlesNeedingStatusesCreated = articlesMissingStatuses(articlesNeedingStatuses) +// if articlesNeedingStatusesCreated.isEmpty { +// return +// } +// createAndSaveStatusesForArticles(articlesNeedingStatusesCreated, database) +// +// assertNoMissingStatuses(articles) +// } // func ensureStatusesForParsedArticles(_ parsedArticles: [ParsedItem], _ callback: @escaping RSVoidCompletionBlock) { @@ -95,128 +114,144 @@ final class StatusesTable: DatabaseTable { private extension StatusesTable { - func attachCachedStatuses(_ articles: Set
) { - - articles.forEach { (oneArticle) in - - if let cachedStatus = cache[oneArticle.databaseID] { - oneArticle.status = cachedStatus - } - } - } - - func assertNoMissingStatuses(_ articles: Set
) { - - for oneArticle in articles { - if oneArticle.status == nil { - assertionFailure("All articles must have a status at this point.") - return - } - } - } - // MARK: Fetching - - func fetchAndCacheStatusesForArticles(_ articles: Set
, _ database: FMDatabase) { - - fetchAndCacheStatusesForArticleIDs(articles.articleIDs(), database) - } - - func fetchAndCacheStatusesForArticleIDs(_ articleIDs: Set, _ database: FMDatabase) { - - if let statuses = fetchStatusesForArticleIDs(articleIDs, database) { - cache.addObjectsNotCached(Array(statuses)) - } - } - - func fetchStatusesForArticleIDs(_ articleIDs: Set, _ database: FMDatabase) -> Set? { - - guard let resultSet = selectRowsWhere(key: DatabaseKey.articleID, inValues: Array(articleIDs), in: database) else { - return nil - } - return articleStatusesWithResultSet(resultSet) - } - - func articleStatusesWithResultSet(_ resultSet: FMResultSet) -> Set { - - return resultSet.mapToSet(articleStatusWithRow) - } - - func articleStatusWithRow(_ row: FMResultSet) -> ArticleStatus? { + + func statusWithRow(_ row: FMResultSet) -> ArticleStatus? { guard let articleID = row.string(forColumn: DatabaseKey.articleID) else { return nil } - if let cachedStatus = cache[articleID] { + if let cachedStatus = cache[articleID] as? ArticleStatus { return cachedStatus } + let status = ArticleStatus(articleID: articleID, row: row) cache[articleID] = status return status } + +// func attachCachedStatuses(_ articles: Set
) { +// +// articles.forEach { (oneArticle) in +// +// if let cachedStatus = cache[oneArticle.databaseID] { +// oneArticle.status = cachedStatus +// } +// } +// } + +// func assertNoMissingStatuses(_ articles: Set
) { +// +// for oneArticle in articles { +// if oneArticle.status == nil { +// assertionFailure("All articles must have a status at this point.") +// return +// } +// } +// } + + // MARK: Fetching + +// func fetchAndCacheStatusesForArticles(_ articles: Set
, _ database: FMDatabase) { +// +// fetchAndCacheStatusesForArticleIDs(articles.articleIDs(), database) +// } +// +// func fetchAndCacheStatusesForArticleIDs(_ articleIDs: Set, _ database: FMDatabase) { +// +// if let statuses = fetchStatusesForArticleIDs(articleIDs, database) { +// cache.addObjectsNotCached(Array(statuses)) +// } +// } +// +// func fetchStatusesForArticleIDs(_ articleIDs: Set, _ database: FMDatabase) -> Set? { +// +// guard let resultSet = selectRowsWhere(key: DatabaseKey.articleID, inValues: Array(articleIDs), in: database) else { +// return nil +// } +// return articleStatusesWithResultSet(resultSet) +// } +// +// func articleStatusesWithResultSet(_ resultSet: FMResultSet) -> Set { +// +// return resultSet.mapToSet(articleStatusWithRow) +// } +// +// func articleStatusWithRow(_ row: FMResultSet) -> ArticleStatus? { +// +// guard let articleID = row.string(forColumn: DatabaseKey.articleID) else { +// return nil +// } +// if let cachedStatus = cache[articleID] { +// return cachedStatus +// } +// let status = ArticleStatus(articleID: articleID, row: row) +// cache[articleID] = status +// return status +// } // MARK: Updating - func markArticleStatuses(_ statuses: Set, statusKey: String, flag: Bool) { +// func markArticleStatuses(_ statuses: Set, statusKey: String, flag: Bool) { +// +// // Ignore the statuses where status.[statusKey] == flag. Update the remainder and save in database. +// +// var articleIDsToUpdate = Set() +// +// 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) +// } +// } - // Ignore the statuses where status.[statusKey] == flag. Update the remainder and save in database. - - var articleIDsToUpdate = Set() - - 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, statusKey: String, flag: Bool) { - - updateRowsWithValue(NSNumber(value: flag), valueKey: statusKey, whereKey: DatabaseKey.articleID, matches: Array(articleIDs)) - } +// private func updateArticleStatusesInDatabase(_ articleIDs: Set, statusKey: String, flag: Bool) { +// +// updateRowsWithValue(NSNumber(value: flag), valueKey: statusKey, whereKey: DatabaseKey.articleID, matches: Array(articleIDs)) +// } // MARK: Creating - func saveStatuses(_ statuses: Set, _ database: FMDatabase) { - - let statusArray = statuses.map { $0.databaseDictionary() } - insertRows(statusArray, insertType: .orIgnore, in: database) - } - - func createAndSaveStatusesForArticles(_ articles: Set
, _ database: FMDatabase) { - - let articleIDs = Set(articles.map { $0.databaseID }) - createAndSaveStatusesForArticleIDs(articleIDs, database) - } - - func createAndSaveStatusesForArticleIDs(_ articleIDs: Set, _ database: FMDatabase) { - - let now = Date() - let statuses = articleIDs.map { ArticleStatus(articleID: $0, dateArrived: now) } - cache.addObjectsNotCached(statuses) - - saveStatuses(Set(statuses), database) - } +// func saveStatuses(_ statuses: Set, _ database: FMDatabase) { +// +// let statusArray = statuses.map { $0.databaseDictionary() } +// insertRows(statusArray, insertType: .orIgnore, in: database) +// } +// +// func createAndSaveStatusesForArticles(_ articles: Set
, _ database: FMDatabase) { +// +// let articleIDs = Set(articles.map { $0.databaseID }) +// createAndSaveStatusesForArticleIDs(articleIDs, database) +// } +// +// func createAndSaveStatusesForArticleIDs(_ articleIDs: Set, _ database: FMDatabase) { +// +// let now = Date() +// let statuses = articleIDs.map { ArticleStatus(articleID: $0, dateArrived: now) } +// cache.addObjectsNotCached(statuses) +// +// saveStatuses(Set(statuses), database) +// } // MARK: Utilities - func articleIDsMissingCachedStatuses(_ articleIDs: Set) -> Set { - - return Set(articleIDs.filter { !cache.objectWithIDIsCached($0) }) - } - - func articlesMissingStatuses(_ articles: Set
) -> Set
{ - - return articles.withNilProperty(\Article.status) - } +// func articleIDsMissingCachedStatuses(_ articleIDs: Set) -> Set { +// +// return Set(articleIDs.filter { !cache.objectWithIDIsCached($0) }) +// } +// +// func articlesMissingStatuses(_ articles: Set
) -> Set
{ +// +// return articles.withNilProperty(\Article.status) +// } } //extension ParsedItem { diff --git a/Frameworks/RSDatabase/RSDatabase/DatabaseObjectCache.swift b/Frameworks/RSDatabase/RSDatabase/DatabaseObjectCache.swift index 06f695cda..596ba1a68 100644 --- a/Frameworks/RSDatabase/RSDatabase/DatabaseObjectCache.swift +++ b/Frameworks/RSDatabase/RSDatabase/DatabaseObjectCache.swift @@ -14,6 +14,10 @@ public final class DatabaseObjectCache { private var dictionary = [String: DatabaseObject]() + public init() { + // Compiler seems to want a public init method. + } + public func addObjects(_ objects: [DatabaseObject]) { objects.forEach { add($0) } diff --git a/ToDo.ooutline b/ToDo.ooutline index 0c83d3e5a..7ecc05bb7 100644 Binary files a/ToDo.ooutline and b/ToDo.ooutline differ