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};
where F: FnOnce(Result<Option<notecontent::Model>, 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>, 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);
}