welds-connections 0.4.23

An async ORM for (postgres, mssql, mysql, sqlite)
Documentation
use super::Client;
use super::ExecuteResult;
use super::Param;
use super::Row;
use super::Syntax;
use crate::Fetch;
use crate::errors::Result;
use crate::{TransactStart, Transaction};
use async_trait::async_trait;

#[cfg(feature = "unstable-api")]
use crate::StreamClient;
#[cfg(feature = "unstable-api")]
use futures_core::stream::BoxStream;

/// This is a wrapper around a connection that could be Any underlying database
/// only for the connection type features that have been enabled
#[derive(Clone)]
pub enum AnyClient {
    #[cfg(feature = "sqlite")]
    Sqlite(crate::sqlite::SqliteClient),
    #[cfg(feature = "sqlite-sync")]
    SqliteSync(crate::sqlite_sync::SqliteClient),
    #[cfg(feature = "postgres")]
    Postgres(crate::postgres::PostgresClient),
    #[cfg(feature = "mysql")]
    Mysql(crate::mysql::MysqlClient),
    #[cfg(feature = "mssql")]
    Mssql(crate::mssql::MssqlClient),
    #[cfg(feature = "noop")]
    Noop(crate::noop::NoopClient),
}

#[maybe_async::maybe_async]
#[async_trait]
impl Client for AnyClient {
    /// Execute a sql command. returns the number of rows that were affected
    async fn execute(&self, sql: &str, params: &[&(dyn Param + Sync)]) -> Result<ExecuteResult> {
        match self {
            #[cfg(feature = "sqlite")]
            AnyClient::Sqlite(c) => c.execute(sql, params).await,
            #[cfg(feature = "sqlite-sync")]
            AnyClient::SqliteSync(c) => c.execute(sql, params),
            #[cfg(feature = "postgres")]
            AnyClient::Postgres(c) => c.execute(sql, params).await,
            #[cfg(feature = "mysql")]
            AnyClient::Mysql(c) => c.execute(sql, params).await,
            #[cfg(feature = "mssql")]
            AnyClient::Mssql(c) => c.execute(sql, params).await,
            #[cfg(feature = "noop")]
            AnyClient::Noop(c) => c.execute(sql, params).await,
        }
    }

    /// Runs SQL and returns a collection of rows from the database.
    async fn fetch_rows(&self, sql: &str, params: &[&(dyn Param + Sync)]) -> Result<Vec<Row>> {
        match self {
            #[cfg(feature = "sqlite")]
            AnyClient::Sqlite(c) => c.fetch_rows(sql, params).await,
            #[cfg(feature = "sqlite-sync")]
            AnyClient::SqliteSync(c) => c.fetch_rows(sql, params),
            #[cfg(feature = "postgres")]
            AnyClient::Postgres(c) => c.fetch_rows(sql, params).await,
            #[cfg(feature = "mysql")]
            AnyClient::Mysql(c) => c.fetch_rows(sql, params).await,
            #[cfg(feature = "mssql")]
            AnyClient::Mssql(c) => c.fetch_rows(sql, params).await,
            #[cfg(feature = "noop")]
            AnyClient::Noop(c) => c.fetch_rows(sql, params).await,
        }
    }

    /// Run several `fetch_rows` command on the same connection in the connection pool
    async fn fetch_many<'s, 'args, 't>(
        &self,
        args: &[Fetch<'s, 'args, 't>],
    ) -> Result<Vec<Vec<Row>>> {
        match self {
            #[cfg(feature = "sqlite")]
            AnyClient::Sqlite(c) => c.fetch_many(args).await,
            #[cfg(feature = "sqlite-sync")]
            AnyClient::SqliteSync(c) => c.fetch_many(args),
            #[cfg(feature = "postgres")]
            AnyClient::Postgres(c) => c.fetch_many(args).await,
            #[cfg(feature = "mysql")]
            AnyClient::Mysql(c) => c.fetch_many(args).await,
            #[cfg(feature = "mssql")]
            AnyClient::Mssql(c) => c.fetch_many(args).await,
            #[cfg(feature = "noop")]
            AnyClient::Noop(c) => c.fetch_many(args).await,
        }
    }

    // Returns what syntax (dialect) of SQL the backend is expecting
    fn syntax(&self) -> Syntax {
        match self {
            #[cfg(feature = "sqlite")]
            AnyClient::Sqlite(c) => c.syntax(),
            #[cfg(feature = "sqlite-sync")]
            AnyClient::SqliteSync(c) => c.syntax(),
            #[cfg(feature = "postgres")]
            AnyClient::Postgres(c) => c.syntax(),
            #[cfg(feature = "mysql")]
            AnyClient::Mysql(c) => c.syntax(),
            #[cfg(feature = "mssql")]
            AnyClient::Mssql(c) => c.syntax(),
            #[cfg(feature = "noop")]
            AnyClient::Noop(c) => c.syntax(),
        }
    }
}

#[cfg(all(not(feature = "__sync"), feature = "unstable-api"))]
#[async_trait]
impl StreamClient for AnyClient {
    /// Run the SQL streaming the results back in a future::stream
    async fn stream<'client, 'e, 'params>(
        &'client self,
        sql: &str,
        params: &[&'params (dyn Param + Sync)],
    ) -> BoxStream<'e, Result<Row>>
    where
        'client: 'e,
        'params: 'e,
    {
        match self {
            #[cfg(feature = "sqlite")]
            AnyClient::Sqlite(c) => c.stream(sql, params).await,
            #[cfg(feature = "postgres")]
            AnyClient::Postgres(c) => c.stream(sql, params).await,
            #[cfg(feature = "mysql")]
            AnyClient::Mysql(c) => c.stream(sql, params).await,
            #[cfg(feature = "mssql")]
            AnyClient::Mssql(c) => c.stream(sql, params).await,
            #[cfg(feature = "noop")]
            AnyClient::Noop(c) => c.stream(sql, params).await,
        }
    }
}

#[maybe_async::maybe_async]
#[async_trait]
impl TransactStart for AnyClient {
    async fn begin<'t>(&'t self) -> Result<Transaction<'t>> {
        match self {
            #[cfg(feature = "sqlite")]
            AnyClient::Sqlite(c) => c.begin().await,
            #[cfg(feature = "sqlite-sync")]
            AnyClient::SqliteSync(c) => c.begin(),
            #[cfg(feature = "postgres")]
            AnyClient::Postgres(c) => c.begin().await,
            #[cfg(feature = "mysql")]
            AnyClient::Mysql(c) => c.begin().await,
            #[cfg(feature = "mssql")]
            AnyClient::Mssql(c) => c.begin().await,
            #[cfg(feature = "noop")]
            AnyClient::Noop(_) => panic!("transaction not supporting in test mode"),
        }
    }
}

impl AsRef<AnyClient> for AnyClient {
    fn as_ref(&self) -> &AnyClient {
        self
    }
}