Data migration capabilities + bug fix for singleton

sync
Laurent 1 year ago
parent fe78bbbe43
commit 234bb42ea7
  1. 4
      LeStorage/Services.swift
  2. 8
      LeStorage/Store.swift
  3. 9
      LeStorage/StoreCenter.swift
  4. 32
      LeStorage/StoredCollection.swift

@ -400,6 +400,10 @@ public class Services {
return nil return nil
} }
func migrateToken(_ services: Services, userName: String) throws {
try self._storeToken(username: userName, token: services.keychainStore.getToken())
}
} }
struct ErrorMessage { struct ErrorMessage {

@ -83,7 +83,6 @@ open class Store {
/// - sendsUpdate: Indicates if updates of items should be sent to the server /// - sendsUpdate: Indicates if updates of items should be sent to the server
public func registerCollection<T : Storable>(synchronized: Bool, indexed: Bool = false, inMemory: Bool = false, sendsUpdate: Bool = true) -> StoredCollection<T> { public func registerCollection<T : Storable>(synchronized: Bool, indexed: Bool = false, inMemory: Bool = false, sendsUpdate: Bool = true) -> StoredCollection<T> {
// register collection
let collection = StoredCollection<T>(synchronized: synchronized, store: self, indexed: indexed, inMemory: inMemory, sendsUpdate: sendsUpdate) let collection = StoredCollection<T>(synchronized: synchronized, store: self, indexed: indexed, inMemory: inMemory, sendsUpdate: sendsUpdate)
self._collections[T.resourceName()] = collection self._collections[T.resourceName()] = collection
@ -107,6 +106,11 @@ open class Store {
let storedObject = StoredSingleton<T>(synchronized: synchronized, store: self, inMemory: inMemory, sendsUpdate: sendsUpdate) let storedObject = StoredSingleton<T>(synchronized: synchronized, store: self, inMemory: inMemory, sendsUpdate: sendsUpdate)
self._collections[T.resourceName()] = storedObject self._collections[T.resourceName()] = storedObject
if synchronized {
StoreCenter.main.loadApiCallCollection(type: T.self)
}
return storedObject return storedObject
} }
@ -256,7 +260,7 @@ open class Store {
/// Returns whether all collections have loaded locally /// Returns whether all collections have loaded locally
public func collectionsAllLoaded() -> Bool { public func collectionsAllLoaded() -> Bool {
return self._collections.values.allSatisfy { $0.hasLoadedLocally } return self._collections.values.allSatisfy { $0.hasLoaded }
} }
fileprivate var _validIds: [String] = [] fileprivate var _validIds: [String] = []

@ -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)
}
} }

@ -23,7 +23,7 @@ protocol CollectionHolder {
protocol SomeCollection: CollectionHolder, Identifiable { protocol SomeCollection: CollectionHolder, Identifiable {
var resourceName: String { get } var resourceName: String { get }
var synchronized: Bool { get } var synchronized: Bool { get }
var hasLoadedLocally: Bool { get } var hasLoaded: Bool { get }
func allItems() -> [any Storable] func allItems() -> [any Storable]
@ -75,10 +75,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
fileprivate var asynchronousIO: Bool = true fileprivate var asynchronousIO: Bool = true
/// Indicates if the collection has loaded locally, with or without a file /// Indicates if the collection has loaded locally, with or without a file
fileprivate(set) public var hasLoadedLocally: Bool = false fileprivate(set) public var hasLoaded: Bool = false
/// Indicates if the collection has loaded objects from the server
fileprivate(set) public var hasLoadedFromServer: Bool = false
init(synchronized: Bool, store: Store, indexed: Bool = false, asynchronousIO: Bool = true, inMemory: Bool = false, sendsUpdate: Bool = true) { init(synchronized: Bool, store: Store, indexed: Bool = false, asynchronousIO: Bool = true, inMemory: Bool = false, sendsUpdate: Bool = true) {
self.synchronized = synchronized self.synchronized = synchronized
@ -141,8 +138,6 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
/// Decodes the json file into the items array /// Decodes the json file into the items array
fileprivate func _decodeJSONFile() throws { fileprivate func _decodeJSONFile() throws {
defer { self.hasLoadedLocally = true }
let fileURL = try self._store.fileURL(type: T.self) let fileURL = try self._store.fileURL(type: T.self)
if FileManager.default.fileExists(atPath: fileURL.path()) { if FileManager.default.fileExists(atPath: fileURL.path()) {
@ -176,8 +171,10 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
} }
fileprivate func _setAsLoaded() { fileprivate func _setAsLoaded() {
self.hasLoadedLocally = true self.hasLoaded = true
NotificationCenter.default.post(name: NSNotification.Name.CollectionDidLoad, object: self) DispatchQueue.main.async {
NotificationCenter.default.post(name: NSNotification.Name.CollectionDidLoad, object: self)
}
} }
fileprivate func _setItems(_ items: [T]) { fileprivate func _setItems(_ items: [T]) {
@ -202,13 +199,10 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
if items.count > 0 { if items.count > 0 {
try self._addOrUpdate(contentOfs: items, shouldSync: false) try self._addOrUpdate(contentOfs: items, shouldSync: false)
} }
self.hasLoadedFromServer = true
DispatchQueue.main.async {
NotificationCenter.default.post(name: NSNotification.Name.CollectionDidLoad, object: self)
}
} catch { } catch {
Logger.error(error) Logger.error(error)
} }
self._setAsLoaded()
} }
func loadCollectionsFromServerIfNoFile() async throws { func loadCollectionsFromServerIfNoFile() async throws {
@ -364,6 +358,18 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
try self.delete(contentOfs: self.items) 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 // MARK: - SomeCall
/// Returns the collection items as [any Storable] /// Returns the collection items as [any Storable]

Loading…
Cancel
Save