From ca8e3315bd0acbf80de06940bc1f27f38ed487b2 Mon Sep 17 00:00:00 2001 From: Jayden Grubb Date: Sat, 17 Jun 2023 21:30:17 +1000 Subject: [PATCH] server: add implies/suggests named filters Add new named filters: - suggests: find tags that suggest the search criteria - suggested-by: find tags that are suggested by the search criteria - implies: find tags that imply the search criteria - implied-by: find tags that are implied by the search criteria --- .../search/configs/tag_search_config.py | 44 +++++++++++++++++++ server/szurubooru/search/configs/util.py | 35 +++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/server/szurubooru/search/configs/tag_search_config.py b/server/szurubooru/search/configs/tag_search_config.py index 5d416035..6143be0e 100644 --- a/server/szurubooru/search/configs/tag_search_config.py +++ b/server/szurubooru/search/configs/tag_search_config.py @@ -96,6 +96,50 @@ class TagSearchConfig(BaseSearchConfig): ["implication-count"], search_util.create_num_filter(model.Tag.implication_count), ), + ( + ["suggested-by"], + search_util.create_nested_filter( + model.Tag.tag_id, + model.TagSuggestion.child_id, + model.TagSuggestion.parent_id, + model.TagName.tag_id, + model.TagName.name, + search_util.create_str_filter, + ), + ), + ( + ["suggests"], + search_util.create_nested_filter( + model.Tag.tag_id, + model.TagSuggestion.parent_id, + model.TagSuggestion.child_id, + model.TagName.tag_id, + model.TagName.name, + search_util.create_str_filter, + ), + ), + ( + ["implied-by"], + search_util.create_nested_filter( + model.Tag.tag_id, + model.TagImplication.child_id, + model.TagImplication.parent_id, + model.TagName.tag_id, + model.TagName.name, + search_util.create_str_filter, + ), + ), + ( + ["implies"], + search_util.create_nested_filter( + model.Tag.tag_id, + model.TagImplication.parent_id, + model.TagImplication.child_id, + model.TagName.tag_id, + model.TagName.name, + search_util.create_str_filter, + ), + ), ] ) diff --git a/server/szurubooru/search/configs/util.py b/server/szurubooru/search/configs/util.py index 58e6ebe5..cd4cb438 100644 --- a/server/szurubooru/search/configs/util.py +++ b/server/szurubooru/search/configs/util.py @@ -226,3 +226,38 @@ def create_subquery_filter( return query.filter(expression) return wrapper + + +def create_nested_filter( + left_id_column: SaColumn, + right_id_column: SaColumn, + filter_column: SaColumn, + nested_id_column: SaColumn, + nested_filter_column: SaColumn, + filter_factory: SaColumn, + subquery_decorator: Callable[[SaQuery], None] = None, +) -> Filter: + filter_func = filter_factory(nested_filter_column) + + def wrapper( + query: SaQuery, + criterion: Optional[criteria.BaseCriterion], + negated: bool, + ) -> SaQuery: + assert criterion + nested = db.session.query(nested_id_column.label("foreign_id")) + nested = nested.options(sa.orm.lazyload("*")) + nested = filter_func(nested, criterion, False) + nested = nested.subquery("t") + subquery = db.session.query(right_id_column.label("foreign_id")) + if subquery_decorator: + subquery = subquery_decorator(subquery) + subquery = subquery.options(sa.orm.lazyload("*")) + subquery = subquery.filter(filter_column.in_(nested)) + subquery = subquery.subquery("t") + expression = left_id_column.in_(subquery) + if negated: + expression = ~expression + return query.filter(expression) + + return wrapper