arcature_db/db/connect.rs
1use sea_orm::SqlxPostgresConnector;
2use sqlx::PgPool;
3
4use super::Db;
5use crate::config::DbConfig;
6use crate::error::DbConnectError;
7use crate::pool::build;
8
9impl Db {
10 /// Connect to PostgreSQL using resolved configuration.
11 ///
12 /// Validates the configuration (min > max, zero durations) before any
13 /// expensive async work runs (Phase 4 spec §19), then builds one `PgPool`
14 /// and derives the SeaORM `DatabaseConnection` over it.
15 ///
16 /// # Errors
17 ///
18 /// Returns [`DbConnectError::Config`] if the configuration is internally
19 /// inconsistent, or [`DbConnectError::Pool`] if the pool cannot be
20 /// established (network, auth, server unavailable).
21 pub async fn connect(config: DbConfig) -> Result<Db, DbConnectError> {
22 config.validate().map_err(DbConnectError::config)?;
23
24 let pool = build(&config).await.map_err(DbConnectError::pool)?;
25 let orm = SqlxPostgresConnector::from_sqlx_postgres_pool(pool.clone());
26 Ok(Db::from_pool_orm(pool, orm))
27 }
28
29 /// Construct a `Db` from an existing `PgPool`.
30 ///
31 /// This is the database escape hatch (Phase 4 spec §9): an expert can
32 /// build and configure the pool themselves, then hand it to Arcature.
33 /// The SeaORM connection is derived over the same pool — no second pool
34 /// is created.
35 pub fn from_pool(pool: PgPool) -> Db {
36 let orm = SqlxPostgresConnector::from_sqlx_postgres_pool(pool.clone());
37 Db::from_pool_orm(pool, orm)
38 }
39}