145 lines
4.1 KiB
Swift
145 lines
4.1 KiB
Swift
import Dependencies
|
|
import DependenciesMacros
|
|
import SharedModels
|
|
import Vapor
|
|
|
|
public extension DatabaseClient {
|
|
@DependencyClient
|
|
struct Vendors: Sendable {
|
|
public var create: @Sendable (Vendor.Create) async throws -> Vendor
|
|
public var delete: @Sendable (Vendor.ID) async throws -> Void
|
|
public var fetchAll: @Sendable (FetchRequest) async throws -> [Vendor]
|
|
public var get: @Sendable (Vendor.ID, GetRequest?) async throws -> Vendor?
|
|
public var update: @Sendable (Vendor.ID, Vendor.Update, GetRequest?) async throws -> Vendor
|
|
|
|
public enum FetchRequest: Sendable {
|
|
case all
|
|
case withBranches
|
|
}
|
|
|
|
public enum GetRequest: Sendable {
|
|
case withBranches
|
|
}
|
|
|
|
@Sendable
|
|
public func fetchAll() async throws -> [Vendor] {
|
|
try await fetchAll(.all)
|
|
}
|
|
|
|
@Sendable
|
|
public func get(_ id: Vendor.ID) async throws -> Vendor? {
|
|
try await get(id, nil)
|
|
}
|
|
|
|
@Sendable
|
|
public func update(
|
|
_ id: Vendor.ID,
|
|
with updates: Vendor.Update,
|
|
returnWithBranches: Bool = false
|
|
) async throws -> Vendor {
|
|
try await update(id, updates, returnWithBranches ? GetRequest.withBranches : nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension Vendor: Content {}
|
|
extension Vendor.Create: Content {}
|
|
extension Vendor.Update: Content {}
|
|
extension DatabaseClient.Vendors.FetchRequest: Content {}
|
|
extension DatabaseClient.Vendors.GetRequest: Content {}
|
|
|
|
extension DatabaseClient.Vendors: TestDependencyKey {
|
|
public static let testValue: DatabaseClient.Vendors = Self()
|
|
}
|
|
|
|
#if DEBUG
|
|
|
|
typealias VendorMockStorage = MockStorage<
|
|
Vendor,
|
|
Vendor.Create,
|
|
DatabaseClient.Vendors.FetchRequest,
|
|
DatabaseClient.Vendors.GetRequest,
|
|
Vendor.Update
|
|
>
|
|
|
|
private extension VendorMockStorage {
|
|
|
|
// swiftlint:disable function_body_length
|
|
static func vendors(_ mocks: [Vendor]) -> Self {
|
|
@Dependency(\.date.now) var now
|
|
@Dependency(\.uuid) var uuid
|
|
@Dependency(\.database.vendorBranches) var vendorBranches
|
|
|
|
return .init(
|
|
mocks,
|
|
create: {
|
|
Vendor(
|
|
id: uuid(),
|
|
name: $0.name,
|
|
createdAt: now,
|
|
updatedAt: now
|
|
)
|
|
},
|
|
fetch: { _ in
|
|
{ _ in true }
|
|
},
|
|
fetchExtras: { request, models in
|
|
guard request == .withBranches else { return models }
|
|
let branches = try await vendorBranches.fetchAll()
|
|
return models.map { model in
|
|
Vendor(
|
|
id: model.id,
|
|
name: model.name,
|
|
branches: Array(branches.filter { $0.vendorID == model.id }),
|
|
createdAt: model.createdAt,
|
|
updatedAt: model.updatedAt
|
|
)
|
|
}
|
|
},
|
|
get: { req, model in
|
|
guard req == .withBranches else { return model }
|
|
let branches = try await vendorBranches.fetchAll(.for(vendorID: model.id))
|
|
return Vendor(
|
|
id: model.id,
|
|
name: model.name,
|
|
branches: branches,
|
|
createdAt: model.createdAt,
|
|
updatedAt: model.updatedAt
|
|
)
|
|
},
|
|
update: { model, updates, get in
|
|
var branches: [VendorBranch]?
|
|
|
|
if get == .withBranches {
|
|
branches = try await vendorBranches.fetchAll(.for(vendorID: model.id))
|
|
}
|
|
|
|
let vendor = Vendor(
|
|
id: model.id,
|
|
name: updates.name ?? model.name,
|
|
branches: branches ?? model.branches,
|
|
createdAt: model.createdAt,
|
|
updatedAt: now
|
|
)
|
|
model = vendor
|
|
}
|
|
)
|
|
}
|
|
// swiftlint:enable function_body_length
|
|
}
|
|
|
|
public extension DatabaseClient.Vendors {
|
|
static func mock(_ mocks: [Vendor]) -> Self {
|
|
let storage = VendorMockStorage.vendors(mocks)
|
|
return .init(
|
|
create: { try await storage.create($0) },
|
|
delete: { try await storage.delete($0) },
|
|
fetchAll: { try await storage.fetchAll($0) },
|
|
get: { try await storage.get($0, $1) },
|
|
update: { req, updates, get in try await storage.update(req, updates, get) }
|
|
)
|
|
}
|
|
}
|
|
|
|
#endif
|