create_rust_app/database/
mod.rs1use 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)]
23pub 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 #[must_use]
37 pub fn new() -> Self {
38 Self {
39 pool: Self::get_or_init_pool(),
40 }
41 }
42
43 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 #[must_use]
70 pub fn connection_url() -> String {
71 std::env::var("DATABASE_URL").expect("DATABASE_URL environment variable expected.")
72 }
73}