Quellcode durchsuchen

add batch delete for related entites without date property

polscm32 aka Marvout vor 1 Jahr
Ursprung
Commit
e80e72c240
2 geänderte Dateien mit 86 neuen und 1 gelöschten Zeilen
  1. 22 1
      FreeAPS/Sources/Application/FreeAPSApp.swift
  2. 64 0
      Model/CoreDataStack.swift

+ 22 - 1
FreeAPS/Sources/Application/FreeAPSApp.swift

@@ -105,10 +105,31 @@ import Swinject
     private func purgeOldNSManagedObjects() async throws {
         try await coreDataStack.batchDeleteOlderThan(GlucoseStored.self, dateKey: "date", days: 90)
         try await coreDataStack.batchDeleteOlderThan(PumpEventStored.self, dateKey: "timestamp", days: 90)
+        try await coreDataStack.batchDeleteOlderThan(
+            parentType: PumpEventStored.self,
+            childType: BolusStored.self,
+            dateKey: "timestamp",
+            days: 90,
+            relationshipKey: "pumpEvent"
+        )
+        try await coreDataStack.batchDeleteOlderThan(
+            parentType: PumpEventStored.self,
+            childType: TempBasalStored.self,
+            dateKey: "timestamp",
+            days: 90,
+            relationshipKey: "pumpEvent"
+        )
         try await coreDataStack.batchDeleteOlderThan(OrefDetermination.self, dateKey: "deliverAt", days: 90)
         try await coreDataStack.batchDeleteOlderThan(OpenAPS_Battery.self, dateKey: "date", days: 90)
         try await coreDataStack.batchDeleteOlderThan(CarbEntryStored.self, dateKey: "date", days: 90)
-        try await coreDataStack.batchDeleteOlderThan(Forecast.self, dateKey: "date", days: 90)
+        try await coreDataStack.batchDeleteOlderThan(Forecast.self, dateKey: "date", days: 2)
+        try await coreDataStack.batchDeleteOlderThan(
+            parentType: Forecast.self,
+            childType: ForecastValue.self,
+            dateKey: "date",
+            days: 2,
+            relationshipKey: "forecast"
+        )
         try await coreDataStack.batchDeleteOlderThan(OverrideStored.self, dateKey: "date", days: 3)
         try await coreDataStack.batchDeleteOlderThan(OverrideRunStored.self, dateKey: "startDate", days: 3)
 

+ 64 - 0
Model/CoreDataStack.swift

@@ -221,6 +221,70 @@ extension CoreDataStack {
             throw CoreDataError.batchDeleteError
         }
     }
+
+    func batchDeleteOlderThan<Parent: NSManagedObject, Child: NSManagedObject>(
+        parentType: Parent.Type,
+        childType: Child.Type,
+        dateKey: String,
+        days: Int,
+        relationshipKey: String // The key of the Child Entity that links to the parent Entity
+    ) async throws {
+        let taskContext = newTaskContext()
+        taskContext.name = "deleteContext"
+        taskContext.transactionAuthor = "batchDelete"
+
+        // Get the target date
+        let targetDate = Calendar.current.date(byAdding: .day, value: -days, to: Date())!
+
+        // Fetch Parent objects older than the target date
+        let fetchParentRequest = NSFetchRequest<NSManagedObjectID>(entityName: String(describing: parentType))
+        fetchParentRequest.predicate = NSPredicate(format: "%K < %@", dateKey, targetDate as NSDate)
+        fetchParentRequest.resultType = .managedObjectIDResultType
+
+        do {
+            let parentObjectIDs = try await taskContext.perform {
+                try taskContext.fetch(fetchParentRequest)
+            }
+
+            guard !parentObjectIDs.isEmpty else {
+                debugPrint("No \(parentType) objects found older than \(days) days.")
+                return
+            }
+
+            // Fetch Child objects related to the fetched Parent objects
+            let fetchChildRequest = NSFetchRequest<NSManagedObjectID>(entityName: String(describing: childType))
+            fetchChildRequest.predicate = NSPredicate(format: "ANY %K IN %@", relationshipKey, parentObjectIDs)
+            fetchChildRequest.resultType = .managedObjectIDResultType
+
+            let childObjectIDs = try await taskContext.perform {
+                try taskContext.fetch(fetchChildRequest)
+            }
+
+            guard !childObjectIDs.isEmpty else {
+                debugPrint("No \(childType) objects found related to \(parentType) objects older than \(days) days.")
+                return
+            }
+
+            // Execute the batch delete for Child objects
+            try await taskContext.perform {
+                let batchDeleteRequest = NSBatchDeleteRequest(objectIDs: childObjectIDs)
+                guard let fetchResult = try? taskContext.execute(batchDeleteRequest),
+                      let batchDeleteResult = fetchResult as? NSBatchDeleteResult,
+                      let success = batchDeleteResult.result as? Bool, success
+                else {
+                    debugPrint("Failed to execute batch delete request \(DebuggingIdentifiers.failed)")
+                    throw CoreDataError.batchDeleteError
+                }
+            }
+
+            debugPrint(
+                "Successfully deleted \(childType) data related to \(parentType) objects older than \(days) days. \(DebuggingIdentifiers.succeeded)"
+            )
+        } catch {
+            debugPrint("Failed to fetch or delete data: \(error.localizedDescription) \(DebuggingIdentifiers.failed)")
+            throw CoreDataError.batchDeleteError
+        }
+    }
 }
 
 // MARK: - Fetch Requests