Private
Public Access
1
0
Files
Kordophone/kordophone-db/src/database.rs

87 lines
2.1 KiB
Rust
Raw Normal View History

use anyhow::Result;
use async_trait::async_trait;
2025-06-06 16:39:31 -07:00
use diesel::prelude::*;
pub use std::sync::Arc;
pub use tokio::sync::Mutex;
use crate::repository::Repository;
use crate::settings::Settings;
use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
#[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;
}
pub struct Database {
pub connection: SqliteConnection,
}
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)
.map_err(|e| anyhow::anyhow!("Error running migrations: {}", e))?;
Ok(Self { connection })
}
pub fn new_in_memory() -> Result<Self> {
Self::new(":memory:")
}
}
#[async_trait]
impl DatabaseAccess for Database {
async fn with_repository<F, R>(&mut self, f: F) -> R
where
F: FnOnce(&mut Repository) -> R + Send,
R: Send,
{
let mut repository = Repository::new(&mut self.connection);
f(&mut repository)
}
async fn with_settings<F, R>(&mut self, f: F) -> R
where
F: FnOnce(&mut Settings) -> R + Send,
R: Send,
{
let mut settings = Settings::new(&mut self.connection);
f(&mut settings)
}
}
#[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
}
}