Searching for files with both tags, rather than either tag when filtering by tag names.

This commit is contained in:
Roland 2023-04-06 12:52:29 -06:00
parent 7cf91754ef
commit 3b3cea4d70
No known key found for this signature in database
GPG key ID: 9D6DBD3ACF11AB93
3 changed files with 24 additions and 17 deletions

View file

@ -239,8 +239,15 @@ def test_search_videos(test_client, test_session, video_factory, assert_video_se
channel_id=simple_channel.id)
vid3: Video = video_factory(upload_date='2022-09-18', with_video_file=True, title='vid3')
tag1, tag2 = tag_factory(), tag_factory()
vid1.add_tag(tag1)
# vid2 has two tags
vid2.add_tag(tag1)
vid2.add_tag(tag2)
vid3.add_tag(tag2)
test_session.commit()
assert test_session.query(Video).count() == 3
assert test_session.query(FileGroup).count() == 3
@ -250,12 +257,14 @@ def test_search_videos(test_client, test_session, video_factory, assert_video_se
assert_video_search(assert_total=3, assert_ids=[vid3.id, vid2.id], order_by='-upload_date', limit=2)
assert_video_search(assert_total=3, assert_ids=[vid2.id, vid1.id], order_by='-upload_date', limit=2, offset=1)
assert_video_search(assert_total=1, assert_ids=[vid2.id], order_by='-upload_date', channel_id=simple_channel.id)
assert_video_search(assert_total=1, assert_ids=[vid1.id], tag_names=[tag1.name])
assert_video_search(assert_total=1, assert_ids=[vid1.id], tag_names=[tag1.name], limit=1)
assert_video_search(assert_total=2, assert_ids=[vid3.id, vid1.id], tag_names=[tag1.name, tag2.name])
assert_video_search(assert_total=2, assert_ids=[vid1.id, vid2.id], tag_names=[tag1.name])
assert_video_search(assert_total=2, assert_ids=[vid3.id, vid2.id], tag_names=[tag2.name])
assert_video_search(assert_total=2, assert_ids=[vid1.id], tag_names=[tag1.name], limit=1)
# Only vid2 has both tags.
assert_video_search(assert_total=1, assert_ids=[vid2.id], tag_names=[tag1.name, tag2.name])
# No results, no total is returned from the DB.
assert_video_search(assert_total=0, assert_ids=[], tag_names=[tag1.name], offset=1)
assert_video_search(assert_total=0, assert_ids=[], tag_names=[tag1.name], offset=2)
# Check all order_by.
for order_by in video_lib.VIDEO_ORDERS:

View file

@ -580,14 +580,15 @@ def tag_names_to_clauses(tags: List[str]):
return '', params, ''
where_tags = []
joins = []
for idx, tag_name in enumerate(tags):
where_tags.append(f't.name = %(tag_name{idx})s')
where_tags.append(f't{idx}.name = %(tag_name{idx})s')
params[f'tag_name{idx}'] = tag_name
where_tags = ' OR '.join(where_tags)
joins.append(f'LEFT JOIN tag_file tf{idx} ON tf{idx}.file_group_id = fg.id '
f'LEFT JOIN tag t{idx} ON t{idx}.id = tf{idx}.tag_id')
where_tags = ' AND '.join(where_tags)
wheres = f'({where_tags})'
join = '''LEFT JOIN tag_file tf ON tf.file_group_id = fg.id
LEFT JOIN tag t ON t.id = tf.tag_id'''
join = '\n'.join(joins)
return wheres, params, join

View file

@ -538,23 +538,20 @@ def test_get_primary_file(test_directory, video_file, srt_file3, example_epub, e
assert lib.get_primary_file([example_pdf, example_mobi, example_epub]) == example_epub
COMMON_JOIN = '''LEFT JOIN tag_file tf ON tf.file_group_id = fg.id
LEFT JOIN tag t ON t.id = tf.tag_id'''
@pytest.mark.parametrize(
'tags,wheres,params,join', [
(
['one'],
'(t.name = %(tag_name0)s)',
'(t0.name = %(tag_name0)s)',
dict(tag_name0='one'),
COMMON_JOIN,
'LEFT JOIN tag_file tf0 ON tf0.file_group_id = fg.id LEFT JOIN tag t0 ON t0.id = tf0.tag_id',
),
(
['one', 'two'],
'(t.name = %(tag_name0)s OR t.name = %(tag_name1)s)',
'(t0.name = %(tag_name0)s AND t1.name = %(tag_name1)s)',
dict(tag_name0='one', tag_name1='two'),
COMMON_JOIN,
'LEFT JOIN tag_file tf0 ON tf0.file_group_id = fg.id LEFT JOIN tag t0 ON t0.id = tf0.tag_id'
'\nLEFT JOIN tag_file tf1 ON tf1.file_group_id = fg.id LEFT JOIN tag t1 ON t1.id = tf1.tag_id',
),
(
[],