]> uap-core.de Git - note.git/commitdiff
implement saving note content to local storage
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 12 Jul 2026 10:37:39 +0000 (12:37 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 12 Jul 2026 10:37:39 +0000 (12:37 +0200)
application/src/backend.rs
application/src/note.rs

index d9cb8248a7bf55f42ed5c3084eee3bdc7613cef8..6174580efe02425cdb608451d9601ea3c4678a3c 100644 (file)
@@ -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)
 }
 
index 43f6dadc45b9cdc378b237b185d467bb015efb9c..c5fb537719754eee05f967b6cc9a93e75e7e8388 100644 (file)
@@ -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);
+                    }
                 }
             });
         });