From 75d2158163a5eb6be74d109d9ef316c7fa53805a Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 19 Apr 2020 14:10:12 -0700 Subject: [PATCH] =?UTF-8?q?Perform=20a=20one-time=20(per=20local=20account?= =?UTF-8?q?)=20cleanup=20made=20necessary=20by=20the=20retention=20policy?= =?UTF-8?q?=20change=20=E2=80=94=C2=A0mark=20articles=20older=20than=20the?= =?UTF-8?q?=2090-day=20window=20as=20read.=20This=20way=20users=20won?= =?UTF-8?q?=E2=80=99t=20get=20a=20flood=20of=20old,=20unread=20articles=20?= =?UTF-8?q?when=20they=20run=20this=20new=20version.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frameworks/Account/Account.swift | 12 ++++++++++++ Frameworks/Account/AccountMetadata.swift | 9 +++++++++ .../ArticlesDatabase/ArticlesDatabase.swift | 18 ++++++++++++++++++ .../ArticlesDatabase/ArticlesTable.swift | 16 ++++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/Frameworks/Account/Account.swift b/Frameworks/Account/Account.swift index 812ad9693..9824386d4 100644 --- a/Frameworks/Account/Account.swift +++ b/Frameworks/Account/Account.swift @@ -279,7 +279,19 @@ public final class Account: DisplayNameProvider, UnreadCountProvider, Container, webFeedMetadataFile.load() opmlFile.load() + var shouldHandleRetentionPolicyChange = false + if type == .onMyMac { + let didHandlePolicyChange = metadata.performedApril2020RetentionPolicyChange ?? false + shouldHandleRetentionPolicyChange = !didHandlePolicyChange + } + DispatchQueue.main.async { + if shouldHandleRetentionPolicyChange { + // Handle one-time database changes made necessary by April 2020 retention policy change. + self.database.performApril2020RetentionPolicyChange() + self.metadata.performedApril2020RetentionPolicyChange = true + } + self.database.cleanupDatabaseAtStartup(subscribedToWebFeedIDs: self.flattenedWebFeeds().webFeedIDs()) self.fetchAllUnreadCounts() } diff --git a/Frameworks/Account/AccountMetadata.swift b/Frameworks/Account/AccountMetadata.swift index f4c50ab44..9f5845a64 100644 --- a/Frameworks/Account/AccountMetadata.swift +++ b/Frameworks/Account/AccountMetadata.swift @@ -24,6 +24,7 @@ final class AccountMetadata: Codable { case lastArticleFetchEndTime case endpointURL case lastCredentialRenewTime = "lastCredentialRenewTime" + case performedApril2020RetentionPolicyChange } var name: String? { @@ -92,6 +93,14 @@ final class AccountMetadata: Codable { } } + var performedApril2020RetentionPolicyChange: Bool? { + didSet { + if performedApril2020RetentionPolicyChange != oldValue { + valueDidChange(.performedApril2020RetentionPolicyChange) + } + } + } + weak var delegate: AccountMetadataDelegate? func valueDidChange(_ key: CodingKeys) { diff --git a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift index d0f3c424c..0ee215866 100644 --- a/Frameworks/ArticlesDatabase/ArticlesDatabase.swift +++ b/Frameworks/ArticlesDatabase/ArticlesDatabase.swift @@ -277,6 +277,24 @@ public final class ArticlesDatabase { articlesTable.deleteArticlesNotInSubscribedToFeedIDs(subscribedToWebFeedIDs) articlesTable.deleteOldStatuses() } + + /// Do database cleanups made necessary by the retention policy change in April 2020. + /// + /// The retention policy for feed-based systems changed in April 2020: + /// we keep articles only for as long as they’re in the feed. + /// This change could result in a bunch of older articles suddenly + /// appearing as unread articles. + /// + /// These are articles that were in the database, + /// but weren’t appearing in the UI because they were beyond the 90-day window. + /// (The previous retention policy used a 90-day window.) + /// + /// This function marks everything as read that’s beyond that 90-day window. + /// It’s intended to be called only once on an account. + public func performApril2020RetentionPolicyChange() { + precondition(retentionStyle == .feedBased) + articlesTable.markOlderStatusesAsRead() + } } // MARK: - Private diff --git a/Frameworks/ArticlesDatabase/ArticlesTable.swift b/Frameworks/ArticlesDatabase/ArticlesTable.swift index 635d1d9b3..ff36a8f9b 100644 --- a/Frameworks/ArticlesDatabase/ArticlesTable.swift +++ b/Frameworks/ArticlesDatabase/ArticlesTable.swift @@ -580,6 +580,22 @@ final class ArticlesTable: DatabaseTable { } } } + + /// Mark statuses beyond the 90-day window as read. + /// + /// This is not intended for wide use: this is part of implementing + /// the April 2020 retention policy change for feed-based accounts. + func markOlderStatusesAsRead() { + queue.runInDatabase { databaseResult in + guard let database = databaseResult.database else { + return + } + + let sql = "update statuses set read = true where dateArrived