From 775bed665b17244dd81e22e7bd2820d3554ddf87 Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 8 May 2025 11:09:30 +0200 Subject: [PATCH] Fixes and improvements --- LeStorage/Codables/SyncData.swift | 16 ++++++++-------- LeStorage/Services.swift | 6 +++--- LeStorage/StoreCenter.swift | 22 +++++++++++----------- LeStorage/SyncedCollection.swift | 31 ++++++++++++++++--------------- 4 files changed, 38 insertions(+), 37 deletions(-) diff --git a/LeStorage/Codables/SyncData.swift b/LeStorage/Codables/SyncData.swift index 26ab696..1dab2c4 100644 --- a/LeStorage/Codables/SyncData.swift +++ b/LeStorage/Codables/SyncData.swift @@ -28,8 +28,8 @@ class SyncData { var grants: [SyncedStorableArray] = [] var revocations: [ObjectIdentifierArray] = [] var revocationParents: [[ObjectIdentifierArray]] = [] - var relationshipSets: [SyncedStorableArray] = [] - var relationshipRemovals: [ObjectIdentifierArray] = [] +// var relationshipSets: [SyncedStorableArray] = [] +// var relationshipRemovals: [ObjectIdentifierArray] = [] var sharedRelationshipSets: [SyncedStorableArray] = [] var sharedRelationshipRemovals: [ObjectIdentifierArray] = [] var date: String? @@ -60,12 +60,12 @@ class SyncData { } } - if let relationshipSets = json["relationship_sets"] as? [String: Any] { - self.relationshipSets = try storeCenter.decodeDictionary(relationshipSets) - } - if let relationshipRemovals = json["relationship_removals"] as? [String: Any] { - self.relationshipRemovals = try storeCenter.decodeObjectIdentifierDictionary(relationshipRemovals) - } +// if let relationshipSets = json["relationship_sets"] as? [String: Any] { +// self.relationshipSets = try storeCenter.decodeDictionary(relationshipSets) +// } +// if let relationshipRemovals = json["relationship_removals"] as? [String: Any] { +// self.relationshipRemovals = try storeCenter.decodeObjectIdentifierDictionary(relationshipRemovals) +// } if let sharedRelationshipSets = json["shared_relationship_sets"] as? [String: Any] { self.sharedRelationshipSets = try storeCenter.decodeDictionary(sharedRelationshipSets) } diff --git a/LeStorage/Services.swift b/LeStorage/Services.swift index 270f87c..8066d67 100644 --- a/LeStorage/Services.swift +++ b/LeStorage/Services.swift @@ -33,7 +33,7 @@ let changePasswordCall: ServiceCall = ServiceCall( path: "change-password/", method: .put, requiresToken: true) let postDeviceTokenCall: ServiceCall = ServiceCall( path: "device-token/", method: .post, requiresToken: true) -let getUserDataAccessCall: ServiceCall = ServiceCall( +let getUserDataAccessCallContent: ServiceCall = ServiceCall( path: "data-access-content/", method: .get, requiresToken: true) let userNamesCall: ServiceCall = ServiceCall( path: "user-names/", method: .get, requiresToken: true) @@ -630,8 +630,8 @@ public class Services { } /// Returns the list of DataAccess - func getUserDataAccess() async throws { - let request = try self._baseRequest(call: getUserDataAccessCall) + func getUserDataAccessContent() async throws { + let request = try self._baseRequest(call: getUserDataAccessCallContent) if let data = try await self._runRequest(request) { await self.storeCenter.userDataAccessRetrieved(data) } diff --git a/LeStorage/StoreCenter.swift b/LeStorage/StoreCenter.swift index d7e3078..964e494 100644 --- a/LeStorage/StoreCenter.swift +++ b/LeStorage/StoreCenter.swift @@ -48,7 +48,7 @@ public class StoreCenter { lazy fileprivate var _deleteLogs: StoredCollection = { self.mainStore.registerCollection() }() /// A synchronized collection of DataAccess - fileprivate var _dataAccess: SyncedCollection? = nil + fileprivate(set) var dataAccessCollection: SyncedCollection? = nil /// A collection storing FailedAPICall objects fileprivate var _failedAPICallsCollection: SyncedCollection? = nil @@ -101,7 +101,7 @@ public class StoreCenter { self.tokenKeychain = KeychainStore(serverId: urlManager.api) if self.useSynchronization { - self._dataAccess = self.mainStore.registerSynchronizedCollection() + self.dataAccessCollection = self.mainStore.registerSynchronizedCollection() } Logger.log("Sync URL: \(urlManager.api)") @@ -250,7 +250,7 @@ public class StoreCenter { self._failedAPICallsCollection?.reset() self._stores.removeAll() - self._dataAccess?.reset() + self.dataAccessCollection?.reset() self._deleteLogs.reset() self._settingsStorage.update { settings in @@ -557,7 +557,7 @@ public class StoreCenter { if self.useSynchronization { Task { do { - try await self.service().getUserDataAccess() + try await self.service().getUserDataAccessContent() } catch { Logger.error(error) } @@ -637,8 +637,8 @@ public class StoreCenter { await self._syncDelete(syncData.deletions) self._syncAddOrUpdate(syncData.grants, shared: true) await self.syncRevoke(syncData.revocations, parents: syncData.revocationParents) - self._syncAddOrUpdate(syncData.relationshipSets) - await self._syncDelete(syncData.relationshipRemovals) +// self._syncAddOrUpdate(syncData.relationshipSets) +// await self._syncDelete(syncData.relationshipRemovals) self._syncAddOrUpdate(syncData.sharedRelationshipSets, shared: true) self._syncRevoke(syncData.sharedRelationshipRemovals) @@ -1020,7 +1020,7 @@ public class StoreCenter { /// Returns the list of users have access to a data given its id public func authorizedUsers(for modelId: String) -> [String] { - guard let dataAccessCollection = self._dataAccess else { + guard let dataAccessCollection = self.dataAccessCollection else { return [] } if let dataAccess = dataAccessCollection.first(where: { $0.modelId == modelId }) { @@ -1031,7 +1031,7 @@ public class StoreCenter { public func setAuthorizedUsersAsync(for instance: T, users: [String]) async throws { - guard let dataAccessCollection = self._dataAccess else { + guard let dataAccessCollection = self.dataAccessCollection else { throw StoreError.synchronizationInactive } guard let userId = self.userId else { @@ -1040,15 +1040,15 @@ public class StoreCenter { if let dataAccess = dataAccessCollection.first(where: { $0.modelId == instance.stringId }) { if users.isEmpty { - await dataAccessCollection.deleteAsync(instance: dataAccess) + try await dataAccessCollection.deleteAsync(instance: dataAccess) } else { dataAccess.sharedWith.removeAll() dataAccess.sharedWith = users - await dataAccessCollection.addOrUpdateAsync(instance: dataAccess) + try await dataAccessCollection.addOrUpdateAsync(instance: dataAccess) } } else { let dataAccess = DataAccess(owner: userId, sharedWith: users, modelName: String(describing: type(of: instance)), modelId: instance.stringId) - await dataAccessCollection.addOrUpdateAsync(instance: dataAccess) + try await dataAccessCollection.addOrUpdateAsync(instance: dataAccess) } } diff --git a/LeStorage/SyncedCollection.swift b/LeStorage/SyncedCollection.swift index c0b6e17..03704b4 100644 --- a/LeStorage/SyncedCollection.swift +++ b/LeStorage/SyncedCollection.swift @@ -53,6 +53,11 @@ public class SyncedCollection: BaseCollection, SomeSynced } } + func loadOnceAsync() async throws { + let items: [T] = try await self.storeCenter.service().get() + await self.loadItems(items, clear: true) + } + /// Updates a local item from a server instance. This method is typically used when the server makes update /// to an object when it's inserted. The SyncedCollection possibly needs to update its own copy with new values. /// - serverInstance: the instance of the object on the server @@ -85,12 +90,12 @@ public class SyncedCollection: BaseCollection, SomeSynced // MARK: - Basic operations with sync /// Adds or update an instance asynchronously and waits for network operations - func addOrUpdateAsync(instance: T) async { + func addOrUpdateAsync(instance: T) async throws { if let result = _addOrUpdateCore(instance: instance) { if result.isNewItem { - await self._executeBatchOnce(OperationBatch(insert: result.item)) + try await self._executeBatchOnce(OperationBatch(insert: result.item)) } else { - await self._executeBatchOnce(OperationBatch(update: result.item)) + try await self._executeBatchOnce(OperationBatch(update: result.item)) } } } @@ -185,9 +190,9 @@ public class SyncedCollection: BaseCollection, SomeSynced Task { await self._sendOperationBatch(batch) } } - func addOrUpdateAsync(contentOfs sequence: any Sequence) async { + func addOrUpdateAsync(contentOfs sequence: any Sequence) async throws { let batch = self._addOrUpdateCore(contentOfs: sequence) - await self._executeBatchOnce(batch) + try await self._executeBatchOnce(batch) } /// Proceeds to delete all instance of the collection, properly cleaning up dependencies and sending API calls @@ -224,19 +229,19 @@ public class SyncedCollection: BaseCollection, SomeSynced } /// 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) async { + public func deleteAsync(contentOfs sequence: any RandomAccessCollection) async throws{ guard sequence.isNotEmpty else { return } let batch = self._deleteCore(contentOfs: sequence) - await self._executeBatchOnce(batch) + try await self._executeBatchOnce(batch) } /// Deletes an instance and writes - func deleteAsync(instance: T) async { + func deleteAsync(instance: T) async throws{ defer { self.setChanged() } self._deleteNoWrite(instance: instance) - await self._executeBatchOnce(OperationBatch(delete: instance)) + try await self._executeBatchOnce(OperationBatch(delete: instance)) } /// Deletes an instance and writes @@ -327,12 +332,8 @@ public class SyncedCollection: BaseCollection, SomeSynced } } - fileprivate func _executeBatchOnce(_ batch: OperationBatch) async { - do { - try await self.storeCenter.singleBatchExecution(batch) - } catch { - Logger.error(error) - } + fileprivate func _executeBatchOnce(_ batch: OperationBatch) async throws { + try await self.storeCenter.singleBatchExecution(batch) } // MARK: Single calls