Make progress on saving updated articles.
This commit is contained in:
parent
9ee20ee270
commit
f40b400dd5
@ -335,7 +335,7 @@ private extension ArticlesTable {
|
||||
|
||||
assert(Thread.isMainThread)
|
||||
|
||||
updateRelatedObjects(_ parsedItems: [String: ParsedItem], _ articles: [String: Article])
|
||||
// updateRelatedObjects(_ parsedItems: [String: ParsedItem], _ articles: [String: Article])
|
||||
|
||||
}
|
||||
|
||||
@ -391,80 +391,93 @@ private extension ArticlesTable {
|
||||
}
|
||||
}
|
||||
|
||||
func updateRelatedAttachments(_ parsedItems: [String: ParsedItem], _ articles: [String: Article]) {
|
||||
// MARK: Save New Articles
|
||||
|
||||
var articlesWithChanges = Set<Article>()
|
||||
func saveNewArticles(_ articles: Set<Article>, _ database: FMDatabase) {
|
||||
|
||||
for (articleID, parsedItem) in parsedItems {
|
||||
guard let article = articles[articleID] else {
|
||||
continue
|
||||
}
|
||||
if !parsedItemTagsMatchArticlesTag(parsedItem, article) {
|
||||
articlesChanges.insert(article)
|
||||
}
|
||||
}
|
||||
|
||||
if articlesWithChanges.isEmpty {
|
||||
return
|
||||
}
|
||||
queue.update { (database) in
|
||||
tagsLookupTable.saveRelatedObjects(for: articlesWithChanges.databaseObjects(), in: database)
|
||||
}
|
||||
saveRelatedObjectsForNewArticles(articles, database)
|
||||
|
||||
let databaseDictionaries = articles.map { $0.databaseDictionary() }
|
||||
insertRows(databaseDictionaries, insertType: .orReplace, in: database)
|
||||
}
|
||||
|
||||
func updateRelatedTags(_ parsedItems: [String: ParsedItem], _ articles: [String: Article]) {
|
||||
func saveRelatedObjectsForNewArticles(_ articles: Set<Article>, _ database: FMDatabase) {
|
||||
|
||||
var articlesWithChanges = Set<Article>()
|
||||
let databaseObjects = articles.databaseObjects()
|
||||
|
||||
for (articleID, parsedItem) in parsedItems {
|
||||
guard let article = articles[articleID] else {
|
||||
continue
|
||||
}
|
||||
if !parsedItemTagsMatchArticlesTag(parsedItem, article) {
|
||||
articlesChanges.insert(article)
|
||||
authorsLookupTable.saveRelatedObjects(for: databaseObjects, in: database)
|
||||
attachmentsLookupTable.saveRelatedObjects(for: databaseObjects, in: database)
|
||||
tagsLookupTable.saveRelatedObjects(for: databaseObjects, in: database)
|
||||
}
|
||||
|
||||
// MARK: Update Existing Articles
|
||||
|
||||
// TODO: use a keypath instead of separate functions. Fix code duplication.
|
||||
|
||||
func articlesWithTagChanges(_ updatedArticles: Set<Article>, _ fetchedArticles: [String: Article]) -> Set<Article> {
|
||||
|
||||
return updatedArticles.filter{ (updatedArticle) -> Bool in
|
||||
if let fetchedArticle = fetchedArticles[updatedArticle.articleID] {
|
||||
return updatedArticle.tags != fetchedArticles.tags
|
||||
}
|
||||
assertionFailure("Expected to find matching fetched article.");
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if articlesWithChanges.isEmpty {
|
||||
return
|
||||
func articlesWithAttachmentChanges(_ updatedArticles: Set<Article>, _ fetchedArticles: [String: Article]) -> Set<Article> {
|
||||
|
||||
return updatedArticles.filter{ (updatedArticle) -> Bool in
|
||||
if let fetchedArticle = fetchedArticles[updatedArticle.articleID] {
|
||||
return updatedArticle.attachments != fetchedArticles.attachments
|
||||
}
|
||||
assertionFailure("Expected to find matching fetched article.");
|
||||
return true
|
||||
}
|
||||
queue.update { (database) in
|
||||
}
|
||||
|
||||
func articlesWithAuthorChanges(_ updatedArticles: Set<Article>, _ fetchedArticles: [String: Article]) -> Set<Article> {
|
||||
|
||||
return updatedArticles.filter{ (updatedArticle) -> Bool in
|
||||
if let fetchedArticle = fetchedArticles[updatedArticle.articleID] {
|
||||
return updatedArticle.authors != fetchedArticles.authors
|
||||
}
|
||||
assertionFailure("Expected to find matching fetched article.");
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func updateRelatedTags(_ updatedArticles: Set<Article>, _ fetchedArticles: [String: Article], _ database: FMDatabase) {
|
||||
|
||||
let articlesWithChanges = articlesWithTagChanges(updatedArticles, fetchedArticles)
|
||||
if !articlesWithChanges.isEmpty {
|
||||
tagsLookupTable.saveRelatedObjects(for: articlesWithChanges.databaseObjects(), in: database)
|
||||
}
|
||||
}
|
||||
|
||||
func parsedItemTagsMatchArticlesTag(_ parsedItem: ParsedItem, _ article: Article) -> Bool {
|
||||
func updateRelatedAttachments(_ updatedArticles: Set<Article>, _ fetchedArticles: [String: Article], _ database: FMDatabase) {
|
||||
|
||||
let parsedItemTags = parsedItem.tags
|
||||
let articleTags = article.tags
|
||||
|
||||
if parsedItemTags == nil && articleTags == nil {
|
||||
return true
|
||||
let articlesWithChanges = articlesWithAttachmentChanges(updatedArticles, fetchedArticles)
|
||||
if !articlesWithChanges.isEmpty {
|
||||
attachmentsLookupTable.saveRelatedObjects(for: articlesWithChanges.databaseObjects(), in: database)
|
||||
}
|
||||
if parsedItemTags != nil && articleTags == nil {
|
||||
return false
|
||||
}
|
||||
if parsedItemTags == nil && articleTags != nil {
|
||||
return true
|
||||
}
|
||||
return Set(parsedItemTags!) == articleTags!
|
||||
}
|
||||
|
||||
func saveNewParsedItems(_ parsedItems: [String: ParsedItem], _ feed: Feed) {
|
||||
func updateRelatedAuthors(_ updatedArticles: Set<Article>, _ fetchedArticles: [String: Article], _ database: FMDatabase) {
|
||||
|
||||
// These parsedItems have no existing status or Article.
|
||||
|
||||
queue.update { (database) in
|
||||
|
||||
let articleIDs = Set(parsedItems.keys)
|
||||
self.statusesTable.ensureStatusesForArticleIDs(articleIDs, database)
|
||||
|
||||
let articles = self.articlesWithParsedItems(Set(parsedItems.values), feed)
|
||||
self.saveUncachedNewArticles(articles, database)
|
||||
let articlesWithChanges = articlesWithAuthorChanges(updatedArticles, fetchedArticles)
|
||||
if !articlesWithChanges.isEmpty {
|
||||
authorsLookupTable.saveRelatedObjects(for: articlesWithChanges.databaseObjects(), in: database)
|
||||
}
|
||||
}
|
||||
|
||||
func saveUpdatedArticles(_ updatedArticles: Set<Article>, _ fetchedArticles: [String: Article], _ database: FMDatabase) {
|
||||
|
||||
updateRelatedTags(updatedArticles, fetchedArticles, database)
|
||||
updateRelatedAttachments(updatedArticles, fetchedArticles, database)
|
||||
updatedRelatedAuthors(updatedArticles, fetchedArticles, database)
|
||||
}
|
||||
|
||||
func articlesWithParsedItems(_ parsedItems: Set<ParsedItem>, _ feed: Feed) -> Set<Article> {
|
||||
|
||||
// These Articles don’t get cached. Background-queue only.
|
||||
@ -474,31 +487,9 @@ private extension ArticlesTable {
|
||||
|
||||
func articleWithParsedItem(_ parsedItem: ParsedItem, _ feedID: String) -> Article? {
|
||||
|
||||
guard let account = account else {
|
||||
assertionFailure("account is unexpectedly nil.")
|
||||
return nil
|
||||
}
|
||||
|
||||
return Article(parsedItem: parsedItem, feedID: feedID, account: account)
|
||||
return Article(parsedItem: parsedItem, feedID: feedID, accountID: accountID)
|
||||
}
|
||||
|
||||
func saveUncachedNewArticles(_ articles: Set<Article>, _ database: FMDatabase) {
|
||||
|
||||
saveRelatedObjects(articles, database)
|
||||
|
||||
let databaseDictionaries = articles.map { $0.databaseDictionary() }
|
||||
insertRows(databaseDictionaries, insertType: .orIgnore, in: database)
|
||||
}
|
||||
|
||||
func saveRelatedObjects(_ articles: Set<Article>, _ database: FMDatabase) {
|
||||
|
||||
let databaseObjects = articles.databaseObjects()
|
||||
|
||||
authorsLookupTable.saveRelatedObjects(for: databaseObjects, in: database)
|
||||
attachmentsLookupTable.saveRelatedObjects(for: databaseObjects, in: database)
|
||||
tagsLookupTable.saveRelatedObjects(for: databaseObjects, in: database)
|
||||
}
|
||||
|
||||
func statusIndicatesArticleIsIgnorable(_ status: ArticleStatus) -> Bool {
|
||||
|
||||
// Ignorable articles: either userDeleted==1 or (not starred and arrival date > 4 months).
|
||||
|
@ -24,12 +24,9 @@ public final class Database {
|
||||
private let articlesTable: ArticlesTable
|
||||
private var articleArrivalCutoffDate = NSDate.rs_dateWithNumberOfDays(inThePast: 3 * 31)!
|
||||
private let minimumNumberOfArticles = 10
|
||||
private weak var delegate: AccountDelegate?
|
||||
private weak var account: Account?
|
||||
|
||||
public init(databaseFile: String, delegate: AccountDelegate, account: Account) {
|
||||
public init(databaseFile: String) {
|
||||
|
||||
self.delegate = delegate
|
||||
self.account = account
|
||||
self.databaseFile = databaseFile
|
||||
self.queue = RSDatabaseQueue(filepath: databaseFile, excludeFromBackup: false)
|
||||
|
@ -13,7 +13,7 @@ import RSParser
|
||||
|
||||
extension Article {
|
||||
|
||||
convenience init?(row: FMResultSet, authors: Set<Author>, attachments: Set<Attachment>, tags: Set<String>, accountID: String) {
|
||||
init?(row: FMResultSet, authors: Set<Author>, attachments: Set<Attachment>, tags: Set<String>, accountID: String) {
|
||||
|
||||
guard let feedID = row.string(forColumn: DatabaseKey.feedID) else {
|
||||
return nil
|
||||
@ -38,7 +38,7 @@ extension Article {
|
||||
self.init(account: account, articleID: articleID, 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)
|
||||
}
|
||||
|
||||
convenience init(parsedItem: ParsedItem, accountID: String, feedID: String) {
|
||||
init(parsedItem: ParsedItem, accountID: String, feedID: String) {
|
||||
|
||||
let authors = Author.authorsWithParsedAuthors(parsedItem.authors)
|
||||
let attachments = Attachment.attachmentsWithParsedAttachments(parsedItem.attachments)
|
||||
|
@ -34,7 +34,7 @@ extension Author {
|
||||
return nil
|
||||
}
|
||||
|
||||
let authors = parsedAuthors.flatMap { Author(parsedAuthor: $0) }
|
||||
let authors = Set(parsedAuthors.flatMap { Author(parsedAuthor: $0) })
|
||||
return authors.isEmpty ? nil : authors
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user