You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
5.6 KiB
198 lines
5.6 KiB
//
|
|
// ApiCall.swift
|
|
// LeStorage
|
|
//
|
|
// Created by Laurent Morvillier on 04/02/2024.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public protocol SomeCall: Identifiable, Storable {
|
|
var id: String { get }
|
|
var lastAttemptDate: Date { get }
|
|
var attemptsCount: Int { get }
|
|
|
|
var method: HTTPMethod { get }
|
|
var dataId: String? { get }
|
|
var dataContent: String? { get }
|
|
}
|
|
|
|
public enum CallOption: String, Codable {
|
|
case additive // keeps the content of the current collection
|
|
}
|
|
|
|
public class ApiCall<T: Storable>: ModelObject, Storable, SomeCall {
|
|
|
|
public required override init() {
|
|
self.method = .get
|
|
super.init()
|
|
}
|
|
|
|
public static func resourceName() -> String { return "apicalls_" + T.resourceName() }
|
|
static func tokenExemptedMethods() -> [HTTPMethod] { return [] }
|
|
|
|
public var id: String = Store.randomId()
|
|
|
|
/// The transactionId serves to group calls together
|
|
var transactionId: String = Store.randomId()
|
|
|
|
/// Creation date of the call
|
|
var creationDate: Date? = Date()
|
|
|
|
/// The HTTP method of the call
|
|
public var method: HTTPMethod
|
|
|
|
/// The content of the call
|
|
var data: T?
|
|
|
|
/// The number of times the call has been executed
|
|
public var attemptsCount: Int = 0
|
|
|
|
/// The date of the last execution
|
|
public var lastAttemptDate: Date = Date()
|
|
|
|
/// The parameters to add in the URL to obtain : "?p1=v1&p2=v2"
|
|
var urlParameters: [String : String]? = nil
|
|
|
|
/// The option for the call
|
|
var option: CallOption? = nil
|
|
|
|
init(method: HTTPMethod, data: T?, transactionId: String? = nil, option: CallOption? = nil) {
|
|
self.method = method
|
|
self.data = data
|
|
if let transactionId {
|
|
self.transactionId = transactionId
|
|
}
|
|
self.option = option
|
|
}
|
|
|
|
public func copy(from other: any Storable) {
|
|
fatalError("should not happen")
|
|
}
|
|
|
|
func formattedURLParameters() -> String? {
|
|
return self.urlParameters?.toQueryString()
|
|
}
|
|
|
|
func urlExtension() -> String {
|
|
switch self.method {
|
|
case HTTPMethod.put, HTTPMethod.delete:
|
|
return T.path(id: self.data?.stringId)
|
|
case HTTPMethod.post:
|
|
return T.path()
|
|
case HTTPMethod.get:
|
|
if let parameters = self.urlParameters?.toQueryString() {
|
|
return T.path() + parameters
|
|
} else {
|
|
return T.path()
|
|
}
|
|
}
|
|
}
|
|
|
|
public var dataId: String? {
|
|
return self.data?.stringId
|
|
}
|
|
|
|
public var dataContent: String? {
|
|
if let data = self.data {
|
|
return try? data.jsonString()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
var storeId: String? { return self.urlParameters?[Services.storeIdURLParameter] }
|
|
|
|
public static func relationships() -> [Relationship] { return [] }
|
|
}
|
|
|
|
class OldApiCall<T: Storable>: ModelObject, Storable, SomeCall {
|
|
|
|
static func resourceName() -> String { return "apicalls_" + T.resourceName() }
|
|
static func tokenExemptedMethods() -> [HTTPMethod] { return [] }
|
|
|
|
var id: String = Store.randomId()
|
|
|
|
/// The transactionId to group calls together
|
|
var transactionId: String? = Store.randomId()
|
|
|
|
/// Creation date of the call
|
|
var creationDate: Date? = Date()
|
|
|
|
/// The HTTP method of the call
|
|
var method: HTTPMethod
|
|
|
|
/// The content of the call
|
|
var body: String?
|
|
|
|
/// The id of the underlying data stored in the body
|
|
var dataId: String?
|
|
|
|
/// The number of times the call has been executed
|
|
var attemptsCount: Int = 0
|
|
|
|
/// The date of the last execution
|
|
var lastAttemptDate: Date = Date()
|
|
|
|
/// The parameters to add in the URL to obtain : "?p1=v1&p2=v2"
|
|
var urlParameters: [String : String]? = nil
|
|
|
|
init(method: HTTPMethod, dataId: String? = nil, body: String? = nil, transactionId: String? = nil) {
|
|
self.method = method
|
|
self.dataId = dataId
|
|
self.body = body
|
|
if let transactionId {
|
|
self.transactionId = transactionId
|
|
}
|
|
}
|
|
|
|
init(method: HTTPMethod, data: T, transactionId: String? = nil) throws {
|
|
self.method = method
|
|
self.dataId = data.stringId
|
|
self.body = try data.jsonString()
|
|
if let transactionId {
|
|
self.transactionId = transactionId
|
|
}
|
|
}
|
|
|
|
func copy(from other: any Storable) {
|
|
fatalError("should not happen")
|
|
}
|
|
|
|
func formattedURLParameters() -> String? {
|
|
return self.urlParameters?.toQueryString()
|
|
}
|
|
|
|
func urlExtension() -> String {
|
|
switch self.method {
|
|
case HTTPMethod.put, HTTPMethod.delete:
|
|
return T.path(id: self.dataId)
|
|
case HTTPMethod.post:
|
|
return T.path()
|
|
case HTTPMethod.get:
|
|
if let parameters = self.urlParameters?.toQueryString() {
|
|
return T.path() + parameters
|
|
} else {
|
|
return T.path()
|
|
}
|
|
}
|
|
}
|
|
|
|
var dataContent: String? { return self.body }
|
|
|
|
static func relationships() -> [Relationship] { return [] }
|
|
|
|
func toNewApiCall() -> ApiCall<T>? {
|
|
if let instance: T = try? self.body?.decode() {
|
|
let apiCall = ApiCall(method: self.method, data: instance, transactionId: self.transactionId)
|
|
apiCall.id = self.id
|
|
apiCall.creationDate = self.creationDate
|
|
apiCall.attemptsCount = self.attemptsCount
|
|
apiCall.lastAttemptDate = self.lastAttemptDate
|
|
apiCall.urlParameters = self.urlParameters
|
|
return apiCall
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
}
|
|
|