Listenbrainz: fixed listens parsing. fixes #262
This commit is contained in:
@@ -45,9 +45,13 @@ createQuery(Session& session, const Track::FindParameters& params)
|
||||
|
||||
auto query {session.getDboSession().query<TrackId>(params.distinct ? "SELECT DISTINCT t.id FROM track t" : "SELECT t.id FROM track t")};
|
||||
|
||||
assert(params.keywords.empty() || params.name.empty());
|
||||
for (std::string_view keyword : params.keywords)
|
||||
query.where("t.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + Utils::escapeLikeKeyword(keyword) + "%");
|
||||
|
||||
if (!params.name.empty())
|
||||
query.where("t.name = ?").bind(params.name);
|
||||
|
||||
if (params.writtenAfter.isValid())
|
||||
query.where("t.file_last_write > ?").bind(params.writtenAfter);
|
||||
|
||||
@@ -80,11 +84,15 @@ createQuery(Session& session, const Track::FindParameters& params)
|
||||
query.where(oss.str());
|
||||
}
|
||||
|
||||
if (params.artist.isValid())
|
||||
if (params.artist.isValid() || !params.artistName.empty())
|
||||
{
|
||||
query.join("artist a ON a.id = t_a_l.artist_id")
|
||||
.join("track_artist_link t_a_l ON t_a_l.track_id = t.id")
|
||||
.where("a.id = ?").bind(params.artist);
|
||||
.join("track_artist_link t_a_l ON t_a_l.track_id = t.id");
|
||||
|
||||
if (params.artist.isValid())
|
||||
query.where("a.id = ?").bind(params.artist);
|
||||
if (!params.artistName.empty())
|
||||
query.where("a.name = ?").bind(params.artistName);
|
||||
|
||||
if (!params.trackArtistLinkTypes.empty())
|
||||
{
|
||||
@@ -109,6 +117,11 @@ createQuery(Session& session, const Track::FindParameters& params)
|
||||
query.where("t.release_id IS NULL");
|
||||
else if (params.release.isValid())
|
||||
query.where("t.release_id = ?").bind(params.release);
|
||||
else if (!params.releaseName.empty())
|
||||
{
|
||||
query.join("release r ON t.release_id = r.id");
|
||||
query.where("r.name = ?").bind(params.releaseName);
|
||||
}
|
||||
|
||||
if (params.trackList.isValid())
|
||||
{
|
||||
@@ -117,6 +130,9 @@ createQuery(Session& session, const Track::FindParameters& params)
|
||||
query.where("t_l.id = ?").bind(params.trackList);
|
||||
}
|
||||
|
||||
if (params.trackNumber)
|
||||
query.where("t.track_number = ?").bind(*params.trackNumber);
|
||||
|
||||
switch (params.sortMethod)
|
||||
{
|
||||
case TrackSortMethod::None:
|
||||
@@ -282,19 +298,6 @@ Track::find(Session& session, const FindParameters& parameters)
|
||||
return Utils::execQuery(query, parameters.range);
|
||||
}
|
||||
|
||||
RangeResults<TrackId>
|
||||
Track::findByNameAndReleaseName(Session& session, std::string_view trackName, std::string_view releaseName)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto query {session.getDboSession().query<TrackId>("SELECT t.id from track t")
|
||||
.join("release r ON t.release_id = r.id")
|
||||
.where("t.name = ?").bind(trackName)
|
||||
.where("r.name = ?").bind(releaseName)};
|
||||
|
||||
return Utils::execQuery(query, Range {});
|
||||
}
|
||||
|
||||
RangeResults<TrackId>
|
||||
Track::findSimilarTracks(Session& session, const std::vector<TrackId>& tracks, Range range)
|
||||
{
|
||||
|
||||
@@ -59,30 +59,38 @@ class Track : public Object<Track, TrackId>
|
||||
public:
|
||||
struct FindParameters
|
||||
{
|
||||
std::vector<ClusterId> clusters; // if non empty, tracks that belong to these clusters
|
||||
std::vector<std::string_view> keywords; // if non empty, name must match all of these keywords
|
||||
std::vector<ClusterId> clusters; // if non empty, tracks that belong to these clusters
|
||||
std::vector<std::string_view> keywords; // if non empty, name must match all of these keywords
|
||||
std::string name; // if non empty, must match this name
|
||||
TrackSortMethod sortMethod {TrackSortMethod::None};
|
||||
Range range;
|
||||
Wt::WDateTime writtenAfter;
|
||||
UserId starringUser; // only tracks starred by this user
|
||||
std::optional<Scrobbler> scrobbler; // and for this scrobbler
|
||||
ArtistId artist; // only tracks that involve this user
|
||||
ArtistId artist; // only tracks that involve this artist
|
||||
std::string artistName; // only tracks that involve this artist name
|
||||
EnumSet<TrackArtistLinkType> trackArtistLinkTypes; // and for these link types
|
||||
bool nonRelease {}; // only tracks that do not belong to a release
|
||||
ReleaseId release; // matching this release
|
||||
std::string releaseName; // matching this release name
|
||||
TrackListId trackList; // matching this trackList
|
||||
std::optional<int> trackNumber; // matching this track number
|
||||
bool distinct {true};
|
||||
|
||||
FindParameters& setClusters(const std::vector<ClusterId>& _clusters) { clusters = _clusters; return *this; }
|
||||
FindParameters& setKeywords(const std::vector<std::string_view>& _keywords) { keywords = _keywords; return *this; }
|
||||
FindParameters& setName(std::string_view _name) { name = _name; return *this; }
|
||||
FindParameters& setSortMethod(TrackSortMethod _method) { sortMethod = _method; return *this; }
|
||||
FindParameters& setRange(Range _range) { range = _range; return *this; }
|
||||
FindParameters& setWrittenAfter(const Wt::WDateTime& _after) { writtenAfter = _after; return *this; }
|
||||
FindParameters& setStarringUser(UserId _user, Scrobbler _scrobbler) { starringUser = _user; scrobbler = _scrobbler; return *this; }
|
||||
FindParameters& setArtist(ArtistId _artist, EnumSet<TrackArtistLinkType> _trackArtistLinkTypes = {}) { artist = _artist; trackArtistLinkTypes = _trackArtistLinkTypes; return *this; }
|
||||
FindParameters& setArtistName(std::string_view _artistName, EnumSet<TrackArtistLinkType> _trackArtistLinkTypes = {}) { artistName = _artistName; trackArtistLinkTypes = _trackArtistLinkTypes; return *this; }
|
||||
FindParameters& setNonRelease(bool _nonRelease) { nonRelease = _nonRelease; return *this; }
|
||||
FindParameters& setRelease(ReleaseId _release) { release = _release; return *this; }
|
||||
FindParameters& setReleaseName(std::string_view _releaseName) { releaseName = _releaseName; return *this; }
|
||||
FindParameters& setTrackList(TrackListId _trackList) { trackList = _trackList; return *this; }
|
||||
FindParameters& setTrackNumber(int _trackNumber) { trackNumber = _trackNumber; return *this; }
|
||||
FindParameters& setDistinct(bool _distinct) { distinct = _distinct; return *this; }
|
||||
};
|
||||
|
||||
@@ -103,7 +111,6 @@ class Track : public Object<Track, TrackId>
|
||||
static RangeResults<TrackId> findSimilarTracks(Session& session, const std::vector<TrackId>& trackIds, Range range);
|
||||
|
||||
static RangeResults<TrackId> find(Session& session, const FindParameters& parameters);
|
||||
static RangeResults<TrackId> findByNameAndReleaseName(Session& session, std::string_view trackName, std::string_view releaseName);
|
||||
static RangeResults<PathResult> findPaths(Session& session, Range range);
|
||||
static RangeResults<TrackId> findRecordingMBIDDuplicates(Session& session, Range range);
|
||||
static RangeResults<TrackId> findWithRecordingMBIDAndMissingFeatures(Session& session, Range range);
|
||||
|
||||
@@ -65,6 +65,7 @@ TEST_F(DatabaseFixture, Artist_singleTrack)
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
|
||||
track.get().modify()->setName("MyTrackName");
|
||||
TrackArtistLink::create(session, track.get(), artist.get(), TrackArtistLinkType::Artist);
|
||||
}
|
||||
|
||||
@@ -89,6 +90,23 @@ TEST_F(DatabaseFixture, Artist_singleTrack)
|
||||
EXPECT_TRUE(track->getArtists({TrackArtistLinkType::ReleaseArtist}).empty());
|
||||
EXPECT_EQ(track->getArtists({}).size(), 1);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
auto tracks {Track::find(session, Track::FindParameters{}.setName("MyTrackName").setArtistName("MyArtist"))};
|
||||
ASSERT_EQ(tracks.results.size(), 1);
|
||||
EXPECT_EQ(tracks.results.front(), track.getId());
|
||||
}
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
auto tracks {Track::find(session, Track::FindParameters{}.setName("MyTrackName").setArtistName("MyArtistFoo"))};
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
auto tracks {Track::find(session, Track::FindParameters{}.setName("MyTrackNameFoo").setArtistName("MyArtist"))};
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, Artist_singleTracktMultiRoles)
|
||||
|
||||
@@ -84,18 +84,18 @@ TEST_F(DatabaseFixture, Release_singleTrack)
|
||||
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
auto tracks {Track::findByNameAndReleaseName(session, "MyTrackName", "MyReleaseName")};
|
||||
auto tracks {Track::find(session, Track::FindParameters{}.setName("MyTrackName").setReleaseName("MyReleaseName"))};
|
||||
ASSERT_EQ(tracks.results.size(), 1);
|
||||
EXPECT_EQ(tracks.results.front(), track.getId());
|
||||
}
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
auto tracks {Track::findByNameAndReleaseName(session, "MyTrackName", "MyReleaseFoo")};
|
||||
auto tracks {Track::find(session, Track::FindParameters{}.setName("MyTrackName").setReleaseName("MyReleaseFoo"))};
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
auto tracks {Track::findByNameAndReleaseName(session, "MyTrackFoo", "MyReleaseName")};
|
||||
auto tracks {Track::find(session, Track::FindParameters{}.setName("MyTrackFoo").setReleaseName("MyReleaseName"))};
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user