Я пишу бэкэнд с использованием Swift 5 и Vapor 4, база данных — PostgreSQL 12. У меня вопрос: как взаимодействовать с базой данных (CRUD) локально, без запросов POST или GET? Во всех руководствах снова показано, как выполнять CRUD только на основе запроса через HTTPS. Я уже задавал этот вопрос: https://stackoverflow.com/questions/58755538/vapor-3-postgresql-crud-without-requests-http НО ЭТО НЕ ДВОЙНОЙ ВОПРОС, Vapor 4 работает совершенно иначе! Пожалуйста, посмотрите мой текущий рабочий класс для Vapor 3 (на основе этого ответа: Можно ли использовать Vapor 3 Postgres Fluent в автономном скрипте?):
import Vapor
import FluentPostgreSQL
final class WorkWithPostgres {
private let databaseConfig = PostgreSQLDatabaseConfig(hostname: "localhost", port: 5432, username: "RutrackerTech", database: "vaporpostgres", password: "ru628trac4er")
let postgres: PostgreSQLDatabase
static let shared = WorkWithPostgres()
private init() {
postgres = PostgreSQLDatabase(config: databaseConfig)
}
/// Will it create undeleted memory leaks?
func shutdownGracefully(worker: MultiThreadedEventLoopGroup, completion: (() -> Void)?) {
worker.shutdownGracefully { error in
completion?()
}
}
/// Will it create udeleted memory leaks?
func connect(completion: ((MultiThreadedEventLoopGroup, PostgreSQLConnection) -> Void)?) {
let worker = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let eventLoopFuturePostgreSQLConnection = postgres.newConnection(on: worker)
let _ = eventLoopFuturePostgreSQLConnection.map { postgreSQLConnection in
completion?(worker, postgreSQLConnection)
}
}
func readAll<T: PostgreSQLModel>(postgreSQLModel: T.Type, completion: (([T]) -> Void)?) {
connect { worker, connection in
let _ = postgreSQLModel.query(on: connection).all().map { databaseData in
self.shutdownGracefully(worker: worker) {
completion?(databaseData)
}
}
}
}
func create<T: PostgreSQLModel>(postgreSQLModel: T) {
connect { worker, connection in
let _ = postgreSQLModel.save(on: connection).whenComplete {
self.shutdownGracefully(worker: worker, completion: nil)
}
}
}
}
Самая большая проблема: я не могу найти замену PostgreSQLDatabase
в FluentPostgresDriver
или в Fluent
. Или, может быть, должен быть другой подход к решению этой задачи?
Спасибо, что прочитали, буду благодарен за любую помощь или совет!
В Fluent 4 нет такой вещи, как соединение — вы можете просто использовать тип
database
. Итак, вашmodel.save(on:)
становитсяmodel.save(on: database)
Хорошо, а где я возьму «базу данных»? — person Alex; 25.06.2020
Что вы подразумеваете под базой данных дублей? У вас уже есть это в этом коде
let postgres: PostgreSQLDatabase
— person Alex; 25.06.2020PostgreSQLDatabase — больше не доступен в Vapor 4. — person Alex; 25.06.2020
Вы можете получить базу данных из
Application
илиRequest
— где бы вы ни использовали ее, у вас будет доступ к одному из них. — person Alex; 25.06.2020Предположим, я не хочу использовать Request внутри (я не буду отправлять запросы на свой собственный сервер localhost), должен ли я использовать Application все время? — person Alex; 25.06.2020
Почти наверняка да — person Alex; 25.06.2020
Хорошо, например, у меня есть какой-то класс, как я могу использовать в нем Application? — person Alex; 25.06.2020
Вам нужно будет ввести его из любого места, где вы вызываете этот класс или создаете его. — person Alex; 25.06.2020
Итак, правильная идея — не работать с базой данных, как я сделал с Vapor 3. Теперь в Vapor 4 вы должны использовать экземпляр
Database
. Где взять? Могу предложить вам 2 варианта. Сначалаboot(_ app: Application)
вboot.swift
или вconfigure(_ app: Application)
вconfigure.swift
. Итак,app
будет иметь следующие варианты работы с базой данных:<Model>.query(on: app.db)
. Второй вариант —req
в любом запросе.req
должен иметь типRequest
, например:<Model>.query(on: req.db)
. ПоModel
вы можете взять любой класс, унаследованный от классаModel
, например:final class User: Model, Content {
Вы должны организовать свой код для вызова изboot.swift
илиconfigure.swift
или из любого запроса, например, вroutes.swift