use std::sync::Arc;
#[cfg(feature = "postgres")]
use sqlx::{Pool, Postgres};
#[cfg(feature = "sqlite")]
use sqlx::{Pool, Sqlite};
#[derive(Clone)]
pub enum Database {
#[cfg(feature = "postgres")]
Postgres(Arc<Pool<Postgres>>),
#[cfg(feature = "sqlite")]
Sqlite(Arc<Pool<Sqlite>>),
}
impl Database {
#[cfg(feature = "postgres")]
pub async fn postgres(database_url: &str) -> Result<Self, sqlx::Error> {
let pool = sqlx::postgres::PgPoolOptions::new()
.max_connections(10)
.connect(database_url)
.await?;
Ok(Database::Postgres(Arc::new(pool)))
}
#[cfg(feature = "sqlite")]
pub async fn sqlite(database_url: &str) -> Result<Self, sqlx::Error> {
let pool = sqlx::sqlite::SqlitePoolOptions::new()
.max_connections(5)
.connect(database_url)
.await?;
Ok(Database::Sqlite(Arc::new(pool)))
}
#[cfg(feature = "postgres")]
pub async fn execute_pg(&self, query: &str) -> Result<u64, sqlx::Error> {
match self {
Database::Postgres(pool) => {
let result = sqlx::query(query).execute(&**pool).await?;
Ok(result.rows_affected())
}
#[allow(unreachable_patterns)]
_ => Err(sqlx::Error::Configuration("Wrong database type".into())),
}
}
#[cfg(feature = "sqlite")]
pub async fn execute_sqlite(&self, query: &str) -> Result<u64, sqlx::Error> {
match self {
Database::Sqlite(pool) => {
let result = sqlx::query(query).execute(&**pool).await?;
Ok(result.rows_affected())
}
#[allow(unreachable_patterns)]
_ => Err(sqlx::Error::Configuration("Wrong database type".into())),
}
}
#[cfg(feature = "postgres")]
pub fn pg_pool(&self) -> Option<&Pool<Postgres>> {
match self {
Database::Postgres(pool) => Some(pool),
#[allow(unreachable_patterns)]
_ => None,
}
}
#[cfg(feature = "sqlite")]
pub fn sqlite_pool(&self) -> Option<&Pool<Sqlite>> {
match self {
Database::Sqlite(pool) => Some(pool),
#[allow(unreachable_patterns)]
_ => None,
}
}
}
pub trait Bindable: Send + Sync {
#[cfg(feature = "postgres")]
fn bind_pg(&self, args: &mut sqlx::postgres::PgArguments);
#[cfg(feature = "sqlite")]
fn bind_sqlite(&self, args: &mut sqlx::sqlite::SqliteArguments<'_>);
}