Searching albums by name also search in disc subtitles, fixes #698

This commit is contained in:
emeric
2026-07-12 16:45:11 +02:00
parent 78c624bde2
commit 547479d2d7
2 changed files with 88 additions and 2 deletions
+22 -2
View File
@@ -97,6 +97,9 @@ namespace lms::db
query.join("track t ON t.release_id = r.id"); query.join("track t ON t.release_id = r.id");
} }
if (!params.keywords.empty())
query.leftJoin("medium m ON m.release_id = r.id");
if (params.parentDirectory.isValid()) if (params.parentDirectory.isValid())
{ {
query.join("directory d ON t.directory_id = d.id"); query.join("directory d ON t.directory_id = d.id");
@@ -149,8 +152,25 @@ namespace lms::db
if (!params.name.empty()) if (!params.name.empty())
query.where("r.name = ?").bind(params.name); query.where("r.name = ?").bind(params.name);
for (std::string_view keyword : params.keywords) if (!params.keywords.empty())
query.where("r.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeForLikeKeyword(keyword) + "%"); {
std::vector<std::string> nameClauses;
std::vector<std::string> mediumNameClauses;
for (const std::string_view keyword : params.keywords)
{
nameClauses.push_back("r.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
query.bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
}
for (const std::string_view keyword : params.keywords)
{
mediumNameClauses.push_back("m.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
query.bind("%" + utils::escapeForLikeKeyword(keyword) + "%");
}
query.where("(" + core::stringUtils::joinStrings(nameClauses, " AND ") + ") OR (" + core::stringUtils::joinStrings(mediumNameClauses, " AND ") + ")");
}
if (params.starringUser.isValid()) if (params.starringUser.isValid())
{ {
+66
View File
@@ -416,6 +416,72 @@ namespace lms::db::tests
} }
} }
TEST_F(DatabaseFixture, ReleaseSearchByMediumName)
{
ScopedRelease release{ session, "The Beatles In Mono" };
ScopedMedium medium{ session, release.lockAndGet() };
ScopedTrack track{ session };
{
auto transaction{ session.createWriteTransaction() };
track.get().modify()->setRelease(release.get());
track.get().modify()->setMedium(medium.get());
medium.get().modify()->setName("Sgt. Pepper's Lonely Hearts Club Band");
}
{
auto transaction{ session.createReadTransaction() };
// matches only the medium (discsubtitle), not the release name
{
const auto releases{ Release::findIds(session, Release::FindParameters{}.setKeywords({ "Sgt. Pepper" })) };
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front(), release.getId());
}
// release name search still works
{
const auto releases{ Release::findIds(session, Release::FindParameters{}.setKeywords({ "Beatles In Mono" })) };
ASSERT_EQ(releases.size(), 1);
EXPECT_EQ(releases.front(), release.getId());
}
// no match on either field
{
const auto releases{ Release::findIds(session, Release::FindParameters{}.setKeywords({ "NoSuchKeyword" })) };
EXPECT_EQ(releases.size(), 0);
}
}
}
TEST_F(DatabaseFixture, ReleaseSearchByMediumName_multipleMediaNoDuplicates)
{
ScopedRelease release{ session, "The Beatles In Mono" };
ScopedMedium medium1{ session, release.lockAndGet() };
ScopedMedium medium2{ session, release.lockAndGet() };
ScopedTrack track1{ session };
ScopedTrack track2{ session };
{
auto transaction{ session.createWriteTransaction() };
track1.get().modify()->setRelease(release.get());
track1.get().modify()->setMedium(medium1.get());
medium1.get().modify()->setName("Sgt. Pepper's Lonely Hearts Club Band");
track2.get().modify()->setRelease(release.get());
track2.get().modify()->setMedium(medium2.get());
medium2.get().modify()->setName("Abbey Road");
}
{
auto transaction{ session.createReadTransaction() };
const auto releases{ Release::findIds(session, Release::FindParameters{}.setKeywords({ "Sgt. Pepper" })) };
ASSERT_EQ(releases.size(), 1); // not duplicated despite the 1:N join
EXPECT_EQ(releases.front(), release.getId());
}
}
TEST_F(DatabaseFixture, MultiTracksSingleReleaseTotalDiscTrack) TEST_F(DatabaseFixture, MultiTracksSingleReleaseTotalDiscTrack)
{ {
ScopedRelease release1{ session, "MyRelease" }; ScopedRelease release1{ session, "MyRelease" };