authenticator/models/
database.rs1use std::{fs, fs::File, path::PathBuf, sync::LazyLock};
2
3use anyhow::Result;
4use diesel::{prelude::*, r2d2, r2d2::ConnectionManager};
5use diesel_migrations::{EmbeddedMigrations, MigrationHarness, embed_migrations};
6
7type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
8
9static DB_PATH: LazyLock<PathBuf> =
10 LazyLock::new(|| gtk::glib::user_data_dir().join("authenticator"));
11static POOL: LazyLock<Pool> = LazyLock::new(|| init_pool().expect("Failed to create a pool"));
12
13pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations/");
14
15pub(crate) fn connection() -> Pool {
16 POOL.clone()
17}
18
19fn init_pool() -> Result<Pool> {
20 fs::create_dir_all(&*DB_PATH)?;
21 let db_path = DB_PATH.join("authenticator.db");
22 if !db_path.exists() {
23 File::create(&db_path)?;
24 }
25 let manager = ConnectionManager::<SqliteConnection>::new(db_path.to_str().unwrap());
26 let pool = r2d2::Pool::builder().build(manager)?;
27
28 {
29 let mut db = pool.get()?;
30 tracing::info!("Running DB Migrations...");
31 db.run_pending_migrations(MIGRATIONS)
32 .expect("Failed to run migrations");
33 }
34 tracing::info!("Database pool initialized.");
35 Ok(pool)
36}