diff --git a/src/libs/database/impl/objects/Artist.cpp b/src/libs/database/impl/objects/Artist.cpp index 3d9c13c1..d974d43f 100644 --- a/src/libs/database/impl/objects/Artist.cpp +++ b/src/libs/database/impl/objects/Artist.cpp @@ -55,7 +55,6 @@ namespace lms::db || params.track.isValid() || params.filters.clusters.size() == 1 || params.filters.codec.has_value() - || params.filters.mediaLibrary.isValid() || params.filters.label.isValid() || params.filters.releaseType.isValid()) { @@ -66,7 +65,6 @@ namespace lms::db || params.sortMethod == ArtistSortMethod::AddedDesc || params.writtenAfter.isValid() || params.filters.codec.has_value() - || params.filters.mediaLibrary.isValid() || params.filters.label.isValid() || params.filters.releaseType.isValid()) { @@ -78,9 +76,6 @@ namespace lms::db if (params.filters.codec.has_value()) query.where("t.codec = ?").bind(detail::getDbCodec(*params.filters.codec)); - if (params.filters.mediaLibrary.isValid()) - query.where("t.media_library_id = ?").bind(params.filters.mediaLibrary); - if (params.filters.label.isValid()) { query.join("release_label r_l ON r_l.release_id = t.release_id"); @@ -97,6 +92,15 @@ namespace lms::db if (params.releaseArtistsOnly) query.join("release_artist_link r_a_l ON r_a_l.artist_id = a.id"); + if (params.filters.mediaLibrary.isValid()) + { + query.where( + "EXISTS (SELECT 1 FROM track_artist_link t_a_l JOIN track t ON t.id = t_a_l.track_id WHERE t_a_l.artist_id = a.id AND t.media_library_id = ?)" + " OR EXISTS (SELECT 1 FROM release_artist_link r_a_l JOIN release r ON r.id = r_a_l.release_id JOIN track t ON t.release_id = r.id WHERE r_a_l.artist_id = a.id AND t.media_library_id = ?)") + .bind(params.filters.mediaLibrary) + .bind(params.filters.mediaLibrary); + } + if (params.trackArtistLinkType.has_value()) query.where("+t_a_l.type = ?").bind(*params.trackArtistLinkType); // Exclude this since the query planner does not do a good job when db is not analyzed diff --git a/src/libs/database/test/Artist.cpp b/src/libs/database/test/Artist.cpp index c58acccb..5a8f0e7f 100644 --- a/src/libs/database/test/Artist.cpp +++ b/src/libs/database/test/Artist.cpp @@ -390,6 +390,123 @@ namespace lms::db::tests } } + TEST_F(DatabaseFixture, Artist_singleTrack_singleRelease_mediaLibrary) + { + ScopedTrack track1{ session }; + ScopedTrack track2{ session }; + ScopedArtist artist{ session, "MyArtist" }; + ScopedRelease release2{ session, "MyRelease" }; + ScopedMediaLibrary library1{ session, "Library1", "/root1" }; + ScopedMediaLibrary library2{ session, "Library2", "/root2" }; + ScopedMediaLibrary otherLibrary{ session, "OtherLibrary", "/otherRoot" }; + + { + auto transaction{ session.createWriteTransaction() }; + + track1.get().modify()->setName("Track1"); + session.create(track1.get(), artist.get(), TrackArtistLinkType::Artist); + track1.get().modify()->setMediaLibrary(library1.get()); + + track2.get().modify()->setName("Track2"); + track2.get().modify()->setRelease(release2.get()); + session.create(release2.get(), artist.get(), false); + track2.get().modify()->setMediaLibrary(library2.get()); + } + + { + auto transaction{ session.createReadTransaction() }; + auto artists{ Artist::findIds(session, Artist::FindParameters{}) }; + ASSERT_EQ(artists.results.size(), 1); + EXPECT_EQ(artists.results.front(), artist.getId()); + } + + { + auto transaction{ session.createReadTransaction() }; + auto artists{ Artist::findIds(session, Artist::FindParameters{}.setFilters(Filters{}.setMediaLibrary(library1->getId()))) }; + ASSERT_EQ(artists.results.size(), 1); + EXPECT_EQ(artists.results.front(), artist.getId()); + } + { + auto transaction{ session.createReadTransaction() }; + auto artists{ Artist::findIds(session, Artist::FindParameters{}.setFilters(Filters{}.setMediaLibrary(library2->getId()))) }; + ASSERT_EQ(artists.results.size(), 1); + EXPECT_EQ(artists.results.front(), artist.getId()); + } + { + auto transaction{ session.createReadTransaction() }; + auto artists{ Artist::findIds(session, Artist::FindParameters{}.setFilters(Filters{}.setMediaLibrary(otherLibrary->getId()))) }; + EXPECT_EQ(artists.results.size(), 0); + } + } + + TEST_F(DatabaseFixture, Artist_singleTrack_singleRelease_single_mediaLibrary) + { + ScopedTrack track{ session }; + ScopedArtist artist{ session, "MyArtist" }; + ScopedRelease release{ session, "MyRelease" }; + ScopedMediaLibrary library{ session, "Library1", "/root1" }; + + { + auto transaction{ session.createWriteTransaction() }; + + track.get().modify()->setName("Track1"); + track.get().modify()->setRelease(release.get()); + track.get().modify()->setMediaLibrary(library.get()); + + session.create(track.get(), artist.get(), TrackArtistLinkType::Artist); + session.create(release.get(), artist.get(), false); + } + + { + auto transaction{ session.createReadTransaction() }; + auto artists{ Artist::findIds(session, Artist::FindParameters{}) }; + ASSERT_EQ(artists.results.size(), 1); + EXPECT_EQ(artists.results.front(), artist.getId()); + } + + { + auto transaction{ session.createReadTransaction() }; + auto artists{ Artist::findIds(session, Artist::FindParameters{}.setFilters(Filters{}.setMediaLibrary(library->getId()))) }; + ASSERT_EQ(artists.results.size(), 1); + EXPECT_EQ(artists.results.front(), artist.getId()); + } + + { + auto transaction{ session.createReadTransaction() }; + + Artist::FindParameters params; + params.setTrackArtistLinkType(TrackArtistLinkType::Artist); + params.setFilters(Filters{}.setMediaLibrary(library.getId())); + + auto artists{ Artist::findIds(session, params) }; + ASSERT_EQ(artists.results.size(), 1); + EXPECT_EQ(artists.results.front(), artist.getId()); + } + + { + auto transaction{ session.createReadTransaction() }; + + Artist::FindParameters params; + params.setTrackArtistLinkType(TrackArtistLinkType::Performer); + params.setFilters(Filters{}.setMediaLibrary(library.getId())); + + auto artists{ Artist::findIds(session, params) }; + EXPECT_EQ(artists.results.size(), 0); + } + + { + auto transaction{ session.createReadTransaction() }; + + Artist::FindParameters params; + params.setReleaseArtistsOnly(true); + params.setFilters(Filters{}.setMediaLibrary(library.getId())); + + auto artists{ Artist::findIds(session, params) }; + EXPECT_EQ(artists.results.size(), 1); + EXPECT_EQ(artists.results.front(), artist.getId()); + } + } + TEST_F(DatabaseFixture, Artist_singleTracktMultiRoles) { ScopedTrack track{ session };