From 3478ffee2cd6792b11e3920b8c3212c255682d44 Mon Sep 17 00:00:00 2001 From: Andrew Phillips Date: Mon, 25 Aug 2025 20:59:45 -0300 Subject: [PATCH] refactor: optimize item service to reduce redundant database queries Co-authored-by: aider (openai/andrew/openrouter/deepseek/deepseek-chat-v3.1) --- src/modes/server/api/item.rs | 18 +++++++++++++++--- src/services/item_service.rs | 9 ++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/modes/server/api/item.rs b/src/modes/server/api/item.rs index c8de022..9ffa634 100644 --- a/src/modes/server/api/item.rs +++ b/src/modes/server/api/item.rs @@ -168,7 +168,7 @@ pub async fn handle_get_item_latest_content( let item_service = AsyncItemService::new(state.data_dir.clone(), state.db.clone(), state.item_service.clone()); - // First find the item to get its ID + // First find the item to get its ID and metadata let item_with_meta = item_service .find_item(vec![], tags, HashMap::new()) .await; @@ -176,7 +176,8 @@ pub async fn handle_get_item_latest_content( match item_with_meta { Ok(item) => { let item_id = item.item.id.unwrap(); - stream_item_content_response(&item_service, item_id, params.allow_binary, params.offset, params.length).await + let metadata = item.meta_as_map(); + stream_item_content_response_with_metadata(&item_service, item_id, &metadata, params.allow_binary, params.offset, params.length).await } Err(CoreError::ItemNotFoundGeneric) => Err(StatusCode::NOT_FOUND), Err(e) => { @@ -239,6 +240,17 @@ async fn stream_item_content_response( })?; let metadata = item_with_meta.meta_as_map(); + stream_item_content_response_with_metadata(item_service, item_id, &metadata, allow_binary, offset, length).await +} + +async fn stream_item_content_response_with_metadata( + item_service: &AsyncItemService, + item_id: i64, + metadata: &HashMap, + allow_binary: bool, + offset: u64, + length: u64, +) -> Result { let mime_type = metadata .get("mime_type") .map(|s| s.to_string()) @@ -265,7 +277,7 @@ async fn stream_item_content_response( } // Now stream the content with the specified offset and length using pre-fetched metadata - match item_service.stream_item_content_by_id_with_metadata(item_id, &metadata, true, offset, length).await { + match item_service.stream_item_content_by_id_with_metadata(item_id, metadata, true, offset, length).await { Ok((stream, _)) => { let body = axum::body::Body::from_stream(stream); let response = Response::builder() diff --git a/src/services/item_service.rs b/src/services/item_service.rs index 900dc48..d050d23 100644 --- a/src/services/item_service.rs +++ b/src/services/item_service.rs @@ -104,8 +104,15 @@ impl ItemService { let item = item_maybe.ok_or(CoreError::ItemNotFoundGeneric)?; debug!("ITEM_SERVICE: Found matching item: {:?}", item); + + // Get tags and meta directly instead of calling get_item which makes redundant queries let item_id = item.id.ok_or_else(|| CoreError::InvalidInput("Item missing ID".to_string()))?; - self.get_item(conn, item_id) + let tags = db::get_item_tags(conn, &item)?; + debug!("ITEM_SERVICE: Found {} tags for item {}", tags.len(), item_id); + let meta = db::get_item_meta(conn, &item)?; + debug!("ITEM_SERVICE: Found {} meta entries for item {}", meta.len(), item_id); + + Ok(ItemWithMeta { item, tags, meta }) } pub fn list_items(&self, conn: &Connection, tags: &[String], meta: &HashMap) -> Result, CoreError> {