From 234bb42ea7554b45b63e074e04c3787c8bb3afcf Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 4 Jul 2024 17:57:36 +0200 Subject: [PATCH] Data migration capabilities + bug fix for singleton --- LeStorage/Services.swift | 4 ++++ LeStorage/Store.swift | 8 ++++++-- LeStorage/StoreCenter.swift | 9 +++++++++ LeStorage/StoredCollection.swift | 32 +++++++++++++++++++------------- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/LeStorage/Services.swift b/LeStorage/Services.swift index 8f38be3..8f2b4aa 100644 --- a/LeStorage/Services.swift +++ b/LeStorage/Services.swift @@ -400,6 +400,10 @@ public class Services { return nil } + func migrateToken(_ services: Services, userName: String) throws { + try self._storeToken(username: userName, token: services.keychainStore.getToken()) + } + } struct ErrorMessage { diff --git a/LeStorage/Store.swift b/LeStorage/Store.swift index 981c8aa..e34361a 100644 --- a/LeStorage/Store.swift +++ b/LeStorage/Store.swift @@ -83,7 +83,6 @@ open class Store { /// - sendsUpdate: Indicates if updates of items should be sent to the server public func registerCollection(synchronized: Bool, indexed: Bool = false, inMemory: Bool = false, sendsUpdate: Bool = true) -> StoredCollection { - // register collection let collection = StoredCollection(synchronized: synchronized, store: self, indexed: indexed, inMemory: inMemory, sendsUpdate: sendsUpdate) self._collections[T.resourceName()] = collection @@ -107,6 +106,11 @@ open class Store { let storedObject = StoredSingleton(synchronized: synchronized, store: self, inMemory: inMemory, sendsUpdate: sendsUpdate) self._collections[T.resourceName()] = storedObject + + if synchronized { + StoreCenter.main.loadApiCallCollection(type: T.self) + } + return storedObject } @@ -256,7 +260,7 @@ open class Store { /// Returns whether all collections have loaded locally public func collectionsAllLoaded() -> Bool { - return self._collections.values.allSatisfy { $0.hasLoadedLocally } + return self._collections.values.allSatisfy { $0.hasLoaded } } fileprivate var _validIds: [String] = [] diff --git a/LeStorage/StoreCenter.swift b/LeStorage/StoreCenter.swift index 34ca0fd..b4527eb 100644 --- a/LeStorage/StoreCenter.swift +++ b/LeStorage/StoreCenter.swift @@ -406,4 +406,13 @@ public class StoreCenter { } } + // MARK: - Migration + + public func migrateToken(_ services: Services) throws { + guard let userName = self.userName() else { + return + } + try self.service().migrateToken(services, userName: userName) + } + } diff --git a/LeStorage/StoredCollection.swift b/LeStorage/StoredCollection.swift index f66ba0b..c6b5fbd 100644 --- a/LeStorage/StoredCollection.swift +++ b/LeStorage/StoredCollection.swift @@ -23,7 +23,7 @@ protocol CollectionHolder { protocol SomeCollection: CollectionHolder, Identifiable { var resourceName: String { get } var synchronized: Bool { get } - var hasLoadedLocally: Bool { get } + var hasLoaded: Bool { get } func allItems() -> [any Storable] @@ -75,10 +75,7 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti fileprivate var asynchronousIO: Bool = true /// Indicates if the collection has loaded locally, with or without a file - fileprivate(set) public var hasLoadedLocally: Bool = false - - /// Indicates if the collection has loaded objects from the server - fileprivate(set) public var hasLoadedFromServer: Bool = false + fileprivate(set) public var hasLoaded: Bool = false init(synchronized: Bool, store: Store, indexed: Bool = false, asynchronousIO: Bool = true, inMemory: Bool = false, sendsUpdate: Bool = true) { self.synchronized = synchronized @@ -141,8 +138,6 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti /// Decodes the json file into the items array fileprivate func _decodeJSONFile() throws { - defer { self.hasLoadedLocally = true } - let fileURL = try self._store.fileURL(type: T.self) if FileManager.default.fileExists(atPath: fileURL.path()) { @@ -176,8 +171,10 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti } fileprivate func _setAsLoaded() { - self.hasLoadedLocally = true - NotificationCenter.default.post(name: NSNotification.Name.CollectionDidLoad, object: self) + self.hasLoaded = true + DispatchQueue.main.async { + NotificationCenter.default.post(name: NSNotification.Name.CollectionDidLoad, object: self) + } } fileprivate func _setItems(_ items: [T]) { @@ -202,13 +199,10 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti if items.count > 0 { try self._addOrUpdate(contentOfs: items, shouldSync: false) } - self.hasLoadedFromServer = true - DispatchQueue.main.async { - NotificationCenter.default.post(name: NSNotification.Name.CollectionDidLoad, object: self) - } } catch { Logger.error(error) } + self._setAsLoaded() } func loadCollectionsFromServerIfNoFile() async throws { @@ -364,6 +358,18 @@ public class StoredCollection: RandomAccessCollection, SomeCollecti try self.delete(contentOfs: self.items) } + // MARK: - Migrations + + public func insertAllIntoCurrentService() { + for item in self.items { + self._sendInsertionIfNecessary(item) + } + } + + public func insertIntoCurrentService(item: T) { + self._sendInsertionIfNecessary(item) + } + // MARK: - SomeCall /// Returns the collection items as [any Storable]