|
|
|
|
@ -680,36 +680,65 @@ public class StoreCenter { |
|
|
|
|
/// - updateArrays: the server updates |
|
|
|
|
/// - shared: indicates if the content should be flagged as shared |
|
|
|
|
@MainActor |
|
|
|
|
func _syncAddOrUpdate(_ updateArrays: [SyncedStorableArray], shared: SharingStatus? = nil) async { |
|
|
|
|
fileprivate func _syncAddOrUpdate(_ updateArrays: [SyncedStorableArray], shared: SharingStatus? = nil) async { |
|
|
|
|
|
|
|
|
|
for updateArray in updateArrays { |
|
|
|
|
for item in updateArray.items { |
|
|
|
|
let storeId: String? = item.getStoreId() |
|
|
|
|
await self.synchronizationAddOrUpdate(item, storeId: storeId, shared: shared) |
|
|
|
|
await self._syncAddOrUpdate(updateArray, type: updateArray.type, shared: shared) |
|
|
|
|
// for item in updateArray.items { |
|
|
|
|
// let storeId: String? = item.getStoreId() |
|
|
|
|
// await self.synchronizationAddOrUpdate(item, storeId: storeId, shared: shared) |
|
|
|
|
// } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@MainActor |
|
|
|
|
fileprivate func _syncAddOrUpdate<T: SyncedStorable>(_ updateArray: SyncedStorableArray, type: T.Type, shared: SharingStatus? = nil) async { |
|
|
|
|
|
|
|
|
|
let itemsByStore = updateArray.items.group { $0.getStoreId() } |
|
|
|
|
for (storeId, items) in itemsByStore { |
|
|
|
|
let store = self._requestStore(id: storeId) |
|
|
|
|
store.synchronizationAddOrUpdate(items as! [T], shared: shared) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Processes data that should be deleted inside the app |
|
|
|
|
fileprivate func _syncDelete(_ deletionArrays: [ObjectIdentifierArray]) async { |
|
|
|
|
|
|
|
|
|
for deletionArray in deletionArrays { |
|
|
|
|
for deletedObject in deletionArray.items { |
|
|
|
|
await self.synchronizationDelete(id: deletedObject.modelId, type: deletionArray.type, storeId: deletedObject.storeId) |
|
|
|
|
await self._syncDelete(deletionArray, type: deletionArray.type) |
|
|
|
|
|
|
|
|
|
// for deletedObject in deletionArray.items { |
|
|
|
|
// await self.synchronizationDelete(id: deletedObject.modelId, type: deletionArray.type, storeId: deletedObject.storeId) |
|
|
|
|
// } |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _syncDelete<T : SyncedStorable>(_ deletionArray: ObjectIdentifierArray, type: T.Type) async { |
|
|
|
|
for deletedObject in deletionArray.items { |
|
|
|
|
|
|
|
|
|
let itemsByStore = deletionArray.items.group { $0.storeId } |
|
|
|
|
for (storeId, items) in itemsByStore { |
|
|
|
|
let store = self._requestStore(id: storeId) |
|
|
|
|
await store.synchronizationDelete(items, type: T.self) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// await self.synchronizationDelete(id: deletedObject.modelId, type: deletionArray.type, storeId: deletedObject.storeId) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Processes data that has been revoked |
|
|
|
|
fileprivate func syncRevoke(_ revokedArrays: [ObjectIdentifierArray], parents: [[ObjectIdentifierArray]]) async { |
|
|
|
|
|
|
|
|
|
await self._syncRevoke(revokedArrays) |
|
|
|
|
for revokedArray in revokedArrays { |
|
|
|
|
for revoked in revokedArray.items { |
|
|
|
|
await self.synchronizationDelete(id: revoked.modelId, type: revokedArray.type, storeId: revoked.storeId) // or synchronizationRevoke ? |
|
|
|
|
} |
|
|
|
|
await self._syncDelete(revokedArray, type: revokedArray.type) |
|
|
|
|
|
|
|
|
|
// for revoked in revokedArray.items { |
|
|
|
|
// await self.synchronizationDelete(id: revoked.modelId, type: revokedArray.type, storeId: revoked.storeId) // or synchronizationRevoke ? |
|
|
|
|
// } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for level in parents { |
|
|
|
|
@ -719,10 +748,28 @@ public class StoreCenter { |
|
|
|
|
|
|
|
|
|
fileprivate func _syncRevoke(_ revokeArrays: [ObjectIdentifierArray]) async { |
|
|
|
|
for revokeArray in revokeArrays { |
|
|
|
|
for revoked in revokeArray.items { |
|
|
|
|
await self.synchronizationRevoke(id: revoked.modelId, type: revokeArray.type, storeId: revoked.storeId) |
|
|
|
|
await self._syncRevoke(revokeArray: revokeArray) |
|
|
|
|
// for revoked in revokeArray.items { |
|
|
|
|
// await self.synchronizationRevoke(id: revoked.modelId, type: revokeArray.type, storeId: revoked.storeId) |
|
|
|
|
// } |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@MainActor |
|
|
|
|
fileprivate func _syncRevoke(revokeArray: ObjectIdentifierArray) async { |
|
|
|
|
|
|
|
|
|
let itemsByStore = revokeArray.items.group { $0.storeId } |
|
|
|
|
for (storeId, items) in itemsByStore { |
|
|
|
|
let store = self._requestStore(id: storeId) |
|
|
|
|
await store.synchronizationRevoke(items, type: revokeArray.type) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// for revoked in revokeArray.items { |
|
|
|
|
// |
|
|
|
|
// |
|
|
|
|
// |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns a Type object for a class name |
|
|
|
|
@ -740,52 +787,45 @@ public class StoreCenter { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns whether a data has already been deleted by, to avoid inserting it again |
|
|
|
|
fileprivate func _hasAlreadyBeenDeleted<T: Storable>(_ instance: T) -> Bool { |
|
|
|
|
func hasAlreadyBeenDeleted<T: Storable>(_ instance: T) -> Bool { |
|
|
|
|
return self._deleteLogs.contains(where: { |
|
|
|
|
$0.dataId == instance.stringId && $0.operation == .delete |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Adds or updates an instance into the store |
|
|
|
|
func synchronizationAddOrUpdate<T: SyncedStorable>(_ instance: T, storeId: String?, shared: SharingStatus?) async { |
|
|
|
|
let hasAlreadyBeenDeleted: Bool = self._hasAlreadyBeenDeleted(instance) |
|
|
|
|
if !hasAlreadyBeenDeleted { |
|
|
|
|
await self._requestStore(id: storeId).addOrUpdateIfNewer(instance, shared: shared) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// func synchronizationAddOrUpdate<T: SyncedStorable>(_ instance: T, storeId: String?, shared: SharingStatus?) async { |
|
|
|
|
// let hasAlreadyBeenDeleted: Bool = self.hasAlreadyBeenDeleted(instance) |
|
|
|
|
// if !hasAlreadyBeenDeleted { |
|
|
|
|
// await self._requestStore(id: storeId).addOrUpdateIfNewer(instance, shared: shared) |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
/// Deletes an instance with the given parameters |
|
|
|
|
@MainActor |
|
|
|
|
func synchronizationDelete<T: SyncedStorable>(id: String, type: T.Type, storeId: String?) { |
|
|
|
|
do { |
|
|
|
|
try self._store(id: storeId).deleteNoSyncNoCascade(type: type, id: id) |
|
|
|
|
} catch { |
|
|
|
|
Logger.error(error) |
|
|
|
|
} |
|
|
|
|
self._cleanupDataLog(dataId: id) |
|
|
|
|
} |
|
|
|
|
// @MainActor |
|
|
|
|
// func synchronizationDelete<T: SyncedStorable>(id: String, type: T.Type, storeId: String?) { |
|
|
|
|
// do { |
|
|
|
|
// try self._store(id: storeId).deleteNoSyncNoCascade(type: type, id: id) |
|
|
|
|
// } catch { |
|
|
|
|
// Logger.error(error) |
|
|
|
|
// } |
|
|
|
|
// self.cleanupDataLog(dataId: id) |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
/// Revokes a data that has been shared with the user |
|
|
|
|
@MainActor |
|
|
|
|
func synchronizationRevoke<T: SyncedStorable>(id: String, type: T.Type, storeId: String?) { |
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
if let instance = self._instance(id: id, type: type, storeId: storeId) { |
|
|
|
|
if instance.sharing != nil && !self.isReferenced(instance: instance) { |
|
|
|
|
try self._store(id: storeId).deleteNoSyncNoCascade(type: type, id: id) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// if self._instanceShared(id: id, type: type, storeId: storeId) { |
|
|
|
|
// let count = self.isReferenced(type: type, id: id) |
|
|
|
|
// if count == 0 { |
|
|
|
|
// @MainActor |
|
|
|
|
// func synchronizationRevoke<T: SyncedStorable>(id: String, type: T.Type, storeId: String?) { |
|
|
|
|
// |
|
|
|
|
// do { |
|
|
|
|
// if let instance = self._instance(id: id, type: type, storeId: storeId) { |
|
|
|
|
// if instance.sharing != nil && !self.isReferenced(instance: instance) { |
|
|
|
|
// try self._store(id: storeId).deleteNoSyncNoCascade(type: type, id: id) |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
} catch { |
|
|
|
|
Logger.error(error) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// } catch { |
|
|
|
|
// Logger.error(error) |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
fileprivate func _instance<T: SyncedStorable>(id: String, type: T.Type, storeId: String?) -> T? { |
|
|
|
|
let realId: T.ID = T.buildRealId(id: id) |
|
|
|
|
@ -800,7 +840,7 @@ public class StoreCenter { |
|
|
|
|
// } |
|
|
|
|
|
|
|
|
|
/// Deletes a data log by data id |
|
|
|
|
fileprivate func _cleanupDataLog(dataId: String) { |
|
|
|
|
func cleanupDataLog(dataId: String) { |
|
|
|
|
let logs = self._deleteLogs.filter { $0.dataId == dataId } |
|
|
|
|
self._deleteLogs.delete(contentOfs: logs) |
|
|
|
|
} |
|
|
|
|
|