mithril_persistence/sqlite/
connection_pool.rs

1use std::{ops::Deref, time::Duration};
2
3use mithril_common::StdResult;
4use mithril_resource_pool::{Reset, ResourcePool, ResourcePoolItem};
5
6use crate::sqlite::SqliteConnection;
7
8/// SqliteConnection wrapper for a pooled connection
9pub struct SqlitePooledConnection(SqliteConnection);
10
11impl SqlitePooledConnection {
12    /// Create a new SqlitePooledConnection
13    pub fn new(connection: SqliteConnection) -> Self {
14        Self(connection)
15    }
16}
17
18impl Deref for SqlitePooledConnection {
19    type Target = SqliteConnection;
20
21    fn deref(&self) -> &Self::Target {
22        &self.0
23    }
24}
25
26impl Reset for SqlitePooledConnection {}
27
28/// Pool of Sqlite connections
29pub struct SqliteConnectionPool {
30    connection_pool: ResourcePool<SqlitePooledConnection>,
31}
32
33impl SqliteConnectionPool {
34    /// Create a new pool with the given size by calling the given builder function
35    pub fn build(
36        size: usize,
37        builder: impl Fn() -> StdResult<SqliteConnection>,
38    ) -> StdResult<Self> {
39        let mut connections: Vec<SqlitePooledConnection> = Vec::with_capacity(size);
40        for _count in 0..size {
41            connections.push(SqlitePooledConnection::new(builder()?));
42        }
43
44        Ok(Self {
45            connection_pool: ResourcePool::new(connections.len(), connections),
46        })
47    }
48
49    /// Get a connection from the pool
50    pub fn connection(&self) -> StdResult<ResourcePoolItem<SqlitePooledConnection>> {
51        let timeout = Duration::from_millis(1000);
52        let connection = self.connection_pool.acquire_resource(timeout)?;
53
54        Ok(connection)
55    }
56
57    /// Returns a single resource pool connection
58    pub fn build_from_connection(connection: SqliteConnection) -> Self {
59        let connection_pool = ResourcePool::new(1, vec![SqlitePooledConnection::new(connection)]);
60
61        Self { connection_pool }
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68    use crate::database::test_helper::cardano_tx_db_connection;
69
70    #[test]
71    fn can_build_pool_of_given_size() {
72        let pool = SqliteConnectionPool::build(10, cardano_tx_db_connection).unwrap();
73
74        assert_eq!(pool.connection_pool.size(), 10);
75    }
76}