feat(db): add Db handle with pool connect and readiness ping
This commit is contained in:
@@ -1 +1,40 @@
|
|||||||
//! Database access. All SQL lives in this crate.
|
//! Database access. All SQL lives in this crate.
|
||||||
|
|
||||||
|
use sqlx::postgres::{PgPool, PgPoolOptions};
|
||||||
|
|
||||||
|
/// A handle to the organization's PostgreSQL database.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Db {
|
||||||
|
pool: PgPool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Db {
|
||||||
|
/// Connect to the database at `database_url`, opening a connection pool.
|
||||||
|
pub async fn connect(database_url: &str) -> Result<Self, sqlx::Error> {
|
||||||
|
let pool = PgPoolOptions::new()
|
||||||
|
.max_connections(5)
|
||||||
|
.connect(database_url)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(Self { pool })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Build a handle from an existing pool (used in tests).
|
||||||
|
pub fn from_pool(pool: PgPool) -> Self {
|
||||||
|
Self { pool }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Borrow the underlying pool for repository modules.
|
||||||
|
pub fn pool(&self) -> &PgPool {
|
||||||
|
&self.pool
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Readiness check: run a trivial query to confirm the database answers.
|
||||||
|
pub async fn ping(&self) -> Result<(), sqlx::Error> {
|
||||||
|
sqlx::query_scalar::<_, i32>("SELECT 1")
|
||||||
|
.fetch_one(&self.pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
use db::Db;
|
||||||
|
use sqlx::PgPool;
|
||||||
|
|
||||||
|
#[sqlx::test]
|
||||||
|
async fn ping_succeeds(pool: PgPool) {
|
||||||
|
let db = Db::from_pool(pool);
|
||||||
|
db.ping()
|
||||||
|
.await
|
||||||
|
.expect("ping should succeed against a live database");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user