Deduplicate preferences by last update (#991)

Fixes #990
This commit is contained in:
Davide 2024-12-09 09:13:16 +01:00 committed by GitHub
parent 93a15cd766
commit a642b27d2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 32 additions and 2 deletions

View File

@ -33,5 +33,6 @@ final class CDModulePreferencesV3: NSManagedObject {
} }
@NSManaged var uuid: UUID? @NSManaged var uuid: UUID?
@NSManaged var lastUpdate: Date?
@NSManaged var excludedEndpoints: Set<CDExcludedEndpoint>? @NSManaged var excludedEndpoints: Set<CDExcludedEndpoint>?
} }

View File

@ -33,6 +33,7 @@ final class CDProviderPreferencesV3: NSManagedObject {
} }
@NSManaged var providerId: String? @NSManaged var providerId: String?
@NSManaged var lastUpdate: Date?
@NSManaged var favoriteServerIds: Data? @NSManaged var favoriteServerIds: Data?
@NSManaged var excludedEndpoints: Set<CDExcludedEndpoint>? @NSManaged var excludedEndpoints: Set<CDExcludedEndpoint>?
} }

View File

@ -6,11 +6,13 @@
<relationship name="providerPreferences" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="CDProviderPreferencesV3" inverseName="excludedEndpoints" inverseEntity="CDProviderPreferencesV3"/> <relationship name="providerPreferences" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="CDProviderPreferencesV3" inverseName="excludedEndpoints" inverseEntity="CDProviderPreferencesV3"/>
</entity> </entity>
<entity name="CDModulePreferencesV3" representedClassName="CDModulePreferencesV3" syncable="YES"> <entity name="CDModulePreferencesV3" representedClassName="CDModulePreferencesV3" syncable="YES">
<attribute name="lastUpdate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="uuid" optional="YES" attributeType="UUID" usesScalarValueType="NO"/> <attribute name="uuid" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
<relationship name="excludedEndpoints" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="CDExcludedEndpoint" inverseName="modulePreferences" inverseEntity="CDExcludedEndpoint"/> <relationship name="excludedEndpoints" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="CDExcludedEndpoint" inverseName="modulePreferences" inverseEntity="CDExcludedEndpoint"/>
</entity> </entity>
<entity name="CDProviderPreferencesV3" representedClassName="CDProviderPreferencesV3" syncable="YES"> <entity name="CDProviderPreferencesV3" representedClassName="CDProviderPreferencesV3" syncable="YES">
<attribute name="favoriteServerIds" optional="YES" attributeType="Binary"/> <attribute name="favoriteServerIds" optional="YES" attributeType="Binary"/>
<attribute name="lastUpdate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="providerId" optional="YES" attributeType="String"/> <attribute name="providerId" optional="YES" attributeType="String"/>
<relationship name="excludedEndpoints" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="CDExcludedEndpoint" inverseName="providerPreferences" inverseEntity="CDExcludedEndpoint"/> <relationship name="excludedEndpoints" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="CDExcludedEndpoint" inverseName="providerPreferences" inverseEntity="CDExcludedEndpoint"/>
</entity> </entity>

View File

@ -46,9 +46,22 @@ private final class CDModulePreferencesRepositoryV3: ModulePreferencesRepository
entity = try context.performAndWait { entity = try context.performAndWait {
let request = CDModulePreferencesV3.fetchRequest() let request = CDModulePreferencesV3.fetchRequest()
request.predicate = NSPredicate(format: "uuid == %@", moduleId.uuidString) request.predicate = NSPredicate(format: "uuid == %@", moduleId.uuidString)
request.sortDescriptors = [.init(key: "lastUpdate", ascending: false)]
do { do {
let entity = try request.execute().first ?? CDModulePreferencesV3(context: context) let entities = try request.execute()
// dedup by lastUpdate
entities.enumerated().forEach {
guard $0.offset > 0 else {
return
}
$0.element.excludedEndpoints?.forEach(context.delete(_:))
context.delete($0.element)
}
let entity = entities.first ?? CDModulePreferencesV3(context: context)
entity.uuid = moduleId entity.uuid = moduleId
entity.lastUpdate = Date()
return entity return entity
} catch { } catch {
pp_log(.app, .error, "Unable to load preferences for module \(moduleId): \(error)") pp_log(.app, .error, "Unable to load preferences for module \(moduleId): \(error)")

View File

@ -46,9 +46,22 @@ private final class CDProviderPreferencesRepositoryV3: ProviderPreferencesReposi
entity = try context.performAndWait { entity = try context.performAndWait {
let request = CDProviderPreferencesV3.fetchRequest() let request = CDProviderPreferencesV3.fetchRequest()
request.predicate = NSPredicate(format: "providerId == %@", providerId.rawValue) request.predicate = NSPredicate(format: "providerId == %@", providerId.rawValue)
request.sortDescriptors = [.init(key: "lastUpdate", ascending: false)]
do { do {
let entity = try request.execute().first ?? CDProviderPreferencesV3(context: context) let entities = try request.execute()
// dedup by lastUpdate
entities.enumerated().forEach {
guard $0.offset > 0 else {
return
}
$0.element.excludedEndpoints?.forEach(context.delete(_:))
context.delete($0.element)
}
let entity = entities.first ?? CDProviderPreferencesV3(context: context)
entity.providerId = providerId.rawValue entity.providerId = providerId.rawValue
entity.lastUpdate = Date()
return entity return entity
} catch { } catch {
pp_log(.app, .error, "Unable to load preferences for provider \(providerId): \(error)") pp_log(.app, .error, "Unable to load preferences for provider \(providerId): \(error)")