Я пишу бэкэнд с использованием 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