use migration::prelude::Utc;
use crate::lockmanager::LockManager;
use crate::note::{create_nodename, randomize_nodename};
-use crate::storage::{get_collection_storage_path, get_note_storage_path, write_file};
+use crate::storage::{get_collection_storage_path, get_file_content, get_note_storage_path, write_file, write_tmp_file};
pub struct Backend {
rt: Arc<Runtime>,
});
let _ = self.tx.send(cmd);
}
-
+
pub fn save_note<F>(&self, initiator: u64, id: NoteId, mut note: note::ActiveModel, content: Option<notecontent::ActiveModel>, callback: F)
where F: FnOnce(SaveNoteResult) + Send + 'static {
let Set(collection_id) = note.collection_id else {
if let Some(note_path) = note_path {
// local storage
- callback(OpenExternResult::Ok((note_path, false)));
+ callback(OpenExternResult::Ok((PathBuf::from(note_path), false)));
} else {
- // TODO: copy content from db to tmp file
+ // get file from database and write it to a tmp file
+ let content_result = get_file_content(&backend.db, note_id).await;
+ match content_result {
+ Ok(Some(content)) => {
+ let filename = format!("file_content_{}", content.id);
+ let path = write_tmp_file(filename.as_str(), content.content).await;
+ match path {
+ Ok(path) => {
+ callback(OpenExternResult::Ok((path, true)));
+ },
+ Err(e) => {
+ callback(OpenExternResult::FsErr(e));
+ }
+ }
+
+ },
+ Ok(None) => {
+ callback(OpenExternResult::DbErr(DbErr::Custom("Content not found".into())));
+ }
+ Err(e) => {
+ callback(OpenExternResult::DbErr(e));
+ }
+ }
}
});
let _ = self.tx.send(cmd);
}
pub enum OpenExternResult {
- Ok((String, bool)), // path, istmp
+ Ok((PathBuf, bool)), // path, istmp
DbErr(DbErr),
FsErr(Error)
}
use std::io::ErrorKind;
use std::path::Path;
-use sea_orm::{DatabaseConnection, DbErr, EntityTrait, QuerySelect, RelationTrait};
+use sea_orm::entity::prelude::*;
+use sea_orm::{ColumnTrait, DatabaseConnection, DbErr, EntityTrait, QuerySelect, RelationTrait};
use tokio::fs;
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
-use entity::{collection, note, repository};
+use entity::{collection, filecontent, note, repository};
use entity::collection::LocalStorageSetting;
+use entity::filecontent::Model as FileContent;
use migration::JoinType;
/// Checks if a collection should use local storage
}
}
+pub async fn get_file_content(db: &DatabaseConnection, note_id: i32) -> Result<Option<FileContent>, DbErr> {
+ filecontent::Entity::find()
+ .filter(filecontent::Column::NoteId.eq(note_id))
+ .one(db).await
+}
+
pub async fn write_file(path: &Path, content: &str) -> std::io::Result<()> {
let mut file = match File::create(path).await {
Ok(f) => f,
file.write_all(content.as_bytes()).await?;
Ok(())
-}
\ No newline at end of file
+}
+
+pub async fn write_tmp_file(name: &str, data: Vec<u8>) -> std::io::Result<std::path::PathBuf> {
+ let path = std::env::temp_dir().join(name);
+
+ let mut file = File::create(&path).await?;
+ file.write_all(&data).await?;
+ file.flush().await?;
+
+ Ok(path)
+}
* 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 backend::backend::{BackendHandle, NoteId, OpenExternResult};
use ui_rs::{action, doc_cast, ui_actions, UiModel};
pub id: NoteId,
pub nodename: String,
- pub local_path: Option<String>,
+ pub local_path: Option<PathBuf>,
pub is_tmp_file: bool,
pub is_opening: bool,
};
if let Some(path) = &self.local_path {
- println!("open file: {}", path);
- open_file(path.as_str());
+ println!("open file: {}", path.to_string_lossy());
+ open_file(path.to_string_lossy().as_ref());
} else if let NoteId::Id(note_id) = self.id {
self.is_opening = true;
let proxy = doc.doc_proxy();
note.is_opening = false;
match result {
OpenExternResult::Ok((path, istmp)) => {
- println!("open file: {}", path);
- open_file(path.as_str());
+ println!("open file: {}", path.to_string_lossy());
+ open_file(path.to_string_lossy().as_ref());
note.local_path = Some(path);
note.is_tmp_file = istmp;
}
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
use std::collections::HashMap;
use sea_orm::entity::prelude::*;
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+use sea_orm::entity::prelude::*;
+use sea_orm::{ActiveModelBehavior, DeriveEntityModel, DeriveRelation, EnumIter};
+
+#[sea_orm::model]
+#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
+#[sea_orm(table_name = "file_content")]
+pub struct Model {
+ #[sea_orm(primary_key)]
+ pub id: i32,
+
+ #[sea_orm(unique)]
+ pub note_id: i32,
+
+ pub content: Vec<u8>,
+
+ #[sea_orm(belongs_to, from = "note_id", to = "note_id")]
+ pub note: HasOne<crate::note::Entity>
+}
+
+impl ActiveModelBehavior for ActiveModel {}
pub mod collection;
pub mod note;
pub mod notecontent;
-pub mod repository;
\ No newline at end of file
+pub mod repository;
+pub mod filecontent;
\ No newline at end of file
use sea_orm::entity::prelude::*;
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
#[sea_orm::model]
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
#[sea_orm(belongs_to, from = "collection_id", to = "collection_id")]
pub repository: HasOne<super::collection::Entity>,
- #[sea_orm(has_one)]
- pub content: HasOne<crate::notecontent::Entity>,
-
pub version: i64
}
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
use sea_orm::entity::prelude::*;
use sea_orm::{ActiveModelBehavior, DeriveEntityModel, DeriveRelation, EnumIter};
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
use sea_orm::entity::prelude::*;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 Olaf Wintermann. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
use sea_orm::entity::prelude::*;
pub fn new_from_box2<F>(data: Box<T>, init: F) -> UiDoc<T>
where F: FnOnce(&mut T, &UiDoc<T>) {
unsafe {
- let doc = ui_document_new(10000 + mem::size_of::<*mut Box<T>>());
+ let doc = ui_document_new(mem::size_of::<*mut Box<T>>());
let ctx = UiContext::from_ptr(ui_document_context(doc));
ui_app_ref();
ui_reg_destructor(ctx.ptr, std::ptr::null_mut(), doc_app_unref);