use sqlx::AnyPool;
use sqlx::any::AnyPoolOptions;
use rusty_gasket::BoxError;
use rusty_gasket::plugin::{Plugin, PluginOrdering, PrepareContext, ShutdownContext};
use rusty_gasket::db::config::DatabaseConfig;
#[derive(Debug, Default)]
pub struct DatabasePlugin;
impl Plugin for DatabasePlugin {
fn name(&self) -> &'static str {
"gasket:database"
}
fn ordering(&self) -> PluginOrdering {
PluginOrdering::new().before(["gasket:server"])
}
async fn prepare(&self, ctx: &mut PrepareContext) -> Result<(), BoxError> {
let db_config: DatabaseConfig = if ctx.config.has_section("database") {
ctx.config.section("database")?
} else {
DatabaseConfig::from_env()?
};
let backend = db_config.backend.resolve(&db_config.url)?;
sqlx::any::install_default_drivers();
let pool = AnyPoolOptions::new()
.max_connections(db_config.max_connections)
.min_connections(db_config.min_connections)
.acquire_timeout(std::time::Duration::from_secs(
db_config.acquire_timeout_secs,
))
.connect(&db_config.url)
.await
.map_err(|e| format!("Failed to connect to {backend} database: {e}"))?;
tracing::info!(
backend = %backend,
max_connections = db_config.max_connections,
"Database pool created"
);
ctx.extensions.insert(pool);
ctx.extensions.insert(backend);
Ok(())
}
async fn shutdown(&self, ctx: &ShutdownContext) -> Result<(), BoxError> {
if let Some(pool) = ctx.extensions.get::<AnyPool>() {
tracing::info!("Closing database pool");
pool.close().await;
}
Ok(())
}
}