Files
vapor-po/Sources/DatabaseClientLive/VendorBranches.swift

144 lines
3.3 KiB
Swift

import DatabaseClient
import FluentKit
import Foundation
import SharedModels
public extension DatabaseClient.VendorBranches {
static func live(database db: any Database) -> Self {
.init { create in
let model = try create.toModel()
try await model.save(on: db)
return model.toDTO()
} delete: { id in
guard let model = try await VendorBranchModel.find(id, on: db) else {
throw NotFoundError()
}
try await model.delete(on: db)
} fetchAll: { request in
var query = VendorBranchModel.query(on: db)
switch request {
case .all:
break
case .withVendor:
query = query.with(\.$vendor)
case let .for(vendorID: vendorID):
let branches = try await VendorModel.query(on: db)
.filter(\.$id == vendorID)
.with(\.$branches)
.first()?
.branches
.map { $0.toDTO() }
guard let branches else { throw NotFoundError() }
return branches
}
return try await query.all().map { $0.toDTO() }
} get: { id in
try await VendorBranchModel.find(id, on: db).map { $0.toDTO() }
} update: { id, updates in
guard let model = try await VendorBranchModel.find(id, on: db) else {
throw NotFoundError()
}
try model.applyUpdates(updates)
try await model.save(on: db)
return model.toDTO()
}
}
}
extension VendorBranch {
struct Migrate: AsyncMigration {
let name = "CreateVendorBranch"
func prepare(on database: Database) async throws {
try await database.schema(VendorBranchModel.schema)
.id()
.field("name", .string, .required)
.field("vendor_id", .uuid, .required)
.field("created_at", .datetime)
.field("updated_at", .datetime)
.foreignKey("vendor_id", references: VendorModel.schema, "id", onDelete: .cascade)
.create()
}
func revert(on database: Database) async throws {
try await database.schema(VendorBranchModel.schema).delete()
}
}
}
extension VendorBranch.Create {
func toModel() throws -> VendorBranchModel {
try validate()
return .init(name: name, vendorId: vendorID)
}
func validate() throws {
guard !name.isEmpty else {
throw ValidationError(message: "Vendor branch name should not be empty.")
}
}
}
extension VendorBranch.Update {
func validate() throws {
if let name {
guard !name.isEmpty else {
throw ValidationError(message: "Vendor branch name should not be empty.")
}
}
}
}
final class VendorBranchModel: Model, @unchecked Sendable {
static let schema = "vendor_branch"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Timestamp(key: "created_at", on: .create)
var createdAt: Date?
@Timestamp(key: "updated_at", on: .update)
var updatedAt: Date?
@Parent(key: "vendor_id")
var vendor: VendorModel
init() {}
init(id: UUID? = nil, name: String, vendorId: Vendor.ID) {
self.id = id
self.name = name
$vendor.id = vendorId
}
func toDTO() -> VendorBranch {
.init(
id: id,
name: name,
vendorID: $vendor.id,
createdAt: createdAt,
updatedAt: updatedAt
)
}
func applyUpdates(_ updates: VendorBranch.Update) throws {
try updates.validate()
if let name = updates.name {
self.name = name
}
}
}