diff --git a/src/libs/database/impl/TrackArtistLink.cpp b/src/libs/database/impl/TrackArtistLink.cpp index f3ca0ca9..5667dd40 100644 --- a/src/libs/database/impl/TrackArtistLink.cpp +++ b/src/libs/database/impl/TrackArtistLink.cpp @@ -30,11 +30,11 @@ namespace lms::db { namespace { - Wt::Dbo::Query createQuery(Session& session, const TrackArtistLink::FindParameters& params) + Wt::Dbo::Query> createQuery(Session& session, const TrackArtistLink::FindParameters& params) { session.checkReadTransaction(); - auto query{ session.getDboSession()->query("SELECT DISTINCT t_a_l.id FROM track_artist_link t_a_l") }; + auto query{ session.getDboSession()->query>("SELECT t_a_l FROM track_artist_link t_a_l") }; if (params.linkType) query.where("t_a_l.type = ?").bind(*params.linkType); @@ -51,6 +51,8 @@ namespace lms::db if (params.track.isValid()) query.where("t.id = ?").bind(params.track); + query.groupBy("t_a_l.id"); + return query; } } @@ -79,12 +81,14 @@ namespace lms::db return utils::fetchQuerySingleResult(session.getDboSession()->find().where("id = ?").bind(id)); } - RangeResults TrackArtistLink::find(Session& session, const FindParameters& params) + void TrackArtistLink::find(Session& session, const FindParameters& parameters, const std::function& func) { - session.checkReadTransaction(); + const auto query{ createQuery(session, parameters) }; - auto query{ createQuery(session, params) }; - return utils::execRangeQuery(query, params.range); + utils::forEachQueryResult(query, [&](const TrackArtistLink::pointer& link) + { + func(link); + }); } core::EnumSet TrackArtistLink::findUsedTypes(Session& session) diff --git a/src/libs/database/include/database/TrackArtistLink.hpp b/src/libs/database/include/database/TrackArtistLink.hpp index 36af08ea..e3fe7580 100644 --- a/src/libs/database/include/database/TrackArtistLink.hpp +++ b/src/libs/database/include/database/TrackArtistLink.hpp @@ -62,7 +62,7 @@ namespace lms::db TrackArtistLink() = default; TrackArtistLink(ObjectPtr track, ObjectPtr artist, TrackArtistLinkType type, std::string_view subType); - static RangeResults find(Session& session, const FindParameters& parameters); + static void find(Session& session, const FindParameters& parameters, const std::function&); static pointer find(Session& session, TrackArtistLinkId linkId); static pointer create(Session& session, ObjectPtr track, ObjectPtr artist, TrackArtistLinkType type, std::string_view subType = {}); static core::EnumSet findUsedTypes(Session& session); diff --git a/src/libs/subsonic/impl/responses/Song.cpp b/src/libs/subsonic/impl/responses/Song.cpp index 68c8bbc2..8ecb40f9 100644 --- a/src/libs/subsonic/impl/responses/Song.cpp +++ b/src/libs/subsonic/impl/responses/Song.cpp @@ -65,7 +65,6 @@ namespace lms::api::subsonic std::string path; // The track path has to be relative from the root - const auto release{ track->getRelease() }; if (release) { @@ -191,40 +190,31 @@ namespace lms::api::subsonic trackResponse.setAttribute("musicBrainzId", mbid ? mbid->getAsString() : ""); } - trackResponse.createEmptyArrayChild("contributors"); { TrackArtistLink::FindParameters params; params.setTrack(track->getId()); - for (const TrackArtistLinkId linkId : TrackArtistLink::find(context.dbSession, params).results) + trackResponse.createEmptyArrayChild("albumartists"); + trackResponse.createEmptyArrayChild("artists"); + trackResponse.createEmptyArrayChild("contributors"); + + TrackArtistLink::find(context.dbSession, params, [&](const TrackArtistLink::pointer& link) { - TrackArtistLink::pointer link{ TrackArtistLink::find(context.dbSession, linkId) }; - // Don't report artists nor release artists as they are set in dedicated fields - if (link && link->getType() != TrackArtistLinkType::Artist && link->getType() != TrackArtistLinkType::ReleaseArtist) - trackResponse.addArrayChild("contributors", createContributorNode(link)); - } + switch (link->getType()) + { + case TrackArtistLinkType::Artist: + trackResponse.addArrayChild("artists", createArtistNode(link->getArtist())); + break; + case TrackArtistLinkType::ReleaseArtist: + trackResponse.addArrayChild("albumartists", createArtistNode(link->getArtist())); + break; + default: + trackResponse.addArrayChild("contributors", createContributorNode(link)); + } + }); } - auto addArtistLinks{ [&](Response::Node::Key nodeName, TrackArtistLinkType type) - { - trackResponse.createEmptyArrayChild(nodeName); - - TrackArtistLink::FindParameters params; - params.setTrack(track->getId()); - params.setLinkType(type); - - for (const TrackArtistLinkId linkId : TrackArtistLink::find(context.dbSession, params).results) - { - TrackArtistLink::pointer link{ TrackArtistLink::find(context.dbSession, linkId) }; - if (link) - trackResponse.addArrayChild(nodeName, createArtistNode(link->getArtist())); - } - } }; - - addArtistLinks("artists", TrackArtistLinkType::Artist); trackResponse.setAttribute("displayArtist", track->getArtistDisplayName()); - - addArtistLinks("albumartists", TrackArtistLinkType::ReleaseArtist); if (release) trackResponse.setAttribute("displayAlbumArtist", release->getArtistDisplayName()); diff --git a/src/lms/ui/explore/ReleaseView.cpp b/src/lms/ui/explore/ReleaseView.cpp index 841cd234..963bbbe0 100644 --- a/src/lms/ui/explore/ReleaseView.cpp +++ b/src/lms/ui/explore/ReleaseView.cpp @@ -95,18 +95,10 @@ namespace lms::ui TrackArtistLink::FindParameters params; params.setRelease(releaseId); params.setLinkType(TrackArtistLinkType::Performer); - const auto links{ TrackArtistLink::find(LmsApp->getDbSession(), params) }; - if (links.results.empty()) - return; - - for (const TrackArtistLinkId linkId : links.results) - { - const TrackArtistLink::pointer link{ TrackArtistLink::find(LmsApp->getDbSession(), linkId) }; - if (!link) - continue; - - artistMap[std::string{ link->getSubType() }].insert(link->getArtist()->getId()); - } + TrackArtistLink::find(LmsApp->getDbSession(), params, [&](const TrackArtistLink::pointer& link) + { + artistMap[std::string{ link->getSubType() }].insert(link->getArtist()->getId()); + }); }; addArtists(TrackArtistLinkType::Composer, "Lms.Explore.Artists.linktype-composer"); diff --git a/src/lms/ui/explore/TrackListHelpers.cpp b/src/lms/ui/explore/TrackListHelpers.cpp index a5ced047..05cd698c 100644 --- a/src/lms/ui/explore/TrackListHelpers.cpp +++ b/src/lms/ui/explore/TrackListHelpers.cpp @@ -82,18 +82,11 @@ namespace lms::ui::TrackListHelpers TrackArtistLink::FindParameters params; params.setTrack(trackId); params.setLinkType(TrackArtistLinkType::Performer); - const auto links{ TrackArtistLink::find(LmsApp->getDbSession(), params) }; - if (links.results.empty()) - return; - for (const TrackArtistLinkId linkId : links.results) - { - const TrackArtistLink::pointer link{ TrackArtistLink::find(LmsApp->getDbSession(), linkId) }; - if (!link) - continue; - - artistMap[std::string{ link->getSubType() }].insert(link->getArtist()->getId()); - } + TrackArtistLink::find(LmsApp->getDbSession(), params, [&](const TrackArtistLink::pointer& link) + { + artistMap[std::string{ link->getSubType() }].insert(link->getArtist()->getId()); + }); }; addArtists(TrackArtistLinkType::Composer, "Lms.Explore.Artists.linktype-composer");