Skip to main content

convert_invert/internals/database/
mod.rs

1use diesel::prelude::*;
2use diesel::r2d2::{self, ConnectionManager};
3use dotenvy::dotenv;
4use std::{env, time::Duration};
5
6pub mod manager;
7pub mod model;
8pub mod schema;
9
10pub type DbPool = r2d2::Pool<ConnectionManager<PgConnection>>;
11
12#[derive(Debug, Clone, Copy)]
13pub struct DbPoolSnapshot {
14    pub connections: u32,
15    pub idle_connections: u32,
16}
17
18impl DbPoolSnapshot {
19    pub fn in_use_connections(self) -> u32 {
20        self.connections.saturating_sub(self.idle_connections)
21    }
22}
23
24pub fn db_pool_snapshot(pool: &DbPool) -> DbPoolSnapshot {
25    let state = pool.state();
26    DbPoolSnapshot {
27        connections: state.connections,
28        idle_connections: state.idle_connections,
29    }
30}
31
32pub fn db_pool_max_size_from_env(default: u32) -> u32 {
33    env::var("DB_POOL_MAX_SIZE")
34        .ok()
35        .and_then(|value| value.parse().ok())
36        .unwrap_or(default)
37}
38
39pub fn db_pool_timeout_from_env(default_secs: u64) -> Duration {
40    let secs = env::var("DB_POOL_TIMEOUT_SECS")
41        .ok()
42        .and_then(|value| value.parse().ok())
43        .unwrap_or(default_secs);
44    Duration::from_secs(secs)
45}
46
47pub fn init_pool() -> anyhow::Result<DbPool> {
48    dotenv().ok();
49    let database_url = env::var("DATABASE_URL")?;
50    let manager = ConnectionManager::<PgConnection>::new(database_url);
51    r2d2::Pool::builder()
52        .max_size(db_pool_max_size_from_env(18))
53        .connection_timeout(db_pool_timeout_from_env(15))
54        .build(manager)
55        .map_err(Into::into)
56}
57
58pub fn establish_connection() -> anyhow::Result<PgConnection> {
59    dotenv().ok();
60
61    let database_url = env::var("DATABASE_URL")?;
62    PgConnection::establish(&database_url).map_err(Into::into)
63}