daemon: implement solution for background sync
This commit is contained in:
@@ -5,6 +5,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.94"
|
||||
async-trait = "0.1.88"
|
||||
bincode = "1.3.3"
|
||||
chrono = "0.4.38"
|
||||
diesel = { version = "2.2.6", features = ["chrono", "sqlite", "time"] }
|
||||
@@ -12,4 +13,5 @@ diesel_migrations = { version = "2.2.0", features = ["sqlite"] }
|
||||
kordophone = { path = "../kordophone" }
|
||||
serde = { version = "1.0.215", features = ["derive"] }
|
||||
time = "0.3.37"
|
||||
tokio = "1.44.2"
|
||||
uuid = { version = "1.11.0", features = ["v4"] }
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
use anyhow::Result;
|
||||
use diesel::prelude::*;
|
||||
use async_trait::async_trait;
|
||||
|
||||
pub use std::sync::Arc;
|
||||
pub use tokio::sync::Mutex;
|
||||
|
||||
use crate::repository::Repository;
|
||||
use crate::settings::Settings;
|
||||
@@ -10,6 +14,19 @@ use kordophone::model::JwtToken;
|
||||
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,
|
||||
}
|
||||
@@ -26,38 +43,64 @@ impl Database {
|
||||
pub fn new_in_memory() -> Result<Self> {
|
||||
Self::new(":memory:")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_repository<F, R>(&mut self, f: F) -> R
|
||||
#[async_trait]
|
||||
impl DatabaseAccess for Database {
|
||||
async fn with_repository<F, R>(&mut self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Repository) -> R,
|
||||
F: FnOnce(&mut Repository) -> R + Send,
|
||||
R: Send,
|
||||
{
|
||||
let mut repository = Repository::new(&mut self.connection);
|
||||
f(&mut repository)
|
||||
}
|
||||
|
||||
pub fn with_settings<F, R>(&mut self, f: F) -> R
|
||||
async fn with_settings<F, R>(&mut self, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Settings) -> R,
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
static TOKEN_KEY: &str = "token";
|
||||
|
||||
impl TokenManagement for Database {
|
||||
fn get_token(&mut self) -> Option<JwtToken> {
|
||||
async fn get_token(&mut self) -> Option<JwtToken> {
|
||||
self.with_settings(|settings| {
|
||||
let token: Result<Option<JwtToken>> = settings.get(TOKEN_KEY);
|
||||
match token {
|
||||
Ok(data) => data,
|
||||
Err(_) => None,
|
||||
}
|
||||
})
|
||||
}).await
|
||||
}
|
||||
|
||||
fn set_token(&mut self, token: JwtToken) {
|
||||
self.with_settings(|settings| settings.put(TOKEN_KEY, &token).unwrap());
|
||||
async fn set_token(&mut self, token: JwtToken) {
|
||||
self.with_settings(|settings| settings.put(TOKEN_KEY, &token).unwrap()).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
database::Database,
|
||||
database::{Database, DatabaseAccess},
|
||||
repository::Repository,
|
||||
models::{
|
||||
conversation::{Conversation, ConversationBuilder},
|
||||
|
||||
Reference in New Issue
Block a user