use axum::{body::Body, http::Request, middleware::Next, response::Response};
use sqlx::{PgPool, Postgres, Transaction};
tokio::task_local! {
static REQUEST_POOL: PgPool;
}
pub fn current() -> Option<PgPool> {
REQUEST_POOL.try_with(|pool| pool.clone()).ok()
}
pub fn resolve(fallback: &PgPool) -> PgPool {
current().unwrap_or_else(|| fallback.clone())
}
pub async fn begin(fallback: &PgPool) -> Result<Transaction<'static, Postgres>, sqlx::Error> {
let mut tx = resolve(fallback).begin().await?;
if let Some(scope) = backbone_orm::org_scope::current_org_scope() {
backbone_orm::org_scope::bind_org_scope_on(&mut tx, &scope).await?;
}
Ok(tx)
}
pub async fn bind_request_pool(req: Request<Body>, next: Next) -> Response {
match req.extensions().get::<PgPool>().cloned() {
Some(pool) => REQUEST_POOL.scope(pool, next.run(req)).await,
None => next.run(req).await,
}
}
pub async fn with_pool_scope<F: std::future::Future<Output = O>, O>(pool: PgPool, fut: F) -> O {
REQUEST_POOL.scope(pool, fut).await
}