|
|
|
|
@ -182,6 +182,8 @@ public class StoreCenter { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// MARK: - Store management |
|
|
|
|
|
|
|
|
|
/// Registers a store into the list of stores |
|
|
|
|
/// - Parameters: |
|
|
|
|
@ -200,7 +202,7 @@ public class StoreCenter { |
|
|
|
|
/// - Parameters: |
|
|
|
|
/// - identifier: The store identifer |
|
|
|
|
/// - parameter: The parameter name used to filter data on the server |
|
|
|
|
public func requestStore(identifier: String) -> Store { |
|
|
|
|
func requestStore(identifier: String) -> Store { |
|
|
|
|
if let store = self._stores[identifier] { |
|
|
|
|
return store |
|
|
|
|
} else { |
|
|
|
|
@ -210,6 +212,29 @@ public class StoreCenter { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns the store corresponding to the provided id, and creates one if necessary, otherwise returns the main store |
|
|
|
|
fileprivate func _requestStore(id: String?) -> Store { |
|
|
|
|
if let storeId = id { |
|
|
|
|
if let store = self._stores[storeId] { |
|
|
|
|
return store |
|
|
|
|
} else { |
|
|
|
|
let store = Store(storeCenter: self, identifier: storeId) |
|
|
|
|
self._registerStore(store: store) |
|
|
|
|
return store |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
return self.mainStore |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fileprivate func _store(id: String?) -> Store? { |
|
|
|
|
if let storeId = id, let store = self._stores[storeId] { |
|
|
|
|
return store |
|
|
|
|
} else { |
|
|
|
|
return self.mainStore |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public func store(identifier: String) throws -> Store { |
|
|
|
|
if let store = self._stores[identifier] { |
|
|
|
|
return store |
|
|
|
|
@ -217,6 +242,15 @@ public class StoreCenter { |
|
|
|
|
throw StoreError.storeNotRegistered(id: identifier) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Deletes the directory using its identifier |
|
|
|
|
/// - Parameters: |
|
|
|
|
/// - identifier: The name of the directory |
|
|
|
|
public func destroyStore(identifier: String) { |
|
|
|
|
let directory = "\(self.directoryName)/\(identifier)" |
|
|
|
|
FileManager.default.deleteDirectoryInDocuments(directoryName: directory) |
|
|
|
|
self._stores.removeValue(forKey: identifier) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// MARK: - Settings |
|
|
|
|
|
|
|
|
|
/// Sets the user info given a user |
|
|
|
|
@ -535,7 +569,7 @@ public class StoreCenter { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func itemsRetrieved<T: SyncedStorable>(_ results: [T], storeId: String?, clear: Bool) async { |
|
|
|
|
await self._store(id: storeId).loadCollectionItems(results, clear: clear) |
|
|
|
|
await self._requestStore(id: storeId).loadCollectionItems(results, clear: clear) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns the names of all collections |
|
|
|
|
@ -631,7 +665,7 @@ public class StoreCenter { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let array = try self.decodeDictionary(json) |
|
|
|
|
await self._syncAddOrUpdate(array, shared: true) |
|
|
|
|
await self._syncAddOrUpdate(array, shared: .shared) |
|
|
|
|
} catch { |
|
|
|
|
Logger.error(error) |
|
|
|
|
} |
|
|
|
|
@ -642,11 +676,12 @@ public class StoreCenter { |
|
|
|
|
|
|
|
|
|
await self._syncAddOrUpdate(syncData.updates) |
|
|
|
|
await self._syncDelete(syncData.deletions) |
|
|
|
|
await self._syncAddOrUpdate(syncData.grants, shared: true) |
|
|
|
|
await self._syncAddOrUpdate(syncData.shared, shared: .shared) |
|
|
|
|
await self._syncAddOrUpdate(syncData.grants, shared: .granted) |
|
|
|
|
await self.syncRevoke(syncData.revocations, parents: syncData.revocationParents) |
|
|
|
|
// self._syncAddOrUpdate(syncData.relationshipSets) |
|
|
|
|
// await self._syncDelete(syncData.relationshipRemovals) |
|
|
|
|
await self._syncAddOrUpdate(syncData.sharedRelationshipSets, shared: true) |
|
|
|
|
await self._syncAddOrUpdate(syncData.sharedRelationshipSets, shared: .granted) |
|
|
|
|
await self._syncRevoke(syncData.sharedRelationshipRemovals) |
|
|
|
|
|
|
|
|
|
Logger.log("sync content: updates = \(syncData.updates.count) / deletions = \(syncData.deletions.count), grants = \(syncData.grants.count)") |
|
|
|
|
@ -668,7 +703,7 @@ public class StoreCenter { |
|
|
|
|
/// - updateArrays: the server updates |
|
|
|
|
/// - shared: indicates if the content should be flagged as shared |
|
|
|
|
@MainActor |
|
|
|
|
func _syncAddOrUpdate(_ updateArrays: [SyncedStorableArray], shared: Bool = false) async { |
|
|
|
|
func _syncAddOrUpdate(_ updateArrays: [SyncedStorableArray], shared: SharingStatus? = nil) async { |
|
|
|
|
|
|
|
|
|
for updateArray in updateArrays { |
|
|
|
|
for item in updateArray.items { |
|
|
|
|
@ -727,21 +762,6 @@ public class StoreCenter { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns the store corresponding to the provided id, and creates one if necessary |
|
|
|
|
fileprivate func _store(id: String?) -> Store { |
|
|
|
|
if let storeId = id { |
|
|
|
|
if let store = self._stores[storeId] { |
|
|
|
|
return store |
|
|
|
|
} else { |
|
|
|
|
let store = Store(storeCenter: self, identifier: storeId) |
|
|
|
|
self._registerStore(store: store) |
|
|
|
|
return store |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
return self.mainStore |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns whether a data has already been deleted by, to avoid inserting it again |
|
|
|
|
fileprivate func _hasAlreadyBeenDeleted<T: Storable>(_ instance: T) -> Bool { |
|
|
|
|
return self._deleteLogs.contains(where: { |
|
|
|
|
@ -750,10 +770,10 @@ public class StoreCenter { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Adds or updates an instance into the store |
|
|
|
|
func synchronizationAddOrUpdate<T: SyncedStorable>(_ instance: T, storeId: String?, shared: Bool) async { |
|
|
|
|
func synchronizationAddOrUpdate<T: SyncedStorable>(_ instance: T, storeId: String?, shared: SharingStatus?) async { |
|
|
|
|
let hasAlreadyBeenDeleted: Bool = self._hasAlreadyBeenDeleted(instance) |
|
|
|
|
if !hasAlreadyBeenDeleted { |
|
|
|
|
await self._store(id: storeId).addOrUpdateIfNewer(instance, shared: shared) |
|
|
|
|
await self._requestStore(id: storeId).addOrUpdateIfNewer(instance, shared: shared) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -761,7 +781,7 @@ public class StoreCenter { |
|
|
|
|
@MainActor |
|
|
|
|
func synchronizationDelete<T: SyncedStorable>(id: String, type: T.Type, storeId: String?) { |
|
|
|
|
do { |
|
|
|
|
try self._store(id: storeId).deleteNoSyncNoCascade(type: type, id: id) |
|
|
|
|
try self._store(id: storeId)?.deleteNoSyncNoCascade(type: type, id: id) |
|
|
|
|
} catch { |
|
|
|
|
Logger.error(error) |
|
|
|
|
} |
|
|
|
|
@ -776,7 +796,7 @@ public class StoreCenter { |
|
|
|
|
if self._instanceShared(id: id, type: type) { |
|
|
|
|
let count = self.mainStore.referenceCount(type: type, id: id) |
|
|
|
|
if count == 0 { |
|
|
|
|
try self._store(id: storeId).deleteNoSyncNoCascade(type: type, id: id) |
|
|
|
|
try self._store(id: storeId)?.deleteNoSyncNoCascade(type: type, id: id) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} catch { |
|
|
|
|
@ -788,7 +808,7 @@ public class StoreCenter { |
|
|
|
|
fileprivate func _instanceShared<T: SyncedStorable>(id: String, type: T.Type) -> Bool { |
|
|
|
|
let realId: T.ID = T.buildRealId(id: id) |
|
|
|
|
let instance: T? = self.mainStore.findById(realId) |
|
|
|
|
return instance?.shared == true |
|
|
|
|
return instance?.sharing != nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Deletes a data log by data id |
|
|
|
|
@ -967,15 +987,6 @@ public class StoreCenter { |
|
|
|
|
return !self._blackListedUserName.contains(where: { $0 == userName }) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Deletes the directory using its identifier |
|
|
|
|
/// - Parameters: |
|
|
|
|
/// - identifier: The name of the directory |
|
|
|
|
public func destroyStore(identifier: String) { |
|
|
|
|
let directory = "\(self.directoryName)/\(identifier)" |
|
|
|
|
FileManager.default.deleteDirectoryInDocuments(directoryName: directory) |
|
|
|
|
self._stores.removeValue(forKey: identifier) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// MARK: - Instant update |
|
|
|
|
|
|
|
|
|
/// Updates a local object with a server instance |
|
|
|
|
|