merge with main

sync2
Laurent 9 months ago
commit 70cb758dba
  1. 67
      LeStorage/ApiCallCollection.swift
  2. 21
      LeStorage/Services.swift

@ -238,38 +238,40 @@ actor ApiCallCollection<T: SyncedStorable>: SomeCallCollection {
fileprivate func _call(method: HTTPMethod, instance: T? = nil) async throws -> ApiCall<T>? { fileprivate func _call(method: HTTPMethod, instance: T? = nil) async throws -> ApiCall<T>? {
if let instance { if let instance {
return try await self._callForInstance(method, instance: instance) return try await self._callForInstance(instance, method: method)
} else { } else {
if self.items.contains(where: { $0.method == .get }) { if self.items.contains(where: { $0.method == .get }) {
return nil return nil
} else { } else {
return try self._createCall(.get) return try self._createGetCall()
} }
} }
} }
fileprivate func _callForInstance(_ method: HTTPMethod, instance: T) async throws -> ApiCall<T>? { fileprivate func _callForInstance(_ instance: T, method: HTTPMethod, transactionId: String? = nil) async throws -> ApiCall<T> {
if let existingCall = self.items.first(where: { $0.dataId == instance.stringId }) { // cleanup
switch method { let existingCalls = self.items.filter { $0.dataId == instance.stringId }
case .delete: self._deleteCalls(existingCalls)
self.deleteById(existingCall.id) // delete the existing call as we don't need it
if existingCall.method == HTTPMethod.post { // create
return nil // if the post has not been done, we can just stop here let call = try self._createCall(method, instance: instance, transactionId: transactionId)
} else { self._prepareCall(apiCall: call)
return try self._createCall(method, instance: instance) // otherwise it's a put and we want to send the delete return call
} }
default: // here we should only trying to PUT, so we update the existing POST/PUT with the instance new values
existingCall.body = try instance.jsonString() fileprivate func _deleteCalls(_ calls: [ApiCall<T>]) {
return existingCall for call in calls {
self.deleteById(call.id)
} }
} else {
return try self._createCall(method, instance: instance)
} }
fileprivate func _createGetCall() throws -> ApiCall<T> {
return try self._createCall(.get, instance: nil)
} }
/// Creates an API call for the Storable [instance] and an HTTP [method] /// Creates an API call for the Storable [instance] and an HTTP [method]
fileprivate func _createCall(_ method: HTTPMethod, instance: T? = nil, transactionId: String? = nil) throws -> ApiCall<T> { fileprivate func _createCall(_ method: HTTPMethod, instance: T?, transactionId: String? = nil) throws -> ApiCall<T> {
if let instance { if let instance {
let jsonString = try instance.jsonString() let jsonString = try instance.jsonString()
return ApiCall(method: method, dataId: instance.stringId, body: jsonString, transactionId: transactionId) return ApiCall(method: method, dataId: instance.stringId, body: jsonString, transactionId: transactionId)
@ -302,31 +304,34 @@ actor ApiCallCollection<T: SyncedStorable>: SomeCallCollection {
var apiCalls: [ApiCall<T>] = [] var apiCalls: [ApiCall<T>] = []
let transactionId = Store.randomId() let transactionId = Store.randomId()
for insert in batch.inserts { for insert in batch.inserts {
let call = try self._createCall(.post, instance: insert, transactionId: transactionId) let call = try await self._callForInstance(insert, method: .post, transactionId: transactionId)
self._prepareCall(apiCall: call)
apiCalls.append(call) apiCalls.append(call)
} }
for update in batch.updates { for update in batch.updates {
let call = try self._createCall(.put, instance: update, transactionId: transactionId) let call = try await self._callForInstance(update, method: .put, transactionId: transactionId)
self._prepareCall(apiCall: call)
apiCalls.append(call) apiCalls.append(call)
} }
for delete in batch.deletes { for delete in batch.deletes {
let call = try self._createCall(.delete, instance: delete, transactionId: transactionId) let call = try await self._callForInstance(delete, method: .delete, transactionId: transactionId)
self._prepareCall(apiCall: call)
apiCalls.append(call) apiCalls.append(call)
} }
return try await self._executeApiCalls(apiCalls) return try await self._executeApiCalls(apiCalls)
} }
/// Initiates the process of sending the data with the server // /// Initiates the process of sending the data with the server
fileprivate func _sendServerRequest<V: Decodable>(_ method: HTTPMethod, instance: T? = nil) async throws -> V? { //<<<<<<< HEAD
if let apiCall = try await self._call(method: method, instance: instance) { // fileprivate func _sendServerRequest<V: Decodable>(_ method: HTTPMethod, instance: T? = nil) async throws -> V? {
return try await self._prepareAndSendCall(apiCall) // if let apiCall = try await self._call(method: method, instance: instance) {
} else { // return try await self._prepareAndSendCall(apiCall)
return nil //=======
} // fileprivate func _synchronize<V: Decodable>(_ instance: T, method: HTTPMethod) async throws -> V? {
} // if let apiCall = try await self._callForInstance(instance, method: method) {
// return try await self._executeApiCall(apiCall)
//>>>>>>> main
// } else {
// return nil
// }
// }
fileprivate func _prepareAndSendCall<V: Decodable>(_ apiCall: ApiCall<T>) async throws -> V? { fileprivate func _prepareAndSendCall<V: Decodable>(_ apiCall: ApiCall<T>) async throws -> V? {
self._prepareCall(apiCall: apiCall) self._prepareCall(apiCall: apiCall)

@ -352,6 +352,27 @@ public class Services {
return request return request
} }
//=======
//
// /// Executes a PUT request
// public func put<T: Storable>(_ instance: T) async throws -> T {
// var postRequest = try self._putRequest(type: T.self, id: instance.stringId)
// postRequest.httpBody = try jsonEncoder.encode(instance)
// return try await self._runRequest(postRequest)
// }
//
// public func delete<T: Storable>(_ instance: T) async throws -> T {
// let deleteRequest = try self._deleteRequest(type: T.self, id: instance.stringId)
// return try await self._runRequest(deleteRequest)
// }
//
// /// Executes an ApiCall
// func runApiCall<T: Storable, V: Decodable>(_ apiCall: ApiCall<T>) async throws -> V {
// let request = try self._request(from: apiCall)
// print("HTTP \(request.httpMethod ?? "") : id = \(apiCall.dataId)")
// return try await self._runRequest(request, apiCall: apiCall)
//>>>>>>> main
// }
/// Returns the URLRequest for an ApiCall /// Returns the URLRequest for an ApiCall
/// - Parameters: /// - Parameters:

Loading…
Cancel
Save