create_rust_app/database/
mod.rs

1use diesel::r2d2::{self, ConnectionManager, PooledConnection};
2use diesel_logger::LoggingConnection;
3use once_cell::sync::OnceCell;
4
5#[cfg(feature = "database_postgres")]
6type DbCon = diesel::PgConnection;
7
8#[cfg(feature = "database_sqlite")]
9type DbCon = diesel::SqliteConnection;
10
11#[cfg(all(feature = "database_postgres", debug_assertions))]
12#[allow(dead_code)]
13pub type DieselBackend = diesel::pg::Pg;
14
15#[cfg(all(feature = "database_sqlite", debug_assertions))]
16#[allow(dead_code)]
17pub type DieselBackend = diesel::sqlite::Sqlite;
18
19pub type Pool = r2d2::Pool<ConnectionManager<DbCon>>;
20pub type Connection = LoggingConnection<PooledConnection<ConnectionManager<DbCon>>>;
21
22#[derive(Clone)]
23/// wrapper function for a database pool
24pub struct Database {
25    pub pool: &'static Pool,
26}
27
28impl Default for Database {
29    fn default() -> Self {
30        Self::new()
31    }
32}
33
34impl Database {
35    /// create a new [`Database`]
36    #[must_use]
37    pub fn new() -> Self {
38        Self {
39            pool: Self::get_or_init_pool(),
40        }
41    }
42
43    /// get a [`Connection`] to a database
44    ///
45    /// # Errors
46    ///
47    /// * if the pool is unable to get a connection
48    pub fn get_connection(&self) -> Result<Connection, anyhow::Error> {
49        Ok(LoggingConnection::new(self.pool.get()?))
50    }
51
52    fn get_or_init_pool() -> &'static Pool {
53        static POOL: OnceCell<Pool> = OnceCell::new();
54        #[cfg(debug_assertions)]
55        crate::load_env_vars();
56
57        POOL.get_or_init(|| {
58            Pool::builder()
59                .connection_timeout(std::time::Duration::from_secs(5))
60                .build(ConnectionManager::<DbCon>::new(Self::connection_url()))
61                .unwrap()
62        })
63    }
64
65    /// get the connection url for the database
66    ///
67    /// # Panics
68    /// * if the `DATABASE_URL` environment variable is not set
69    #[must_use]
70    pub fn connection_url() -> String {
71        std::env::var("DATABASE_URL").expect("DATABASE_URL environment variable expected.")
72    }
73}