|
|
|
|
@ -132,8 +132,8 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Starts the JSON file decoding synchronously or asynchronously |
|
|
|
|
fileprivate func _loadFromFile() throws { |
|
|
|
|
// let url: URL = try self._urlForJSONFile() |
|
|
|
|
|
|
|
|
|
if self.asynchronousIO { |
|
|
|
|
Task(priority: .high) { |
|
|
|
|
@ -214,6 +214,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// A method the treat the collection as a single instance holder |
|
|
|
|
func setSingletonNoSync(instance: T) { |
|
|
|
|
defer { |
|
|
|
|
self._hasChanged = true |
|
|
|
|
@ -251,6 +252,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Adds or update a sequence of elements |
|
|
|
|
public func addOrUpdate(contentOfs sequence: any Sequence<T>) throws { |
|
|
|
|
try self._addOrUpdate(contentOfs: sequence) |
|
|
|
|
} |
|
|
|
|
@ -310,6 +312,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Proceeds to delete all instance of the collection, properly cleaning up dependencies and sending API calls |
|
|
|
|
public func deleteAll() throws { |
|
|
|
|
try self.delete(contentOfs: self.items) |
|
|
|
|
} |
|
|
|
|
@ -350,10 +353,12 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
Logger.log("End write") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Simply clears the items of the collection |
|
|
|
|
func clear() { |
|
|
|
|
self.items.removeAll() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Removes the items of the collection, deletes the corresponding file, and also reset the related API calls collection |
|
|
|
|
public func reset() { |
|
|
|
|
self.items.removeAll() |
|
|
|
|
|
|
|
|
|
@ -373,6 +378,8 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
|
|
|
|
|
// MARK: - Synchronization |
|
|
|
|
|
|
|
|
|
/// Returns an APICall instance for the Storable [instance] and an HTTP [method] |
|
|
|
|
/// The method updates existing calls or creates a new one |
|
|
|
|
fileprivate func _callForInstance(_ instance: T, method: HTTPMethod) throws -> ApiCall<T>? { |
|
|
|
|
guard let apiCallCollection = self.apiCallsCollection else { |
|
|
|
|
throw StoredCollectionError.missingApiCallCollection |
|
|
|
|
@ -395,6 +402,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Creates an API call for the Storable [instance] and an HTTP [method] |
|
|
|
|
fileprivate func _createCall(_ instance: T, method: HTTPMethod) throws -> ApiCall<T> { |
|
|
|
|
let baseURL = try _store.service().baseURL |
|
|
|
|
let jsonString = try instance.jsonString() |
|
|
|
|
@ -410,6 +418,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
return ApiCall(url: url, method: method.rawValue, dataId: String(instance.id), body: jsonString) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Prepares a call for execution by updating its properties and adding it to its collection for storage |
|
|
|
|
fileprivate func _prepareCall(apiCall: ApiCall<T>) throws { |
|
|
|
|
apiCall.lastAttemptDate = Date() |
|
|
|
|
apiCall.attemptsCount += 1 |
|
|
|
|
@ -488,14 +497,15 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
/// Indicates if the collection is currently retrying ApiCalls |
|
|
|
|
fileprivate var _isRetryingCalls: Bool = false |
|
|
|
|
|
|
|
|
|
/// Reschedule API calls if necessary |
|
|
|
|
func rescheduleApiCallsIfNecessary() { |
|
|
|
|
if !self._isRetryingCalls { |
|
|
|
|
self._rescheduleApiCalls() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Reschedule API calls |
|
|
|
|
fileprivate func _rescheduleApiCalls() { |
|
|
|
|
// return |
|
|
|
|
|
|
|
|
|
guard let apiCallsCollection, apiCallsCollection.isNotEmpty else { |
|
|
|
|
return |
|
|
|
|
@ -532,6 +542,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Deletes an API call by [id] |
|
|
|
|
func deleteApiCallById(_ id: String) throws { |
|
|
|
|
guard let apiCallsCollection else { |
|
|
|
|
throw StoreError.apiCallCollectionNotRegistered(type: T.resourceName()) |
|
|
|
|
@ -539,6 +550,7 @@ public class StoredCollection<T: Storable>: RandomAccessCollection, SomeCollecti |
|
|
|
|
try apiCallsCollection.deleteById(id) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/// Returns if the API call collection is not empty |
|
|
|
|
func hasPendingAPICalls() -> Bool { |
|
|
|
|
guard let apiCallsCollection else { return false } |
|
|
|
|
return apiCallsCollection.isNotEmpty |
|
|
|
|
|