This commit is contained in:
Jayden Grubb 2024-11-21 16:44:08 +10:00 committed by GitHub
commit 6bf88990fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 209 additions and 0 deletions

View file

@ -50,6 +50,22 @@
<td><code>post-count</code></td> <td><code>post-count</code></td>
<td>alias of <code>usages</code></td> <td>alias of <code>usages</code></td>
</tr> </tr>
<tr>
<td><code>suggests</code></td>
<td>with given suggested tags (accepts wildcards)</td>
</tr>
<tr>
<td><code>implies</code></td>
<td>with given implied tags (accepts wildcards)</td>
</tr>
<tr>
<td><code>suggested-by</code></td>
<td>suggested by given tags (accepts wildcards)</td>
</tr>
<tr>
<td><code>implied-by</code></td>
<td>implied by given tags (accepts wildcards)</td>
</tr>
<tr> <tr>
<td><code>suggestion-count</code></td> <td><code>suggestion-count</code></td>
<td>with given number of suggestions</td> <td>with given number of suggestions</td>

View file

@ -96,6 +96,50 @@ class TagSearchConfig(BaseSearchConfig):
["implication-count"], ["implication-count"],
search_util.create_num_filter(model.Tag.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 query.filter(expression)
return wrapper 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

View file

@ -370,6 +370,120 @@ def test_filter_by_implication_count(
verify_unpaged(input, expected_tag_names) verify_unpaged(input, expected_tag_names)
@pytest.mark.parametrize(
"input,expected_tag_names",
[
("suggests:sug1", ["t1", "t3"]),
("suggests:sug2", ["t1"]),
("suggests:sug3", ["t2"]),
("suggests:t1", []),
("-suggests:sug1", ["sug1", "sug2", "sug3", "t2"]),
],
)
def test_filter_by_suggests_tags(
verify_unpaged, tag_factory, input, expected_tag_names
):
sug1 = tag_factory(names=["sug1"])
sug2 = tag_factory(names=["sug2"])
sug3 = tag_factory(names=["sug3"])
tag1 = tag_factory(names=["t1"])
tag2 = tag_factory(names=["t2"])
tag3 = tag_factory(names=["t3"])
db.session.add_all([sug1, sug3, tag2, sug2, tag1, tag3])
tag1.suggestions.append(sug1)
tag1.suggestions.append(sug2)
tag2.suggestions.append(sug3)
tag3.suggestions.append(sug1)
db.session.flush()
verify_unpaged(input, expected_tag_names)
@pytest.mark.parametrize(
"input,expected_tag_names",
[
("suggested-by:t1", ["sug1", "sug2"]),
("suggested-by:t2", ["sug3"]),
("suggested-by:t3", ["sug4", "t2"]),
("-suggested-by:t3", ["sug1", "sug2", "sug3", "t1", "t3",]),
],
)
def test_filter_by_suggests_by_tags(
verify_unpaged, tag_factory, input, expected_tag_names
):
sug1 = tag_factory(names=["sug1"])
sug2 = tag_factory(names=["sug2"])
sug3 = tag_factory(names=["sug3"])
sug4 = tag_factory(names=["sug4"])
tag1 = tag_factory(names=["t1"])
tag2 = tag_factory(names=["t2"])
tag3 = tag_factory(names=["t3"])
db.session.add_all([sug1, sug3, tag2, sug2, tag1, tag3, sug4])
tag1.suggestions.append(sug1)
tag1.suggestions.append(sug2)
tag2.suggestions.append(sug3)
tag3.suggestions.append(tag2)
tag3.suggestions.append(sug4)
db.session.flush()
verify_unpaged(input, expected_tag_names)
@pytest.mark.parametrize(
"input,expected_tag_names",
[
("implies:sug1", ["t1", "t3"]),
("implies:sug2", ["t1"]),
("implies:sug3", ["t2"]),
("implies:t1", []),
("-implies:sug1", ["sug1", "sug2", "sug3", "t2"]),
],
)
def test_filter_by_implies_tags(
verify_unpaged, tag_factory, input, expected_tag_names
):
sug1 = tag_factory(names=["sug1"])
sug2 = tag_factory(names=["sug2"])
sug3 = tag_factory(names=["sug3"])
tag1 = tag_factory(names=["t1"])
tag2 = tag_factory(names=["t2"])
tag3 = tag_factory(names=["t3"])
db.session.add_all([sug1, sug3, tag2, sug2, tag1, tag3])
tag1.implications.append(sug1)
tag1.implications.append(sug2)
tag2.implications.append(sug3)
tag3.implications.append(sug1)
db.session.flush()
verify_unpaged(input, expected_tag_names)
@pytest.mark.parametrize(
"input,expected_tag_names",
[
("implied-by:t1", ["sug1", "sug2"]),
("implied-by:t2", ["sug3"]),
("implied-by:t3", ["sug4", "t2",]),
("-implied-by:t3", ["sug1", "sug2", "sug3", "t1", "t3",]),
],
)
def test_filter_by_implied_by_tags(
verify_unpaged, tag_factory, input, expected_tag_names
):
sug1 = tag_factory(names=["sug1"])
sug2 = tag_factory(names=["sug2"])
sug3 = tag_factory(names=["sug3"])
sug4 = tag_factory(names=["sug4"])
tag1 = tag_factory(names=["t1"])
tag2 = tag_factory(names=["t2"])
tag3 = tag_factory(names=["t3"])
db.session.add_all([sug1, sug3, tag2, sug2, tag1, tag3, sug4])
tag1.implications.append(sug1)
tag1.implications.append(sug2)
tag2.implications.append(sug3)
tag3.implications.append(tag2)
tag3.implications.append(sug4)
db.session.flush()
verify_unpaged(input, expected_tag_names)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"input,expected_tag_names", "input,expected_tag_names",
[ [