Clean up dangling module preferences (#999)

Erase on module removal, reference is otherwise lost forever.
This commit is contained in:
Davide 2024-12-10 20:33:35 +01:00 committed by GitHub
parent 16a59c6de1
commit ff88b3562d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 36 additions and 5 deletions

View File

@ -106,6 +106,13 @@ private final class CDModulePreferencesRepositoryV3: ModulePreferencesRepository
} }
} }
func erase() {
context.performAndWait {
entity.excludedEndpoints?.forEach(context.delete)
context.delete(entity)
}
}
func save() throws { func save() throws {
try context.performAndWait { try context.performAndWait {
guard context.hasChanges else { guard context.hasChanges else {

View File

@ -43,6 +43,9 @@ struct ProfileCoordinator: View {
@EnvironmentObject @EnvironmentObject
private var iapManager: IAPManager private var iapManager: IAPManager
@EnvironmentObject
private var preferencesManager: PreferencesManager
let profileManager: ProfileManager let profileManager: ProfileManager
let profileEditor: ProfileEditor let profileEditor: ProfileEditor
@ -133,7 +136,7 @@ private extension ProfileCoordinator {
// standard: always save, warn if purchase required // standard: always save, warn if purchase required
func onCommitEditingStandard() async throws { func onCommitEditingStandard() async throws {
let savedProfile = try await profileEditor.save(to: profileManager) let savedProfile = try await profileEditor.save(to: profileManager, preferencesManager: preferencesManager)
do { do {
try iapManager.verify(savedProfile) try iapManager.verify(savedProfile)
} catch AppError.ineligibleProfile(let requiredFeatures) { } catch AppError.ineligibleProfile(let requiredFeatures) {
@ -151,7 +154,7 @@ private extension ProfileCoordinator {
paywallReason = .init(requiredFeatures) paywallReason = .init(requiredFeatures)
return return
} }
try await profileEditor.save(to: profileManager) try await profileEditor.save(to: profileManager, preferencesManager: preferencesManager)
onDismiss() onDismiss()
} }

View File

@ -51,6 +51,10 @@ public final class ModulePreferences: ObservableObject, ModulePreferencesReposit
repository?.removeExcludedEndpoint(endpoint) repository?.removeExcludedEndpoint(endpoint)
} }
public func erase() {
repository?.erase()
}
public func save() throws { public func save() throws {
try repository?.save() try repository?.save()
} }

View File

@ -70,6 +70,9 @@ private final class DummyModulePreferencesRepository: ModulePreferencesRepositor
func removeExcludedEndpoint(_ endpoint: ExtendedEndpoint) { func removeExcludedEndpoint(_ endpoint: ExtendedEndpoint) {
} }
func erase() {
}
func save() throws { func save() throws {
} }
} }

View File

@ -34,5 +34,7 @@ public protocol ModulePreferencesRepository {
func removeExcludedEndpoint(_ endpoint: ExtendedEndpoint) func removeExcludedEndpoint(_ endpoint: ExtendedEndpoint)
func erase()
func save() throws func save() throws
} }

View File

@ -188,7 +188,6 @@ extension ProfileEditor {
// update local view // update local view
editableProfile.modules = profile.modulesBuilders() editableProfile.modules = profile.modulesBuilders()
removedModules.removeAll()
return profile return profile
} }
@ -204,10 +203,23 @@ extension ProfileEditor {
} }
@discardableResult @discardableResult
public func save(to profileManager: ProfileManager) async throws -> Profile { public func save(to profileManager: ProfileManager, preferencesManager: PreferencesManager) async throws -> Profile {
do { do {
let newProfile = try build() let newProfile = try build()
try await profileManager.save(newProfile, isLocal: true, remotelyShared: isShared) try await profileManager.save(newProfile, isLocal: true, remotelyShared: isShared)
removedModules.keys.forEach {
do {
pp_log(.App.profiles, .info, "Erase preferences for removed module \($0)")
let repository = try preferencesManager.preferencesRepository(forModuleWithId: $0)
repository.erase()
try repository.save()
} catch {
pp_log(.App.profiles, .error, "Unable to erase preferences for removed module \($0): \(error)")
}
}
removedModules.removeAll()
return newProfile return newProfile
} catch { } catch {
pp_log(.App.profiles, .fault, "Unable to save edited profile: \(error)") pp_log(.App.profiles, .fault, "Unable to save edited profile: \(error)")

View File

@ -251,7 +251,7 @@ extension ProfileEditorTests {
} }
.store(in: &subscriptions) .store(in: &subscriptions)
try await sut.save(to: manager) try await sut.save(to: manager, preferencesManager: PreferencesManager())
await fulfillment(of: [exp]) await fulfillment(of: [exp])
} }
} }