artis 0.2.13

Artis is a SQL library
Documentation
use std::future::Future;
use std::u64;
use std::{fmt::Debug, sync::Arc};

use serde::de::DeserializeOwned;

use crate::decode::{decode, decode_pluck};
use crate::types::{Args, ExecResult, IntoArtis, IntoChunk, RawType};
use crate::ArtisTx;
use crate::IntoRaw;
use crate::{BoxFuture, Result, Value};

pub trait ArtisExecutor: Debug + Send + Sync {
    fn query(&self, raw: String, args: Args) -> BoxFuture<'_, Result<Value>>;

    fn exec(&self, raw: String, args: Args) -> BoxFuture<'_, Result<ExecResult>>;

    fn begin(&self) -> BoxFuture<'_, Result<ArtisTx>>;
}

#[derive(Debug, Clone)]
pub struct Artis {
    c: Arc<Box<dyn ArtisExecutor>>,
}

impl From<Box<dyn ArtisExecutor>> for Artis {
    fn from(value: Box<dyn ArtisExecutor>) -> Self {
        Self { c: Arc::new(value) }
    }
}

impl Artis {
    pub async fn begin(&self) -> Result<ArtisTx> {
        Ok(self.c.begin().await?)
    }

    pub async fn chunk<F, T, R>(&self, func: F) -> Result<R>
    where
        F: FnOnce(Arc<ArtisTx>) -> T,
        T: Future<Output = Result<R>>,
    {
        let rb = Arc::new(self.c.begin().await?);
        Ok(rb.chunk(func(Arc::clone(&rb))).await?)
    }
}

impl IntoChunk for Artis {
    async fn chunk<F, T, R>(&self, func: F) -> Result<R>
    where
        F: FnOnce(Arc<ArtisTx>) -> T,
        T: Future<Output = Result<R>>,
    {
        Ok(self.chunk(func).await?)
    }
}

impl IntoArtis for Artis {
    async fn fetch<T: DeserializeOwned>(&self, i: &dyn IntoRaw) -> Result<T> {
        let (raw, args) = i.into_raw(RawType::Fetch);
        Ok(decode(self.c.query(raw, args).await?)?)
    }

    async fn pluck<T: DeserializeOwned>(&self, i: &dyn IntoRaw, colume: &'static str) -> Result<T> {
        let (raw, args) = i.into_raw(RawType::Fetch);
        Ok(decode_pluck(self.c.query(raw, args).await?, colume)?)
    }

    async fn saving(&self, i: &dyn IntoRaw) -> Result<Value> {
        let (raw, args) = i.into_raw(RawType::Saving);
        Ok(self.c.exec(raw, args).await?.last_insert_id)
    }

    async fn update(&self, i: &dyn IntoRaw) -> Result<u64> {
        let (raw, args) = i.into_raw(RawType::Update);
        Ok(self.c.exec(raw, args).await?.rows_affected)
    }

    async fn delete(&self, i: &dyn IntoRaw) -> Result<u64> {
        let (raw, args) = i.into_raw(RawType::Delete);
        Ok(self.c.exec(raw, args).await?.rows_affected)
    }

    async fn query(&self, i: &dyn IntoRaw) -> Result<Value> {
        let (raw, args) = i.into_raw(RawType::Fetch);
        Ok(self.c.query(raw, args).await?)
    }

    async fn exec(&self, raw: &str, args: Args) -> Result<ExecResult> {
        Ok(self.c.exec(raw.into(), args).await?)
    }
}