|
|
|
|
@ -212,7 +212,7 @@ public class StoredCollection<T: Storable>: SomeCollection { |
|
|
|
|
|
|
|
|
|
/// Sets a collection of items and indexes them |
|
|
|
|
func setItems(_ items: [T]) { |
|
|
|
|
self.items.removeAll() |
|
|
|
|
self.clear() |
|
|
|
|
for item in items { |
|
|
|
|
self._addItem(instance: item) |
|
|
|
|
} |
|
|
|
|
@ -277,7 +277,7 @@ public class StoredCollection<T: Storable>: SomeCollection { |
|
|
|
|
defer { |
|
|
|
|
self.requestWriteIfNecessary() |
|
|
|
|
} |
|
|
|
|
self.items.removeAll() |
|
|
|
|
self.clear() |
|
|
|
|
self._addItem(instance: instance) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -333,6 +333,7 @@ public class StoredCollection<T: Storable>: SomeCollection { |
|
|
|
|
self.addPendingOperation(method: .add, instance: instance, actionOption: actionOption) |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
self.invalidateCache() |
|
|
|
|
|
|
|
|
|
self._affectStoreIdIfNecessary(instance: instance) |
|
|
|
|
self.items.append(instance) |
|
|
|
|
@ -359,6 +360,7 @@ public class StoredCollection<T: Storable>: SomeCollection { |
|
|
|
|
self.addPendingOperation(method: .update, instance: instance, actionOption: actionOption) |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
self.invalidateCache() |
|
|
|
|
|
|
|
|
|
let item = self.items[index] |
|
|
|
|
if item !== instance { |
|
|
|
|
@ -408,6 +410,7 @@ public class StoredCollection<T: Storable>: SomeCollection { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func localDeleteOnly(instance: T) { |
|
|
|
|
self.invalidateCache() |
|
|
|
|
self.items.removeAll { $0.id == instance.id } |
|
|
|
|
self._indexes?.removeValue(forKey: instance.id) |
|
|
|
|
} |
|
|
|
|
@ -437,12 +440,12 @@ public class StoredCollection<T: Storable>: SomeCollection { |
|
|
|
|
return self.items.first(where: { $0.id == id }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Proceeds to "hard" delete the items without synchronizing them |
|
|
|
|
/// Also removes related API calls |
|
|
|
|
/// Deletes a list of items |
|
|
|
|
public func deleteDependencies(_ items: any Sequence<T>) { |
|
|
|
|
defer { |
|
|
|
|
self.requestWriteIfNecessary() |
|
|
|
|
} |
|
|
|
|
self.invalidateCache() |
|
|
|
|
let itemsArray = Array(items) // fix error if items is self.items |
|
|
|
|
for item in itemsArray { |
|
|
|
|
if let index = self.items.firstIndex(where: { $0.id == item.id }) { |
|
|
|
|
@ -534,12 +537,13 @@ public class StoredCollection<T: Storable>: SomeCollection { |
|
|
|
|
|
|
|
|
|
/// Simply clears the items of the collection |
|
|
|
|
public func clear() { |
|
|
|
|
self.invalidateCache() |
|
|
|
|
self.items.removeAll() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Removes the items of the collection and deletes the corresponding file |
|
|
|
|
public func reset() { |
|
|
|
|
self.items.removeAll() |
|
|
|
|
self.clear() |
|
|
|
|
self.store.removeFile(type: T.self) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -572,6 +576,31 @@ public class StoredCollection<T: Storable>: SomeCollection { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// MARK: - Cached queries |
|
|
|
|
|
|
|
|
|
fileprivate var _cacheVersion = 0 |
|
|
|
|
fileprivate var _queryCache: [AnyHashable: (version: Int, result: Any)] = [:] |
|
|
|
|
|
|
|
|
|
// Generic query method with caching |
|
|
|
|
public func cached<Result>( |
|
|
|
|
key: AnyHashable, |
|
|
|
|
compute: ([T]) -> Result |
|
|
|
|
) -> Result { |
|
|
|
|
if let cached = self._queryCache[key], |
|
|
|
|
cached.version == self._cacheVersion, |
|
|
|
|
let result = cached.result as? Result { |
|
|
|
|
return result |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let result = compute(items) |
|
|
|
|
self._queryCache[key] = (self._cacheVersion, result) |
|
|
|
|
return result |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private func invalidateCache() { |
|
|
|
|
self._cacheVersion += 1 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
extension StoredCollection: RandomAccessCollection { |
|
|
|
|
|