db_pool/async/
conn_pool.rs

1use std::{ops::Deref, sync::Arc};
2
3use uuid::Uuid;
4
5use super::backend::{r#trait::Backend, Error as BackendError};
6
7struct ConnectionPool<B: Backend> {
8    backend: Arc<B>,
9    db_id: Uuid,
10    conn_pool: Option<B::Pool>,
11    is_restricted: bool,
12}
13
14impl<B: Backend> Deref for ConnectionPool<B> {
15    type Target = B::Pool;
16
17    fn deref(&self) -> &Self::Target {
18        self.conn_pool
19            .as_ref()
20            .expect("conn_pool must always contain a [Some] value")
21    }
22}
23
24impl<B: Backend> Drop for ConnectionPool<B> {
25    fn drop(&mut self) {
26        self.conn_pool = None;
27        tokio::task::block_in_place(|| {
28            tokio::runtime::Handle::current().block_on(async {
29                (*self.backend)
30                    .drop(self.db_id, self.is_restricted)
31                    .await
32                    .ok();
33            });
34        });
35    }
36}
37
38/// Reusable connection pool wrapper
39pub struct ReusableConnectionPool<B: Backend>(ConnectionPool<B>);
40
41impl<B: Backend> ReusableConnectionPool<B> {
42    pub(crate) async fn new(
43        backend: Arc<B>,
44    ) -> Result<Self, BackendError<B::BuildError, B::PoolError, B::ConnectionError, B::QueryError>>
45    {
46        let db_id = Uuid::new_v4();
47        let conn_pool = backend.create(db_id, true).await?;
48
49        Ok(Self(ConnectionPool {
50            backend,
51            db_id,
52            conn_pool: Some(conn_pool),
53            is_restricted: true,
54        }))
55    }
56
57    pub(crate) async fn clean(
58        &mut self,
59    ) -> Result<(), BackendError<B::BuildError, B::PoolError, B::ConnectionError, B::QueryError>>
60    {
61        self.0.backend.clean(self.0.db_id).await
62    }
63}
64
65impl<B: Backend> Deref for ReusableConnectionPool<B> {
66    type Target = B::Pool;
67
68    fn deref(&self) -> &Self::Target {
69        &self.0
70    }
71}
72
73/// Single-use connection pool wrapper
74pub struct SingleUseConnectionPool<B: Backend>(ConnectionPool<B>);
75
76impl<B: Backend> SingleUseConnectionPool<B> {
77    pub(crate) async fn new(
78        backend: Arc<B>,
79    ) -> Result<Self, BackendError<B::BuildError, B::PoolError, B::ConnectionError, B::QueryError>>
80    {
81        let db_id = Uuid::new_v4();
82        let conn_pool = backend.create(db_id, false).await?;
83
84        Ok(Self(ConnectionPool {
85            backend,
86            db_id,
87            conn_pool: Some(conn_pool),
88            is_restricted: false,
89        }))
90    }
91}
92
93impl<B: Backend> Deref for SingleUseConnectionPool<B> {
94    type Target = B::Pool;
95
96    fn deref(&self) -> &Self::Target {
97        &self.0
98    }
99}