diff --git a/sync-server/src/app_state/database/queries.rs b/sync-server/src/app_state/database/queries.rs index 5ba1a97d..66cda538 100644 --- a/sync-server/src/app_state/database/queries.rs +++ b/sync-server/src/app_state/database/queries.rs @@ -8,6 +8,20 @@ use super::{ use anyhow::{Context as _, Result, ensure}; impl Database { + pub async fn get_missing_document( + tx: &mut Transaction<'_>, + ids: &[DocumentId], + ) -> Result> { + Ok(sqlx::query_scalar( + "SELECT value FROM json_each(?) AS requested + WHERE NOT EXISTS (SELECT 1 FROM documents WHERE document_id = requested.value) + LIMIT 1", + ) + .bind(serde_json::to_string(ids)?) + .fetch_optional(&mut **tx) + .await?) + } + pub async fn get_request_event( tx: &mut Transaction<'_>, request_id: uuid::Uuid, diff --git a/sync-server/src/server/endpoints/put_file_manifest.rs b/sync-server/src/server/endpoints/put_file_manifest.rs index 98b559d2..9ba9156a 100644 --- a/sync-server/src/server/endpoints/put_file_manifest.rs +++ b/sync-server/src/server/endpoints/put_file_manifest.rs @@ -62,18 +62,14 @@ pub async fn put_file_manifest( return Ok(Json(FileManifestUpdateResponse::StaleBase(latest))); } - for id in push.entries.keys() { - if state - .database - .get_latest_document_version(&vault_id, id, Some(&mut tx)) + if let Some(id) = + Database::get_missing_document(&mut tx, &push.entries.keys().copied().collect::>()) .await .map_err(server_error)? - .is_none() - { - return Err(client_error(anyhow!( - "File manifest references missing content: {id}" - ))); - } + { + return Err(client_error(anyhow!( + "File manifest references missing content: {id}" + ))); } let file_manifest = FileManifest {