Skip to main content

ff_backend_postgres/
pool.rs

1//! PgPool construction helper.
2//!
3//! **RFC-v0.7 Wave 0.** Reads `BackendConnection::Postgres { url,
4//! max_connections, min_connections, acquire_timeout }` and builds a
5//! `sqlx::PgPool`. Future waves add TLS root-store plumbing, LISTEN-
6//! connection setup (Q1 + Q2), transaction-pooler detection (Q2
7//! footnote on PgBouncer session-mode requirement), etc. Today this
8//! is a thin pass-through to `sqlx::postgres::PgPoolOptions` so the
9//! backend `connect` constructor has a single call site for pool
10//! setup.
11
12use ff_core::backend::{BackendConfig, BackendConnection, PostgresConnection};
13use ff_core::engine_error::EngineError;
14use sqlx::PgPool;
15use sqlx::postgres::PgPoolOptions;
16
17use crate::error::map_sqlx_error;
18
19/// Build a `sqlx::PgPool` from a [`BackendConfig`] whose connection
20/// arm is [`BackendConnection::Postgres`].
21///
22/// Returns `EngineError::Unavailable { op: "pg.pool.build" }` when
23/// the config's connection arm is not Postgres — the Valkey backend
24/// has its own dial path, and a mis-routed config is a programmer
25/// error the backend surfaces as a typed error rather than a panic.
26pub async fn build_pool(config: &BackendConfig) -> Result<PgPool, EngineError> {
27    let BackendConnection::Postgres(pg) = &config.connection else {
28        return Err(EngineError::Unavailable {
29            op: "pg.pool.build (non-Postgres BackendConnection)",
30        });
31    };
32    build_pool_from_connection(pg).await
33}
34
35/// Lower-level helper: build a `PgPool` directly from a
36/// [`PostgresConnection`]. Separated from [`build_pool`] so tests +
37/// future migration-CLI tooling can feed a bare connection shape
38/// without constructing a full `BackendConfig`.
39pub async fn build_pool_from_connection(pg: &PostgresConnection) -> Result<PgPool, EngineError> {
40    PgPoolOptions::new()
41        .max_connections(pg.max_connections)
42        .min_connections(pg.min_connections)
43        .acquire_timeout(pg.acquire_timeout)
44        .connect(&pg.url)
45        .await
46        .map_err(map_sqlx_error)
47}