From ae0886cd2ea0a5b076d5ef531381316dbaf16a92 Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 25 Dec 2025 15:17:50 -0500 Subject: [PATCH] Fix tag count sorting, hopefully --- src/tags.rs | 68 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/src/tags.rs b/src/tags.rs index a98a73e..4e83a70 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -507,31 +507,51 @@ impl TagDao for SqliteTagDao { trace_db_call(context, "query", "get_files_with_all_tags", |_| { use diesel::dsl::*; - let exclude_subquery = tagged_photo::table - .filter(tagged_photo::tag_id.eq_any(exclude_tag_ids.clone())) - .select(tagged_photo::photo_name) - .into_boxed(); + // Create the placeholders for the IN clauses + let tag_placeholders = std::iter::repeat_n("?", tag_ids.len()) + .collect::>() + .join(","); + let exclude_placeholders = std::iter::repeat_n("?", exclude_tag_ids.len()) + .collect::>() + .join(","); - tagged_photo::table - .filter(tagged_photo::tag_id.eq_any(tag_ids.clone())) - .filter(tagged_photo::photo_name.ne_all(exclude_subquery)) - .group_by(tagged_photo::photo_name) - .select(( - tagged_photo::photo_name, - count_distinct(tagged_photo::tag_id), - )) - .having(count_distinct(tagged_photo::tag_id).ge(tag_ids.len() as i64)) - .get_results::<(String, i64)>(&mut self.connection) - .map(|results| { - results - .into_iter() - .map(|(file_name, tag_count)| FileWithTagCount { - file_name, - tag_count, - }) - .collect() - }) - .with_context(|| format!("Unable to get Tagged photos with ids: {:?}", tag_ids)) + let query = sql_query(format!( + r#" + WITH filtered_photos AS ( + SELECT photo_name + FROM tagged_photo tp + WHERE tp.tag_id IN ({}) + AND tp.photo_name NOT IN ( + SELECT photo_name + FROM tagged_photo + WHERE tag_id IN ({}) + ) + GROUP BY photo_name + HAVING COUNT(DISTINCT tag_id) >= {} + ) + SELECT + fp.photo_name as file_name, + COUNT(DISTINCT tp2.tag_id) as tag_count + FROM filtered_photos fp + JOIN tagged_photo tp2 ON fp.photo_name = tp2.photo_name + GROUP BY fp.photo_name"#, + tag_placeholders, + exclude_placeholders, + tag_ids.len() + )) + .into_boxed(); + + // Bind all parameters + let query = tag_ids + .into_iter() + .fold(query, |q, id| q.bind::(id)); + let query = exclude_tag_ids + .into_iter() + .fold(query, |q, id| q.bind::(id)); + + query + .load::(&mut self.connection) + .with_context(|| "Unable to get tagged photos with all specified tags") }) }