Gregory Schier
2025-06-27 13:32:52 -07:00
parent 25d50246c0
commit 9ab02130b0
6 changed files with 38 additions and 21 deletions

View File

@@ -15,7 +15,7 @@ pub enum Error {
#[error("Yaml error: {0}")] #[error("Yaml error: {0}")]
YamlParseError(#[from] serde_yaml::Error), YamlParseError(#[from] serde_yaml::Error),
#[error("Yaml error: {0}")] #[error(transparent)]
ModelError(#[from] yaak_models::error::Error), ModelError(#[from] yaak_models::error::Error),
#[error("Sync error: {0}")] #[error("Sync error: {0}")]
@@ -24,10 +24,10 @@ pub enum Error {
#[error("I/o error: {0}")] #[error("I/o error: {0}")]
IoError(#[from] io::Error), IoError(#[from] io::Error),
#[error("Yaml error: {0}")] #[error("JSON error: {0}")]
JsonParseError(#[from] serde_json::Error), JsonParseError(#[from] serde_json::Error),
#[error("Yaml error: {0}")] #[error("UTF8 error: {0}")]
Utf8ConversionError(#[from] FromUtf8Error), Utf8ConversionError(#[from] FromUtf8Error),
#[error("Git error: {0}")] #[error("Git error: {0}")]

View File

@@ -2,13 +2,14 @@ use crate::connection_or_tx::ConnectionOrTx;
use crate::error::Error::DBRowNotFound; use crate::error::Error::DBRowNotFound;
use crate::models::{AnyModel, UpsertModelInfo}; use crate::models::{AnyModel, UpsertModelInfo};
use crate::util::{ModelChangeEvent, ModelPayload, UpdateSource}; use crate::util::{ModelChangeEvent, ModelPayload, UpdateSource};
use log::error;
use rusqlite::OptionalExtension; use rusqlite::OptionalExtension;
use sea_query::{ use sea_query::{
Asterisk, Expr, IntoColumnRef, IntoIden, IntoTableRef, OnConflict, Query, SimpleExpr, Asterisk, Expr, IntoColumnRef, IntoIden, IntoTableRef, OnConflict, Query, SimpleExpr,
SqliteQueryBuilder, SqliteQueryBuilder,
}; };
use sea_query_rusqlite::RusqliteBinder; use sea_query_rusqlite::RusqliteBinder;
use tokio::sync::mpsc; use std::sync::mpsc;
pub struct DbContext<'a> { pub struct DbContext<'a> {
pub(crate) events_tx: mpsc::Sender<ModelPayload>, pub(crate) events_tx: mpsc::Sender<ModelPayload>,
@@ -150,16 +151,15 @@ impl<'a> DbContext<'a> {
update_source: source.clone(), update_source: source.clone(),
change: ModelChangeEvent::Upsert, change: ModelChangeEvent::Upsert,
}; };
self.events_tx.try_send(payload).unwrap();
if let Err(e) = self.events_tx.send(payload.clone()) {
error!("Failed to send model change {source:?}: {e:?}");
}
Ok(m) Ok(m)
} }
pub(crate) fn delete<'s, M>( pub(crate) fn delete<'s, M>(&self, m: &M, source: &UpdateSource) -> crate::error::Result<M>
&self,
m: &M,
update_source: &UpdateSource,
) -> crate::error::Result<M>
where where
M: Into<AnyModel> + Clone + UpsertModelInfo, M: Into<AnyModel> + Clone + UpsertModelInfo,
{ {
@@ -171,11 +171,13 @@ impl<'a> DbContext<'a> {
let payload = ModelPayload { let payload = ModelPayload {
model: m.clone().into(), model: m.clone().into(),
update_source: update_source.clone(), update_source: source.clone(),
change: ModelChangeEvent::Delete, change: ModelChangeEvent::Delete,
}; };
self.events_tx.try_send(payload).unwrap(); if let Err(e) = self.events_tx.send(payload) {
error!("Failed to send model change {source:?}: {e:?}");
}
Ok(m.clone()) Ok(m.clone())
} }
} }

View File

@@ -6,12 +6,12 @@ use log::error;
use r2d2::Pool; use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
use std::fs::create_dir_all; use std::fs::create_dir_all;
use std::sync::mpsc;
use std::time::Duration; use std::time::Duration;
use tauri::async_runtime::Mutex; use tauri::async_runtime::Mutex;
use tauri::plugin::TauriPlugin; use tauri::plugin::TauriPlugin;
use tauri::{Emitter, Manager, Runtime, generate_handler}; use tauri::{Emitter, Manager, Runtime, generate_handler};
use tauri_plugin_dialog::{DialogExt, MessageDialogKind}; use tauri_plugin_dialog::{DialogExt, MessageDialogKind};
use tokio::sync::mpsc;
mod commands; mod commands;
@@ -72,11 +72,11 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
app_handle.manage(SqliteConnection::new(pool.clone())); app_handle.manage(SqliteConnection::new(pool.clone()));
{ {
let (tx, mut rx) = mpsc::channel(128); let (tx, rx) = mpsc::channel();
app_handle.manage(QueryManager::new(pool, tx)); app_handle.manage(QueryManager::new(pool, tx));
let app_handle = app_handle.clone(); let app_handle = app_handle.clone();
tauri::async_runtime::spawn(async move { tauri::async_runtime::spawn(async move {
while let Some(p) = rx.recv().await { for p in rx {
let name = match p.change { let name = match p.change {
ModelChangeEvent::Upsert => "upserted_model", ModelChangeEvent::Upsert => "upserted_model",
ModelChangeEvent::Delete => "deleted_model", ModelChangeEvent::Delete => "deleted_model",

View File

@@ -6,9 +6,8 @@ use crate::util::ModelPayload;
use r2d2::Pool; use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
use rusqlite::TransactionBehavior; use rusqlite::TransactionBehavior;
use std::sync::{Arc, Mutex}; use std::sync::{mpsc, Arc, Mutex};
use tauri::{Manager, Runtime, State}; use tauri::{Manager, Runtime, State};
use tokio::sync::mpsc;
pub trait QueryManagerExt<'a, R> { pub trait QueryManagerExt<'a, R> {
fn db_manager(&'a self) -> State<'a, QueryManager>; fn db_manager(&'a self) -> State<'a, QueryManager>;

View File

@@ -6,8 +6,11 @@ use thiserror::Error;
pub enum Error { pub enum Error {
#[error("Yaml error: {0}")] #[error("Yaml error: {0}")]
YamlParseError(#[from] serde_yaml::Error), YamlParseError(#[from] serde_yaml::Error),
#[error("Sync parse error: {0}")]
ParseError(String),
#[error("Yaml error: {0}")] #[error(transparent)]
ModelError(#[from] yaak_models::error::Error), ModelError(#[from] yaak_models::error::Error),
#[error("Unknown model: {0}")] #[error("Unknown model: {0}")]
@@ -16,7 +19,7 @@ pub enum Error {
#[error("I/o error: {0}")] #[error("I/o error: {0}")]
IoError(#[from] io::Error), IoError(#[from] io::Error),
#[error("Yaml error: {0}")] #[error("JSON error: {0}")]
JsonParseError(#[from] serde_json::Error), JsonParseError(#[from] serde_json::Error),
#[error("Invalid sync file: {0}")] #[error("Invalid sync file: {0}")]

View File

@@ -1,6 +1,7 @@
use crate::error::Error::UnknownModel; use crate::error::Error::UnknownModel;
use crate::error::Result; use crate::error::Result;
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use log::warn;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha1::{Digest, Sha1}; use sha1::{Digest, Sha1};
use std::fs; use std::fs;
@@ -37,9 +38,21 @@ impl SyncModel {
let ext = file_path.extension().unwrap_or_default(); let ext = file_path.extension().unwrap_or_default();
if ext == "yml" || ext == "yaml" { if ext == "yml" || ext == "yaml" {
Ok(Some((serde_yaml::from_str(&content_str)?, checksum))) Ok(match serde_yaml::from_str::<SyncModel>(&content_str) {
Ok(m) => Some((m, checksum)),
Err(e) => {
warn!("Error parsing {:?} {:?}", file_path.file_name(), e);
None
}
})
} else if ext == "json" { } else if ext == "json" {
Ok(Some((serde_json::from_str(&content_str)?, checksum))) Ok(match serde_json::from_str::<SyncModel>(&content_str) {
Ok(m) => Some((m, checksum)),
Err(e) => {
warn!("Error parsing {:?} {:?}", file_path.file_name(), e);
None
}
})
} else { } else {
Ok(None) Ok(None)
} }