use prax_query::error::QueryResult;
use prax_query::raw::Sql;
use prax_query::row::FromRow;
use prax_query::traits::{Model, QueryEngine};
#[derive(Clone)]
pub struct PraxClient<E: QueryEngine> {
engine: E,
}
impl<E: QueryEngine> PraxClient<E> {
pub fn new(engine: E) -> Self {
Self { engine }
}
pub fn engine(&self) -> &E {
&self.engine
}
pub async fn query_raw<T>(&self, sql: Sql) -> QueryResult<Vec<T>>
where
T: Model + FromRow + Send + 'static,
{
let (s, p) = sql.build();
self.engine.query_many::<T>(&s, p).await
}
pub async fn execute_raw(&self, sql: Sql) -> QueryResult<u64> {
let (s, p) = sql.build();
self.engine.execute_raw(&s, p).await
}
pub async fn transaction<R, Fut, F>(&self, f: F) -> QueryResult<R>
where
F: FnOnce(PraxClient<E>) -> Fut + Send + 'static,
Fut: std::future::Future<Output = QueryResult<R>> + Send + 'static,
R: Send + 'static,
{
self.engine
.transaction(move |tx_engine| async move { f(PraxClient::new(tx_engine)).await })
.await
}
}
#[macro_export]
macro_rules! client {
($($model:ident),+ $(,)?) => {
pub trait PraxClientExt<E: $crate::__prelude::QueryEngine> {
$( $crate::__client_accessor_trait!($model); )+
}
impl<E: $crate::__prelude::QueryEngine> PraxClientExt<E>
for $crate::PraxClient<E>
{
$( $crate::__client_accessor_impl!($model); )+
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __client_accessor_trait {
($model:ident) => {
$crate::__paste::paste! {
fn [<$model:snake>](&self) -> [<$model:snake>]::Client<E>;
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __client_accessor_impl {
($model:ident) => {
$crate::__paste::paste! {
fn [<$model:snake>](&self) -> [<$model:snake>]::Client<E> {
[<$model:snake>]::Client::new(self.engine().clone())
}
}
};
}
#[doc(hidden)]
pub use ::pastey as __paste;
#[doc(hidden)]
pub mod __prelude {
pub use prax_query::traits::QueryEngine;
}