Adds StoreLibrary to manage stores + fix init bug

sync3
Laurent 5 months ago
parent a3ec0820e4
commit dbd50eced0
  1. 4
      LeStorage.xcodeproj/project.pbxproj
  2. 58
      LeStorage/StoreCenter.swift
  3. 63
      LeStorage/StoreLibrary.swift
  4. 4
      LeStorage/StoredCollection.swift

@ -22,6 +22,7 @@
C488C8802CCBDC210082001F /* NetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C488C87F2CCBDC210082001F /* NetworkMonitor.swift */; };
C49774DF2DC4B3D7005CD239 /* SyncData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49774DE2DC4B3D7005CD239 /* SyncData.swift */; };
C49779FC2DDB5D89005CD239 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49779FB2DDB5D89005CD239 /* String+Extensions.swift */; };
C4977BA92DEDFE6D005CD239 /* StoreLibrary.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4977BA82DEDFE6D005CD239 /* StoreLibrary.swift */; };
C49B6E502C2089B6002BDE1B /* ApiCallCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49B6E4F2C2089B6002BDE1B /* ApiCallCollection.swift */; };
C49EF0242BD6BDC50077B5AA /* FileManager+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EF0232BD6BDC50077B5AA /* FileManager+Extensions.swift */; };
C4A47D4F2B6D280200ADC637 /* StoredCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A47D4E2B6D280200ADC637 /* StoredCollection.swift */; };
@ -81,6 +82,7 @@
C488C87F2CCBDC210082001F /* NetworkMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitor.swift; sourceTree = "<group>"; };
C49774DE2DC4B3D7005CD239 /* SyncData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncData.swift; sourceTree = "<group>"; };
C49779FB2DDB5D89005CD239 /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = "<group>"; };
C4977BA82DEDFE6D005CD239 /* StoreLibrary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreLibrary.swift; sourceTree = "<group>"; };
C49B6E4F2C2089B6002BDE1B /* ApiCallCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApiCallCollection.swift; sourceTree = "<group>"; };
C49EF0232BD6BDC50077B5AA /* FileManager+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+Extensions.swift"; sourceTree = "<group>"; };
C4A47D4E2B6D280200ADC637 /* StoredCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoredCollection.swift; sourceTree = "<group>"; };
@ -169,6 +171,7 @@
C4AC9CE92CF754CC00CC13DF /* Relationship.swift */,
C4A47D602B6D3C1300ADC637 /* Services.swift */,
C425D4572B6D2519002A7B48 /* Store.swift */,
C4977BA82DEDFE6D005CD239 /* StoreLibrary.swift */,
C4FC2E282C2B2EC30021F3BF /* StoreCenter.swift */,
C4A47D642B6E92FE00ADC637 /* Storable.swift */,
C4A47D4E2B6D280200ADC637 /* StoredCollection.swift */,
@ -366,6 +369,7 @@
C4D477972CB66EEA0077713D /* Date+Extensions.swift in Sources */,
C488C8802CCBDC210082001F /* NetworkMonitor.swift in Sources */,
C4A47D6D2B71364600ADC637 /* ModelObject.swift in Sources */,
C4977BA92DEDFE6D005CD239 /* StoreLibrary.swift in Sources */,
C49779FC2DDB5D89005CD239 /* String+Extensions.swift in Sources */,
C400D7232CC2AF560092237C /* GetSyncData.swift in Sources */,
C4A47D4F2B6D280200ADC637 /* StoredCollection.swift in Sources */,

@ -13,12 +13,11 @@ public class StoreCenter {
/// The main instance
public static let main: StoreCenter = StoreCenter()
fileprivate lazy var _storeLibrary: StoreLibrary = { StoreLibrary(storeCenter: self) }()
/// The name of the directory to store the json files
let directoryName: String
/// A dictionary of Stores associated to their id
fileprivate var _stores: [String: Store] = [:]
/// Returns a default Store instance
public lazy var mainStore: Store = { Store(storeCenter: self) }()
@ -185,50 +184,29 @@ public class StoreCenter {
// MARK: - Store management
/// Registers a store into the list of stores
/// - Parameters:
/// - store: A store to save
fileprivate func _registerStore(store: Store) {
guard let identifier = store.identifier else {
fatalError("The store has no identifier")
}
if self._stores[identifier] != nil {
fatalError("A store with this identifier has already been registered: \(identifier)")
}
self._stores[identifier] = store
}
/// Returns a store using its identifier, and registers it if it does not exists
/// - Parameters:
/// - identifier: The store identifer
/// - parameter: The parameter name used to filter data on the server
func requestStore(identifier: String) -> Store {
if let store = self._stores[identifier] {
return store
} else {
let store = Store(storeCenter: self, identifier: identifier)
self._registerStore(store: store)
return store
}
return self._storeLibrary.requestStore(identifier: identifier)
}
/// 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
}
return self._storeLibrary.requestStore(identifier: storeId)
// 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] {
if let storeId = id, let store = self._storeLibrary[storeId] {
return store
} else {
return self.mainStore
@ -236,7 +214,7 @@ public class StoreCenter {
}
public func store(identifier: String) throws -> Store {
if let store = self._stores[identifier] {
if let store = self._storeLibrary[identifier] {
return store
}
throw StoreError.storeNotRegistered(id: identifier)
@ -246,9 +224,7 @@ public class StoreCenter {
/// - 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)
self._storeLibrary.destroyStore(identifier: identifier)
}
// MARK: - Settings
@ -290,7 +266,7 @@ public class StoreCenter {
self.resetApiCalls()
self._failedAPICallsCollection?.reset()
self._stores.removeAll()
self._storeLibrary.reset()
self.dataAccessCollection?.reset()
self._deleteLogs.reset()
@ -840,7 +816,7 @@ public class StoreCenter {
func relationshipStore<T: SyncedStorable>(instance: T, relationship: Relationship) -> Store? {
switch relationship.storeLookup {
case .main: return Store.main
case .child: return self._stores[instance.stringId]
case .child: return self._storeLibrary[instance.stringId]
case .same: return instance.store
}
}

@ -0,0 +1,63 @@
//
// StoreLibrary.swift
// LeStorage
//
// Created by Laurent Morvillier on 02/06/2025.
//
import Foundation
class StoreLibrary {
private let storeCenter: StoreCenter
/// A dictionary of Stores associated to their id
fileprivate var _stores: [String: Store] = [:]
init(storeCenter: StoreCenter) {
self.storeCenter = storeCenter
}
subscript(identifier: String) -> Store? {
get {
return self._stores[identifier]
}
}
/// Registers a store into the list of stores
/// - Parameters:
/// - store: A store to save
fileprivate func _registerStore(store: Store) {
guard let identifier = store.identifier else {
fatalError("The store has no identifier")
}
if self._stores[identifier] != nil {
fatalError("A store with this identifier has already been registered: \(identifier)")
}
self._stores[identifier] = store
}
/// Returns a store using its identifier, and registers it if it does not exists
/// - Parameters:
/// - identifier: The store identifer
/// - parameter: The parameter name used to filter data on the server
func requestStore(identifier: String) -> Store {
if let store = self._stores[identifier] {
return store
} else {
let store = Store(storeCenter: self.storeCenter, identifier: identifier)
self._registerStore(store: store)
return store
}
}
public func destroyStore(identifier: String) {
let directory = "\(self.storeCenter.directoryName)/\(identifier)"
FileManager.default.deleteDirectoryInDocuments(directoryName: directory)
self._stores.removeValue(forKey: identifier)
}
func reset() {
self._stores.removeAll()
}
}

@ -201,10 +201,8 @@ public class StoredCollection<T: Storable>: SomeCollection {
/// Sets a collection of items and indexes them
func setItems(_ items: [T]) {
for item in items {
item.store = self.store
self.addItem(instance: item)
}
self.items = items
self._updateIndexIfNecessary()
}
@MainActor

Loading…
Cancel
Save