* 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;
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};
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;
}
};
+ 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 {
}
}
} 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
.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),
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 {
}
}
+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)
}