hdbconnect/
r2d2.rs

1//! Connection Pooling with r2d2.
2
3use crate::{
4    ConnectParams, Connection, ConnectionConfiguration, HdbError, HdbResult, IntoConnectParams,
5};
6use log::trace;
7
8/// Implementation of r2d2's
9/// [`ManageConnection`](https://docs.rs/r2d2/*/r2d2/trait.ManageConnection.html).
10///
11/// ## Example
12///
13/// ```rust,no_run
14/// use hdbconnect::{
15///     ConnectionConfiguration, ConnectParams, ConnectionManager, IntoConnectParamsBuilder
16/// };
17///
18/// # use hdbconnect::HdbResult;
19/// # fn foo() -> HdbResult<()> {
20/// let pool = r2d2::Pool::builder()
21///     .max_size(15)
22///     .build(ConnectionManager::with_configuration(
23///         "hdbsql://abcd123:2222"
24///             .into_connect_params_builder()?
25///             .with_dbuser("MEIER")
26///             .with_password("schlau"),
27///         ConnectionConfiguration::default().with_auto_commit(false),
28///     )?).unwrap();
29///
30/// let conn = pool.get().unwrap();
31/// conn.query("select 1 from dummy")?;
32/// # Ok(())}
33/// ```
34///
35#[derive(Debug)]
36pub struct ConnectionManager {
37    connect_params: ConnectParams,
38    connect_config: ConnectionConfiguration,
39}
40impl ConnectionManager {
41    /// Creates a new `ConnectionManager`.
42    ///
43    /// # Errors
44    ///
45    /// `HdbError::Usage` if not enough or inconsistent information was provided
46    pub fn new<P: IntoConnectParams>(p: P) -> HdbResult<Self> {
47        Ok(Self {
48            connect_params: p.into_connect_params()?,
49            connect_config: ConnectionConfiguration::default(),
50        })
51    }
52    /// Creates a new `ConnectionManager` with provided configuration.
53    ///
54    /// # Errors
55    ///
56    /// `HdbError::Usage` if not enough or inconsistent information was provided
57    pub fn with_configuration<P: IntoConnectParams>(
58        p: P,
59        c: ConnectionConfiguration,
60    ) -> HdbResult<Self> {
61        Ok(Self {
62            connect_params: p.into_connect_params()?,
63            connect_config: c,
64        })
65    }
66}
67
68impl r2d2::ManageConnection for ConnectionManager {
69    type Connection = Connection;
70    type Error = HdbError;
71
72    fn connect(&self) -> Result<Self::Connection, Self::Error> {
73        trace!("ConnectionManager::connect()");
74        Connection::with_configuration(&self.connect_params, &self.connect_config)
75    }
76
77    fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error> {
78        trace!("ConnectionManager::is_valid()");
79        conn.query("SELECT 'IsConnectionStillAlive' from dummy")
80            .map(|_| ())
81    }
82
83    fn has_broken(&self, conn: &mut Self::Connection) -> bool {
84        trace!("ConnectionManager::has_broken()");
85        conn.is_broken().unwrap_or(false)
86    }
87}