cleanup and minor refactoring

sync3
Laurent 6 months ago
parent 307180a88b
commit 28687133f6
  1. 54
      LeStorage/BaseCollection.swift
  2. 44
      LeStorage/SyncedCollection.swift

@ -45,16 +45,16 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
fileprivate(set) var pendingOperationManager: PendingOperationManager<T>? = nil fileprivate(set) var pendingOperationManager: PendingOperationManager<T>? = nil
/// Indicates whether the collection has changed, thus requiring a write operation /// Indicates whether the collection has changed, thus requiring a write operation
fileprivate var _hasChanged: Bool = false { fileprivate var _triggerWrite: Bool = false {
didSet { didSet {
if self._hasChanged == true { if self._triggerWrite == true {
self._scheduleWrite() self._scheduleWrite()
DispatchQueue.main.async { DispatchQueue.main.async {
NotificationCenter.default.post( NotificationCenter.default.post(
name: NSNotification.Name.CollectionDidChange, object: self) name: NSNotification.Name.CollectionDidChange, object: self)
} }
self._hasChanged = false self._triggerWrite = false
} }
} }
} }
@ -109,8 +109,8 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
// MARK: - Loading // MARK: - Loading
/// Sets the collection as changed to trigger a write /// Sets the collection as changed to trigger a write
func setChanged() { func triggerWrite() {
self._hasChanged = true self._triggerWrite = true
} }
/// Migrates if necessary and asynchronously decodes the json file /// Migrates if necessary and asynchronously decodes the json file
@ -188,7 +188,7 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
func addOrUpdateItem(instance: T) { func addOrUpdateItem(instance: T) {
defer { defer {
self._hasChanged = true self._triggerWrite = true
} }
if let index = self.items.firstIndex(where: { $0.id == instance.id }) { if let index = self.items.firstIndex(where: { $0.id == instance.id }) {
@ -202,23 +202,16 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
/// A method the treat the collection as a single instance holder /// A method the treat the collection as a single instance holder
func setSingletonNoSync(instance: T) { func setSingletonNoSync(instance: T) {
defer { defer {
self._hasChanged = true self._triggerWrite = true
} }
self.items.removeAll() self.items.removeAll()
self.addItem(instance: instance) self.addItem(instance: instance)
} }
/// Deletes an item by its id
public func deleteById(_ id: T.ID) {
if let instance = self.findById(id) {
self.delete(instance: instance)
}
}
/// Deletes the instance in the collection and sets the collection as changed to trigger a write /// Deletes the instance in the collection and sets the collection as changed to trigger a write
public func delete(instance: T) { public func delete(instance: T) {
defer { defer {
self._hasChanged = true self._triggerWrite = true
} }
self.deleteItem(instance) self.deleteItem(instance)
} }
@ -227,7 +220,7 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
public func delete(contentOfs sequence: any RandomAccessCollection<T>) { public func delete(contentOfs sequence: any RandomAccessCollection<T>) {
defer { defer {
self._hasChanged = true self._triggerWrite = true
} }
for instance in sequence { for instance in sequence {
@ -242,16 +235,16 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
} }
/// Adds a sequence of objects inside the collection and performs a write /// Adds a sequence of objects inside the collection and performs a write
func addSequence(_ sequence: any Sequence<T>, checkLoaded: Bool = true) { func addSequence(_ sequence: any Sequence<T>) {
defer { defer {
self._hasChanged = true self._triggerWrite = true
} }
for instance in sequence { for instance in sequence {
if let index = self.items.firstIndex(where: { $0.id == instance.id }) { if let index = self.items.firstIndex(where: { $0.id == instance.id }) {
self.updateItem(instance, index: index, checkLoaded: checkLoaded) self.updateItem(instance, index: index)
} else { // insert } else { // insert
self.addItem(instance: instance, checkLoaded: checkLoaded) self.addItem(instance: instance)
} }
} }
@ -269,9 +262,9 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
} }
/// Adds an instance to the collection /// Adds an instance to the collection
@discardableResult func addItem(instance: T, checkLoaded: Bool = true, shouldBeSynchronized: Bool = false) -> Bool { @discardableResult func addItem(instance: T, shouldBeSynchronized: Bool = false) -> Bool {
if checkLoaded && !self.hasLoaded { if !self.hasLoaded {
self.addPendingOperation(method: .addOrUpdate, instance: instance, shouldBeSynchronized: shouldBeSynchronized) self.addPendingOperation(method: .addOrUpdate, instance: instance, shouldBeSynchronized: shouldBeSynchronized)
return false return false
} }
@ -285,9 +278,9 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
} }
/// Updates an instance to the collection by index /// Updates an instance to the collection by index
@discardableResult func updateItem(_ instance: T, index: Int, checkLoaded: Bool = true, shouldBeSynchronized: Bool = false) -> Bool { @discardableResult func updateItem(_ instance: T, index: Int, shouldBeSynchronized: Bool = false) -> Bool {
if checkLoaded && !self.hasLoaded { if !self.hasLoaded {
self.addPendingOperation(method: .addOrUpdate, instance: instance, shouldBeSynchronized: shouldBeSynchronized) self.addPendingOperation(method: .addOrUpdate, instance: instance, shouldBeSynchronized: shouldBeSynchronized)
return false return false
} }
@ -358,7 +351,7 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
/// Also removes related API calls /// Also removes related API calls
public func deleteDependencies(_ items: any Sequence<T>) { public func deleteDependencies(_ items: any Sequence<T>) {
defer { defer {
self._hasChanged = true self._triggerWrite = true
} }
let itemsArray = Array(items) // fix error if items is self.items let itemsArray = Array(items) // fix error if items is self.items
for item in itemsArray { for item in itemsArray {
@ -368,11 +361,6 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
} }
} }
/// Proceeds to delete all instance of the collection, properly cleaning up dependencies and sending API calls
public func deleteAll() throws {
self.delete(contentOfs: self.items)
}
// MARK: - Pending operations // MARK: - Pending operations
func addPendingOperation(method: StorageMethod, instance: T, shouldBeSynchronized: Bool) { func addPendingOperation(method: StorageMethod, instance: T, shouldBeSynchronized: Bool) {
@ -443,7 +431,7 @@ public class BaseCollection<T: Storable>: SomeCollection, CollectionHolder {
public func reset() { public func reset() {
self.items.removeAll() self.items.removeAll()
self.store.removeFile(type: T.self) self.store.removeFile(type: T.self)
setChanged() triggerWrite()
} }
public var type: any Storable.Type { return T.self } public var type: any Storable.Type { return T.self }
@ -488,7 +476,7 @@ public class StoredCollection<T: Storable>: BaseCollection<T>, RandomAccessColle
} }
set(newValue) { set(newValue) {
self.items[index] = newValue self.items[index] = newValue
self._hasChanged = true self._triggerWrite = true
} }
} }
@ -510,7 +498,7 @@ extension SyncedCollection: RandomAccessCollection {
} }
set(newValue) { set(newValue) {
self.items[index] = newValue self.items[index] = newValue
self._hasChanged = true self._triggerWrite = true
} }
} }
} }

@ -79,7 +79,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
fileprivate func _updateLocalInstance(_ serverInstance: T) { fileprivate func _updateLocalInstance(_ serverInstance: T) {
if let localInstance = self.findById(serverInstance.id) { if let localInstance = self.findById(serverInstance.id) {
localInstance.copy(from: serverInstance) localInstance.copy(from: serverInstance)
self.setChanged() self.triggerWrite()
} }
} }
@ -87,12 +87,13 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
func loadItems(_ items: [T], clear: Bool = false) { func loadItems(_ items: [T], clear: Bool = false) {
if clear { if clear {
self.setItems(items) self.setItems(items)
self.setAsLoaded()
} else { } else {
self.addOrUpdateNoSync(contentOfs: items, checkLoaded: false) self.setAsLoaded()
self.addOrUpdateNoSync(contentOfs: items)
} }
self.setAsLoaded() self.triggerWrite()
self.setChanged()
} }
// MARK: - Basic operations with sync // MARK: - Basic operations with sync
@ -113,7 +114,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
instance.lastUpdate = Date() instance.lastUpdate = Date()
if let index = self.items.firstIndex(where: { $0.id == instance.id }) { if let index = self.items.firstIndex(where: { $0.id == instance.id }) {
if self.updateItem(instance, index: index, shouldBeSynchronized: true) { if self.updateItem(instance, index: index, shouldBeSynchronized: true) {
self.setChanged() self.triggerWrite()
if instance.shared == true { if instance.shared == true {
self._cleanUpSharedDependencies() self._cleanUpSharedDependencies()
} }
@ -121,7 +122,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
} }
} else { } else {
if self.addItem(instance: instance, shouldBeSynchronized: true) { if self.addItem(instance: instance, shouldBeSynchronized: true) {
self.setChanged() self.triggerWrite()
return (instance, true) return (instance, true)
} }
} }
@ -131,7 +132,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
fileprivate func _addOrUpdateCore(contentOfs sequence: any Sequence<T>) -> OperationBatch<T> { fileprivate func _addOrUpdateCore(contentOfs sequence: any Sequence<T>) -> OperationBatch<T> {
defer { defer {
self.setChanged() self.triggerWrite()
} }
let date = Date() let date = Date()
@ -161,17 +162,12 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
let batch = self._addOrUpdateCore(contentOfs: sequence) let batch = self._addOrUpdateCore(contentOfs: sequence)
Task { await self._sendOperationBatch(batch) } Task { await self._sendOperationBatch(batch) }
} }
/// Proceeds to delete all instance of the collection, properly cleaning up dependencies and sending API calls
override public func deleteAll() throws {
self.delete(contentOfs: self.items)
}
/// Deletes all items of the sequence by id and sets the collection as changed to trigger a write /// Deletes all items of the sequence by id and sets the collection as changed to trigger a write
fileprivate func _deleteCore(contentOfs sequence: any RandomAccessCollection<T>) -> OperationBatch<T> { fileprivate func _deleteCore(contentOfs sequence: any RandomAccessCollection<T>) -> OperationBatch<T> {
defer { defer {
self.setChanged() self.triggerWrite()
} }
var deleted: [T] = [] var deleted: [T] = []
@ -198,7 +194,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
/// Deletes an instance and writes /// Deletes an instance and writes
override public func delete(instance: T) { override public func delete(instance: T) {
defer { defer {
self.setChanged() self.triggerWrite()
} }
self.deleteItem(instance, shouldBeSynchronized: true) self.deleteItem(instance, shouldBeSynchronized: true)
self.storeCenter.createDeleteLog(instance) self.storeCenter.createDeleteLog(instance)
@ -290,7 +286,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
} }
/// Deletes all items of the sequence by id and sets the collection as changed to trigger a write /// Deletes all items of the sequence by id and sets the collection as changed to trigger a write
public func deleteAsync(contentOfs sequence: any RandomAccessCollection<T>) async throws{ public func deleteAsync(contentOfs sequence: any RandomAccessCollection<T>) async throws {
guard sequence.isNotEmpty else { return } guard sequence.isNotEmpty else { return }
let batch = self._deleteCore(contentOfs: sequence) let batch = self._deleteCore(contentOfs: sequence)
try await self._executeBatchOnce(batch) try await self._executeBatchOnce(batch)
@ -299,7 +295,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
/// Deletes an instance and writes /// Deletes an instance and writes
func deleteAsync(instance: T) async throws { func deleteAsync(instance: T) async throws {
defer { defer {
self.setChanged() self.triggerWrite()
} }
self.deleteItem(instance, shouldBeSynchronized: true) self.deleteItem(instance, shouldBeSynchronized: true)
self.storeCenter.createDeleteLog(instance) self.storeCenter.createDeleteLog(instance)
@ -314,14 +310,14 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
} }
/// Adds or update a sequence of elements without synchronizing it /// Adds or update a sequence of elements without synchronizing it
func addOrUpdateNoSync(contentOfs sequence: any Sequence<T>, checkLoaded: Bool = false) { func addOrUpdateNoSync(contentOfs sequence: any Sequence<T>) {
self.addSequence(sequence, checkLoaded: false) self.addSequence(sequence)
} }
/// Deletes the instance in the collection without synchronization /// Deletes the instance in the collection without synchronization
func deleteNoSync(contentOfs sequence: any Sequence<T>) { func deleteNoSync(contentOfs sequence: any Sequence<T>) {
defer { defer {
self.setChanged() self.triggerWrite()
} }
for item in sequence { for item in sequence {
self.deleteItem(item, shouldBeSynchronized: false) self.deleteItem(item, shouldBeSynchronized: false)
@ -331,7 +327,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
/// Deletes the instance in the collection without synchronization /// Deletes the instance in the collection without synchronization
func deleteNoSync(instance: T) { func deleteNoSync(instance: T) {
defer { defer {
self.setChanged() self.triggerWrite()
} }
self.deleteItem(instance, shouldBeSynchronized: false) self.deleteItem(instance, shouldBeSynchronized: false)
} }
@ -343,13 +339,13 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
// Delete the instance and its non-used shared dependencies // Delete the instance and its non-used shared dependencies
self.deleteUnusedShared(instance, shouldBeSynchronized: false) self.deleteUnusedShared(instance, shouldBeSynchronized: false)
self.setChanged() self.triggerWrite()
} }
/// Deletes the instance in the collection without synchronization /// Deletes the instance in the collection without synchronization
func deleteByStringIdNoSync(_ id: String) { func deleteByStringIdNoSync(_ id: String) {
defer { defer {
self.setChanged() self.triggerWrite()
} }
let realId = T.buildRealId(id: id) let realId = T.buildRealId(id: id)
if let instance = self.findById(realId) { if let instance = self.findById(realId) {
@ -402,7 +398,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
/// Adds or update an instance if it is newer than the local instance /// Adds or update an instance if it is newer than the local instance
func addOrUpdateIfNewer(_ instance: T, shared: Bool) { func addOrUpdateIfNewer(_ instance: T, shared: Bool) {
defer { defer {
self.setChanged() self.triggerWrite()
} }
if let index = self.items.firstIndex(where: { $0.id == instance.id }) { if let index = self.items.firstIndex(where: { $0.id == instance.id }) {
@ -428,7 +424,7 @@ public class SyncedCollection<T : SyncedStorable>: BaseCollection<T>, SomeSynced
Task { Task {
await self._sendInsertion(instance) await self._sendInsertion(instance)
await MainActor.run { await MainActor.run {
self.setChanged() self.triggerWrite()
} }
} }
} }

Loading…
Cancel
Save