Add 'core/' from commit 'b0dfc4146ca0da535a87f8509aec68817fb2ab14'
git-subtree-dir: core git-subtree-mainline:a07f3dcd23git-subtree-split:b0dfc4146c
This commit is contained in:
94
core/kordophone-db/src/database.rs
Normal file
94
core/kordophone-db/src/database.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
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)?;
|
||||
|
||||
// Performance optimisations for SQLite. These are safe defaults that speed
|
||||
// up concurrent writes and cut the fsync cost dramatically while still
|
||||
// keeping durability guarantees that are good enough for an end-user
|
||||
// application.
|
||||
diesel::sql_query("PRAGMA journal_mode = WAL;").execute(&mut connection)?;
|
||||
diesel::sql_query("PRAGMA synchronous = NORMAL;").execute(&mut connection)?;
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user