Delete articles and statuses from feeds no longer subscribed-to. At startup. Fix #899.

This commit is contained in:
Brent Simmons 2019-10-24 22:28:26 -07:00
parent cd4135bf9a
commit 3354d5a569
4 changed files with 45 additions and 0 deletions

View File

@ -254,6 +254,7 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container,
pullObjectsFromDisk()
DispatchQueue.main.async {
self.database.cleanupDatabaseAtStartup(subscribedToFeedIDs: self.flattenedFeeds().feedIDs())
self.fetchAllUnreadCounts()
}

View File

@ -152,6 +152,15 @@ public final class ArticlesDatabase {
public func emptyCaches() {
articlesTable.emptyCaches()
}
// MARK: - Cleanup
// These are to be used only at startup. These are to prevent the database from growing forever.
/// Calls the various clean-up functions.
public func cleanupDatabaseAtStartup(subscribedToFeedIDs: Set<String>) {
articlesTable.deleteArticlesNotInSubscribedToFeedIDs(subscribedToFeedIDs)
}
}
// MARK: - Private

View File

@ -423,6 +423,31 @@ final class ArticlesTable: DatabaseTable {
self.databaseArticlesCache = [String: DatabaseArticle]()
}
}
// MARK: - Cleanup
/// Delete articles from feeds that are no longer in the current set of subscribed-to feeds.
/// This deletes from the articles and articleStatuses tables,
/// and, via a trigger, it also deletes from the search index.
func deleteArticlesNotInSubscribedToFeedIDs(_ feedIDs: Set<String>) {
if feedIDs.isEmpty {
return
}
queue.run { (database) in
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(feedIDs.count))!
let sql = "select articleID from articles where feedID not in \(placeholders);"
let parameters = Array(feedIDs) as [Any]
guard let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) else {
return
}
let articleIDs = resultSet.mapToSet{ $0.string(forColumn: DatabaseKey.articleID) }
if articleIDs.isEmpty {
return
}
self.removeArticles(articleIDs, database)
self.statusesTable.removeStatuses(articleIDs, database)
}
}
}
// MARK: - Private
@ -730,6 +755,10 @@ private extension ArticlesTable {
// Drop Articles that we can ignore.
return Set(articles.filter{ !statusIndicatesArticleIsIgnorable($0.status) })
}
func removeArticles(_ articleIDs: Set<String>, _ database: FMDatabase) {
deleteRowsWhere(key: DatabaseKey.articleID, equalsAnyValue: Array(articleIDs), in: database)
}
}
private extension Set where Element == ParsedItem {

View File

@ -134,6 +134,12 @@ final class StatusesTable: DatabaseTable {
return d
}
// MARK: - Cleanup
func removeStatuses(_ articleIDs: Set<String>, _ database: FMDatabase) {
deleteRowsWhere(key: DatabaseKey.articleID, equalsAnyValue: Array(articleIDs), in: database)
}
}
// MARK: - Private