]> uap-core.de Git - note.git/commitdiff
change get_note_content result type, add local path/lastmodified to result
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 18 Jul 2026 09:19:19 +0000 (11:19 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 18 Jul 2026 09:19:19 +0000 (11:19 +0200)
application/backend/src/backend.rs
application/backend/src/storage.rs
application/note/src/note.rs
dav-rs/src/dav/query.rs

index 14823ea8353487927f11da537c899ec4b90a06f1..4f0661a81ffcaa5096ae3c6a99a2b0ea3bf4c81a 100644 (file)
@@ -34,6 +34,7 @@ use sea_orm::{ActiveModelTrait, Database, DatabaseConnection, EntityTrait, Query
 use tokio::runtime::Runtime;
 use std::sync::{Arc};
 use std::thread::JoinHandle;
+use std::time::SystemTime;
 use tokio::fs;
 use tokio::sync::{broadcast, mpsc};
 use tokio::sync::broadcast::error::SendError;
@@ -47,7 +48,7 @@ use entity::notecontent::{Entity as NoteContent};
 use migration::prelude::Utc;
 use crate::lockmanager::LockManager;
 use crate::note::{create_nodename, randomize_nodename};
-use crate::storage::{get_collection_storage_path, get_file_content, get_note_storage_path, write_file, write_tmp_file};
+use crate::storage::{get_collection_storage_path, get_file_content, get_last_modified, get_note_storage_path, write_file, write_tmp_file};
 
 pub struct Backend {
     rt: Arc<Runtime>,
@@ -382,7 +383,7 @@ impl BackendHandle {
     }
     
     pub fn get_note_content<F>(&self, note_id: i32, callback: F)
-    where F: FnOnce(Result<Option<notecontent::Model>, DbErr>) + Send + 'static {
+    where F: FnOnce(Result<Option<NoteContentRet>, DbErr>) + Send + 'static {
         let backend = self.backend.clone();
         let cmd = Box::pin(async move {
             // check if the note content is stored in the filesystem or database
@@ -401,10 +402,12 @@ impl BackendHandle {
                 let content = fs::read_to_string(path).await;
                 match content {
                     Ok(content) => {
-                        let model = notecontent::Model {
-                            id: 0,
-                            note_id: 0,
-                            content: content,
+                        let lastmodified = get_last_modified(path).await;
+                        let model = NoteContentRet {
+                            content_id: 0,
+                            text: content,
+                            local_path: Some(PathBuf::from(path)),
+                            local_lastmodified: lastmodified
                         };
                         callback(Ok(Some(model)));
                     },
@@ -426,7 +429,23 @@ impl BackendHandle {
                 let result = NoteContent::find()
                     .filter(notecontent::Column::NoteId.eq(note_id))
                     .order_by_id_asc().one(&backend.db).await;
-                callback(result);
+                match result {
+                    Ok(Some(model)) => {
+                        let ret = NoteContentRet {
+                            content_id: model.id,
+                            text: model.content,
+                            local_path: None,
+                            local_lastmodified: None
+                        };
+                        callback(Ok(Some(ret)));
+                    },
+                    Ok(None) => {
+                        callback(Ok(None));
+                    }
+                    Err(e) => {
+                        callback(Err(e));
+                    }
+                }
             }
         });
         let _ = self.tx.send(cmd);
@@ -638,6 +657,13 @@ impl BackendHandle {
 }
 
 
+pub struct NoteContentRet {
+    pub content_id: i32,
+    pub text: String,
+    pub local_path: Option<PathBuf>,
+    pub local_lastmodified: Option<SystemTime>
+}
+
 
 pub enum SaveNoteResult {
     Ok((entity::note::Model, i32)),
index 57ff85441e1b931d15d6fb276684b508a54a0416..6271822988adc2c3ffeeb93da020f6d9fcf6da91 100644 (file)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
-
+use std::fs::metadata;
 use std::io::ErrorKind;
 use std::path::Path;
+use std::time::SystemTime;
 use sea_orm::entity::prelude::*;
 use sea_orm::{ColumnTrait, DatabaseConnection, DbErr, EntityTrait, QuerySelect, RelationTrait};
 use tokio::fs;
@@ -100,6 +101,16 @@ pub async fn get_file_content(db: &DatabaseConnection, note_id: i32) -> Result<O
         .one(db).await
 }
 
+pub async fn get_last_modified(path: &Path) -> Option<SystemTime> {
+    let stat_result = tokio::fs::metadata(path).await;
+    if let Ok(stat) = stat_result {
+        if let Ok(last_modified) = stat.modified() {
+            return Some(last_modified)
+        }
+    }
+    return None
+}
+
 pub async fn write_file(path: &Path, content: &str) -> std::io::Result<()> {
     let mut file = match File::create(path).await {
         Ok(f) => f,
index 025fd1025ab784efb1237232c14c1447b14a2557..93b1713f276c76f540c449fb7db2a6b04ef643ab 100644 (file)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
-
+use std::path::PathBuf;
 use std::rc::Rc;
 use std::sync::atomic::{AtomicU64, Ordering};
+use std::time::SystemTime;
 use sea_orm::{NotSet, Set};
 use sea_orm::sea_query::prelude::Utc;
-use backend::backend::{BackendHandle, BroadcastMessage, NoteId, NoteTitleUpdate, SaveNoteResult};
+use backend::backend::{BackendHandle, BroadcastMessage, NoteContentRet, NoteId, NoteTitleUpdate, SaveNoteResult};
 use backend::lockmanager::NoteLock;
 use entity::note::NoteType;
 use ui_rs::{action, doc_cast, ui_actions, UiModel};
@@ -67,6 +68,9 @@ pub struct Note {
 
     modified: bool,
 
+    pub local_path: Option<PathBuf>,
+    pub local_lastmodified: Option<SystemTime>,
+
     #[bind("note_type")]
     pub note_type: UiInteger,
 
@@ -96,6 +100,8 @@ impl Note {
             title_start: -1,
             title_end: -1,
             modified: false,
+            local_path: None,
+            local_lastmodified: None,
 
             note_type: Default::default(),
             text: Default::default(),
@@ -168,10 +174,12 @@ impl Note {
         self.note_type.set(NoteTypeTabView::TextArea as i64);
     }
     
-    pub fn init_content(&mut self, content: &entity::notecontent::Model) {
-        self.content_id = content.id;
-        self.text.set(content.content.as_str());
-        self.update_title(content.content.as_str(), false);
+    pub fn init_content(&mut self, content: NoteContentRet) {
+        self.content_id = content.content_id;
+        self.text.set(content.text.as_str());
+        self.update_title(content.text.as_str(), false);
+        self.local_path = content.local_path;
+        self.local_lastmodified = content.local_lastmodified;
     }
 
     pub fn load_content(&mut self) {
@@ -189,7 +197,7 @@ impl Note {
                 match result {
                     Ok(content) => {
                         if let Some(content) = content {
-                            note.init_content(&content);
+                            note.init_content(content);
                         } else {
                             println!("note {}: no content", note_id);
                         }
index 4a3d648e32aa999403f35deb78b9dc5970440e86..3912ec5d50a295ada5ad812e87944f871365f400 100644 (file)
@@ -71,6 +71,9 @@ impl DavQuery {
 
         unsafe {
             let stmt = dav_parse_statement(cxstr);
+            if stmt.is_null() {
+                return Err(DavError::QlError("dav_parse_statement returned NULL".to_string()));
+            }
             let errrorcode = dav_sql_statement_get_errorcode(stmt);
             let result = if errrorcode != 0 {
                 let errrorcode = dav_sql_statement_get_errorcode(stmt);
@@ -89,6 +92,9 @@ impl DavQuery {
         }
     }
 
+    /// compiles the query to
+    ///
+    /// select {properties} from {from} with depth {depth} where {filter}
     fn compile(&self) -> String {
         let properties = self
             .properties