feat: Begins implementing dependencies as db controllers.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"originHash" : "c59e2480163811f4420fdf7da7e204df5b85f36e4d4106acb2ef4eedb9a90e2e",
|
"originHash" : "8af359d8d0bd04e1f21c9125fce09eb7d6a61a45a372b7485f4ecf4068fb7a53",
|
||||||
"pins" : [
|
"pins" : [
|
||||||
{
|
{
|
||||||
"identity" : "async-http-client",
|
"identity" : "async-http-client",
|
||||||
@@ -19,6 +19,15 @@
|
|||||||
"version" : "1.20.0"
|
"version" : "1.20.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "combine-schedulers",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/combine-schedulers",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "5928286acce13def418ec36d05a001a9641086f2",
|
||||||
|
"version" : "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "console-kit",
|
"identity" : "console-kit",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
@@ -145,6 +154,15 @@
|
|||||||
"version" : "1.2.0"
|
"version" : "1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-clocks",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-clocks",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "cc46202b53476d64e824e0b6612da09d84ffde8e",
|
||||||
|
"version" : "1.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-collections",
|
"identity" : "swift-collections",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
@@ -154,6 +172,15 @@
|
|||||||
"version" : "1.1.4"
|
"version" : "1.1.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-concurrency-extras",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-concurrency-extras",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "82a4ae7170d98d8538ec77238b7eb8e7199ef2e8",
|
||||||
|
"version" : "1.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-crypto",
|
"identity" : "swift-crypto",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
@@ -163,6 +190,15 @@
|
|||||||
"version" : "3.10.0"
|
"version" : "3.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-dependencies",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/swift-dependencies.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "85f89f5d0ce5a18945f65371d40ca997da85a41a",
|
||||||
|
"version" : "1.6.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-distributed-tracing",
|
"identity" : "swift-distributed-tracing",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
@@ -262,6 +298,15 @@
|
|||||||
"version" : "1.1.0"
|
"version" : "1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-syntax",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/swiftlang/swift-syntax",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "0687f71944021d616d34d922343dcef086855920",
|
||||||
|
"version" : "600.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-system",
|
"identity" : "swift-system",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
@@ -288,6 +333,15 @@
|
|||||||
"revision" : "4232d34efa49f633ba61afde365d3896fc7f8740",
|
"revision" : "4232d34efa49f633ba61afde365d3896fc7f8740",
|
||||||
"version" : "2.15.0"
|
"version" : "2.15.0"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "xctest-dynamic-overlay",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "a3f634d1a409c7979cabc0a71b3f26ffa9fc8af1",
|
||||||
|
"version" : "1.4.3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version" : 3
|
"version" : 3
|
||||||
|
|||||||
@@ -2,48 +2,52 @@
|
|||||||
import PackageDescription
|
import PackageDescription
|
||||||
|
|
||||||
let package = Package(
|
let package = Package(
|
||||||
name: "hhe-po",
|
name: "hhe-po",
|
||||||
platforms: [
|
platforms: [
|
||||||
.macOS(.v13)
|
.macOS(.v13)
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
// 💧 A server-side Swift web framework.
|
// 💧 A server-side Swift web framework.
|
||||||
.package(url: "https://github.com/vapor/vapor.git", from: "4.110.1"),
|
.package(url: "https://github.com/vapor/vapor.git", from: "4.110.1"),
|
||||||
// 🗄 An ORM for SQL and NoSQL databases.
|
// 🗄 An ORM for SQL and NoSQL databases.
|
||||||
.package(url: "https://github.com/vapor/fluent.git", from: "4.9.0"),
|
.package(url: "https://github.com/vapor/fluent.git", from: "4.9.0"),
|
||||||
// 🪶 Fluent driver for SQLite.
|
// 🪶 Fluent driver for SQLite.
|
||||||
.package(url: "https://github.com/vapor/fluent-sqlite-driver.git", from: "4.6.0"),
|
.package(url: "https://github.com/vapor/fluent-sqlite-driver.git", from: "4.6.0"),
|
||||||
// 🍃 An expressive, performant, and extensible templating language built for Swift.
|
// 🍃 An expressive, performant, and extensible templating language built for Swift.
|
||||||
.package(url: "https://github.com/vapor/leaf.git", from: "4.3.0"),
|
.package(url: "https://github.com/vapor/leaf.git", from: "4.3.0"),
|
||||||
// 🔵 Non-blocking, event-driven networking for Swift. Used for custom executors
|
// 🔵 Non-blocking, event-driven networking for Swift. Used for custom executors
|
||||||
.package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"),
|
.package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"),
|
||||||
],
|
.package(url: "https://github.com/pointfreeco/swift-dependencies.git", from: "1.6.3")
|
||||||
targets: [
|
],
|
||||||
.executableTarget(
|
targets: [
|
||||||
name: "App",
|
.executableTarget(
|
||||||
dependencies: [
|
name: "App",
|
||||||
.product(name: "Fluent", package: "fluent"),
|
dependencies: [
|
||||||
.product(name: "FluentSQLiteDriver", package: "fluent-sqlite-driver"),
|
.product(name: "Fluent", package: "fluent"),
|
||||||
.product(name: "Leaf", package: "leaf"),
|
.product(name: "FluentSQLiteDriver", package: "fluent-sqlite-driver"),
|
||||||
.product(name: "Vapor", package: "vapor"),
|
.product(name: "Leaf", package: "leaf"),
|
||||||
.product(name: "NIOCore", package: "swift-nio"),
|
.product(name: "Vapor", package: "vapor"),
|
||||||
.product(name: "NIOPosix", package: "swift-nio"),
|
.product(name: "NIOCore", package: "swift-nio"),
|
||||||
],
|
.product(name: "NIOPosix", package: "swift-nio"),
|
||||||
swiftSettings: swiftSettings
|
.product(name: "Dependencies", package: "swift-dependencies"),
|
||||||
),
|
.product(name: "DependenciesMacros", package: "swift-dependencies")
|
||||||
.testTarget(
|
|
||||||
name: "AppTests",
|
],
|
||||||
dependencies: [
|
swiftSettings: swiftSettings
|
||||||
.target(name: "App"),
|
),
|
||||||
.product(name: "VaporTesting", package: "vapor"),
|
.testTarget(
|
||||||
],
|
name: "AppTests",
|
||||||
swiftSettings: swiftSettings
|
dependencies: [
|
||||||
)
|
.target(name: "App"),
|
||||||
],
|
.product(name: "VaporTesting", package: "vapor")
|
||||||
swiftLanguageModes: [.v5]
|
],
|
||||||
|
swiftSettings: swiftSettings
|
||||||
|
)
|
||||||
|
],
|
||||||
|
swiftLanguageModes: [.v5]
|
||||||
)
|
)
|
||||||
|
|
||||||
var swiftSettings: [SwiftSetting] { [
|
var swiftSettings: [SwiftSetting] { [
|
||||||
.enableUpcomingFeature("DisableOutwardActorInference"),
|
.enableUpcomingFeature("DisableOutwardActorInference"),
|
||||||
.enableExperimentalFeature("StrictConcurrency"),
|
.enableExperimentalFeature("StrictConcurrency")
|
||||||
] }
|
] }
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import Dependencies
|
||||||
import Fluent
|
import Fluent
|
||||||
import Vapor
|
import Vapor
|
||||||
|
|
||||||
struct EmployeeApiController: RouteCollection {
|
struct EmployeeApiController: RouteCollection {
|
||||||
|
|
||||||
private let employeeDB = EmployeeDB()
|
@Dependency(\.employees) var employees
|
||||||
|
|
||||||
func boot(routes: any RoutesBuilder) throws {
|
func boot(routes: any RoutesBuilder) throws {
|
||||||
let protected = routes.apiProtected(route: "employees")
|
let protected = routes.apiProtected(route: "employees")
|
||||||
@@ -19,20 +20,20 @@ struct EmployeeApiController: RouteCollection {
|
|||||||
@Sendable
|
@Sendable
|
||||||
func index(req: Request) async throws -> [Employee.DTO] {
|
func index(req: Request) async throws -> [Employee.DTO] {
|
||||||
let params = try req.query.decode(EmployeesIndexQuery.self)
|
let params = try req.query.decode(EmployeesIndexQuery.self)
|
||||||
return try await employeeDB.fetchAll(active: params.active, on: req.db)
|
return try await employees.fetchAll(params.active ?? false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
func create(req: Request) async throws -> Employee.DTO {
|
func create(req: Request) async throws -> Employee.DTO {
|
||||||
try Employee.Create.validate(content: req)
|
try Employee.Create.validate(content: req)
|
||||||
let create = try req.content.decode(Employee.Create.self)
|
let create = try req.content.decode(Employee.Create.self)
|
||||||
return try await employeeDB.create(create, on: req.db)
|
return try await employees.create(create)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
func get(req: Request) async throws -> Employee.DTO {
|
func get(req: Request) async throws -> Employee.DTO {
|
||||||
guard let id = req.parameters.get("employeeID", as: Employee.IDValue.self),
|
guard let id = req.parameters.get("employeeID", as: Employee.IDValue.self),
|
||||||
let employee = try await employeeDB.get(id: id, on: req.db)
|
let employee = try await employees.get(id)
|
||||||
else {
|
else {
|
||||||
throw Abort(.notFound)
|
throw Abort(.notFound)
|
||||||
}
|
}
|
||||||
@@ -46,7 +47,7 @@ struct EmployeeApiController: RouteCollection {
|
|||||||
throw Abort(.badRequest, reason: "Employee id value not provided")
|
throw Abort(.badRequest, reason: "Employee id value not provided")
|
||||||
}
|
}
|
||||||
let updates = try req.content.decode(Employee.Update.self)
|
let updates = try req.content.decode(Employee.Update.self)
|
||||||
return try await employeeDB.update(id: employeeID, with: updates, on: req.db)
|
return try await employees.update(employeeID, updates)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
@@ -54,7 +55,7 @@ struct EmployeeApiController: RouteCollection {
|
|||||||
guard let employeeID = req.parameters.get("employeeID", as: Employee.IDValue.self) else {
|
guard let employeeID = req.parameters.get("employeeID", as: Employee.IDValue.self) else {
|
||||||
throw Abort(.badRequest, reason: "Employee id value not provided")
|
throw Abort(.badRequest, reason: "Employee id value not provided")
|
||||||
}
|
}
|
||||||
try await employeeDB.delete(id: employeeID, on: req.db)
|
try await employees.delete(employeeID)
|
||||||
return .ok
|
return .ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,114 @@
|
|||||||
|
import Dependencies
|
||||||
|
import DependenciesMacros
|
||||||
import Fluent
|
import Fluent
|
||||||
import Vapor
|
import Vapor
|
||||||
|
|
||||||
|
extension DependencyValues {
|
||||||
|
// An intermediate layer between our api and view controllers that interacts with the
|
||||||
|
// database model.
|
||||||
|
var employees: EmployeeDB {
|
||||||
|
get { self[EmployeeDB.self] }
|
||||||
|
set { self[EmployeeDB.self] = newValue }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@DependencyClient
|
||||||
|
struct EmployeeDB: Sendable {
|
||||||
|
var create: @Sendable (Employee.Create) async throws -> Employee.DTO
|
||||||
|
var fetchAll: @Sendable (Bool) async throws -> [Employee.DTO]
|
||||||
|
var get: @Sendable (Employee.IDValue) async throws -> Employee.DTO?
|
||||||
|
var update: @Sendable (Employee.IDValue, Employee.Update) async throws -> Employee.DTO
|
||||||
|
var delete: @Sendable (Employee.IDValue) async throws -> Void
|
||||||
|
|
||||||
|
func fetchAll() async throws -> [Employee.DTO] {
|
||||||
|
try await fetchAll(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EmployeeDB: TestDependencyKey {
|
||||||
|
static let testValue: EmployeeDB = Self()
|
||||||
|
|
||||||
|
static func live(database: any Database) -> Self {
|
||||||
|
.init(
|
||||||
|
create: { model in
|
||||||
|
let model = model.toModel()
|
||||||
|
try await model.save(on: database)
|
||||||
|
return model.toDTO()
|
||||||
|
},
|
||||||
|
fetchAll: { active in
|
||||||
|
var query = Employee.query(on: database)
|
||||||
|
.sort(\.$lastName)
|
||||||
|
|
||||||
|
if active {
|
||||||
|
query = query.filter(\.$active == active)
|
||||||
|
}
|
||||||
|
|
||||||
|
return try await query.all().map { $0.toDTO() }
|
||||||
|
},
|
||||||
|
get: { id in
|
||||||
|
try await Employee.find(id, on: database).map { $0.toDTO() }
|
||||||
|
},
|
||||||
|
update: { id, updates in
|
||||||
|
guard let employee = try await Employee.find(id, on: database) else {
|
||||||
|
throw Abort(.badRequest, reason: "Employee id not found.")
|
||||||
|
}
|
||||||
|
employee.applyUpdates(updates)
|
||||||
|
try await employee.save(on: database)
|
||||||
|
return employee.toDTO()
|
||||||
|
},
|
||||||
|
delete: { id in
|
||||||
|
guard let employee = try await Employee.find(id, on: database) else {
|
||||||
|
throw Abort(.badRequest, reason: "Employee id not found.")
|
||||||
|
}
|
||||||
|
try await employee.delete(on: database)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// An intermediate layer between our api and view controllers that interacts with the
|
// An intermediate layer between our api and view controllers that interacts with the
|
||||||
// database model.
|
// database model.
|
||||||
struct EmployeeDB {
|
// struct EmployeeDB {
|
||||||
|
//
|
||||||
func create(_ model: Employee.Create, on db: any Database) async throws -> Employee.DTO {
|
// func create(_ model: Employee.Create, on db: any Database) async throws -> Employee.DTO {
|
||||||
let model = model.toModel()
|
// let model = model.toModel()
|
||||||
try await model.save(on: db)
|
// try await model.save(on: db)
|
||||||
return model.toDTO()
|
// return model.toDTO()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func fetchAll(active: Bool? = nil, on db: any Database) async throws -> [Employee.DTO] {
|
// func fetchAll(active: Bool? = nil, on db: any Database) async throws -> [Employee.DTO] {
|
||||||
var query = Employee.query(on: db)
|
// var query = Employee.query(on: db)
|
||||||
.sort(\.$lastName)
|
// .sort(\.$lastName)
|
||||||
|
//
|
||||||
if let active {
|
// if let active {
|
||||||
query = query.filter(\.$active == active)
|
// query = query.filter(\.$active == active)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return try await query.all().map { $0.toDTO() }
|
// return try await query.all().map { $0.toDTO() }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func get(id: Employee.IDValue, on db: any Database) async throws -> Employee.DTO? {
|
// func get(id: Employee.IDValue, on db: any Database) async throws -> Employee.DTO? {
|
||||||
try await Employee.find(id, on: db).map { $0.toDTO() }
|
// try await Employee.find(id, on: db).map { $0.toDTO() }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func update(
|
// func update(
|
||||||
id: Employee.IDValue,
|
// id: Employee.IDValue,
|
||||||
with updates: Employee.Update,
|
// with updates: Employee.Update,
|
||||||
on db: any Database
|
// on db: any Database
|
||||||
) async throws -> Employee.DTO {
|
// ) async throws -> Employee.DTO {
|
||||||
guard let employee = try await Employee.find(id, on: db) else {
|
// guard let employee = try await Employee.find(id, on: db) else {
|
||||||
throw Abort(.badRequest, reason: "Employee id not found.")
|
// throw Abort(.badRequest, reason: "Employee id not found.")
|
||||||
}
|
// }
|
||||||
employee.applyUpdates(updates)
|
// employee.applyUpdates(updates)
|
||||||
try await employee.save(on: db)
|
// try await employee.save(on: db)
|
||||||
return employee.toDTO()
|
// return employee.toDTO()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func delete(id: Employee.IDValue, on db: any Database) async throws {
|
// func delete(id: Employee.IDValue, on db: any Database) async throws {
|
||||||
guard let employee = try await Employee.find(id, on: db) else {
|
// guard let employee = try await Employee.find(id, on: db) else {
|
||||||
throw Abort(.badRequest, reason: "Employee id not found.")
|
// throw Abort(.badRequest, reason: "Employee id not found.")
|
||||||
}
|
// }
|
||||||
try await employee.delete(on: db)
|
// try await employee.delete(on: db)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
|
import Dependencies
|
||||||
import Fluent
|
import Fluent
|
||||||
import Leaf
|
import Leaf
|
||||||
import Vapor
|
import Vapor
|
||||||
|
|
||||||
struct EmployeeViewController: RouteCollection {
|
struct EmployeeViewController: RouteCollection {
|
||||||
|
|
||||||
private let employees = EmployeeDB()
|
@Dependency(\.employees) var employees
|
||||||
private let api = EmployeeApiController()
|
private let api = EmployeeApiController()
|
||||||
|
|
||||||
func boot(routes: any RoutesBuilder) throws {
|
func boot(routes: any RoutesBuilder) throws {
|
||||||
@@ -22,16 +23,15 @@ struct EmployeeViewController: RouteCollection {
|
|||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
func index(req: Request) async throws -> View {
|
func index(req: Request) async throws -> View {
|
||||||
return try await req.view.render("employees/index", EmployeesCTX(db: employees, req: req))
|
return try await req.view.render("employees/index", EmployeesCTX())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
func create(req: Request) async throws -> View {
|
func create(req: Request) async throws -> View {
|
||||||
try Employee.Create.validate(content: req)
|
try Employee.Create.validate(content: req)
|
||||||
let model = try req.content.decode(Employee.Create.self)
|
let model = try req.content.decode(Employee.Create.self)
|
||||||
_ = try await employees.create(model, on: req.db)
|
_ = try await employees.create(model)
|
||||||
// _ = try await db.createEmployee(req: req)
|
return try await req.view.render("employees/index", EmployeesCTX(oob: true))
|
||||||
return try await req.view.render("employees/index", EmployeesCTX(oob: true, db: employees, req: req))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
@@ -41,14 +41,14 @@ struct EmployeeViewController: RouteCollection {
|
|||||||
}
|
}
|
||||||
employee.active.toggle()
|
employee.active.toggle()
|
||||||
try await employee.save(on: req.db)
|
try await employee.save(on: req.db)
|
||||||
let employees = try await employees.fetchAll(on: req.db)
|
let employees = try await employees.fetchAll()
|
||||||
return try await req.view.render("employees/table", ["employees": employees])
|
return try await req.view.render("employees/table", ["employees": employees])
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
func delete(req: Request) async throws -> View {
|
func delete(req: Request) async throws -> View {
|
||||||
_ = try await api.delete(req: req)
|
_ = try await api.delete(req: req)
|
||||||
let employees = try await employees.fetchAll(on: req.db)
|
let employees = try await employees.fetchAll()
|
||||||
return try await req.view.render("employees/table", ["employees": employees])
|
return try await req.view.render("employees/table", ["employees": employees])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ struct EmployeeViewController: RouteCollection {
|
|||||||
@Sendable
|
@Sendable
|
||||||
func update(req: Request) async throws -> View {
|
func update(req: Request) async throws -> View {
|
||||||
_ = try await api.update(req: req)
|
_ = try await api.update(req: req)
|
||||||
return try await req.view.render("employees/index", EmployeesCTX(oob: true, db: employees, req: req))
|
return try await req.view.render("employees/index", EmployeesCTX(oob: true))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
@@ -80,12 +80,11 @@ private struct EmployeesCTX: Content {
|
|||||||
|
|
||||||
init(
|
init(
|
||||||
oob: Bool = false,
|
oob: Bool = false,
|
||||||
employee: Employee? = nil,
|
employee: Employee? = nil
|
||||||
db: EmployeeDB,
|
|
||||||
req: Request
|
|
||||||
) async throws {
|
) async throws {
|
||||||
|
@Dependency(\.employees) var employees
|
||||||
self.oob = oob
|
self.oob = oob
|
||||||
self.employees = try await db.fetchAll(on: req.db)
|
self.employees = try await employees.fetchAll()
|
||||||
self.form = .init(employee: employee.map { $0.toDTO() })
|
self.form = .init(employee: employee.map { $0.toDTO() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import Dependencies
|
||||||
import Fluent
|
import Fluent
|
||||||
import FluentSQLiteDriver
|
import FluentSQLiteDriver
|
||||||
import Leaf
|
import Leaf
|
||||||
@@ -31,8 +32,12 @@ public func configure(_ app: Application) async throws {
|
|||||||
|
|
||||||
app.views.use(.leaf)
|
app.views.use(.leaf)
|
||||||
|
|
||||||
// register routes
|
try withDependencies {
|
||||||
try routes(app)
|
$0.employees = .live(database: app.db(.sqlite))
|
||||||
|
} operation: {
|
||||||
|
// register routes
|
||||||
|
try routes(app)
|
||||||
|
}
|
||||||
|
|
||||||
if app.environment != .production {
|
if app.environment != .production {
|
||||||
try await app.autoMigrate()
|
try await app.autoMigrate()
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ enum Entrypoint {
|
|||||||
try? await app.asyncShutdown()
|
try? await app.asyncShutdown()
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
try await app.execute()
|
try await app.execute()
|
||||||
try await app.asyncShutdown()
|
try await app.asyncShutdown()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user