From e8dd101af1e2b0bd6abf0c1fb390ca407f2d048e Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 4 Apr 2025 09:29:36 +0200 Subject: [PATCH] Fix issue with additive loading and inMemory collections --- LeStorage/BaseCollection.swift | 24 ++++++++++++---------- LeStorage/SyncedCollection.swift | 6 +++--- LeStorage/Utils/Collection+Extension.swift | 4 ++++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/LeStorage/BaseCollection.swift b/LeStorage/BaseCollection.swift index 5e550f9..355b724 100644 --- a/LeStorage/BaseCollection.swift +++ b/LeStorage/BaseCollection.swift @@ -150,12 +150,14 @@ public class BaseCollection: SomeCollection, CollectionHolder { guard let manager = self._pendingOperationManager, manager.items.isNotEmpty else { return } Logger.log(">>> Merge pending: \(manager.items.count)") - for operation in manager.items { - switch operation.method { + let methodGroups = manager.items.group { $0.method } + for (method, group) in methodGroups { + let dataArray = group.map { $0.data } + switch method { case .addOrUpdate: - self.addOrUpdate(instance: operation.data) + self.addOrUpdate(contentOfs: dataArray) case .delete: - self.delete(instance: operation.data) + self.delete(contentOfs: dataArray) } } self._pendingOperationManager = nil @@ -243,16 +245,16 @@ public class BaseCollection: SomeCollection, CollectionHolder { } /// Adds a sequence of objects inside the collection and performs a write - func addSequence(_ sequence: any Sequence) { + func addSequence(_ sequence: any Sequence, checkLoaded: Bool = true) { defer { self._hasChanged = true } for instance in sequence { if let index = self.items.firstIndex(where: { $0.id == instance.id }) { - self.updateItem(instance, index: index) + self.updateItem(instance, index: index, checkLoaded: checkLoaded) } else { // insert - self.addItem(instance: instance) + self.addItem(instance: instance, checkLoaded: checkLoaded) } } @@ -270,9 +272,9 @@ public class BaseCollection: SomeCollection, CollectionHolder { } /// Adds an instance to the collection - @discardableResult func addItem(instance: T) -> Bool { + @discardableResult func addItem(instance: T, checkLoaded: Bool = true) -> Bool { - if !self.hasLoaded { + if checkLoaded && !self.hasLoaded { self._addPendingOperation(method: .addOrUpdate, instance: instance) return false } @@ -286,9 +288,9 @@ public class BaseCollection: SomeCollection, CollectionHolder { } /// Updates an instance to the collection by index - @discardableResult func updateItem(_ instance: T, index: Int) -> Bool { + @discardableResult func updateItem(_ instance: T, index: Int, checkLoaded: Bool = true) -> Bool { - if !self.hasLoaded { + if checkLoaded && !self.hasLoaded { self._addPendingOperation(method: .addOrUpdate, instance: instance) return false } diff --git a/LeStorage/SyncedCollection.swift b/LeStorage/SyncedCollection.swift index fbe2e0a..e4bbc22 100644 --- a/LeStorage/SyncedCollection.swift +++ b/LeStorage/SyncedCollection.swift @@ -78,7 +78,7 @@ public class SyncedCollection: BaseCollection, SomeSynced if clear { self.setItems(items) } else { - self.addOrUpdateNoSync(contentOfs: items) + self.addOrUpdateNoSync(contentOfs: items, checkLoaded: false) } self.setAsLoaded() @@ -188,8 +188,8 @@ public class SyncedCollection: BaseCollection, SomeSynced } /// Adds or update a sequence of elements without synchronizing it - func addOrUpdateNoSync(contentOfs sequence: any Sequence) { - self.addSequence(sequence) + func addOrUpdateNoSync(contentOfs sequence: any Sequence, checkLoaded: Bool = false) { + self.addSequence(sequence, checkLoaded: false) } /// Deletes the instance in the collection without synchronization diff --git a/LeStorage/Utils/Collection+Extension.swift b/LeStorage/Utils/Collection+Extension.swift index b9c4277..a45fee9 100644 --- a/LeStorage/Utils/Collection+Extension.swift +++ b/LeStorage/Utils/Collection+Extension.swift @@ -25,6 +25,10 @@ extension Array { } } + func group(handler: (Element) -> T) -> [T : [Element]] { + return Dictionary(grouping: self, by: { handler($0) }) + } + } extension RandomAccessCollection {