sync2
Laurent 11 months ago
commit f4b135c281
  1. 22
      LeStorage/Store.swift
  2. 48
      LeStorage/StoreCenter.swift
  3. 28
      LeStorage/StoredCollection.swift

@ -32,20 +32,6 @@ public enum StoreError: Error, LocalizedError {
}
//public struct StoreIdentifier {
// var value: String
// var parameterName: String
//
// public init(value: String, parameterName: String) {
// self.value = value
// self.parameterName = parameterName
// }
//
// var urlComponent: String {
// return "?\(self.parameterName)=\(self.value)"
// }
//}
final public class Store {
/// The Store singleton
@ -89,13 +75,13 @@ final public class Store {
/// - Parameters:
/// - indexed: Creates an index to quickly access the data
/// - inMemory: Indicates if the collection should only live in memory, and not write into a file
public func registerCollection<T : Storable>(indexed: Bool = false, inMemory: Bool = false) -> StoredCollection<T> {
public func registerCollection<T : Storable>(indexed: Bool = false, inMemory: Bool = false, limit: Int? = nil) -> StoredCollection<T> {
if let collection: StoredCollection<T> = try? self.collection() {
return collection
}
let collection = StoredCollection<T>(store: self, indexed: indexed, inMemory: inMemory)
let collection = StoredCollection<T>(store: self, indexed: indexed, inMemory: inMemory, limit: limit)
self._collections[T.resourceName()] = collection
return collection
@ -105,13 +91,13 @@ final public class Store {
/// - Parameters:
/// - indexed: Creates an index to quickly access the data
/// - inMemory: Indicates if the collection should only live in memory, and not write into a file
public func registerSynchronizedCollection<T : SyncedStorable>(indexed: Bool = false, inMemory: Bool = false) -> StoredCollection<T> {
public func registerSynchronizedCollection<T : SyncedStorable>(indexed: Bool = false, inMemory: Bool = false, limit: Int? = nil) -> StoredCollection<T> {
if let collection: StoredCollection<T> = try? self.collection() {
return collection
}
let collection = StoredCollection<T>(store: self, indexed: indexed, inMemory: inMemory)
let collection = StoredCollection<T>(store: self, indexed: indexed, inMemory: inMemory, limit: limit)
self._collections[T.resourceName()] = collection
StoreCenter.main.loadApiCallCollection(type: T.self)
return collection

@ -294,7 +294,24 @@ public class StoreCenter {
}
}
}
public func resetLoggingCollections() {
Task {
do {
try FileManager.default.removeItem(at: Log.urlForJSONFile())
try FileManager.default.removeItem(at: FailedAPICall.urlForJSONFile())
let facApiCallCollection: ApiCallCollection<FailedAPICall> = try self.apiCallCollection()
await facApiCallCollection.reset()
let logApiCallCollection: ApiCallCollection<Log> = try self.apiCallCollection()
await logApiCallCollection.reset()
} catch {
Logger.error(error)
}
}
}
/// Resets the ApiCall whose type identifies with the provided collection
/// - Parameters:
/// - collection: The collection identifying the Storable type
@ -699,7 +716,7 @@ public class StoreCenter {
/// This method triggers the framework to save and send failed api calls
public func logsFailedAPICalls() {
self._failedAPICallsCollection = Store.main.registerCollection()
self._failedAPICallsCollection = Store.main.registerCollection(limit: 50)
}
/// If configured for, logs and send to the server a failed API call
@ -823,27 +840,6 @@ public class StoreCenter {
// MARK: - Data Access
// public func giveUserAccess<T: SyncedStorable>(_ user: String, data: T) throws {
// guard let dataAccessCollection = self._dataAccess else {
// throw LeStorageError.dataAccessCollectionNotDefined
// }
// guard let userId = self.userId else {
// throw LeStorageError.cantCreateDataAccessBecauseUserIdIsNil
// }
// let collection: StoredCollection<T> = try Store.main.collection()
// guard collection.findById(data.id) != nil else {
// throw LeStorageError.cantCreateDataAccessBecauseNotInMainStore
// }
//
// if let dataAccess = dataAccessCollection.first(where: { $0.modelId == data.stringId }) {
// dataAccess.sharedWith.append(user)
// dataAccessCollection.addOrUpdate(instance: dataAccess)
// } else {
// let dataAccess = DataAccess(owner: userId, sharedWith: [user], modelName: String(describing: type(of: data)), modelId: data.stringId)
// dataAccessCollection.addOrUpdate(instance: dataAccess)
// }
// }
public func authorizedUsers(for modelId: String) -> [String] {
guard let dataAccessCollection = self._dataAccess else {
return []
@ -882,7 +878,7 @@ public class StoreCenter {
if let logs = self._logs {
return logs
} else {
let logsCollection: StoredCollection<Log> = Store.main.registerCollection()
let logsCollection: StoredCollection<Log> = Store.main.registerCollection(limit: 1000)
self._logs = logsCollection
return logsCollection
}
@ -890,8 +886,10 @@ public class StoreCenter {
/// Logs a message in the logs collection
public func log(message: String) {
let log = Log(message: message)
self._logsCollection().addOrUpdate(instance: log)
DispatchQueue.main.async {
let log = Log(message: message)
self._logsCollection().addOrUpdate(instance: log)
}
}
// MARK: - Migration

@ -67,14 +67,17 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
/// Indicates if the collection has loaded locally, with or without a file
fileprivate(set) public var hasLoaded: Bool = false
fileprivate(set) var limit: Int? = nil
init(store: Store, indexed: Bool = false, inMemory: Bool = false) {
// self.synchronized = synchronized
init(store: Store, indexed: Bool = false, inMemory: Bool = false, limit: Int? = nil) {
if indexed {
self._indexes = [:]
}
self.inMemory = inMemory
self.store = store
self.limit = limit
self.load()
}
@ -176,7 +179,15 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
}
}
// /// Sends a POST request for the instance, and changes the collection to perform a write
// public func writeChangeAndInsertOnServer(instance: T) {
// defer {
// self._hasChanged = true
// }
// self._sendInsertionIfNecessary(instance)
// }
/// A method the treat the collection as a single instance holder
func setSingletonNoSync(instance: T) {
defer {
@ -248,6 +259,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
self.items.append(instance)
instance.store = self.store
self._indexes?[instance.id] = instance
self._applyLimitIfPresent()
}
func updateItem(_ instance: T, index: Int) {
@ -266,15 +278,19 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti
}
func deleteItemIfUnused(_ instance: T) {
// find if instance if referenced elsewhere
// if so, delete
instance.deleteDependencies()
self.items.removeAll { $0.id == instance.id }
self._indexes?.removeValue(forKey: instance.id)
}
fileprivate func _applyLimitIfPresent() {
if let limit {
self.items = self.items.suffix(limit)
}
}
/// Returns the instance corresponding to the provided [id]
public func findById(_ id: T.ID) -> T? {
if let index = self._indexes, let instance = index[id] {

Loading…
Cancel
Save