diesel_async/
stmt_cache.rs1use 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}