From: Olaf Wintermann Date: Sun, 12 Jul 2026 10:37:39 +0000 (+0200) Subject: implement saving note content to local storage X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=refs%2Fheads%2Fmain;p=note.git implement saving note content to local storage --- diff --git a/application/src/backend.rs b/application/src/backend.rs index d9cb824..6174580 100644 --- a/application/src/backend.rs +++ b/application/src/backend.rs @@ -26,8 +26,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ - use std::future::Future; +use std::io::Error; +use std::path::{Path, PathBuf}; use std::pin::Pin; use sea_orm::{ActiveModelTrait, Database, DatabaseConnection, EntityTrait, QueryFilter, ColumnTrait, Set, QueryOrder, DbErr, ExprTrait, RelationTrait, QuerySelect}; use tokio::runtime::Runtime; @@ -35,6 +36,8 @@ use std::sync::{Arc}; use std::thread::JoinHandle; use rand::distr::Alphanumeric; use rand::RngExt; +use tokio::fs::File; +use tokio::io::AsyncWriteExt; use tokio::sync::{broadcast, mpsc}; use tokio::sync::broadcast::error::SendError; use migration::{Expr, JoinType, Migrator, MigratorTrait}; @@ -403,7 +406,7 @@ impl BackendHandle { callback(SaveNoteResult::ValidationError("nodename not set")); return; }; - let nodename = nn.clone(); + let mut nodename = nn.clone(); let Set(version) = note.version else { callback(SaveNoteResult::ValidationError("version not set")); return; @@ -432,6 +435,7 @@ impl BackendHandle { } }; + let mut is_new = false; let result = if let Set(note_id) = note.note_id { let mut update = Note::update_many(); if let Set(kind) = note.kind { @@ -466,10 +470,11 @@ impl BackendHandle { } } } else { + is_new = true; let result = note.clone().insert(&bhandle.backend.db).await; match result { Ok(note) => Ok(note), - Err(e) => { + Err(_e) => { // The main reason why insertion might fail is the // collection+name unique constraint. // Generate a random suffix and try it again @@ -480,7 +485,8 @@ impl BackendHandle { .map(char::from) .collect(); let new_nodename = nodename + "-" + suffix.as_str(); - note.nodename = Set(new_nodename); + note.nodename = Set(new_nodename.clone()); + nodename = new_nodename; let result = note.clone().insert(&bhandle.backend.db).await; match result { Ok(note) => Ok(note), @@ -494,20 +500,38 @@ impl BackendHandle { Ok(note) => { let note_id = note.note_id; let result: SaveNoteResult; - if let Some(mut content) = content { - let result2 = if content.id.is_set() { - content.update(&bhandle.backend.db).await - } else { - content.note_id = Set(note_id); - content.insert(&bhandle.backend.db).await - }; + if let Some(mut content) = content && let Set(note_content) = &content.content { + if let Some(localpath) = local_storage_path { + let path = Path::new(&localpath).join(nodename); - match result2 { - Ok(ctn) => { - result = SaveNoteResult::Ok((note.clone(), ctn.id)); + if is_new && path.exists() { + result = SaveNoteResult::FileAlreadyExists(path); + } else { + let fs_result = write_file(path.as_path(), note_content.as_ref()).await; + match fs_result { + Ok(_) => { + result = SaveNoteResult::Ok((note.clone(), 0)); + }, + Err(e) => { + result = SaveNoteResult::FileError(e); + } + } } - Err(e) => { - result = SaveNoteResult::Error(e); + } else { + let result2 = if content.id.is_set() { + content.update(&bhandle.backend.db).await + } else { + content.note_id = Set(note_id); + content.insert(&bhandle.backend.db).await + }; + + match result2 { + Ok(ctn) => { + result = SaveNoteResult::Ok((note.clone(), ctn.id)); + } + Err(e) => { + result = SaveNoteResult::Error(e); + } } } } else { @@ -534,11 +558,18 @@ impl BackendHandle { } } +async fn write_file(path: &Path, content: &str) -> std::io::Result<()> { + let mut file = File::create(path).await?; + file.write_all(content.as_bytes()).await?; + Ok(()) +} pub enum SaveNoteResult { Ok((entity::note::Model, i32)), VersionConflict, + FileAlreadyExists(PathBuf), Error(DbErr), + FileError(Error), ValidationError(&'static str) } diff --git a/application/src/note.rs b/application/src/note.rs index 43f6dad..c5fb537 100644 --- a/application/src/note.rs +++ b/application/src/note.rs @@ -280,6 +280,12 @@ impl Note { SaveNoteResult::ValidationError(s) => { println!("Failed to save note: validation error: {}", s); } + SaveNoteResult::FileAlreadyExists(path) => { + println!("Failed to save note: file already exists: {}", path.display()); + } + SaveNoteResult::FileError(e) => { + println!("Failed to save note: file error: {}", e); + } } }); });