From 26839656d453cc4d097c147606ed19b417d91611 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sun, 12 Jul 2026 15:54:53 +0200 Subject: [PATCH] implement loading note content from the filesystem --- application/src/backend.rs | 67 +++++++++++++++++++++++++++++++++++--- entity/src/note.rs | 3 ++ 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/application/src/backend.rs b/application/src/backend.rs index 6174580..ccfaaaa 100644 --- a/application/src/backend.rs +++ b/application/src/backend.rs @@ -36,6 +36,7 @@ use std::sync::{Arc}; use std::thread::JoinHandle; use rand::distr::Alphanumeric; use rand::RngExt; +use tokio::fs; use tokio::fs::File; use tokio::io::AsyncWriteExt; use tokio::sync::{broadcast, mpsc}; @@ -388,10 +389,68 @@ impl BackendHandle { where F: FnOnce(Result, DbErr>) + Send + 'static { let backend = self.backend.clone(); let cmd = Box::pin(async move { - let result = NoteContent::find() - .filter(notecontent::Column::NoteId.eq(note_id)) - .order_by_id_asc().one(&backend.db).await; - callback(result); + // check if the note content is stored in the filesystem or database + let storage_result = note::Entity::find_by_id(note_id) + .join(JoinType::InnerJoin, note::Relation::Collection.def()) + .join(JoinType::InnerJoin, collection::Relation::Repository.def()) + .select_only() + .column(collection::Column::Storage) + .column(repository::Column::UseLocalStorage) + .column(repository::Column::LocalPath) + .column(note::Column::Nodename) + .into_tuple::<(LocalStorageSetting, bool, Option, String)>() + .one(&backend.db).await; + let storage = match storage_result { + Ok(storage) => { + if let Some(storage) = storage { + storage + } else { + // Should not happen, a note always has a parent collection, which + // also always is assigned to a repository + return; + } + }, + Err(e) => { + callback(Err(e)); + return; + } + }; + + if let Some(dir) = storage.2 && + (storage.0 == LocalStorageSetting::FileSystem || (storage.0 == LocalStorageSetting::Default && storage.1)) + { + // local storage + let path = Path::new(dir.as_str()).join(storage.3); + let content = fs::read_to_string(path.as_path()).await; + match content { + Ok(content) => { + let model = notecontent::Model { + id: 0, + note_id: 0, + content: content, + }; + callback(Ok(Some(model))); + }, + Err(e) if e.kind() == std::io::ErrorKind::NotFound => { + callback(Ok(None)); + }, + /* + Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => { + + }, + */ + Err(e) => { + let msg = format!("Cannot open file {}", path.display()); + callback(Err(DbErr::Custom(msg))); + } + } + } else { + // note content stored in the database + let result = NoteContent::find() + .filter(notecontent::Column::NoteId.eq(note_id)) + .order_by_id_asc().one(&backend.db).await; + callback(result); + } }); let _ = self.tx.send(cmd); } diff --git a/entity/src/note.rs b/entity/src/note.rs index 86ec50a..e0d91da 100644 --- a/entity/src/note.rs +++ b/entity/src/note.rs @@ -16,6 +16,9 @@ pub struct Model { pub lastmodified: DateTimeWithTimeZone, pub created: DateTimeWithTimeZone, + #[sea_orm(belongs_to, from = "collection_id", to = "collection_id")] + pub repository: HasOne, + #[sea_orm(has_one)] pub content: HasOne, -- 2.52.0