use crate::driver::non_blocking::AsyncDbDriver;
use crate::driver::DriverType;
use crate::pool::PoolStatus;
use crate::prelude::*;
use crate::{database_err, deadpool_err};
use async_trait::async_trait;
cfg_if! {
if #[cfg(feature = "mysql-async")] {
use crate::driver::non_blocking::mysql::*;
}
}
cfg_if! {
if #[cfg(feature = "postgres-async")] {
use crate::driver::non_blocking::postgres::*;
}
}
cfg_if! {
if #[cfg(feature = "oracle-async")] {
use crate::driver::non_blocking::oracle::*;
}
}
cfg_if! {
if #[cfg(feature = "sqlite-async")] {
use crate::driver::non_blocking::sqlite::*;
}
}
cfg_if! {
if #[cfg(feature = "mssql-async")] {
use crate::driver::non_blocking::mssql::*;
}
}
#[async_trait]
pub trait AsyncPool {
#[track_caller]
async fn acquire(&self) -> crate::errors::Result<AsyncPooledConnection>;
#[track_caller]
async fn database(&self) -> crate::errors::Result<AsyncDbDriver>;
async fn status(&self) -> PoolStatus;
async fn close(&self);
}
#[allow(unused)]
#[derive(Clone)]
pub struct AsyncDBPoolWrapper {
_inner: AsyncDBPool,
}
#[derive(Clone)]
pub enum AsyncDBPool {
#[cfg(feature = "mysql-async")]
MysqlAsyncPool(MysqlAsyncPool),
#[cfg(feature = "postgres-async")]
PostgresAsyncPool(PostgresAsyncPool),
#[cfg(feature = "oracle-async")]
OracleAsyncPool(OracleAsyncPool),
#[cfg(feature = "sqlite-async")]
SqliteAsyncPool(SqliteAsyncPool),
#[cfg(feature = "mssql-async")]
MssqlAsyncPool(MssqlAsyncPool),
}
pub enum AsyncPooledConnection {
#[cfg(feature = "mysql-async")]
PooledMysqlAsync(MysqlAsyncConnection),
#[cfg(feature = "postgres-async")]
PooledPostgresAsync(PostgresAsyncConnection),
#[cfg(feature = "oracle-async")]
PooledOracleAsync(OracleAsyncConnection),
#[cfg(feature = "sqlite-async")]
PooledSqliteAsync(SqliteAsyncConnection),
#[cfg(feature = "mssql-async")]
PooledMssqlAsync(MssqlAsyncConnection),
}
#[async_trait]
impl AsyncPool for AsyncDBPool {
async fn acquire(&self) -> Result<AsyncPooledConnection> {
match self {
#[cfg(feature = "mysql-async")]
AsyncDBPool::MysqlAsyncPool(ref pool) => {
let conn = pool.get().await.map_err(|e| {
database_err!(format!("Failed to get async MySQL connection: {}", e))
})?;
Ok(AsyncPooledConnection::PooledMysqlAsync(conn))
}
#[cfg(feature = "postgres-async")]
AsyncDBPool::PostgresAsyncPool(ref pool) => {
let conn = pool.get().await.map_err(|e| {
database_err!(format!("Failed to get async PostgreSQL connection: {}", e))
})?;
Ok(AsyncPooledConnection::PooledPostgresAsync(conn))
}
#[cfg(feature = "oracle-async")]
AsyncDBPool::OracleAsyncPool(ref pool) => {
let conn = pool.get().await.map_err(|e| {
database_err!(format!("Failed to get async Oracle connection: {}", e))
})?;
Ok(AsyncPooledConnection::PooledOracleAsync(conn))
}
#[cfg(feature = "sqlite-async")]
AsyncDBPool::SqliteAsyncPool(ref pool) => {
let conn = pool.get().await.map_err(|e| {
database_err!(format!("Failed to get async SQLite connection: {}", e))
})?;
Ok(AsyncPooledConnection::PooledSqliteAsync(conn))
}
#[cfg(feature = "mssql-async")]
AsyncDBPool::MssqlAsyncPool(ref pool) => {
let conn = pool.get().await.map_err(|e| {
database_err!(format!("Failed to get async SQL Server connection: {}", e))
})?;
Ok(AsyncPooledConnection::PooledMssqlAsync(conn))
}
}
}
async fn database(&self) -> Result<AsyncDbDriver> {
let conn = self.acquire().await?;
match conn {
#[cfg(feature = "mysql-async")]
AsyncPooledConnection::PooledMysqlAsync(conn) => Ok(AsyncDbDriver::MysqlAsyncDriver(
Box::new(MySQLAsync::new(conn)),
)),
#[cfg(feature = "postgres-async")]
AsyncPooledConnection::PooledPostgresAsync(conn) => Ok(
AsyncDbDriver::PostgresAsyncDriver(Box::new(PostgresAsync::new(conn))),
),
#[cfg(feature = "oracle-async")]
AsyncPooledConnection::PooledOracleAsync(conn) => Ok(AsyncDbDriver::OracleAsyncDriver(
Box::new(OracleAsync::new(conn)),
)),
#[cfg(feature = "sqlite-async")]
AsyncPooledConnection::PooledSqliteAsync(conn) => Ok(AsyncDbDriver::SqliteAsyncDriver(
Box::new(SqliteAsync::new(conn)),
)),
#[cfg(feature = "mssql-async")]
AsyncPooledConnection::PooledMssqlAsync(conn) => Ok(AsyncDbDriver::MssqlAsyncDriver(
Box::new(MssqlAsync::new(conn)),
)),
}
}
async fn status(&self) -> PoolStatus {
match self {
#[cfg(feature = "mysql-async")]
AsyncDBPool::MysqlAsyncPool(pool) => {
let size = pool.status().size;
let available = pool.status().available;
PoolStatus { size, available }
}
#[cfg(feature = "postgres-async")]
AsyncDBPool::PostgresAsyncPool(pool) => {
let size = pool.status().size;
let available = pool.status().available;
PoolStatus { size, available }
}
#[cfg(feature = "oracle-async")]
AsyncDBPool::OracleAsyncPool(pool) => {
let size = pool.status().size;
let available = pool.status().available;
PoolStatus { size, available }
}
#[cfg(feature = "sqlite-async")]
AsyncDBPool::SqliteAsyncPool(pool) => {
let size = pool.status().size;
let available = pool.status().available;
PoolStatus { size, available }
}
#[cfg(feature = "mssql-async")]
AsyncDBPool::MssqlAsyncPool(pool) => {
let size = pool.status().size;
let available = pool.status().available;
PoolStatus { size, available }
}
}
}
async fn close(&self) {
match self {
#[cfg(feature = "mysql-async")]
AsyncDBPool::MysqlAsyncPool(pool) => {
pool.close();
}
#[cfg(feature = "postgres-async")]
AsyncDBPool::PostgresAsyncPool(pool) => {
pool.close();
}
#[cfg(feature = "oracle-async")]
AsyncDBPool::OracleAsyncPool(pool) => {
pool.close();
}
#[cfg(feature = "sqlite-async")]
AsyncDBPool::SqliteAsyncPool(pool) => {
pool.close();
}
#[cfg(feature = "mssql-async")]
AsyncDBPool::MssqlAsyncPool(pool) => {
pool.close();
}
}
}
}
#[allow(unused)]
impl AsyncDBPoolWrapper {
#[track_caller]
pub async fn new(mut cfg: AkitaConfig) -> Result<Self> {
let driver_type = cfg.get_platform()?;
match driver_type {
#[cfg(feature = "mysql-async")]
DriverType::MySQL => {
let pool_mysql = init_mysql_async_pool(cfg).await?;
Ok(AsyncDBPoolWrapper {
_inner: AsyncDBPool::MysqlAsyncPool(pool_mysql),
})
}
#[cfg(feature = "sqlite-async")]
DriverType::Sqlite => {
let pool_sqlite = init_sqlite_async_pool(cfg).await?;
Ok(AsyncDBPoolWrapper {
_inner: AsyncDBPool::SqliteAsyncPool(pool_sqlite),
})
}
#[cfg(feature = "oracle-async")]
DriverType::Oracle => {
let pool_oracle = init_oracle_async_pool(cfg).await?;
Ok(AsyncDBPoolWrapper {
_inner: AsyncDBPool::OracleAsyncPool(pool_oracle),
})
}
#[cfg(feature = "postgres-async")]
DriverType::Postgres => {
let pool_postgres = init_postgres_async_pool(cfg).await?;
Ok(AsyncDBPoolWrapper {
_inner: AsyncDBPool::PostgresAsyncPool(pool_postgres),
})
}
#[cfg(feature = "mssql-async")]
DriverType::Mssql => {
let pool_mssql = init_mssql_async_pool(cfg).await?;
Ok(AsyncDBPoolWrapper {
_inner: AsyncDBPool::MssqlAsyncPool(pool_mssql),
})
}
_ => Err(database_err!("Unknown".to_string())),
}
}
#[track_caller]
pub async fn acquire(&self) -> Result<AsyncPooledConnection> {
self._inner.acquire().await
}
#[track_caller]
pub async fn database(&self) -> Result<AsyncDbDriver> {
self._inner.database().await
}
pub fn pool(self) -> AsyncDBPool {
self._inner
}
#[track_caller]
pub async fn connect(&self) -> Result<AsyncPooledConnection> {
match self._inner {
#[cfg(feature = "mysql-async")]
AsyncDBPool::MysqlAsyncPool(ref pool_mysql) => {
let pooled_conn = pool_mysql.get().await;
match pooled_conn {
Ok(pooled_conn) => Ok(AsyncPooledConnection::PooledMysqlAsync(pooled_conn)),
Err(e) => Err(deadpool_err!(e.to_string())),
}
}
#[cfg(feature = "sqlite-async")]
AsyncDBPool::SqliteAsyncPool(ref pool_sqlite) => {
let pooled_conn = pool_sqlite.get().await;
match pooled_conn {
Ok(pooled_conn) => Ok(AsyncPooledConnection::PooledSqliteAsync(pooled_conn)),
Err(e) => Err(deadpool_err!(e.to_string())),
}
}
#[cfg(feature = "oracle-async")]
AsyncDBPool::OracleAsyncPool(ref pool_oracle) => {
let pooled_conn = pool_oracle.get().await;
match pooled_conn {
Ok(pooled_conn) => Ok(AsyncPooledConnection::PooledOracleAsync(pooled_conn)),
Err(e) => Err(deadpool_err!(e.to_string())),
}
}
#[cfg(feature = "mssql-async")]
AsyncDBPool::MssqlAsyncPool(ref pool_mssql) => {
let pooled_conn = pool_mssql.get().await;
match pooled_conn {
Ok(pooled_conn) => Ok(AsyncPooledConnection::PooledMssqlAsync(pooled_conn)),
Err(e) => Err(deadpool_err!(e.to_string())),
}
}
#[cfg(feature = "postgres-async")]
AsyncDBPool::PostgresAsyncPool(ref pool_postgres) => {
let pooled_conn = pool_postgres.get().await;
match pooled_conn {
Ok(pooled_conn) => Ok(AsyncPooledConnection::PooledPostgresAsync(pooled_conn)),
Err(e) => Err(deadpool_err!(e.to_string())),
}
}
}
}
}