use super::config::DatabaseConfig;
use super::{Driver, Pool};
#[derive(Clone)]
pub struct Db {
pool: Pool,
orm: sea_orm::DatabaseConnection,
}
impl Db {
pub async fn connect(config: DatabaseConfig) -> Result<Db, crate::Error> {
config.validate()?;
let pool = build_pool(&config).await?;
let orm = orm_over(pool.clone());
Ok(Db { pool, orm })
}
pub fn from_pool(pool: Pool) -> Db {
let orm = orm_over(pool.clone());
Db { pool, orm }
}
pub fn orm(&self) -> &sea_orm::DatabaseConnection {
&self.orm
}
pub fn sqlx(&self) -> &Pool {
&self.pool
}
pub async fn ping(&self) -> Result<(), crate::Error> {
sqlx::query("SELECT 1")
.execute(&self.pool)
.await
.map_err(|e| crate::Error::Database(e.to_string()))?;
Ok(())
}
pub async fn close(&self) {
self.pool.close().await;
}
}
fn orm_over(pool: Pool) -> sea_orm::DatabaseConnection {
#[cfg(feature = "db-postgres")]
{
sea_orm::SqlxPostgresConnector::from_sqlx_postgres_pool(pool)
}
#[cfg(feature = "db-sqlite")]
{
sea_orm::SqlxSqliteConnector::from_sqlx_sqlite_pool(pool)
}
#[cfg(feature = "db-mysql")]
{
sea_orm::SqlxMySqlConnector::from_sqlx_mysql_pool(pool)
}
}
async fn build_pool(config: &DatabaseConfig) -> Result<Pool, crate::Error> {
let pool_config = config.pool_config();
#[allow(unused_mut)]
let mut options = sqlx::pool::PoolOptions::<Driver>::new()
.max_connections(pool_config.get_max_connections())
.min_connections(pool_config.get_min_connections())
.acquire_timeout(pool_config.get_acquire_timeout())
.idle_timeout(pool_config.get_idle_timeout())
.max_lifetime(pool_config.get_max_lifetime());
#[cfg(feature = "db-postgres")]
if let Some(set_stmt) = config.session_config().set_statement() {
options = options.after_connect(move |conn, _meta| {
let stmt = set_stmt.clone();
Box::pin(async {
sqlx::Executor::execute(conn, sqlx::AssertSqlSafe(stmt))
.await
.map(|_| ())
})
});
}
options
.connect_with(config.connect_options())
.await
.map_err(|e| crate::Error::Database(e.to_string()))
}