use diesel::query_builder::{QueryFragment, QueryId};
use diesel::result::{Error as DieselError, QueryResult};
use diesel_async::scoped_futures::ScopedFutureExt;
use diesel_async::{AsyncConnection, RunQueryDsl as _};
pub trait ApplyOpsAsync: Iterator + Sized {
fn apply_async<Conn>(self, conn: &mut Conn) -> impl Future<Output = QueryResult<usize>> + Send
where
Conn: AsyncConnection,
Self: Send,
Self::Item: QueryFragment<Conn::Backend> + QueryId + Send;
fn apply_transactional_async<'a, Conn>(
self,
conn: &'a mut Conn,
) -> impl Future<Output = QueryResult<usize>> + Send + 'a
where
Conn: AsyncConnection,
Self: Send + 'a,
Self::Item: QueryFragment<Conn::Backend> + QueryId + Send;
}
impl<I> ApplyOpsAsync for I
where
I: Iterator + Sized,
{
async fn apply_async<Conn>(self, conn: &mut Conn) -> QueryResult<usize>
where
Conn: AsyncConnection,
Self: Send,
Self::Item: QueryFragment<Conn::Backend> + QueryId + Send,
{
let mut total = 0_usize;
for op in self {
total = total.saturating_add(op.execute(conn).await?);
}
Ok(total)
}
fn apply_transactional_async<'a, Conn>(
self,
conn: &'a mut Conn,
) -> impl Future<Output = QueryResult<usize>> + Send + 'a
where
Conn: AsyncConnection,
Self: Send + 'a,
Self::Item: QueryFragment<Conn::Backend> + QueryId + Send,
{
conn.transaction::<usize, DieselError, _>(move |conn| self.apply_async(conn).scope_boxed())
}
}