diesel_async/
stmt_cache.rs

1use diesel::connection::statement_cache::{MaybeCached, StatementCallbackReturnType};
2use diesel::QueryResult;
3use futures_core::future::BoxFuture;
4use futures_util::future::Either;
5use futures_util::{FutureExt, TryFutureExt};
6use std::future::{self, Future};
7
8pub(crate) struct CallbackHelper<F>(pub(crate) F);
9
10type PrepareFuture<'a, C, S> = Either<
11    future::Ready<QueryResult<(MaybeCached<'a, S>, C)>>,
12    BoxFuture<'a, QueryResult<(MaybeCached<'a, S>, C)>>,
13>;
14
15impl<S, F, C> StatementCallbackReturnType<S, C> for CallbackHelper<F>
16where
17    F: Future<Output = QueryResult<(S, C)>> + Send,
18    S: 'static,
19{
20    type Return<'a> = PrepareFuture<'a, C, S>;
21
22    fn from_error<'a>(e: diesel::result::Error) -> Self::Return<'a> {
23        Either::Left(future::ready(Err(e)))
24    }
25
26    fn map_to_no_cache<'a>(self) -> Self::Return<'a>
27    where
28        Self: 'a,
29    {
30        Either::Right(
31            self.0
32                .map_ok(|(stmt, conn)| (MaybeCached::CannotCache(stmt), conn))
33                .boxed(),
34        )
35    }
36
37    fn map_to_cache(stmt: &mut S, conn: C) -> Self::Return<'_> {
38        Either::Left(future::ready(Ok((MaybeCached::Cached(stmt), conn))))
39    }
40
41    fn register_cache<'a>(
42        self,
43        callback: impl FnOnce(S) -> &'a mut S + Send + 'a,
44    ) -> Self::Return<'a>
45    where
46        Self: 'a,
47    {
48        Either::Right(
49            self.0
50                .map_ok(|(stmt, conn)| (MaybeCached::Cached(callback(stmt)), conn))
51                .boxed(),
52        )
53    }
54}
55
56pub(crate) struct QueryFragmentHelper {
57    pub(crate) sql: String,
58    pub(crate) safe_to_cache: bool,
59}