2025-04-25 15:42:46 -07:00
|
|
|
use anyhow::Result;
|
2025-04-27 13:40:59 -07:00
|
|
|
use async_trait::async_trait;
|
2025-06-06 16:39:31 -07:00
|
|
|
use diesel::prelude::*;
|
2025-04-27 13:40:59 -07:00
|
|
|
|
|
|
|
|
pub use std::sync::Arc;
|
|
|
|
|
pub use tokio::sync::Mutex;
|
2025-04-25 15:42:46 -07:00
|
|
|
|
|
|
|
|
use crate::repository::Repository;
|
|
|
|
|
use crate::settings::Settings;
|
|
|
|
|
|
|
|
|
|
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
|
|
|
|
|
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
|
|
|
|
|
|
2025-04-27 13:40:59 -07:00
|
|
|
#[async_trait]
|
|
|
|
|
pub trait DatabaseAccess {
|
|
|
|
|
async fn with_repository<F, R>(&mut self, f: F) -> R
|
|
|
|
|
where
|
|
|
|
|
F: FnOnce(&mut Repository) -> R + Send,
|
|
|
|
|
R: Send;
|
|
|
|
|
|
|
|
|
|
async fn with_settings<F, R>(&mut self, f: F) -> R
|
|
|
|
|
where
|
|
|
|
|
F: FnOnce(&mut Settings) -> R + Send,
|
|
|
|
|
R: Send;
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-25 15:42:46 -07:00
|
|
|
pub struct Database {
|
2025-04-25 20:02:18 -07:00
|
|
|
pub connection: SqliteConnection,
|
2025-04-25 15:42:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Database {
|
|
|
|
|
pub fn new(path: &str) -> Result<Self> {
|
|
|
|
|
let mut connection = SqliteConnection::establish(path)?;
|
2025-06-06 16:39:31 -07:00
|
|
|
connection
|
|
|
|
|
.run_pending_migrations(MIGRATIONS)
|
2025-04-25 15:42:46 -07:00
|
|
|
.map_err(|e| anyhow::anyhow!("Error running migrations: {}", e))?;
|
|
|
|
|
|
|
|
|
|
Ok(Self { connection })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_in_memory() -> Result<Self> {
|
|
|
|
|
Self::new(":memory:")
|
|
|
|
|
}
|
2025-04-27 13:40:59 -07:00
|
|
|
}
|
2025-04-25 15:42:46 -07:00
|
|
|
|
2025-04-27 13:40:59 -07:00
|
|
|
#[async_trait]
|
|
|
|
|
impl DatabaseAccess for Database {
|
|
|
|
|
async fn with_repository<F, R>(&mut self, f: F) -> R
|
2025-04-25 16:34:00 -07:00
|
|
|
where
|
2025-04-27 13:40:59 -07:00
|
|
|
F: FnOnce(&mut Repository) -> R + Send,
|
|
|
|
|
R: Send,
|
2025-04-25 16:34:00 -07:00
|
|
|
{
|
|
|
|
|
let mut repository = Repository::new(&mut self.connection);
|
|
|
|
|
f(&mut repository)
|
2025-04-25 15:42:46 -07:00
|
|
|
}
|
|
|
|
|
|
2025-04-27 13:40:59 -07:00
|
|
|
async fn with_settings<F, R>(&mut self, f: F) -> R
|
2025-04-25 16:34:00 -07:00
|
|
|
where
|
2025-04-27 13:40:59 -07:00
|
|
|
F: FnOnce(&mut Settings) -> R + Send,
|
|
|
|
|
R: Send,
|
2025-04-25 16:34:00 -07:00
|
|
|
{
|
|
|
|
|
let mut settings = Settings::new(&mut self.connection);
|
|
|
|
|
f(&mut settings)
|
2025-04-25 15:42:46 -07:00
|
|
|
}
|
2025-04-25 20:02:18 -07:00
|
|
|
}
|
|
|
|
|
|
2025-04-27 13:40:59 -07:00
|
|
|
#[async_trait]
|
|
|
|
|
impl DatabaseAccess for Arc<Mutex<Database>> {
|
|
|
|
|
async fn with_repository<F, R>(&mut self, f: F) -> R
|
|
|
|
|
where
|
|
|
|
|
F: FnOnce(&mut Repository) -> R + Send,
|
|
|
|
|
R: Send,
|
|
|
|
|
{
|
|
|
|
|
let mut database = self.lock().await;
|
|
|
|
|
database.with_repository(f).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn with_settings<F, R>(&mut self, f: F) -> R
|
|
|
|
|
where
|
|
|
|
|
F: FnOnce(&mut Settings) -> R + Send,
|
|
|
|
|
R: Send,
|
|
|
|
|
{
|
|
|
|
|
let mut database = self.lock().await;
|
|
|
|
|
database.with_settings(f).await
|
|
|
|
|
}
|
|
|
|
|
}
|