Implement updated retention policy.
This commit is contained in:
parent
d2812fa132
commit
b2b000dd2e
|
@ -146,7 +146,7 @@ public final class ArticlesDatabase {
|
|||
|
||||
/// Fetch all non-zero unread counts.
|
||||
public func fetchAllUnreadCounts(_ completion: @escaping UnreadCountDictionaryCompletionBlock) {
|
||||
let operation = FetchAllUnreadCountsOperation(databaseQueue: queue, cutoffDate: articlesTable.articleCutoffDate)
|
||||
let operation = FetchAllUnreadCountsOperation(databaseQueue: queue)
|
||||
operationQueue.cancelOperations(named: operation.name!)
|
||||
operation.completionBlock = { operation in
|
||||
let fetchOperation = operation as! FetchAllUnreadCountsOperation
|
||||
|
@ -167,7 +167,7 @@ public final class ArticlesDatabase {
|
|||
|
||||
/// Fetch non-zero unread counts for given webFeedIDs.
|
||||
public func fetchUnreadCounts(for webFeedIDs: Set<String>, _ completion: @escaping UnreadCountDictionaryCompletionBlock) {
|
||||
let operation = FetchUnreadCountsForFeedsOperation(webFeedIDs: webFeedIDs, databaseQueue: queue, cutoffDate: articlesTable.articleCutoffDate)
|
||||
let operation = FetchUnreadCountsForFeedsOperation(webFeedIDs: webFeedIDs, databaseQueue: queue)
|
||||
operation.completionBlock = { operation in
|
||||
let fetchOperation = operation as! FetchUnreadCountsForFeedsOperation
|
||||
completion(fetchOperation.result)
|
||||
|
@ -265,9 +265,11 @@ public final class ArticlesDatabase {
|
|||
|
||||
// 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.
|
||||
/// Calls the various clean-up functions. To be used only at startup.
|
||||
///
|
||||
/// This prevents the database from growing forever. If we didn’t do this:
|
||||
/// 1) The database would grow to an inordinate size, and
|
||||
/// 2) the app would become very slow.
|
||||
public func cleanupDatabaseAtStartup(subscribedToWebFeedIDs: Set<String>) {
|
||||
if retentionStyle == .syncSystem {
|
||||
articlesTable.deleteOldArticles()
|
||||
|
|
|
@ -181,7 +181,7 @@ final class ArticlesTable: DatabaseTable {
|
|||
|
||||
// 1. Ensure statuses for all the incoming articles.
|
||||
// 2. Create incoming articles with parsedItems.
|
||||
// 3. [Deleted - no longer needed]
|
||||
// 3. [Deleted - this step is no longer needed]
|
||||
// 4. Fetch all articles for the feed.
|
||||
// 5. Create array of Articles not in database and save them.
|
||||
// 6. Create array of updated Articles and save what’s changed.
|
||||
|
@ -494,6 +494,8 @@ final class ArticlesTable: DatabaseTable {
|
|||
/// we do this in a careful way: delete articles older than a year,
|
||||
/// check to see how much time has passed, then decide whether or not to continue.
|
||||
/// Repeat for successively more-recent dates.
|
||||
///
|
||||
/// Returns `true` if it deleted old articles all the way up to the 90 day cutoff date.
|
||||
func deleteOldArticles() {
|
||||
precondition(retentionStyle == .syncSystem)
|
||||
|
||||
|
@ -537,10 +539,10 @@ final class ArticlesTable: DatabaseTable {
|
|||
|
||||
switch self.retentionStyle {
|
||||
case .syncSystem:
|
||||
sql = "select articleID from statuses where dateArrived<? and read=1 and starred=0 and articleID not in (select articleID from articles);"
|
||||
sql = "delete from statuses where dateArrived<? and read=1 and starred=0 and articleID not in (select articleID from articles);"
|
||||
cutoffDate = Date().bySubtracting(days: 180)
|
||||
case .feedBased:
|
||||
sql = "select articleID from statuses where dateArrived<? and starred=0 and articleID not in (select articleID from articles);"
|
||||
sql = "delete from statuses where dateArrived<? and starred=0 and articleID not in (select articleID from articles);"
|
||||
cutoffDate = Date().bySubtracting(days: 30)
|
||||
}
|
||||
|
||||
|
@ -672,31 +674,11 @@ private extension ArticlesTable {
|
|||
return cachedArticles.union(articlesWithFetchedAuthors)
|
||||
}
|
||||
|
||||
func fetchArticlesWithWhereClause(_ database: FMDatabase, whereClause: String, parameters: [AnyObject], withLimits: Bool) -> Set<Article> {
|
||||
// Don’t fetch articles that shouldn’t appear in the UI. The rules:
|
||||
// * Must not be deleted.
|
||||
// * Must be either 1) starred or 2) dateArrived must be newer than cutoff date.
|
||||
|
||||
if withLimits {
|
||||
let sql = "select * from articles natural join statuses where \(whereClause) and (starred=1 or dateArrived>?);"
|
||||
return articlesWithSQL(sql, parameters + [articleCutoffDate as AnyObject], database)
|
||||
}
|
||||
else {
|
||||
let sql = "select * from articles natural join statuses where \(whereClause);"
|
||||
return articlesWithSQL(sql, parameters, database)
|
||||
}
|
||||
func fetchArticlesWithWhereClause(_ database: FMDatabase, whereClause: String, parameters: [AnyObject]) -> Set<Article> {
|
||||
let sql = "select * from articles natural join statuses where \(whereClause);"
|
||||
return articlesWithSQL(sql, parameters, database)
|
||||
}
|
||||
|
||||
// func fetchUnreadCount(_ webFeedID: String, _ database: FMDatabase) -> Int {
|
||||
// // Count only the articles that would appear in the UI.
|
||||
// // * Must be unread.
|
||||
// // * Must not be deleted.
|
||||
// // * Must be either 1) starred or 2) dateArrived must be newer than cutoff date.
|
||||
//
|
||||
// let sql = "select count(*) from articles natural join statuses where feedID=? and read=0 and (starred=1 or dateArrived>?);"
|
||||
// return numberWithSQLAndParameters(sql, [webFeedID, articleCutoffDate], in: database)
|
||||
// }
|
||||
|
||||
func fetchArticlesMatching(_ searchString: String, _ database: FMDatabase) -> Set<Article> {
|
||||
let sql = "select rowid from search where search match ?;"
|
||||
let sqlSearchString = sqliteSearchString(with: searchString)
|
||||
|
@ -712,7 +694,7 @@ private extension ArticlesTable {
|
|||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(searchRowIDs.count))!
|
||||
let whereClause = "searchRowID in \(placeholders)"
|
||||
let parameters: [AnyObject] = Array(searchRowIDs) as [AnyObject]
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters, withLimits: true)
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters)
|
||||
}
|
||||
|
||||
func sqliteSearchString(with searchString: String) -> String {
|
||||
|
@ -785,7 +767,7 @@ private extension ArticlesTable {
|
|||
let parameters = webFeedIDs.map { $0 as AnyObject }
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))!
|
||||
let whereClause = "feedID in \(placeholders)"
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters, withLimits: true)
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters)
|
||||
}
|
||||
|
||||
func fetchUnreadArticles(_ webFeedIDs: Set<String>, _ database: FMDatabase) -> Set<Article> {
|
||||
|
@ -796,11 +778,11 @@ private extension ArticlesTable {
|
|||
let parameters = webFeedIDs.map { $0 as AnyObject }
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))!
|
||||
let whereClause = "feedID in \(placeholders) and read=0"
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters, withLimits: true)
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters)
|
||||
}
|
||||
|
||||
func fetchArticlesForFeedID(_ webFeedID: String, withLimits: Bool, _ database: FMDatabase) -> Set<Article> {
|
||||
return fetchArticlesWithWhereClause(database, whereClause: "articles.feedID = ?", parameters: [webFeedID as AnyObject], withLimits: withLimits)
|
||||
return fetchArticlesWithWhereClause(database, whereClause: "articles.feedID = ?", parameters: [webFeedID as AnyObject])
|
||||
}
|
||||
|
||||
func fetchArticles(articleIDs: Set<String>, _ database: FMDatabase) -> Set<Article> {
|
||||
|
@ -810,7 +792,7 @@ private extension ArticlesTable {
|
|||
let parameters = articleIDs.map { $0 as AnyObject }
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(articleIDs.count))!
|
||||
let whereClause = "articleID in \(placeholders)"
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters, withLimits: false)
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters)
|
||||
}
|
||||
|
||||
func fetchArticlesSince(_ webFeedIDs: Set<String>, _ cutoffDate: Date, _ database: FMDatabase) -> Set<Article> {
|
||||
|
@ -823,7 +805,7 @@ private extension ArticlesTable {
|
|||
let parameters = webFeedIDs.map { $0 as AnyObject } + [cutoffDate as AnyObject, cutoffDate as AnyObject]
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))!
|
||||
let whereClause = "feedID in \(placeholders) and (datePublished > ? or (datePublished is null and dateArrived > ?))"
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters, withLimits: false)
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters)
|
||||
}
|
||||
|
||||
func fetchStarredArticles(_ webFeedIDs: Set<String>, _ database: FMDatabase) -> Set<Article> {
|
||||
|
@ -834,7 +816,7 @@ private extension ArticlesTable {
|
|||
let parameters = webFeedIDs.map { $0 as AnyObject }
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))!
|
||||
let whereClause = "feedID in \(placeholders) and starred=1"
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters, withLimits: false)
|
||||
return fetchArticlesWithWhereClause(database, whereClause: whereClause, parameters: parameters)
|
||||
}
|
||||
|
||||
func fetchArticlesMatching(_ searchString: String, _ webFeedIDs: Set<String>, _ database: FMDatabase) -> Set<Article> {
|
||||
|
|
|
@ -22,11 +22,9 @@ public final class FetchAllUnreadCountsOperation: MainThreadOperation {
|
|||
public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock?
|
||||
|
||||
private let queue: DatabaseQueue
|
||||
private let cutoffDate: Date
|
||||
|
||||
init(databaseQueue: DatabaseQueue, cutoffDate: Date) {
|
||||
init(databaseQueue: DatabaseQueue) {
|
||||
self.queue = databaseQueue
|
||||
self.cutoffDate = cutoffDate
|
||||
}
|
||||
|
||||
public func run() {
|
||||
|
@ -49,9 +47,9 @@ public final class FetchAllUnreadCountsOperation: MainThreadOperation {
|
|||
private extension FetchAllUnreadCountsOperation {
|
||||
|
||||
func fetchUnreadCounts(_ database: FMDatabase) {
|
||||
let sql = "select distinct feedID, count(*) from articles natural join statuses where read=0 and (starred=1 or dateArrived>?) group by feedID;"
|
||||
let sql = "select distinct feedID, count(*) from articles natural join statuses where read=0 group by feedID;"
|
||||
|
||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: [cutoffDate]) else {
|
||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: nil) else {
|
||||
informOperationDelegateOfCompletion()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -52,9 +52,9 @@ public final class FetchFeedUnreadCountOperation: MainThreadOperation {
|
|||
private extension FetchFeedUnreadCountOperation {
|
||||
|
||||
func fetchUnreadCount(_ database: FMDatabase) {
|
||||
let sql = "select count(*) from articles natural join statuses where feedID=? and read=0 and (starred=1 or dateArrived>?);"
|
||||
let sql = "select count(*) from articles natural join statuses where feedID=? and read=0;"
|
||||
|
||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: [webFeedID, cutoffDate]) else {
|
||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: [webFeedID]) else {
|
||||
informOperationDelegateOfCompletion()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -23,13 +23,11 @@ public final class FetchUnreadCountsForFeedsOperation: MainThreadOperation {
|
|||
public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock?
|
||||
|
||||
private let queue: DatabaseQueue
|
||||
private let cutoffDate: Date
|
||||
private let webFeedIDs: Set<String>
|
||||
|
||||
init(webFeedIDs: Set<String>, databaseQueue: DatabaseQueue, cutoffDate: Date) {
|
||||
init(webFeedIDs: Set<String>, databaseQueue: DatabaseQueue) {
|
||||
self.webFeedIDs = webFeedIDs
|
||||
self.queue = databaseQueue
|
||||
self.cutoffDate = cutoffDate
|
||||
}
|
||||
|
||||
public func run() {
|
||||
|
@ -53,11 +51,9 @@ private extension FetchUnreadCountsForFeedsOperation {
|
|||
|
||||
func fetchUnreadCounts(_ database: FMDatabase) {
|
||||
let placeholders = NSString.rs_SQLValueList(withPlaceholders: UInt(webFeedIDs.count))!
|
||||
let sql = "select distinct feedID, count(*) from articles natural join statuses where feedID in \(placeholders) and read=0 and (starred=1 or dateArrived>?) group by feedID;"
|
||||
let sql = "select distinct feedID, count(*) from articles natural join statuses where feedID in \(placeholders) and read=0 group by feedID;"
|
||||
|
||||
var parameters = [Any]()
|
||||
parameters += Array(webFeedIDs) as [Any]
|
||||
parameters += [cutoffDate] as [Any]
|
||||
let parameters = Array(webFeedIDs) as [Any]
|
||||
|
||||
guard let resultSet = database.executeQuery(sql, withArgumentsIn: parameters) else {
|
||||
informOperationDelegateOfCompletion()
|
||||
|
|
Loading…
Reference in New Issue