Migrated the Website service and library targets to use Persistence package with PostgreSQL instead.
This commit is contained in:
@@ -42,7 +42,7 @@ struct App {
|
||||
return
|
||||
}
|
||||
|
||||
let app = await application(
|
||||
let app = try await application(
|
||||
reader: reader
|
||||
)
|
||||
|
||||
|
||||
@@ -12,13 +12,14 @@ import WebsiteLibrary
|
||||
/// Reads the log level, server name, static files location, minimum response size to compress, and security headers from the configuration, then assembles
|
||||
/// the router, server configuration, and logger. It warns when the localization catalog cannot be read, since pages would serve raw localization keys.
|
||||
/// It also builds the persistence driver, registers its migrations, and attaches the `Fluent` service so it starts
|
||||
/// and stops alongside the HTTP server; the ephemeral in-memory backend is migrated on startup, while a MySQL/MariaDB backend is migrated out of
|
||||
/// and stops alongside the HTTP server; the ephemeral in-memory backend is migrated on startup, while a PostgreSQL backend is migrated out of
|
||||
/// band (so a shared database is never migrated on boot).
|
||||
/// - Parameter reader: the configuration reader the values are read from.
|
||||
/// - Returns: the configured application, ready to run as a service.
|
||||
/// - Throws: an error when the persistence service cannot be built (e.g. its TLS context fails to build).
|
||||
func application(
|
||||
reader: ConfigReader
|
||||
) async -> some ApplicationProtocol {
|
||||
) async throws -> some ApplicationProtocol {
|
||||
let languages = LanguageList()
|
||||
let logger = logger(
|
||||
serverName: reader.serverName,
|
||||
@@ -37,7 +38,7 @@ func application(
|
||||
driver: reader.driver,
|
||||
logger: logger
|
||||
)
|
||||
let fluent = persistence()
|
||||
let fluent = try persistence()
|
||||
|
||||
let fingerprintAssets = FingerprintAssets(logger: logger)
|
||||
let prepareDB = PrepareDB()
|
||||
@@ -63,7 +64,7 @@ func application(
|
||||
|
||||
app.addServices(fluent)
|
||||
|
||||
// The in-memory backend is recreated on every launch, so it is migrated on startup. The MySQL/MariaDB backend is
|
||||
// The in-memory backend is recreated on every launch, so it is migrated on startup. The PostgreSQL backend is
|
||||
// left untouched here: a shared database is migrated out of band to avoid multi-instance races.
|
||||
if case .inMemory = reader.driver {
|
||||
app.beforeServerStarts {
|
||||
@@ -77,7 +78,7 @@ func application(
|
||||
/// Runs every registered migration against the configured backend, then exits.
|
||||
///
|
||||
/// This is the out-of-band migration path selected by the `database.migrate` flag: it builds the same driver the service would run against, applies the
|
||||
/// migrations, and shuts the database down — so a shared MySQL/MariaDB database is migrated by a single deliberate invocation rather than by every
|
||||
/// migrations, and shuts the database down — so a shared PostgreSQL database is migrated by a single deliberate invocation rather than by every
|
||||
/// booting instance.
|
||||
/// - Parameter reader: the configuration reader the values are read from.
|
||||
func migration(
|
||||
@@ -92,7 +93,7 @@ func migration(
|
||||
logger: logger
|
||||
)
|
||||
|
||||
let fluent = service()
|
||||
let fluent = try service()
|
||||
let prepareDB = PrepareDB()
|
||||
|
||||
await prepareDB(for: fluent)
|
||||
|
||||
@@ -59,7 +59,7 @@ package extension ConfigReader {
|
||||
|
||||
/// The persistence backend the service runs against, derived from the `database.*` keys.
|
||||
///
|
||||
/// When `database.driver` selects MySQL, the connection parameters are assembled from the `database.host`, `database.port`,
|
||||
/// When `database.driver` selects PostgreSQL, the connection parameters are assembled from the `database.host`, `database.port`,
|
||||
/// `database.name`, `database.username`, `database.password` (empty when unset), `database.tls`, and
|
||||
/// `database.pool.maxPerEventLoop` keys. Any other driver value falls back to the in-memory database.
|
||||
var driver: Driver {
|
||||
@@ -67,8 +67,8 @@ package extension ConfigReader {
|
||||
forKey: .Database.driver,
|
||||
default: .Database.driver
|
||||
) {
|
||||
case .Database.driverMySQL:
|
||||
return .mysql(
|
||||
case .Database.driverPostgres:
|
||||
return .postgres(
|
||||
.init(
|
||||
host: string(
|
||||
forKey: .Database.host,
|
||||
@@ -199,7 +199,7 @@ private extension ConfigReader {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
/// The TLS posture for the MySQL connection, mapped from the `database.tls` key: `off` and `require` map to their postures, and any
|
||||
/// The TLS posture for the PostgreSQL connection, mapped from the `database.tls` key: `off` and `require` map to their postures, and any
|
||||
/// other value falls back to `prefer`.
|
||||
var tls: TLS {
|
||||
switch string(
|
||||
|
||||
+2
-2
@@ -23,9 +23,9 @@ extension AbsoluteConfigKey {
|
||||
public static let migrate: AbsoluteConfigKey = .init(.Database.migrate)
|
||||
/// The absolute configuration key for the persistence driver.
|
||||
public static let driver: AbsoluteConfigKey = .init(.Database.driver)
|
||||
/// The absolute configuration key for the MySQL/MariaDB host.
|
||||
/// The absolute configuration key for the PostgreSQL host.
|
||||
public static let host: AbsoluteConfigKey = .init(.Database.host)
|
||||
/// The absolute configuration key for the MySQL/MariaDB port.
|
||||
/// The absolute configuration key for the PostgreSQL port.
|
||||
public static let port: AbsoluteConfigKey = .init(.Database.port)
|
||||
/// The absolute configuration key for the database name.
|
||||
public static let name: AbsoluteConfigKey = .init(.Database.name)
|
||||
|
||||
@@ -21,11 +21,11 @@ extension ConfigKey {
|
||||
public enum Database {
|
||||
/// The configuration key selecting migrate-and-exit mode (run migrations, then exit) instead of serving.
|
||||
public static let migrate: ConfigKey = "database.migrate"
|
||||
/// The configuration key for the persistence driver (`inMemory` or `mysql`).
|
||||
/// The configuration key for the persistence driver (`inMemory` or `postgres`).
|
||||
public static let driver: ConfigKey = "database.driver"
|
||||
/// The configuration key for the MySQL/MariaDB host.
|
||||
/// The configuration key for the PostgreSQL host.
|
||||
public static let host: ConfigKey = "database.host"
|
||||
/// The configuration key for the MySQL/MariaDB port.
|
||||
/// The configuration key for the PostgreSQL port.
|
||||
public static let port: ConfigKey = "database.port"
|
||||
/// The configuration key for the database name.
|
||||
public static let name: ConfigKey = "database.name"
|
||||
|
||||
@@ -17,8 +17,8 @@ extension Int {
|
||||
}
|
||||
/// A namespace for the persistence's default configuration values.
|
||||
public enum Database {
|
||||
/// The default MySQL/MariaDB port.
|
||||
public static let port = 3_306
|
||||
/// The default PostgreSQL port.
|
||||
public static let port = 5_432
|
||||
/// The default maximum pooled connections per event loop.
|
||||
public static let poolMaxPerEventLoop = 4
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ extension String {
|
||||
public enum Database {
|
||||
/// The default persistence driver: in-memory SQLite, which needs no external infrastructure.
|
||||
public static let driver = "inMemory"
|
||||
/// The driver token selecting the MySQL/MariaDB backend.
|
||||
public static let driverMySQL = "mysql"
|
||||
/// The default MySQL/MariaDB host.
|
||||
/// The driver token selecting the PostgreSQL backend.
|
||||
public static let driverPostgres = "postgres"
|
||||
/// The default PostgreSQL host.
|
||||
public static let host = "localhost"
|
||||
/// The default database name.
|
||||
public static let name = "loud"
|
||||
|
||||
@@ -395,8 +395,8 @@ private extension AppTests {
|
||||
func app(
|
||||
staticFilesPath: String,
|
||||
strictTransportSecurity: String? = nil
|
||||
) async -> some ApplicationProtocol {
|
||||
await application(
|
||||
) async throws -> some ApplicationProtocol {
|
||||
try await application(
|
||||
reader: reader(
|
||||
staticFilesPath: staticFilesPath,
|
||||
strictTransportSecurity: strictTransportSecurity
|
||||
|
||||
@@ -39,7 +39,7 @@ struct HealthControllerTests {
|
||||
driver: .inMemory,
|
||||
logger: Logger(label: "test")
|
||||
)
|
||||
let fluent = service()
|
||||
let fluent = try service()
|
||||
|
||||
do {
|
||||
try await app(
|
||||
@@ -70,7 +70,7 @@ struct HealthControllerTests {
|
||||
// Port 1 on the loopback interface has nothing listening, so the probe's connection is refused
|
||||
// immediately instead of timing out.
|
||||
let service = Service(
|
||||
driver: .mysql(
|
||||
driver: .postgres(
|
||||
.init(
|
||||
host: "127.0.0.1",
|
||||
port: 1,
|
||||
@@ -83,7 +83,7 @@ struct HealthControllerTests {
|
||||
),
|
||||
logger: Logger(label: "test")
|
||||
)
|
||||
let fluent = service()
|
||||
let fluent = try service()
|
||||
|
||||
do {
|
||||
try await app(
|
||||
|
||||
Reference in New Issue
Block a user