84 lines
2.6 KiB
Rust
84 lines
2.6 KiB
Rust
//! Database connection pool and RLS context management.
|
|
|
|
use std::time::Duration;
|
|
|
|
use sqlx::{postgres::PgPoolOptions, PgPool};
|
|
use uuid::Uuid;
|
|
|
|
use chattyness_error::AppError;
|
|
|
|
/// Create a new database connection pool for the owner interface.
|
|
///
|
|
/// Uses the `chattyness_owner` role which has full database access.
|
|
pub async fn create_owner_pool(database_url: &str) -> Result<PgPool, AppError> {
|
|
let pool = PgPoolOptions::new()
|
|
.max_connections(5)
|
|
.acquire_timeout(Duration::from_secs(5))
|
|
.connect(database_url)
|
|
.await?;
|
|
|
|
Ok(pool)
|
|
}
|
|
|
|
/// Create a new database connection pool for the public app.
|
|
///
|
|
/// Uses the `chattyness_app` role which has Row-Level Security (RLS) policies.
|
|
pub async fn create_app_pool(database_url: &str) -> Result<PgPool, AppError> {
|
|
let pool = PgPoolOptions::new()
|
|
.max_connections(10)
|
|
.acquire_timeout(Duration::from_secs(5))
|
|
.connect(database_url)
|
|
.await?;
|
|
|
|
Ok(pool)
|
|
}
|
|
|
|
/// Set the current user context for Row-Level Security.
|
|
///
|
|
/// This should be called at the start of each request to enable RLS policies
|
|
/// that depend on the current user ID.
|
|
pub async fn set_user_context(pool: &PgPool, user_id: Option<Uuid>) -> Result<(), AppError> {
|
|
if let Some(id) = user_id {
|
|
sqlx::query("SELECT public.set_current_user_id($1)")
|
|
.bind(id)
|
|
.execute(pool)
|
|
.await?;
|
|
} else {
|
|
// Clear the user context for anonymous requests
|
|
sqlx::query("SELECT public.clear_current_user_id()")
|
|
.execute(pool)
|
|
.await?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Clear the current user context.
|
|
///
|
|
/// Called at the end of a request to ensure the connection is clean
|
|
/// before returning to the pool.
|
|
pub async fn clear_user_context(pool: &PgPool) -> Result<(), AppError> {
|
|
sqlx::query("SELECT public.clear_current_user_id()")
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Set the current guest session context for Row-Level Security.
|
|
///
|
|
/// This should be called for guest users to enable RLS policies
|
|
/// that depend on the current guest session ID.
|
|
pub async fn set_guest_context(pool: &PgPool, guest_session_id: Uuid) -> Result<(), AppError> {
|
|
sqlx::query("SELECT public.set_current_guest_session_id($1)")
|
|
.bind(guest_session_id)
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Clear the current guest session context.
|
|
pub async fn clear_guest_context(pool: &PgPool) -> Result<(), AppError> {
|
|
sqlx::query("SELECT public.set_current_guest_session_id(NULL)")
|
|
.execute(pool)
|
|
.await?;
|
|
Ok(())
|
|
}
|