use std::convert;
use actix_web::web;
use diesel::Connection;
use super::DbConnection;
#[cfg(not(feature = "multidb"))]
use super::Pool;
#[cfg(feature = "multidb")]
use super::multi::MultiPool;
pub use serwus_derive::Canceled;
#[cfg(not(feature = "multidb"))]
pub async fn async_query<F, I, E>(db_pool: Pool, query_func: F) -> Result<I, E>
where
F: FnOnce(&mut DbConnection) -> Result<I, E> + Send + 'static,
I: Send + 'static,
E: From<actix_web::error::BlockingError> + From<r2d2::Error> + std::fmt::Debug + Send + 'static,
{
web::block(move || {
let mut connection = db_pool.get()?;
query_func(&mut connection)
})
.await
.map_err(From::from)
.and_then(convert::identity)
}
#[cfg(not(feature = "multidb"))]
pub async fn async_transaction<F, I, E>(db_pool: Pool, query_func: F) -> Result<I, E>
where
F: FnOnce(&mut DbConnection) -> Result<I, E> + Send + 'static,
I: Send + 'static,
E: From<actix_web::error::BlockingError>
+ From<r2d2::Error>
+ From<diesel::result::Error>
+ std::fmt::Debug
+ Send
+ 'static,
{
web::block(move || {
let mut connection = db_pool.get()?;
connection.transaction(|connection| query_func(connection))
})
.await
.map_err(From::from)
.and_then(convert::identity)
}
pub async fn async_query_in_trans<F, I, E>(
mut connection: DbConnection,
query_func: F,
) -> Result<I, E>
where
F: FnOnce(&mut DbConnection) -> Result<I, E> + Send + 'static,
I: Send + 'static,
E: From<actix_web::error::BlockingError> + From<r2d2::Error> + std::fmt::Debug + Send + 'static,
{
web::block(move || query_func(&mut connection))
.await
.map_err(From::from)
.and_then(convert::identity)
}
#[cfg(feature = "multidb")]
pub async fn async_read_query<F, I, E>(db_pool: MultiPool, query_func: F) -> Result<I, E>
where
F: FnOnce(&mut DbConnection) -> Result<I, E> + Send + 'static,
I: Send + 'static,
E: From<actix_web::error::BlockingError> + From<r2d2::Error> + std::fmt::Debug + Send + 'static,
{
web::block(move || {
let mut connection = db_pool.read()?;
query_func(&mut connection)
})
.await
.map_err(From::from)
.and_then(convert::identity)
}
#[cfg(feature = "multidb")]
pub async fn async_write_query<F, I, E>(db_pool: MultiPool, query_func: F) -> Result<I, E>
where
F: FnOnce(&mut DbConnection) -> Result<I, E> + Send + 'static,
I: Send + 'static,
E: From<actix_web::error::BlockingError> + From<r2d2::Error> + std::fmt::Debug + Send + 'static,
{
web::block(move || {
let mut connection = db_pool.write()?;
query_func(&mut connection)
})
.await
.map_err(From::from)
.and_then(convert::identity)
}
#[cfg(feature = "multidb")]
pub async fn async_read_transaction<F, I, E>(db_pool: MultiPool, query_func: F) -> Result<I, E>
where
F: FnOnce(&mut DbConnection) -> Result<I, E> + Send + 'static,
I: Send + 'static,
E: From<actix_web::error::BlockingError>
+ From<r2d2::Error>
+ From<diesel::result::Error>
+ std::fmt::Debug
+ Send
+ 'static,
{
use diesel::{RunQueryDsl, sql_query};
web::block(move || {
let mut connection = db_pool.read()?;
connection.transaction(|connection| {
sql_query("SET TRANSACTION READ ONLY").execute(connection)?;
query_func(connection)
})
})
.await
.map_err(From::from)
.and_then(convert::identity)
}
#[cfg(feature = "multidb")]
pub async fn async_write_transaction<F, I, E>(db_pool: MultiPool, query_func: F) -> Result<I, E>
where
F: FnOnce(&mut DbConnection) -> Result<I, E> + Send + 'static,
I: Send + 'static,
E: From<actix_web::error::BlockingError>
+ From<r2d2::Error>
+ From<diesel::result::Error>
+ std::fmt::Debug
+ Send
+ 'static,
{
web::block(move || {
let mut connection = db_pool.write()?;
connection.transaction(|connection| query_func(connection))
})
.await
.map_err(From::from)
.and_then(convert::identity)
}