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
This commit is contained in:
Jayden Grubb 2023-06-17 21:30:17 +10:00
parent 782f069031
commit ca8e3315bd
No known key found for this signature in database
GPG key ID: A920A61FBEBEA731
2 changed files with 79 additions and 0 deletions

View file

@ -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,
),
),
]
)

View file

@ -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