From aa3c587002b7df01ddd8c24d4ba48355ce5a25fc Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sat, 22 Nov 2025 20:50:29 +0000 Subject: [PATCH] Dedup paths on create document --- sync-server/src/server/create_document.rs | 15 +++++++++-- sync-server/src/server/update_document.rs | 27 +++++++------------ sync-server/src/utils.rs | 1 + .../src/utils/find_first_available_path.rs | 24 +++++++++++++++++ 4 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 sync-server/src/utils/find_first_available_path.rs diff --git a/sync-server/src/server/create_document.rs b/sync-server/src/server/create_document.rs index 0f698538..a8d80f39 100644 --- a/sync-server/src/server/create_document.rs +++ b/sync-server/src/server/create_document.rs @@ -14,7 +14,10 @@ use crate::{ }, config::user_config::User, errors::{SyncServerError, client_error, server_error}, - utils::{normalize::normalize, sanitize_path::sanitize_path}, + utils::{ + find_first_available_path::find_first_available_path, normalize::normalize, + sanitize_path::sanitize_path, + }, }; #[derive(Deserialize)] @@ -66,11 +69,19 @@ pub async fn create_document( .map_err(server_error)?; let sanitized_relative_path = sanitize_path(&request.relative_path); + let deduped_path = find_first_available_path( + &vault_id, + &sanitized_relative_path, + &state.database, + &mut transaction, + ) + .await + .map_err(server_error)?; let new_version = StoredDocumentVersion { vault_update_id: last_update_id + 1, document_id, - relative_path: sanitized_relative_path, + relative_path: deduped_path, content: request.content.contents.to_vec(), updated_date: chrono::Utc::now(), is_deleted: false, diff --git a/sync-server/src/server/update_document.rs b/sync-server/src/server/update_document.rs index cb81361b..37beabd6 100644 --- a/sync-server/src/server/update_document.rs +++ b/sync-server/src/server/update_document.rs @@ -22,8 +22,8 @@ use crate::{ errors::{SyncServerError, not_found_error, server_error}, server::requests::UpdateBinaryDocumentVersion, utils::{ - dedup_paths::dedup_paths, is_binary::is_binary, - is_file_type_mergable::is_file_type_mergable, normalize::normalize, + dedup_paths::dedup_paths, find_first_available_path::find_first_available_path, + is_binary::is_binary, is_file_type_mergable::is_file_type_mergable, normalize::normalize, sanitize_path::sanitize_path, }, }; @@ -215,21 +215,14 @@ async fn update_document( let new_relative_path = if parent_document.relative_path == latest_version.relative_path && latest_version.relative_path != sanitized_relative_path { - let mut new_relative_path = String::default(); - for candidate in dedup_paths(&sanitized_relative_path) { - if state - .database - .get_latest_document_by_path(&vault_id, &candidate, Some(&mut transaction)) - .await - .map_err(server_error)? - .is_none() - { - new_relative_path = candidate; - break; - } - } - - new_relative_path + find_first_available_path( + &vault_id, + &sanitized_relative_path, + &state.database, + &mut transaction, + ) + .await + .map_err(server_error)? } else { latest_version.relative_path.clone() }; diff --git a/sync-server/src/utils.rs b/sync-server/src/utils.rs index 7345880d..460a1466 100644 --- a/sync-server/src/utils.rs +++ b/sync-server/src/utils.rs @@ -1,4 +1,5 @@ pub mod dedup_paths; +pub mod find_first_available_path; pub mod is_binary; pub mod is_file_type_mergable; pub mod normalize; diff --git a/sync-server/src/utils/find_first_available_path.rs b/sync-server/src/utils/find_first_available_path.rs new file mode 100644 index 00000000..1f662b42 --- /dev/null +++ b/sync-server/src/utils/find_first_available_path.rs @@ -0,0 +1,24 @@ +use crate::app_state::database::models::VaultId; +use crate::{app_state::database::Transaction, utils::dedup_paths::dedup_paths}; +use anyhow::Result; + +pub async fn find_first_available_path( + vault_id: &VaultId, + sanitized_relative_path: &str, + database: &crate::app_state::database::Database, + transaction: &mut Transaction<'_>, +) -> Result { + let mut new_relative_path = String::default(); + for candidate in dedup_paths(&sanitized_relative_path) { + if database + .get_latest_document_by_path(&vault_id, &candidate, Some(transaction)) + .await? + .is_none() + { + new_relative_path = candidate; + break; + } + } + + Ok(new_relative_path) +}