没有请求的 Vapor 3 PostgreSQL CRUD http
Vapor 3 PostgreSQL CRUD without requests http
我正在使用 Xcode 11.2 和 Swift 5.1 基于 Vapor 3.1.10 创建后端,数据库是 PostgreSQL 12。我有一个问题:如何在没有 POST 和 GET 请求。所有教程都展示了如何通过 HTTPS 仅基于 Request 进行增删改查。但是,如果我的应用程序需要在不与网络交互的情况下将某些内容保存在数据库中怎么办?看我的代码:
import Vapor
import FluentPostgreSQL
final class Device: PostgreSQLModel {
var id: Int?
var isWorking: Bool
var serial: Int
init(isWorking: Bool, serial: Int) {
self.isWorking = isWorking
self.serial = serial
}
}
extension Device: Content {}
extension Device: Migration {}
extension Device: Parameter {}
写或读的经典方法是:
import Vapor
final class DeviceController {
func readAll(_ req: Request) throws -> Future<[Device]> {
return Device.query(on: req).all()
}
func create(_ req: Request) throws -> Future<Device> {
return try req.content.decode(Device.self).flatMap { device in
return device.save(on: req)
}
}
}
如何将 req
替换为我可以在本地创建的另一个后台安全线程?
例如:
let device = Device(isWorking: true, serial: 54321)
device.save(on: <#T##DatabaseConnectable#>)
如何替换<#T##DatabaseConnectable#>
?
如有任何帮助或建议,我将不胜感激。
Request
是 Container
,它有 eventLoop
,它是 DatabaseConnectable
。
Application
,是Container
,有eventLoop
,不是DatabaseConnectable
。
如何使用 Application
进行数据库查询?
在任何 Container
上,您可以获得到数据库的池连接,您可能猜到这个连接是 DatabaseConnectable
。
boot.swift
中的示例查询
import Vapor
import FluentSQL
import FluentPostgreSQL
public func boot(_ app: Application) throws {
let _ = app.requestPooledConnection(to: .psql).flatMap { conn in
return User.query(conn).all().map { users in
print("just found \(users.count) users")
}.always {
try? app.releasePooledConnection(conn, to: .psql)
}
}
}
上面的代码将通过 Application
容器中的 .psql
标识符请求到 PostgreSQL 的池连接,然后在该连接上执行查询,然后在 always
中阻止它释放该连接回池.
从哪里获得后台任务的 Container
?
如果您使用 https://github.com/vapor/jobs or https://github.com/MihaelIsaev/VaporCron,您将在任务声明中有一个 Container
对象。
VaporCron
的示例
// in boot.swift
import Vapor
import VaporCron
/// Called after your application has initialized.
public func boot(_ app: Application) throws {
scheduleTasks(on: app)
}
/// Scheduling Cron tasks
private func scheduleTasks(on app: Application) {
do {
_ = try VaporCron.schedule(Every1MinCheck.self, on: app)
} catch {
print("cron schedule error: \(error)")
}
}
// in Every1MinCheck.swift
import Vapor
import VaporCron
import FluentSQL
import PostgreSQL
struct Every1MinCheck: VaporCronSchedulable {
static var expression: String { return "*/1 * * * *" } // every 1 minute
static func task(on container: VaporCronContainer) -> Future<Void> {
return container.requestPooledConnection(to: .psql).flatMap { conn in
return User.query(conn).all().map { users in
print("just found \(users.count) users")
}.always {
try? container.releasePooledConnection(conn, to: .psql)
}
}
}
}
基于这个问答()我实现CRUD是这样的:
import Vapor
import FluentPostgreSQL
final class Device: PostgreSQLModel {
var id: Int?
var isWorking: Bool
var serial: Int
init(isWorking: Bool, serial: Int) {
self.isWorking = isWorking
self.serial = serial
}
}
extension Device: Content {}
extension Device: Migration {}
extension Device: Parameter {}
final class WorkWithPostgres {
let databaseConfig = PostgreSQLDatabaseConfig(hostname: "localhost", port: 5432, username: "username", database: "testestest", password: nil)
let database: PostgreSQLDatabase
static let shared = WorkWithPostgres()
private init() {
database = PostgreSQLDatabase(config: databaseConfig)
}
func readAll<T: PostgreSQLModel>(postgreSQLModel: T.Type, completion: (([T]) -> Void)?) {
let worker = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let conn = database.newConnection(on: worker)
let _ = conn.map { connection in
postgreSQLModel.query(on: connection).all().map { databaseData in
worker.shutdownGracefully { _ in
}
completion?(databaseData)
}
}
}
func create<T: PostgreSQLModel>(postgreSQLModel: T) {
let worker = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let conn = database.newConnection(on: worker)
let _ = conn.map { connection in
let _ = postgreSQLModel.save(on: connection).whenComplete {
worker.shutdownGracefully { _ in
}
}
}
}
}
final class DeviceController {
func readAll(completion: (([Device]) -> Void)?) {
WorkWithPostgres.shared.readAll(postgreSQLModel: Device.self) { devices in
completion?(devices)
}
}
func create(isWorking: Bool, serial: Int) {
let device = Device(isWorking: isWorking, serial: serial)
WorkWithPostgres.shared.create(postgreSQLModel: device)
}
}
它正在运行,但我不确定这样做是否是个好方法。有人知道吗?
我正在使用 Xcode 11.2 和 Swift 5.1 基于 Vapor 3.1.10 创建后端,数据库是 PostgreSQL 12。我有一个问题:如何在没有 POST 和 GET 请求。所有教程都展示了如何通过 HTTPS 仅基于 Request 进行增删改查。但是,如果我的应用程序需要在不与网络交互的情况下将某些内容保存在数据库中怎么办?看我的代码:
import Vapor
import FluentPostgreSQL
final class Device: PostgreSQLModel {
var id: Int?
var isWorking: Bool
var serial: Int
init(isWorking: Bool, serial: Int) {
self.isWorking = isWorking
self.serial = serial
}
}
extension Device: Content {}
extension Device: Migration {}
extension Device: Parameter {}
写或读的经典方法是:
import Vapor
final class DeviceController {
func readAll(_ req: Request) throws -> Future<[Device]> {
return Device.query(on: req).all()
}
func create(_ req: Request) throws -> Future<Device> {
return try req.content.decode(Device.self).flatMap { device in
return device.save(on: req)
}
}
}
如何将 req
替换为我可以在本地创建的另一个后台安全线程?
例如:
let device = Device(isWorking: true, serial: 54321)
device.save(on: <#T##DatabaseConnectable#>)
如何替换<#T##DatabaseConnectable#>
?
如有任何帮助或建议,我将不胜感激。
Request
是 Container
,它有 eventLoop
,它是 DatabaseConnectable
。
Application
,是Container
,有eventLoop
,不是DatabaseConnectable
。
如何使用 Application
进行数据库查询?
在任何 Container
上,您可以获得到数据库的池连接,您可能猜到这个连接是 DatabaseConnectable
。
boot.swift
import Vapor
import FluentSQL
import FluentPostgreSQL
public func boot(_ app: Application) throws {
let _ = app.requestPooledConnection(to: .psql).flatMap { conn in
return User.query(conn).all().map { users in
print("just found \(users.count) users")
}.always {
try? app.releasePooledConnection(conn, to: .psql)
}
}
}
上面的代码将通过 Application
容器中的 .psql
标识符请求到 PostgreSQL 的池连接,然后在该连接上执行查询,然后在 always
中阻止它释放该连接回池.
从哪里获得后台任务的 Container
?
如果您使用 https://github.com/vapor/jobs or https://github.com/MihaelIsaev/VaporCron,您将在任务声明中有一个 Container
对象。
VaporCron
// in boot.swift
import Vapor
import VaporCron
/// Called after your application has initialized.
public func boot(_ app: Application) throws {
scheduleTasks(on: app)
}
/// Scheduling Cron tasks
private func scheduleTasks(on app: Application) {
do {
_ = try VaporCron.schedule(Every1MinCheck.self, on: app)
} catch {
print("cron schedule error: \(error)")
}
}
// in Every1MinCheck.swift
import Vapor
import VaporCron
import FluentSQL
import PostgreSQL
struct Every1MinCheck: VaporCronSchedulable {
static var expression: String { return "*/1 * * * *" } // every 1 minute
static func task(on container: VaporCronContainer) -> Future<Void> {
return container.requestPooledConnection(to: .psql).flatMap { conn in
return User.query(conn).all().map { users in
print("just found \(users.count) users")
}.always {
try? container.releasePooledConnection(conn, to: .psql)
}
}
}
}
基于这个问答(
import Vapor
import FluentPostgreSQL
final class Device: PostgreSQLModel {
var id: Int?
var isWorking: Bool
var serial: Int
init(isWorking: Bool, serial: Int) {
self.isWorking = isWorking
self.serial = serial
}
}
extension Device: Content {}
extension Device: Migration {}
extension Device: Parameter {}
final class WorkWithPostgres {
let databaseConfig = PostgreSQLDatabaseConfig(hostname: "localhost", port: 5432, username: "username", database: "testestest", password: nil)
let database: PostgreSQLDatabase
static let shared = WorkWithPostgres()
private init() {
database = PostgreSQLDatabase(config: databaseConfig)
}
func readAll<T: PostgreSQLModel>(postgreSQLModel: T.Type, completion: (([T]) -> Void)?) {
let worker = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let conn = database.newConnection(on: worker)
let _ = conn.map { connection in
postgreSQLModel.query(on: connection).all().map { databaseData in
worker.shutdownGracefully { _ in
}
completion?(databaseData)
}
}
}
func create<T: PostgreSQLModel>(postgreSQLModel: T) {
let worker = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let conn = database.newConnection(on: worker)
let _ = conn.map { connection in
let _ = postgreSQLModel.save(on: connection).whenComplete {
worker.shutdownGracefully { _ in
}
}
}
}
}
final class DeviceController {
func readAll(completion: (([Device]) -> Void)?) {
WorkWithPostgres.shared.readAll(postgreSQLModel: Device.self) { devices in
completion?(devices)
}
}
func create(isWorking: Bool, serial: Int) {
let device = Device(isWorking: isWorking, serial: serial)
WorkWithPostgres.shared.create(postgreSQLModel: device)
}
}
它正在运行,但我不确定这样做是否是个好方法。有人知道吗?