diesel_async/pooled_connection/
mod.rs1use crate::{AsyncConnection, TransactionManager};
9use diesel::QueryResult;
10use futures_core::future::BoxFuture;
11use futures_util::FutureExt;
12use std::borrow::Cow;
13use std::fmt;
14use std::future::Future;
15
16#[cfg(feature = "bb8")]
17pub mod bb8;
18#[cfg(feature = "deadpool")]
19pub mod deadpool;
20#[cfg(feature = "mobc")]
21pub mod mobc;
22
23#[derive(Debug)]
25pub enum PoolError {
26 ConnectionError(diesel::result::ConnectionError),
28
29 QueryError(diesel::result::Error),
31}
32
33impl fmt::Display for PoolError {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 match *self {
36 PoolError::ConnectionError(ref e) => e.fmt(f),
37 PoolError::QueryError(ref e) => e.fmt(f),
38 }
39 }
40}
41
42impl std::error::Error for PoolError {}
43
44pub type SetupCallback<C> =
46 Box<dyn Fn(&str) -> BoxFuture<diesel::ConnectionResult<C>> + Send + Sync>;
47
48pub type RecycleCheckCallback<C> = dyn Fn(&mut C) -> BoxFuture<QueryResult<()>> + Send + Sync;
50
51#[derive(Default)]
53pub enum RecyclingMethod<C> {
54 Fast,
60 #[default]
64 Verified,
65 CustomQuery(Cow<'static, str>),
67 CustomFunction(Box<RecycleCheckCallback<C>>),
71}
72
73impl<C: fmt::Debug> fmt::Debug for RecyclingMethod<C> {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 match self {
76 Self::Fast => write!(f, "Fast"),
77 Self::Verified => write!(f, "Verified"),
78 Self::CustomQuery(arg0) => f.debug_tuple("CustomQuery").field(arg0).finish(),
79 Self::CustomFunction(_) => f.debug_tuple("CustomFunction").finish(),
80 }
81 }
82}
83
84#[non_exhaustive]
90pub struct ManagerConfig<C> {
91 pub recycling_method: RecyclingMethod<C>,
93 pub custom_setup: SetupCallback<C>,
99}
100
101impl<C> Default for ManagerConfig<C>
102where
103 C: AsyncConnection + 'static,
104{
105 fn default() -> Self {
106 Self {
107 recycling_method: Default::default(),
108 custom_setup: Box::new(|url| C::establish(url).boxed()),
109 }
110 }
111}
112
113#[allow(dead_code)]
120pub struct AsyncDieselConnectionManager<C> {
121 connection_url: String,
122 manager_config: ManagerConfig<C>,
123}
124
125impl<C> fmt::Debug for AsyncDieselConnectionManager<C> {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 write!(
128 f,
129 "AsyncDieselConnectionManager<{}>",
130 std::any::type_name::<C>()
131 )
132 }
133}
134
135impl<C> AsyncDieselConnectionManager<C>
136where
137 C: AsyncConnection + 'static,
138{
139 #[must_use]
142 pub fn new(connection_url: impl Into<String>) -> Self
143 where
144 C: AsyncConnection + 'static,
145 {
146 Self::new_with_config(connection_url, Default::default())
147 }
148
149 #[must_use]
153 pub fn new_with_config(
154 connection_url: impl Into<String>,
155 manager_config: ManagerConfig<C>,
156 ) -> Self {
157 Self {
158 connection_url: connection_url.into(),
159 manager_config,
160 }
161 }
162}
163
164#[doc(hidden)]
165pub trait PoolableConnection: AsyncConnection {
166 fn ping(
171 &mut self,
172 config: &RecyclingMethod<Self>,
173 ) -> impl Future<Output = diesel::QueryResult<()>> + Send
174 where
175 for<'a> Self: 'a,
176 diesel::dsl::select<diesel::dsl::AsExprOf<i32, diesel::sql_types::Integer>>:
177 crate::methods::ExecuteDsl<Self>,
178 diesel::query_builder::SqlQuery: crate::methods::ExecuteDsl<Self>,
179 {
180 use crate::run_query_dsl::RunQueryDsl;
181 use diesel::IntoSql;
182
183 async move {
184 match config {
185 RecyclingMethod::Fast => Ok(()),
186 RecyclingMethod::Verified => {
187 diesel::select(1_i32.into_sql::<diesel::sql_types::Integer>())
188 .execute(self)
189 .await
190 .map(|_| ())
191 }
192 RecyclingMethod::CustomQuery(query) => diesel::sql_query(query.as_ref())
193 .execute(self)
194 .await
195 .map(|_| ()),
196 RecyclingMethod::CustomFunction(c) => c(self).await,
197 }
198 }
199 }
200
201 fn is_broken(&mut self) -> bool {
210 Self::TransactionManager::is_broken_transaction_manager(self)
211 }
212}