use super::DatabaseError;
#[cfg(feature = "sqlx-postgres")]
pub type PgPool = sqlx::PgPool;
#[cfg(feature = "sqlx-mysql")]
pub type MySqlPool = sqlx::MySqlPool;
#[cfg(feature = "sqlx-sqlite")]
pub type SqlitePool = sqlx::SqlitePool;
#[derive(Clone)]
pub struct SqlxPool<DB: sqlx::Database> {
pool: sqlx::Pool<DB>,
}
impl<DB: sqlx::Database> SqlxPool<DB> {
pub fn new(pool: sqlx::Pool<DB>) -> Self {
Self { pool }
}
pub fn pool(&self) -> &sqlx::Pool<DB> {
&self.pool
}
pub fn into_inner(self) -> sqlx::Pool<DB> {
self.pool
}
}
#[cfg(feature = "sqlx-postgres")]
impl SqlxPool<sqlx::Postgres> {
pub async fn connect(url: &str) -> Result<Self, DatabaseError> {
let pool = sqlx::PgPool::connect(url)
.await
.map_err(|e| DatabaseError::Connection(e.to_string()))?;
Ok(Self::new(pool))
}
pub async fn connect_with_options(
options: sqlx::postgres::PgPoolOptions,
url: &str,
) -> Result<Self, DatabaseError> {
let pool = options
.connect(url)
.await
.map_err(|e| DatabaseError::Connection(e.to_string()))?;
Ok(Self::new(pool))
}
}
#[cfg(feature = "sqlx-mysql")]
impl SqlxPool<sqlx::MySql> {
pub async fn connect(url: &str) -> Result<Self, DatabaseError> {
let pool = sqlx::MySqlPool::connect(url)
.await
.map_err(|e| DatabaseError::Connection(e.to_string()))?;
Ok(Self::new(pool))
}
pub async fn connect_with_options(
options: sqlx::mysql::MySqlPoolOptions,
url: &str,
) -> Result<Self, DatabaseError> {
let pool = options
.connect(url)
.await
.map_err(|e| DatabaseError::Connection(e.to_string()))?;
Ok(Self::new(pool))
}
}
#[cfg(feature = "sqlx-sqlite")]
impl SqlxPool<sqlx::Sqlite> {
pub async fn connect(url: &str) -> Result<Self, DatabaseError> {
let pool = sqlx::SqlitePool::connect(url)
.await
.map_err(|e| DatabaseError::Connection(e.to_string()))?;
Ok(Self::new(pool))
}
pub async fn connect_with_options(
options: sqlx::sqlite::SqlitePoolOptions,
url: &str,
) -> Result<Self, DatabaseError> {
let pool = options
.connect(url)
.await
.map_err(|e| DatabaseError::Connection(e.to_string()))?;
Ok(Self::new(pool))
}
pub async fn health_check(&self) -> Result<(), DatabaseError> {
sqlx::query("SELECT 1")
.execute(&self.pool)
.await
.map_err(|e| DatabaseError::Query(e.to_string()))?;
Ok(())
}
}
impl From<sqlx::Error> for DatabaseError {
fn from(err: sqlx::Error) -> Self {
match err {
sqlx::Error::Database(e) => DatabaseError::Query(e.to_string()),
sqlx::Error::PoolTimedOut => {
DatabaseError::Pool("Connection pool timed out".to_string())
}
sqlx::Error::PoolClosed => DatabaseError::Pool("Connection pool is closed".to_string()),
_ => DatabaseError::Query(err.to_string()),
}
}
}