Separated feedback services (stars / love for LB) from scrobbling services, to ease last.fm integration
This commit is contained in:
@@ -133,11 +133,11 @@ createQuery(Session& session, const Artist::FindParameters& params)
|
||||
|
||||
if (params.starringUser.isValid())
|
||||
{
|
||||
assert(params.scrobbler);
|
||||
assert(params.feedbackBackend);
|
||||
query.join("starred_artist s_a ON s_a.artist_id = a.id")
|
||||
.where("s_a.user_id = ?").bind(params.starringUser)
|
||||
.where("s_a.scrobbler = ?").bind(*params.scrobbler)
|
||||
.where("s_a.scrobbling_state <> ?").bind(ScrobblingState::PendingRemove);
|
||||
.where("s_a.backend = ?").bind(*params.feedbackBackend)
|
||||
.where("s_a.sync_state <> ?").bind(SyncState::PendingRemove);
|
||||
}
|
||||
|
||||
if (!params.clusters.empty())
|
||||
|
||||
@@ -29,14 +29,14 @@ namespace
|
||||
{
|
||||
using namespace Database;
|
||||
|
||||
Wt::Dbo::Query<ArtistId> createArtistsQuery(Wt::Dbo::Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType)
|
||||
Wt::Dbo::Query<ArtistId> createArtistsQuery(Wt::Dbo::Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType)
|
||||
{
|
||||
auto query{ session.query<ArtistId>("SELECT a.id from artist a")
|
||||
.join("track t ON t.id = t_a_l.track_id")
|
||||
.join("track_artist_link t_a_l ON t_a_l.artist_id = a.id")
|
||||
.join("listen l ON l.track_id = t.id")
|
||||
.where("l.user_id = ?").bind(userId)
|
||||
.where("l.scrobbler = ?").bind(scrobbler) };
|
||||
.where("l.backend = ?").bind(backend) };
|
||||
|
||||
if (linkType)
|
||||
query.where("t_a_l.type = ?").bind(*linkType);
|
||||
@@ -66,13 +66,13 @@ namespace
|
||||
return query;
|
||||
}
|
||||
|
||||
Wt::Dbo::Query<ReleaseId> createReleasesQuery(Wt::Dbo::Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds)
|
||||
Wt::Dbo::Query<ReleaseId> createReleasesQuery(Wt::Dbo::Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds)
|
||||
{
|
||||
auto query{ session.query<ReleaseId>("SELECT r.id from release r")
|
||||
.join("track t ON t.release_id = r.id")
|
||||
.join("listen l ON l.track_id = t.id")
|
||||
.where("l.user_id = ?").bind(userId)
|
||||
.where("l.scrobbler = ?").bind(scrobbler) };
|
||||
.where("l.backend = ?").bind(backend) };
|
||||
|
||||
if (!clusterIds.empty())
|
||||
{
|
||||
@@ -98,12 +98,12 @@ namespace
|
||||
return query;
|
||||
}
|
||||
|
||||
Wt::Dbo::Query<TrackId> createTracksQuery(Wt::Dbo::Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds)
|
||||
Wt::Dbo::Query<TrackId> createTracksQuery(Wt::Dbo::Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds)
|
||||
{
|
||||
auto query{ session.query<TrackId>("SELECT t.id from track t")
|
||||
.join("listen l ON l.track_id = t.id")
|
||||
.where("l.user_id = ?").bind(userId)
|
||||
.where("l.scrobbler = ?").bind(scrobbler) };
|
||||
.where("l.backend = ?").bind(backend) };
|
||||
|
||||
if (!clusterIds.empty())
|
||||
{
|
||||
@@ -131,16 +131,16 @@ namespace
|
||||
|
||||
namespace Database
|
||||
{
|
||||
Listen::Listen(ObjectPtr<User> user, ObjectPtr<Track> track, Scrobbler scrobbler, const Wt::WDateTime& dateTime)
|
||||
Listen::Listen(ObjectPtr<User> user, ObjectPtr<Track> track, ScrobblingBackend backend, const Wt::WDateTime& dateTime)
|
||||
: _dateTime{ Wt::WDateTime::fromTime_t(dateTime.toTime_t()) }
|
||||
, _scrobbler{ scrobbler }
|
||||
, _backend{ backend }
|
||||
, _user{ getDboPtr(user) }
|
||||
, _track{ getDboPtr(track) }
|
||||
{}
|
||||
|
||||
Listen::pointer Listen::create(Session& session, ObjectPtr<User> user, ObjectPtr<Track> track, Scrobbler scrobbler, const Wt::WDateTime& dateTime)
|
||||
Listen::pointer Listen::create(Session& session, ObjectPtr<User> user, ObjectPtr<Track> track, ScrobblingBackend backend, const Wt::WDateTime& dateTime)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<Listen> {new Listen{ user, track, scrobbler, dateTime }});
|
||||
return session.getDboSession().add(std::unique_ptr<Listen> {new Listen{ user, track, backend, dateTime }});
|
||||
}
|
||||
|
||||
std::size_t Listen::getCount(Session& session)
|
||||
@@ -165,30 +165,30 @@ namespace Database
|
||||
if (parameters.user.isValid())
|
||||
query.where("user_id = ?").bind(parameters.user);
|
||||
|
||||
if (parameters.scrobbler)
|
||||
query.where("scrobbler = ?").bind(*parameters.scrobbler);
|
||||
if (parameters.backend)
|
||||
query.where("backend = ?").bind(*parameters.backend);
|
||||
|
||||
if (parameters.scrobblingState)
|
||||
query.where("scrobbling_state = ?").bind(*parameters.scrobblingState);
|
||||
if (parameters.syncState)
|
||||
query.where("sync_state = ?").bind(*parameters.syncState);
|
||||
|
||||
return Utils::execQuery(query, parameters.range);
|
||||
}
|
||||
|
||||
Listen::pointer Listen::find(Session& session, UserId userId, TrackId trackId, Scrobbler scrobbler, const Wt::WDateTime& dateTime)
|
||||
Listen::pointer Listen::find(Session& session, UserId userId, TrackId trackId, ScrobblingBackend backend, const Wt::WDateTime& dateTime)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
return session.getDboSession().find<Listen>()
|
||||
.where("user_id = ?").bind(userId)
|
||||
.where("track_id = ?").bind(trackId)
|
||||
.where("scrobbler = ?").bind(scrobbler)
|
||||
.where("backend = ?").bind(backend)
|
||||
.where("date_time = ?").bind(Wt::WDateTime::fromTime_t(dateTime.toTime_t()))
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
RangeResults<ArtistId> Listen::getTopArtists(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType, Range range)
|
||||
RangeResults<ArtistId> Listen::getTopArtists(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType, Range range)
|
||||
{
|
||||
auto query{ createArtistsQuery(session.getDboSession(), userId, scrobbler, clusterIds, linkType) };
|
||||
auto query{ createArtistsQuery(session.getDboSession(), userId, backend, clusterIds, linkType) };
|
||||
|
||||
auto collection{ query
|
||||
.orderBy("COUNT(a.id) DESC")
|
||||
@@ -197,72 +197,72 @@ namespace Database
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ReleaseId> Listen::getTopReleases(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, Range range)
|
||||
RangeResults<ReleaseId> Listen::getTopReleases(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, Range range)
|
||||
{
|
||||
auto query{ createReleasesQuery(session.getDboSession(), userId, scrobbler, clusterIds)
|
||||
auto query{ createReleasesQuery(session.getDboSession(), userId, backend, clusterIds)
|
||||
.orderBy("COUNT(r.id) DESC")
|
||||
.groupBy("r.id") };
|
||||
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<TrackId> Listen::getTopTracks(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, Range range)
|
||||
RangeResults<TrackId> Listen::getTopTracks(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, Range range)
|
||||
{
|
||||
auto query{ createTracksQuery(session.getDboSession(), userId, scrobbler, clusterIds)
|
||||
auto query{ createTracksQuery(session.getDboSession(), userId, backend, clusterIds)
|
||||
.orderBy("COUNT(t.id) DESC")
|
||||
.groupBy("t.id") };
|
||||
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ArtistId> Listen::getRecentArtists(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType, Range range)
|
||||
RangeResults<ArtistId> Listen::getRecentArtists(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType, Range range)
|
||||
{
|
||||
auto query{ createArtistsQuery(session.getDboSession(), userId, scrobbler, clusterIds, linkType)
|
||||
auto query{ createArtistsQuery(session.getDboSession(), userId, backend, clusterIds, linkType)
|
||||
.groupBy("a.id").having("l.date_time = MAX(l.date_time)")
|
||||
.orderBy("l.date_time DESC") };
|
||||
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ReleaseId> Listen::getRecentReleases(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, Range range)
|
||||
RangeResults<ReleaseId> Listen::getRecentReleases(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, Range range)
|
||||
{
|
||||
auto query{ createReleasesQuery(session.getDboSession(), userId, scrobbler, clusterIds)
|
||||
auto query{ createReleasesQuery(session.getDboSession(), userId, backend, clusterIds)
|
||||
.groupBy("r.id").having("l.date_time = MAX(l.date_time)")
|
||||
.orderBy("l.date_time DESC") };
|
||||
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<TrackId> Listen::getRecentTracks(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, Range range)
|
||||
RangeResults<TrackId> Listen::getRecentTracks(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, Range range)
|
||||
{
|
||||
auto query{ createTracksQuery(session.getDboSession(), userId, scrobbler, clusterIds)
|
||||
auto query{ createTracksQuery(session.getDboSession(), userId, backend, clusterIds)
|
||||
.groupBy("t.id").having("l.date_time = MAX(l.date_time)")
|
||||
.orderBy("l.date_time DESC") };
|
||||
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
Listen::pointer Listen::getMostRecentListen(Session& session, UserId userId, Scrobbler scrobbler, ReleaseId releaseId)
|
||||
Listen::pointer Listen::getMostRecentListen(Session& session, UserId userId, ScrobblingBackend backend, ReleaseId releaseId)
|
||||
{
|
||||
// TODO not pending remove?
|
||||
return session.getDboSession().query<Wt::Dbo::ptr<Listen>>("SELECT l from listen l")
|
||||
.join("track t ON l.track_id = t.id")
|
||||
.where("t.release_id = ?").bind(releaseId)
|
||||
.where("l.user_id = ?").bind(userId)
|
||||
.where("l.scrobbler = ?").bind(scrobbler)
|
||||
.where("l.backend = ?").bind(backend)
|
||||
.orderBy("l.date_time DESC")
|
||||
.limit(1)
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
Listen::pointer Listen::getMostRecentListen(Session& session, UserId userId, Scrobbler scrobbler, TrackId trackId)
|
||||
Listen::pointer Listen::getMostRecentListen(Session& session, UserId userId, ScrobblingBackend backend, TrackId trackId)
|
||||
{
|
||||
// TODO not pending remove?
|
||||
return session.getDboSession().query<Wt::Dbo::ptr<Listen>>("SELECT l from listen l")
|
||||
.join("track t ON track_id = t.id")
|
||||
.where("t.id = ?").bind(trackId)
|
||||
.where("l.user_id = ?").bind(userId)
|
||||
.where("l.scrobbler = ?").bind(scrobbler)
|
||||
.where("l.backend = ?").bind(backend)
|
||||
.orderBy("l.date_time DESC")
|
||||
.limit(1)
|
||||
.resultValue();
|
||||
|
||||
@@ -72,414 +72,6 @@ namespace Database::Migration
|
||||
Db& _db;
|
||||
};
|
||||
|
||||
static std::string dateTimeToDbFormat(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
return dateTime.toString("yyyy'-'MM'-'dd'T'hh':'mm':'ss'.000'", false).toUTF8();
|
||||
}
|
||||
|
||||
static void migrateFromV5(Session& session)
|
||||
{
|
||||
session.getDboSession().execute("DELETE FROM auth_token"); // format has changed
|
||||
}
|
||||
|
||||
static void migrateFromV6(Session& session)
|
||||
{
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
|
||||
static void migrateFromV7(Session& session)
|
||||
{
|
||||
session.getDboSession().execute("DROP TABLE similarity_settings");
|
||||
session.getDboSession().execute("DROP TABLE similarity_settings_feature");
|
||||
session.getDboSession().execute("ALTER TABLE scan_settings ADD similarity_engine_type INTEGER NOT NULL DEFAULT(" + std::to_string(static_cast<int>(ScanSettings::RecommendationEngineType::Clusters)) + ")");
|
||||
}
|
||||
|
||||
static void migrateFromV8(Session& session)
|
||||
{
|
||||
// Better cover handling, need to rescan the whole files
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV9(Session& session)
|
||||
{
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE IF NOT EXISTS "track_bookmark" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"offset" integer,
|
||||
"comment" text not null,
|
||||
"track_id" bigint,
|
||||
"user_id" bigint,
|
||||
constraint "fk_track_bookmark_track" foreign key ("track_id") references "track" ("id") on delete cascade deferrable initially deferred,
|
||||
constraint "fk_track_bookmark_user" foreign key ("user_id") references "user" ("id") on delete cascade deferrable initially deferred
|
||||
);)");
|
||||
}
|
||||
|
||||
static void migrateFromV10(Session& session)
|
||||
{
|
||||
ScanSettings::get(session).modify()->addAudioFileExtension(".m4b");
|
||||
ScanSettings::get(session).modify()->addAudioFileExtension(".alac");
|
||||
}
|
||||
|
||||
static void migrateFromV11(Session& session)
|
||||
{
|
||||
// Sanitize bad MBID, need to rescan the whole files
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV12(Session& session)
|
||||
{
|
||||
// Artist and release that have a badly parsed name but a MBID had no chance to updat the name
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV13(Session& session)
|
||||
{
|
||||
// Always store UUID in lower case + better WMA parsing
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV14(Session& session)
|
||||
{
|
||||
// SortName now set from metadata
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV15(Session& session)
|
||||
{
|
||||
session.getDboSession().execute("ALTER TABLE user ADD ui_theme INTEGER NOT NULL DEFAULT(" + std::to_string(static_cast<int>(User::defaultUITheme)) + ")");
|
||||
}
|
||||
|
||||
static void migrateFromV16(Session& session)
|
||||
{
|
||||
session.getDboSession().execute("ALTER TABLE track ADD total_disc INTEGER NOT NULL DEFAULT(0)");
|
||||
session.getDboSession().execute("ALTER TABLE track ADD total_track INTEGER NOT NULL DEFAULT(0)");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV17(Session& session)
|
||||
{
|
||||
// Drop colums total_disc/total_track from release
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE "release_backup" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"name" text not null,
|
||||
"mbid" text not null
|
||||
))");
|
||||
session.getDboSession().execute("INSERT INTO release_backup SELECT id,version,name,mbid FROM release");
|
||||
session.getDboSession().execute("DROP TABLE release");
|
||||
session.getDboSession().execute("ALTER TABLE release_backup RENAME TO release");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV18(Session& session)
|
||||
{
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE IF NOT EXISTS "subsonic_settings" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"api_enabled" boolean not null,
|
||||
"artist_list_mode" integer not null
|
||||
))");
|
||||
}
|
||||
|
||||
static void migrateFromV19(Session& session)
|
||||
{
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE "user_backup" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"type" integer not null,
|
||||
"login_name" text not null,
|
||||
"password_salt" text not null,
|
||||
"password_hash" text not null,
|
||||
"last_login" text,
|
||||
"subsonic_transcode_enable" boolean not null,
|
||||
"subsonic_transcode_format" integer not null,
|
||||
"subsonic_transcode_bitrate" integer not null,
|
||||
"subsonic_artist_list_mode" integer not null,
|
||||
"ui_theme" integer not null,
|
||||
"cur_playing_track_pos" integer not null,
|
||||
"repeat_all" boolean not null,
|
||||
"radio" boolean not null
|
||||
))");
|
||||
session.getDboSession().execute(std::string{ "INSERT INTO user_backup SELECT id, version, type, login_name, password_salt, password_hash, last_login, " }
|
||||
+ "1" // default enable transcode
|
||||
+ ", " + std::to_string(static_cast<int>(User::defaultSubsonicTranscodeFormat))
|
||||
+ ", " + std::to_string(User::defaultSubsonicTranscodeBitrate)
|
||||
+ ", " + std::to_string(static_cast<int>(User::defaultSubsonicArtistListMode))
|
||||
+ ", ui_theme, cur_playing_track_pos, repeat_all, radio FROM user");
|
||||
session.getDboSession().execute("DROP TABLE user");
|
||||
session.getDboSession().execute("ALTER TABLE user_backup RENAME TO user");
|
||||
}
|
||||
|
||||
static void migrateFromV20(Session& session)
|
||||
{
|
||||
session.getDboSession().execute("DROP TABLE subsonic_settings");
|
||||
}
|
||||
|
||||
static void migrateFromV21(Session& session)
|
||||
{
|
||||
session.getDboSession().execute("ALTER TABLE track ADD track_replay_gain REAL");
|
||||
session.getDboSession().execute("ALTER TABLE track ADD release_replay_gain REAL");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV22(Session& session)
|
||||
{
|
||||
session.getDboSession().execute("ALTER TABLE track ADD disc_subtitle TEXT NOT NULL DEFAULT ''");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV23(Session& session)
|
||||
{
|
||||
// Better cover detection
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV24(Session& session)
|
||||
{
|
||||
// User's AuthMode
|
||||
session.getDboSession().execute("ALTER TABLE user ADD auth_mode INTEGER NOT NULL DEFAULT(" + std::to_string(static_cast<int>(/*User::defaultAuthMode*/0)) + ")");
|
||||
}
|
||||
|
||||
static void migrateFromV25(Session& session)
|
||||
{
|
||||
// Better cover detection
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV26(Session& session)
|
||||
{
|
||||
// Composer, mixer, etc. support
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV27(Session& session)
|
||||
{
|
||||
// Composer, mixer, etc. support, now fallback on MBID tagged entries as there is no mean to provide MBID by tags for these kinf od artists
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV28(Session& session)
|
||||
{
|
||||
// Drop Auth mode
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE "user_backup" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"type" integer not null,
|
||||
"login_name" text not null,
|
||||
"password_salt" text not null,
|
||||
"password_hash" text not null,
|
||||
"last_login" text,
|
||||
"subsonic_transcode_enable" boolean not null,
|
||||
"subsonic_transcode_format" integer not null,
|
||||
"subsonic_transcode_bitrate" integer not null,
|
||||
"subsonic_artist_list_mode" integer not null,
|
||||
"ui_theme" integer not null,
|
||||
"cur_playing_track_pos" integer not null,
|
||||
"repeat_all" boolean not null,
|
||||
"radio" boolean not null
|
||||
))");
|
||||
session.getDboSession().execute("INSERT INTO user_backup SELECT id, version, type, login_name, password_salt, password_hash, last_login, subsonic_transcode_enable, subsonic_transcode_format, subsonic_transcode_bitrate, subsonic_artist_list_mode, ui_theme, cur_playing_track_pos, repeat_all, radio FROM user");
|
||||
session.getDboSession().execute("DROP TABLE user");
|
||||
session.getDboSession().execute("ALTER TABLE user_backup RENAME TO user");
|
||||
}
|
||||
|
||||
static void migrateFromV29(Session& session)
|
||||
{
|
||||
session.getDboSession().execute("ALTER TABLE tracklist_entry ADD date_time TEXT");
|
||||
session.getDboSession().execute("ALTER TABLE user ADD listenbrainz_token TEXT");
|
||||
session.getDboSession().execute("ALTER TABLE user ADD scrobbler INTEGER NOT NULL DEFAULT(" + std::to_string(static_cast<int>(User::defaultScrobbler)) + ")");
|
||||
session.getDboSession().execute("ALTER TABLE track ADD recording_mbid TEXT");
|
||||
|
||||
session.getDboSession().execute("DELETE from tracklist WHERE name = ?").bind("__played_tracks__");
|
||||
|
||||
// MBID changes
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV30(Session& session)
|
||||
{
|
||||
// drop "year" and "original_year" (rescan needed to convert them into dates)
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE "track_backup" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"scan_version" integer not null,
|
||||
"track_number" integer not null,
|
||||
"disc_number" integer not null,
|
||||
"name" text not null,
|
||||
"duration" integer,
|
||||
"date" integer text,
|
||||
"original_date" integer text,
|
||||
"file_path" text not null,
|
||||
"file_last_write" text,
|
||||
"file_added" text,
|
||||
"has_cover" boolean not null,
|
||||
"mbid" text not null,
|
||||
"copyright" text not null,
|
||||
"copyright_url" text not null,
|
||||
"release_id" bigint, total_disc INTEGER NOT NULL DEFAULT(0), total_track INTEGER NOT NULL DEFAULT(0), track_replay_gain REAL, release_replay_gain REAL, disc_subtitle TEXT NOT NULL DEFAULT '', recording_mbid TEXT,
|
||||
constraint "fk_track_release" foreign key ("release_id") references "release" ("id") on delete cascade deferrable initially deferred
|
||||
))");
|
||||
session.getDboSession().execute("INSERT INTO track_backup SELECT id, version, scan_version, track_number, disc_number, name, duration, \"1900-01-01\", \"1900-01-01\", file_path, file_last_write, file_added, has_cover, mbid, copyright, copyright_url, release_id, total_disc, total_track, track_replay_gain, release_replay_gain, disc_subtitle, recording_mbid FROM track");
|
||||
session.getDboSession().execute("DROP TABLE track");
|
||||
session.getDboSession().execute("ALTER TABLE track_backup RENAME TO track");
|
||||
|
||||
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
|
||||
ScanSettings::get(session).modify()->incScanVersion();
|
||||
}
|
||||
|
||||
static void migrateFromV31(Session& session)
|
||||
{
|
||||
// new star system, using dedicated entries per scrobbler and date time
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE "starred_artist" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"scrobbler" integer not null,
|
||||
"date_time" text,
|
||||
"artist_id" bigint,
|
||||
"user_id" bigint,
|
||||
constraint "fk_starred_artist_artist" foreign key ("artist_id") references "artist" ("id") on delete cascade deferrable initially deferred,
|
||||
constraint "fk_starred_artist_user" foreign key ("user_id") references "user" ("id") on delete cascade deferrable initially deferred
|
||||
))");
|
||||
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE "starred_release" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"scrobbler" integer not null,
|
||||
"date_time" text,
|
||||
"release_id" bigint,
|
||||
"user_id" bigint,
|
||||
constraint "fk_starred_release_release" foreign key ("release_id") references "release" ("id") on delete cascade deferrable initially deferred,
|
||||
constraint "fk_starred_release_user" foreign key ("user_id") references "user" ("id") on delete cascade deferrable initially deferred
|
||||
))");
|
||||
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE "starred_track" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"scrobbler" integer not null,
|
||||
"date_time" text,
|
||||
"track_id" bigint,
|
||||
"user_id" bigint,
|
||||
constraint "fk_starred_track_track" foreign key ("track_id") references "track" ("id") on delete cascade deferrable initially deferred,
|
||||
constraint "fk_starred_track_user" foreign key ("user_id") references "user" ("id") on delete cascade deferrable initially deferred
|
||||
))");
|
||||
|
||||
// Can't migrate using class mapping as mapping may evolve in the future
|
||||
|
||||
// use time_t to avoid rounding issues later
|
||||
const std::string now{ dateTimeToDbFormat(Wt::WDateTime::fromTime_t(Wt::WDateTime::currentDateTime().toTime_t())) };
|
||||
|
||||
std::map<IdType::ValueType, Scrobbler> userScrobblers;
|
||||
auto getScrobbler{ [&](IdType::ValueType userId)
|
||||
{
|
||||
auto itScrobbler {userScrobblers.find(userId)};
|
||||
if (itScrobbler != std::cend(userScrobblers))
|
||||
return itScrobbler->second;
|
||||
|
||||
auto query {session.getDboSession().query<Scrobbler>("SELECT scrobbler FROM user WHERE id = ?").bind(userId)};
|
||||
[[maybe_unused]] auto [itInserted, inserted] {userScrobblers.emplace(userId, query.resultValue())};
|
||||
assert(inserted);
|
||||
return itInserted->second;
|
||||
} };
|
||||
|
||||
auto migrateStarEntries{ [&session, &getScrobbler, &now](const std::string& colName, const std::string& oldTableName, const std::string& newTableName)
|
||||
{
|
||||
using UserIdObjectId = std::tuple<IdType::ValueType /* userId */, IdType::ValueType /* entryId */>;
|
||||
|
||||
std::vector<UserIdObjectId> starredEntries;
|
||||
auto query {session.getDboSession().query<UserIdObjectId>("SELECT user_id, " + colName + " from " + oldTableName)};
|
||||
auto results {query.resultList()};
|
||||
|
||||
LMS_LOG(DB, INFO) << "Found " << results.size() << " " << colName << " to migrate";
|
||||
|
||||
for (const auto& [userId, entryId] : results)
|
||||
{
|
||||
session.getDboSession().execute("INSERT INTO " + newTableName + " ('version', 'scrobbler', 'date_time', '" + colName + "', 'user_id') VALUES (?, ?, ?, ?, ?)")
|
||||
.bind(0)
|
||||
.bind(getScrobbler(userId))
|
||||
.bind(now)
|
||||
.bind(entryId)
|
||||
.bind(userId);
|
||||
}
|
||||
|
||||
session.getDboSession().execute("DROP TABLE " + oldTableName);
|
||||
} };
|
||||
|
||||
migrateStarEntries("artist_id", "user_artist_starred", "starred_artist");
|
||||
migrateStarEntries("release_id", "user_release_starred", "starred_release");
|
||||
migrateStarEntries("track_id", "user_track_starred", "starred_track");
|
||||
|
||||
// new listen system, no longer using tracklists
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE "listen" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"date_time" text,
|
||||
"scrobbler" integer not null,
|
||||
"scrobbling_state" integer not null,
|
||||
"track_id" bigint,
|
||||
"user_id" bigint,
|
||||
constraint "fk_listen_track" foreign key ("track_id") references "track" ("id") on delete cascade deferrable initially deferred,
|
||||
constraint "fk_listen_user" foreign key ("user_id") references "user" ("id") on delete cascade deferrable initially deferred
|
||||
))");
|
||||
|
||||
auto migrateListens{ [&session](const std::string& trackListName, Scrobbler scrobbler)
|
||||
{
|
||||
using UserIdObjectId = std::tuple<IdType::ValueType /* userId */, IdType::ValueType /* trackId */, Wt::WDateTime>;
|
||||
|
||||
std::vector<UserIdObjectId> listens;
|
||||
auto query {session.getDboSession().query<UserIdObjectId>("SELECT t_l.user_id, t_l_e.track_id, t_l_e.date_time FROM tracklist t_l")
|
||||
.join("tracklist_entry t_l_e ON t_l_e.tracklist_id = t_l.id")
|
||||
.where("t_l.name = ?").bind(trackListName)};
|
||||
auto results {query.resultList()};
|
||||
listens.reserve(results.size());
|
||||
|
||||
LMS_LOG(DB, INFO) << "Found " << results.size() << " listens in " << trackListName;
|
||||
|
||||
for (const auto& [userId, trackId, dateTime] : results)
|
||||
{
|
||||
session.getDboSession().execute("INSERT INTO listen ('version', 'date_time', 'scrobbler', 'scrobbling_state', 'track_id', 'user_id') VALUES (?, ?, ?, ?, ?, ?)")
|
||||
.bind(0)
|
||||
.bind(dateTimeToDbFormat(dateTime))
|
||||
.bind(scrobbler)
|
||||
.bind(ScrobblingState::Synchronized) // consider sync is done to avoid duplicate submissions
|
||||
.bind(trackId)
|
||||
.bind(userId);
|
||||
}
|
||||
} };
|
||||
|
||||
migrateListens("__scrobbler_internal_history__", Scrobbler::Internal);
|
||||
migrateListens("__scrobbler_listenbrainz_history__", Scrobbler::ListenBrainz);
|
||||
}
|
||||
|
||||
static void migrateFromV32(Session& session)
|
||||
{
|
||||
ScanSettings::get(session).modify()->addAudioFileExtension(".wv");
|
||||
@@ -605,6 +197,33 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
session.getDboSession().execute("ALTER TABLE user DROP COLUMN subsonic_transcode_enable");
|
||||
}
|
||||
|
||||
static void migrateFromV42(Session& session)
|
||||
{
|
||||
session.getDboSession().execute("DROP INDEX IF EXISTS listen_scrobbler_idx");
|
||||
session.getDboSession().execute("DROP INDEX IF EXISTS listen_user_scrobbler_idx");
|
||||
session.getDboSession().execute("DROP INDEX IF EXISTS listen_user_track_scrobbler_date_time_idx");
|
||||
session.getDboSession().execute("DROP INDEX IF EXISTS starred_artist_user_scrobbler_idx");
|
||||
session.getDboSession().execute("DROP INDEX IF EXISTS starred_artist_artist_user_scrobbler_idx");
|
||||
session.getDboSession().execute("DROP INDEX IF EXISTS starred_release_user_scrobbler_idx");
|
||||
session.getDboSession().execute("DROP INDEX IF EXISTS starred_release_release_user_scrobbler_idx");
|
||||
session.getDboSession().execute("DROP INDEX IF EXISTS starred_track_user_scrobbler_idx");
|
||||
session.getDboSession().execute("DROP INDEX IF EXISTS starred_track_track_user_scrobbler_idx");
|
||||
|
||||
// New feedback service that now handles the star/unstar stuff (that was previously handled by the scrobbling service)
|
||||
session.getDboSession().execute("ALTER TABLE user RENAME COLUMN scrobbler TO scrobbling_backend");
|
||||
session.getDboSession().execute("ALTER TABLE user ADD feedback_backend INTEGER");
|
||||
session.getDboSession().execute("ALTER TABLE listen RENAME COLUMN scrobbler TO backend");
|
||||
session.getDboSession().execute("ALTER TABLE listen RENAME COLUMN scrobbling_state TO sync_state");
|
||||
session.getDboSession().execute("ALTER TABLE starred_artist RENAME COLUMN scrobbler TO backend");
|
||||
session.getDboSession().execute("ALTER TABLE starred_artist RENAME COLUMN scrobbling_state TO sync_state");
|
||||
session.getDboSession().execute("ALTER TABLE starred_release RENAME COLUMN scrobbler TO backend");
|
||||
session.getDboSession().execute("ALTER TABLE starred_release RENAME COLUMN scrobbling_state TO sync_state");
|
||||
session.getDboSession().execute("ALTER TABLE starred_track RENAME COLUMN scrobbler TO backend");
|
||||
session.getDboSession().execute("ALTER TABLE starred_track RENAME COLUMN scrobbling_state TO sync_state");
|
||||
|
||||
session.getDboSession().execute("UPDATE user SET feedback_backend = scrobbling_backend");
|
||||
}
|
||||
|
||||
void doDbMigration(Session& session)
|
||||
{
|
||||
static const std::string outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" };
|
||||
@@ -615,33 +234,6 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
|
||||
const std::map<unsigned, MigrationFunction> migrationFunctions
|
||||
{
|
||||
{5, migrateFromV5},
|
||||
{6, migrateFromV6},
|
||||
{7, migrateFromV7},
|
||||
{8, migrateFromV8},
|
||||
{9, migrateFromV9},
|
||||
{10, migrateFromV10},
|
||||
{11, migrateFromV11},
|
||||
{12, migrateFromV12},
|
||||
{13, migrateFromV13},
|
||||
{14, migrateFromV14},
|
||||
{15, migrateFromV15},
|
||||
{16, migrateFromV16},
|
||||
{17, migrateFromV17},
|
||||
{18, migrateFromV18},
|
||||
{19, migrateFromV19},
|
||||
{20, migrateFromV20},
|
||||
{21, migrateFromV21},
|
||||
{22, migrateFromV22},
|
||||
{23, migrateFromV23},
|
||||
{24, migrateFromV24},
|
||||
{25, migrateFromV25},
|
||||
{26, migrateFromV26},
|
||||
{27, migrateFromV27},
|
||||
{28, migrateFromV28},
|
||||
{29, migrateFromV29},
|
||||
{30, migrateFromV30},
|
||||
{31, migrateFromV31},
|
||||
{32, migrateFromV32},
|
||||
{33, migrateFromV33},
|
||||
{34, migrateFromV34},
|
||||
@@ -652,6 +244,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
|
||||
{39, migrateFromV39},
|
||||
{40, migrateFromV40},
|
||||
{41, migrateFromV41},
|
||||
{42, migrateFromV42},
|
||||
};
|
||||
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Database
|
||||
class Session;
|
||||
|
||||
using Version = std::size_t;
|
||||
static constexpr Version LMS_DATABASE_VERSION{ 42 };
|
||||
static constexpr Version LMS_DATABASE_VERSION{ 43 };
|
||||
class VersionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -64,11 +64,11 @@ namespace Database
|
||||
|
||||
if (params.starringUser.isValid())
|
||||
{
|
||||
assert(params.scrobbler);
|
||||
assert(params.feedbackBackend);
|
||||
query.join("starred_release s_r ON s_r.release_id = r.id")
|
||||
.where("s_r.user_id = ?").bind(params.starringUser)
|
||||
.where("s_r.scrobbler = ?").bind(*params.scrobbler)
|
||||
.where("s_r.scrobbling_state <> ?").bind(ScrobblingState::PendingRemove);
|
||||
.where("s_r.backend = ?").bind(*params.feedbackBackend)
|
||||
.where("s_r.sync_state <> ?").bind(SyncState::PendingRemove);
|
||||
}
|
||||
|
||||
if (params.artist.isValid())
|
||||
|
||||
@@ -158,15 +158,15 @@ namespace Database
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_artist_link_artist_type_idx ON track_artist_link(artist_id,type)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_bookmark_user_idx ON track_bookmark(user_id)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS track_bookmark_user_track_idx ON track_bookmark(user_id,track_id)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS listen_scrobbler_idx ON listen(scrobbler)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS listen_user_scrobbler_idx ON listen(user_id,scrobbler)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS listen_user_track_scrobbler_date_time_idx ON listen(user_id,track_id,scrobbler,date_time)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_artist_user_scrobbler_idx ON starred_artist(user_id,scrobbler)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_artist_artist_user_scrobbler_idx ON starred_artist(artist_id,user_id,scrobbler)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_release_user_scrobbler_idx ON starred_release(user_id,scrobbler)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_release_release_user_scrobbler_idx ON starred_release(release_id,user_id,scrobbler)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_track_user_scrobbler_idx ON starred_track(user_id,scrobbler)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_track_track_user_scrobbler_idx ON starred_track(track_id,user_id,scrobbler)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS listen_backend_idx ON listen(backend)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS listen_user_backend_idx ON listen(user_id,backend)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS listen_user_track_backend_date_time_idx ON listen(user_id,track_id,backend,date_time)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_artist_user_backend_idx ON starred_artist(user_id,backend)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_artist_artist_user_backend_idx ON starred_artist(artist_id,user_id,backend)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_release_user_backend_idx ON starred_release(user_id,backend)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_release_release_user_backend_idx ON starred_release(release_id,user_id,backend)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_track_user_backend_idx ON starred_track(user_id,backend)");
|
||||
_session.execute("CREATE INDEX IF NOT EXISTS starred_track_track_user_backend_idx ON starred_track(track_id,user_id,backend)");
|
||||
}
|
||||
|
||||
// Initial settings tables
|
||||
|
||||
@@ -29,47 +29,42 @@
|
||||
|
||||
namespace Database
|
||||
{
|
||||
StarredArtist::StarredArtist(ObjectPtr<Artist> artist, ObjectPtr<User> user, Scrobbler scrobbler)
|
||||
: _scrobbler {scrobbler}
|
||||
, _artist {getDboPtr(artist)}
|
||||
, _user {getDboPtr(user)}
|
||||
{
|
||||
}
|
||||
StarredArtist::StarredArtist(ObjectPtr<Artist> artist, ObjectPtr<User> user, FeedbackBackend backend)
|
||||
: _backend{ backend }
|
||||
, _artist{ getDboPtr(artist) }
|
||||
, _user{ getDboPtr(user) }
|
||||
{
|
||||
}
|
||||
|
||||
StarredArtist::pointer
|
||||
StarredArtist::create(Session& session, ObjectPtr<Artist> artist, ObjectPtr<User> user, Scrobbler scrobbler)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<StarredArtist> {new StarredArtist {artist, user, scrobbler}});
|
||||
}
|
||||
StarredArtist::pointer StarredArtist::create(Session& session, ObjectPtr<Artist> artist, ObjectPtr<User> user, FeedbackBackend backend)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<StarredArtist> {new StarredArtist{ artist, user, backend }});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
StarredArtist::getCount(Session& session)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().query<int>("SELECT COUNT(*) FROM starred_artist");
|
||||
}
|
||||
std::size_t StarredArtist::getCount(Session& session)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().query<int>("SELECT COUNT(*) FROM starred_artist");
|
||||
}
|
||||
|
||||
StarredArtist::pointer
|
||||
StarredArtist::find(Session& session, StarredArtistId id)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredArtist>().where("id = ?").bind(id).resultValue();
|
||||
}
|
||||
StarredArtist::pointer StarredArtist::find(Session& session, StarredArtistId id)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredArtist>().where("id = ?").bind(id).resultValue();
|
||||
}
|
||||
|
||||
StarredArtist::pointer
|
||||
StarredArtist::find(Session& session, ArtistId artistId, UserId userId, Scrobbler scrobbler)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredArtist>()
|
||||
.where("artist_id = ?").bind(artistId)
|
||||
.where("user_id = ?").bind(userId)
|
||||
.where("scrobbler = ?").bind(scrobbler)
|
||||
.resultValue();
|
||||
}
|
||||
StarredArtist::pointer StarredArtist::find(Session& session, ArtistId artistId, UserId userId, FeedbackBackend backend)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredArtist>()
|
||||
.where("artist_id = ?").bind(artistId)
|
||||
.where("user_id = ?").bind(userId)
|
||||
.where("backend = ?").bind(backend)
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
void
|
||||
StarredArtist::setDateTime(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
_dateTime = Utils::normalizeDateTime(dateTime);
|
||||
}
|
||||
void StarredArtist::setDateTime(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
_dateTime = Utils::normalizeDateTime(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,47 +29,42 @@
|
||||
|
||||
namespace Database
|
||||
{
|
||||
StarredRelease::StarredRelease(ObjectPtr<Release> release, ObjectPtr<User> user, Scrobbler scrobbler)
|
||||
: _scrobbler {scrobbler}
|
||||
, _release {getDboPtr(release)}
|
||||
, _user {getDboPtr(user)}
|
||||
{
|
||||
}
|
||||
StarredRelease::StarredRelease(ObjectPtr<Release> release, ObjectPtr<User> user, FeedbackBackend backend)
|
||||
: _backend{ backend }
|
||||
, _release{ getDboPtr(release) }
|
||||
, _user{ getDboPtr(user) }
|
||||
{
|
||||
}
|
||||
|
||||
StarredRelease::pointer
|
||||
StarredRelease::create(Session& session, ObjectPtr<Release> release, ObjectPtr<User> user, Scrobbler scrobbler)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<StarredRelease>{new StarredRelease{release, user, scrobbler}});
|
||||
}
|
||||
StarredRelease::pointer StarredRelease::create(Session& session, ObjectPtr<Release> release, ObjectPtr<User> user, FeedbackBackend backend)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<StarredRelease>{new StarredRelease{ release, user, backend }});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
StarredRelease::getCount(Session& session)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().query<int>("SELECT COUNT(*) FROM starred_release");
|
||||
}
|
||||
std::size_t StarredRelease::getCount(Session& session)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().query<int>("SELECT COUNT(*) FROM starred_release");
|
||||
}
|
||||
|
||||
StarredRelease::pointer
|
||||
StarredRelease::find(Session& session, StarredReleaseId id)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredRelease>().where("id = ?").bind(id).resultValue();
|
||||
}
|
||||
StarredRelease::pointer StarredRelease::find(Session& session, StarredReleaseId id)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredRelease>().where("id = ?").bind(id).resultValue();
|
||||
}
|
||||
|
||||
StarredRelease::pointer
|
||||
StarredRelease::find(Session& session, ReleaseId releaseId, UserId userId, Scrobbler scrobbler)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredRelease>()
|
||||
.where("release_id = ?").bind(releaseId)
|
||||
.where("user_id = ?").bind(userId)
|
||||
.where("scrobbler = ?").bind(scrobbler)
|
||||
.resultValue();
|
||||
}
|
||||
StarredRelease::pointer StarredRelease::find(Session& session, ReleaseId releaseId, UserId userId, FeedbackBackend backend)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredRelease>()
|
||||
.where("release_id = ?").bind(releaseId)
|
||||
.where("user_id = ?").bind(userId)
|
||||
.where("backend = ?").bind(backend)
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
void
|
||||
StarredRelease::setDateTime(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
_dateTime = Utils::normalizeDateTime(dateTime);
|
||||
}
|
||||
void StarredRelease::setDateTime(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
_dateTime = Utils::normalizeDateTime(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,64 +29,58 @@
|
||||
|
||||
namespace Database
|
||||
{
|
||||
StarredTrack::StarredTrack(ObjectPtr<Track> track, ObjectPtr<User> user, Scrobbler scrobbler)
|
||||
: _scrobbler {scrobbler}
|
||||
, _track {getDboPtr(track)}
|
||||
, _user {getDboPtr(user)}
|
||||
{
|
||||
}
|
||||
StarredTrack::StarredTrack(ObjectPtr<Track> track, ObjectPtr<User> user, FeedbackBackend backend)
|
||||
: _backend{ backend }
|
||||
, _track{ getDboPtr(track) }
|
||||
, _user{ getDboPtr(user) }
|
||||
{
|
||||
}
|
||||
|
||||
StarredTrack::pointer
|
||||
StarredTrack::create(Session& session, ObjectPtr<Track> track, ObjectPtr<User> user, Scrobbler scrobbler)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<StarredTrack> {new StarredTrack{track, user, scrobbler}});
|
||||
}
|
||||
StarredTrack::pointer StarredTrack::create(Session& session, ObjectPtr<Track> track, ObjectPtr<User> user, FeedbackBackend backend)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<StarredTrack> {new StarredTrack{ track, user, backend }});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
StarredTrack::getCount(Session& session)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().query<int>("SELECT COUNT(*) FROM starred_track");
|
||||
}
|
||||
std::size_t StarredTrack::getCount(Session& session)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().query<int>("SELECT COUNT(*) FROM starred_track");
|
||||
}
|
||||
|
||||
StarredTrack::pointer
|
||||
StarredTrack::find(Session& session, StarredTrackId id)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredTrack>().where("id = ?").bind(id).resultValue();
|
||||
}
|
||||
StarredTrack::pointer StarredTrack::find(Session& session, StarredTrackId id)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredTrack>().where("id = ?").bind(id).resultValue();
|
||||
}
|
||||
|
||||
StarredTrack::pointer
|
||||
StarredTrack::find(Session& session, TrackId trackId, UserId userId, Scrobbler scrobbler)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredTrack>()
|
||||
.where("track_id = ?").bind(trackId)
|
||||
.where("user_id = ?").bind(userId)
|
||||
.where("scrobbler = ?").bind(scrobbler)
|
||||
.resultValue();
|
||||
}
|
||||
StarredTrack::pointer StarredTrack::find(Session& session, TrackId trackId, UserId userId, FeedbackBackend backend)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
return session.getDboSession().find<StarredTrack>()
|
||||
.where("track_id = ?").bind(trackId)
|
||||
.where("user_id = ?").bind(userId)
|
||||
.where("backend = ?").bind(backend)
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
RangeResults<StarredTrackId>
|
||||
StarredTrack::find(Session& session, const FindParameters& params)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
RangeResults<StarredTrackId> StarredTrack::find(Session& session, const FindParameters& params)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto query {session.getDboSession().query<StarredTrackId>("SELECT DISTINCT s_t.id FROM starred_track s_t")};
|
||||
auto query{ session.getDboSession().query<StarredTrackId>("SELECT DISTINCT s_t.id FROM starred_track s_t") };
|
||||
|
||||
if (params.scrobbler)
|
||||
query.where("s_t.scrobbler = ?").bind(*params.scrobbler);
|
||||
if (params.scrobblingState)
|
||||
query.where("s_t.scrobbling_state = ?").bind(*params.scrobblingState);
|
||||
if (params.user.isValid())
|
||||
query.where("s_t.user_id = ?").bind(params.user);
|
||||
if (params.backend)
|
||||
query.where("s_t.backend = ?").bind(*params.backend);
|
||||
if (params.syncState)
|
||||
query.where("s_t.sync_state = ?").bind(*params.syncState);
|
||||
if (params.user.isValid())
|
||||
query.where("s_t.user_id = ?").bind(params.user);
|
||||
|
||||
return Utils::execQuery(query, params.range);
|
||||
}
|
||||
return Utils::execQuery(query, params.range);
|
||||
}
|
||||
|
||||
void
|
||||
StarredTrack::setDateTime(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
_dateTime = Utils::normalizeDateTime(dateTime);
|
||||
}
|
||||
void StarredTrack::setDateTime(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
_dateTime = Utils::normalizeDateTime(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,11 +57,11 @@ createQuery(Session& session, const Track::FindParameters& params)
|
||||
|
||||
if (params.starringUser.isValid())
|
||||
{
|
||||
assert(params.scrobbler);
|
||||
assert(params.feedbackBackend);
|
||||
query.join("starred_track s_t ON s_t.track_id = t.id")
|
||||
.where("s_t.user_id = ?").bind(params.starringUser)
|
||||
.where("s_t.scrobbler = ?").bind(*params.scrobbler)
|
||||
.where("s_t.scrobbling_state <> ?").bind(ScrobblingState::PendingRemove);
|
||||
.where("s_t.backend = ?").bind(*params.feedbackBackend)
|
||||
.where("s_t.sync_state <> ?").bind(SyncState::PendingRemove);
|
||||
}
|
||||
|
||||
if (!params.clusters.empty())
|
||||
|
||||
@@ -53,8 +53,10 @@ namespace Database {
|
||||
|
||||
auto query{ session.getDboSession().query<UserId>("SELECT id FROM user") };
|
||||
|
||||
if (params.scrobbler)
|
||||
query.where("scrobbler = ?").bind(*params.scrobbler);
|
||||
if (params.scrobblingBackend)
|
||||
query.where("scrobbling_backend = ?").bind(*params.scrobblingBackend);
|
||||
if (params.feedbackBackend)
|
||||
query.where("feedback_backend = ?").bind(*params.feedbackBackend);
|
||||
|
||||
return Utils::execQuery(query, params.range);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class Artist final : public Object<Artist, ArtistId>
|
||||
Range range;
|
||||
Wt::WDateTime writtenAfter;
|
||||
UserId starringUser; // only artists starred by this user
|
||||
std::optional<Scrobbler> scrobbler; // and for this scrobbler
|
||||
std::optional<FeedbackBackend> feedbackBackend; // and for this feedback backend
|
||||
TrackId track; // artists involved in this track
|
||||
ReleaseId release; // artists involved in this release
|
||||
|
||||
@@ -71,7 +71,7 @@ class Artist final : public Object<Artist, ArtistId>
|
||||
FindParameters& setSortMethod(ArtistSortMethod _sortMethod) {sortMethod = _sortMethod; 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& setStarringUser(UserId _user, FeedbackBackend _feedbackBackend) { starringUser = _user; feedbackBackend = _feedbackBackend; return *this; }
|
||||
FindParameters& setTrack(TrackId _track) { track = _track; return *this; }
|
||||
FindParameters& setRelease(ReleaseId _release) { release = _release; return *this; }
|
||||
};
|
||||
|
||||
@@ -46,47 +46,47 @@ namespace Database
|
||||
struct FindParameters
|
||||
{
|
||||
UserId user;
|
||||
std::optional<Scrobbler> scrobbler;
|
||||
std::optional<ScrobblingState> scrobblingState;
|
||||
std::optional<ScrobblingBackend> backend;
|
||||
std::optional<SyncState> syncState;
|
||||
Range range;
|
||||
|
||||
FindParameters& setUser(UserId _user) { user = _user; return *this; }
|
||||
FindParameters& setScrobbler(Scrobbler _scrobbler) { scrobbler = _scrobbler; return *this; }
|
||||
FindParameters& setScrobblingState(ScrobblingState _scrobblingState) { scrobblingState = _scrobblingState; return *this; }
|
||||
FindParameters& setScrobblingBackend(ScrobblingBackend _backend) { backend = _backend; return *this; }
|
||||
FindParameters& setSyncState(SyncState _syncState) { syncState = _syncState; return *this; }
|
||||
FindParameters& setRange(Range _range) { range = _range; return *this; }
|
||||
};
|
||||
|
||||
// Accessors
|
||||
static std::size_t getCount(Session& session);
|
||||
static pointer find(Session& session, ListenId id);
|
||||
static pointer find(Session& session, UserId userId, TrackId trackId, Scrobbler scrobbler, const Wt::WDateTime& dateTime);
|
||||
static pointer find(Session& session, UserId userId, TrackId trackId, ScrobblingBackend backend, const Wt::WDateTime& dateTime);
|
||||
static RangeResults<ListenId> find(Session& session, const FindParameters& parameters);
|
||||
|
||||
// Stats
|
||||
static RangeResults<ArtistId> getTopArtists(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType, Range range = {});
|
||||
static RangeResults<ReleaseId> getTopReleases(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, Range range = {});
|
||||
static RangeResults<TrackId> getTopTracks(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, Range range = {});
|
||||
static RangeResults<ArtistId> getTopArtists(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType, Range range = {});
|
||||
static RangeResults<ReleaseId> getTopReleases(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, Range range = {});
|
||||
static RangeResults<TrackId> getTopTracks(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, Range range = {});
|
||||
|
||||
static RangeResults<ArtistId> getRecentArtists(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType, Range range = {});
|
||||
static RangeResults<ReleaseId> getRecentReleases(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, Range range = {});
|
||||
static RangeResults<TrackId> getRecentTracks(Session& session, UserId userId, Scrobbler scrobbler, const std::vector<ClusterId>& clusterIds, Range range = {});
|
||||
static RangeResults<ArtistId> getRecentArtists(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, std::optional<TrackArtistLinkType> linkType, Range range = {});
|
||||
static RangeResults<ReleaseId> getRecentReleases(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, Range range = {});
|
||||
static RangeResults<TrackId> getRecentTracks(Session& session, UserId userId, ScrobblingBackend backend, const std::vector<ClusterId>& clusterIds, Range range = {});
|
||||
|
||||
static pointer getMostRecentListen(Session& session, UserId userId, Scrobbler scrobbler, ReleaseId releaseId);
|
||||
static pointer getMostRecentListen(Session& session, UserId userId, Scrobbler scrobbler, TrackId releaseId);
|
||||
static pointer getMostRecentListen(Session& session, UserId userId, ScrobblingBackend backend, ReleaseId releaseId);
|
||||
static pointer getMostRecentListen(Session& session, UserId userId, ScrobblingBackend backend, TrackId releaseId);
|
||||
|
||||
ScrobblingState getScrobblingState() const { return _scrobblingState; }
|
||||
SyncState getSyncState() const { return _syncState; }
|
||||
ObjectPtr<User> getUser() const { return _user; }
|
||||
ObjectPtr<Track> getTrack() const { return _track; }
|
||||
const Wt::WDateTime& getDateTime() const { return _dateTime; }
|
||||
|
||||
void setScrobblingState(ScrobblingState state) { _scrobblingState = state; }
|
||||
void setSyncState(SyncState state) { _syncState = state; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _dateTime, "date_time");
|
||||
Wt::Dbo::field(a, _scrobbler, "scrobbler");
|
||||
Wt::Dbo::field(a, _scrobblingState, "scrobbling_state");
|
||||
Wt::Dbo::field(a, _backend, "backend"); // TODO rename
|
||||
Wt::Dbo::field(a, _syncState, "sync_state"); // TODO rename
|
||||
|
||||
Wt::Dbo::belongsTo(a, _track, "track", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _user, "user", Wt::Dbo::OnDeleteCascade);
|
||||
@@ -94,12 +94,12 @@ namespace Database
|
||||
|
||||
private:
|
||||
friend class Session;
|
||||
Listen(ObjectPtr<User> user, ObjectPtr<Track> track, Scrobbler scrobbler, const Wt::WDateTime& dateTime);
|
||||
static pointer create(Session& session, ObjectPtr<User> user, ObjectPtr<Track> track, Scrobbler scrobbler, const Wt::WDateTime& dateTime);
|
||||
Listen(ObjectPtr<User> user, ObjectPtr<Track> track, ScrobblingBackend backend, const Wt::WDateTime& dateTime);
|
||||
static pointer create(Session& session, ObjectPtr<User> user, ObjectPtr<Track> track, ScrobblingBackend backend, const Wt::WDateTime& dateTime);
|
||||
|
||||
Wt::WDateTime _dateTime;
|
||||
Scrobbler _scrobbler;
|
||||
ScrobblingState _scrobblingState{ ScrobblingState::PendingAdd };
|
||||
Wt::WDateTime _dateTime;
|
||||
ScrobblingBackend _backend;
|
||||
SyncState _syncState{ SyncState::PendingAdd };
|
||||
|
||||
Wt::Dbo::ptr<User> _user;
|
||||
Wt::Dbo::ptr<Track> _track;
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Database
|
||||
Wt::WDateTime writtenAfter;
|
||||
std::optional<DateRange> dateRange;
|
||||
UserId starringUser; // only releases starred by this user
|
||||
std::optional<Scrobbler> scrobbler; // and for this scrobbler
|
||||
std::optional<FeedbackBackend> feedbackBackend; // and for this backend
|
||||
ArtistId artist; // only releases that involved this user
|
||||
EnumSet<TrackArtistLinkType> trackArtistLinkTypes; // and for these link types
|
||||
EnumSet<TrackArtistLinkType> excludedTrackArtistLinkTypes; // but not for these link types
|
||||
@@ -70,7 +70,7 @@ namespace Database
|
||||
FindParameters& setRange(Range _range) { range = _range; return *this; }
|
||||
FindParameters& setWrittenAfter(const Wt::WDateTime& _after) { writtenAfter = _after; return *this; }
|
||||
FindParameters& setDateRange(const std::optional<DateRange>& _dateRange) { dateRange = _dateRange; return *this; }
|
||||
FindParameters& setStarringUser(UserId _user, Scrobbler _scrobbler) { starringUser = _user; scrobbler = _scrobbler; return *this; }
|
||||
FindParameters& setStarringUser(UserId _user, FeedbackBackend _feedbackBackend) { starringUser = _user; feedbackBackend = _feedbackBackend; return *this; }
|
||||
FindParameters& setArtist(ArtistId _artist, EnumSet<TrackArtistLinkType> _trackArtistLinkTypes = {}, EnumSet<TrackArtistLinkType> _excludedTrackArtistLinkTypes = {})
|
||||
{
|
||||
artist = _artist;
|
||||
@@ -104,7 +104,7 @@ namespace Database
|
||||
std::optional<std::string> getCopyrightURL() const;
|
||||
|
||||
// Accessors
|
||||
const std::string& getName() const { return _name; }
|
||||
const std::string& getName() const { return _name; }
|
||||
std::optional<UUID> getMBID() const { return UUID::fromString(_MBID); }
|
||||
std::optional<std::size_t> getTotalDisc() const { return _totalDisc; }
|
||||
std::size_t getDiscCount() const; // may not be total disc (if incomplete for example)
|
||||
|
||||
@@ -30,53 +30,53 @@
|
||||
|
||||
namespace Database
|
||||
{
|
||||
class Artist;
|
||||
class Session;
|
||||
class User;
|
||||
class Artist;
|
||||
class Session;
|
||||
class User;
|
||||
|
||||
class StarredArtist final : public Object<StarredArtist, StarredArtistId>
|
||||
{
|
||||
public:
|
||||
StarredArtist() = default;
|
||||
class StarredArtist final : public Object<StarredArtist, StarredArtistId>
|
||||
{
|
||||
public:
|
||||
StarredArtist() = default;
|
||||
|
||||
// Search utility
|
||||
static std::size_t getCount(Session& session);
|
||||
static pointer find(Session& session, StarredArtistId id);
|
||||
static pointer find(Session& session, ArtistId artistId, UserId userId, Scrobbler scrobbler);
|
||||
// Search utility
|
||||
static std::size_t getCount(Session& session);
|
||||
static pointer find(Session& session, StarredArtistId id);
|
||||
static pointer find(Session& session, ArtistId artistId, UserId userId, FeedbackBackend backend);
|
||||
|
||||
// Accessors
|
||||
ObjectPtr<Artist> getArtist() const { return _artist; }
|
||||
ObjectPtr<User> getUser() const { return _user; }
|
||||
Scrobbler getScrobbler() const { return _scrobbler; }
|
||||
const Wt::WDateTime& getDateTime() const { return _dateTime; }
|
||||
ScrobblingState getScrobblingState() const { return _scrobblingState; }
|
||||
// Accessors
|
||||
ObjectPtr<Artist> getArtist() const { return _artist; }
|
||||
ObjectPtr<User> getUser() const { return _user; }
|
||||
FeedbackBackend getFeedbackBackend() const { return _backend; }
|
||||
const Wt::WDateTime& getDateTime() const { return _dateTime; }
|
||||
SyncState getSyncState() const { return _syncState; }
|
||||
|
||||
// Setters
|
||||
void setDateTime(const Wt::WDateTime& dateTime);
|
||||
void setScrobblingState(ScrobblingState state) { _scrobblingState = state; }
|
||||
// Setters
|
||||
void setDateTime(const Wt::WDateTime& dateTime);
|
||||
void setSyncState(SyncState state) { _syncState = state; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _scrobbler, "scrobbler");
|
||||
Wt::Dbo::field(a, _scrobblingState, "scrobbling_state");
|
||||
Wt::Dbo::field(a, _dateTime, "date_time");
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _backend, "backend");
|
||||
Wt::Dbo::field(a, _syncState, "sync_state");
|
||||
Wt::Dbo::field(a, _dateTime, "date_time");
|
||||
|
||||
Wt::Dbo::belongsTo(a, _artist, "artist", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _user, "user", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
Wt::Dbo::belongsTo(a, _artist, "artist", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _user, "user", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Session;
|
||||
StarredArtist(ObjectPtr<Artist> artist, ObjectPtr<User> user, Scrobbler scrobbler);
|
||||
static pointer create(Session& session, ObjectPtr<Artist> artist, ObjectPtr<User> user, Scrobbler scrobbler);
|
||||
private:
|
||||
friend class Session;
|
||||
StarredArtist(ObjectPtr<Artist> artist, ObjectPtr<User> user, FeedbackBackend scrobblingbackend);
|
||||
static pointer create(Session& session, ObjectPtr<Artist> artist, ObjectPtr<User> user, FeedbackBackend scrobblingbackend);
|
||||
|
||||
Scrobbler _scrobbler; // for which scrobbler
|
||||
ScrobblingState _scrobblingState {ScrobblingState::PendingAdd};
|
||||
Wt::WDateTime _dateTime; // when it was starred
|
||||
FeedbackBackend _backend; // for which backend
|
||||
SyncState _syncState{ SyncState::PendingAdd };
|
||||
Wt::WDateTime _dateTime; // when it was starred
|
||||
|
||||
Wt::Dbo::ptr<Artist> _artist;
|
||||
Wt::Dbo::ptr<User> _user;
|
||||
};
|
||||
Wt::Dbo::ptr<Artist> _artist;
|
||||
Wt::Dbo::ptr<User> _user;
|
||||
};
|
||||
} // namespace Database
|
||||
|
||||
|
||||
@@ -30,53 +30,53 @@
|
||||
|
||||
namespace Database
|
||||
{
|
||||
class Release;
|
||||
class Session;
|
||||
class User;
|
||||
class Release;
|
||||
class Session;
|
||||
class User;
|
||||
|
||||
class StarredRelease final : public Object<StarredRelease, StarredReleaseId>
|
||||
{
|
||||
public:
|
||||
StarredRelease() = default;
|
||||
class StarredRelease final : public Object<StarredRelease, StarredReleaseId>
|
||||
{
|
||||
public:
|
||||
StarredRelease() = default;
|
||||
|
||||
// Search utility
|
||||
static std::size_t getCount(Session& session);
|
||||
static pointer find(Session& session, StarredReleaseId id);
|
||||
static pointer find(Session& session, ReleaseId releaseId, UserId userId, Scrobbler scrobbler);
|
||||
// Search utility
|
||||
static std::size_t getCount(Session& session);
|
||||
static pointer find(Session& session, StarredReleaseId id);
|
||||
static pointer find(Session& session, ReleaseId releaseId, UserId userId, FeedbackBackend backend);
|
||||
|
||||
// Accessors
|
||||
ObjectPtr<Release> getRelease() const { return _release; }
|
||||
ObjectPtr<User> getUser() const { return _user; }
|
||||
Scrobbler getScrobbler() const { return _scrobbler; }
|
||||
const Wt::WDateTime& getDateTime() const { return _dateTime; }
|
||||
ScrobblingState getScrobblingState() const { return _scrobblingState; }
|
||||
// Accessors
|
||||
ObjectPtr<Release> getRelease() const { return _release; }
|
||||
ObjectPtr<User> getUser() const { return _user; }
|
||||
FeedbackBackend getFeedbackBackend() const { return _backend; }
|
||||
const Wt::WDateTime& getDateTime() const { return _dateTime; }
|
||||
SyncState getSyncState() const { return _syncState; }
|
||||
|
||||
// Setters
|
||||
void setDateTime(const Wt::WDateTime& dateTime);
|
||||
void setScrobblingState(ScrobblingState state) { _scrobblingState = state; }
|
||||
// Setters
|
||||
void setDateTime(const Wt::WDateTime& dateTime);
|
||||
void setSyncState(SyncState state) { _syncState = state; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _scrobbler, "scrobbler");
|
||||
Wt::Dbo::field(a, _scrobblingState, "scrobbling_state");
|
||||
Wt::Dbo::field(a, _dateTime, "date_time");
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _backend, "backend");
|
||||
Wt::Dbo::field(a, _syncState, "sync_state");
|
||||
Wt::Dbo::field(a, _dateTime, "date_time");
|
||||
|
||||
Wt::Dbo::belongsTo(a, _release, "release", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _user, "user", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
Wt::Dbo::belongsTo(a, _release, "release", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _user, "user", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Session;
|
||||
StarredRelease(ObjectPtr<Release> release, ObjectPtr<User> user, Scrobbler scrobbler);
|
||||
static pointer create(Session& session, ObjectPtr<Release> release, ObjectPtr<User> user, Scrobbler scrobbler);
|
||||
private:
|
||||
friend class Session;
|
||||
StarredRelease(ObjectPtr<Release> release, ObjectPtr<User> user, FeedbackBackend backend);
|
||||
static pointer create(Session& session, ObjectPtr<Release> release, ObjectPtr<User> user, FeedbackBackend backend);
|
||||
|
||||
Scrobbler _scrobbler; // for which scrobbler
|
||||
ScrobblingState _scrobblingState {ScrobblingState::PendingAdd};
|
||||
Wt::WDateTime _dateTime; // when it was starred
|
||||
FeedbackBackend _backend; // for which backend
|
||||
SyncState _syncState{ SyncState::PendingAdd };
|
||||
Wt::WDateTime _dateTime; // when it was starred
|
||||
|
||||
Wt::Dbo::ptr<Release> _release;
|
||||
Wt::Dbo::ptr<User> _user;
|
||||
};
|
||||
Wt::Dbo::ptr<Release> _release;
|
||||
Wt::Dbo::ptr<User> _user;
|
||||
};
|
||||
} // namespace Database
|
||||
|
||||
|
||||
@@ -31,66 +31,66 @@
|
||||
|
||||
namespace Database
|
||||
{
|
||||
class Track;
|
||||
class Session;
|
||||
class User;
|
||||
class Track;
|
||||
class Session;
|
||||
class User;
|
||||
|
||||
class StarredTrack final : public Object<StarredTrack, StarredTrackId>
|
||||
{
|
||||
public:
|
||||
StarredTrack() = default;
|
||||
class StarredTrack final : public Object<StarredTrack, StarredTrackId>
|
||||
{
|
||||
public:
|
||||
StarredTrack() = default;
|
||||
|
||||
struct FindParameters
|
||||
{
|
||||
std::optional<Scrobbler> scrobbler; // for this scrobbler
|
||||
std::optional<ScrobblingState> scrobblingState; // and these states
|
||||
UserId user; // and this user
|
||||
Range range;
|
||||
struct FindParameters
|
||||
{
|
||||
std::optional<FeedbackBackend> backend; // for this backend
|
||||
std::optional<SyncState> syncState; // and these states
|
||||
UserId user; // and this user
|
||||
Range range;
|
||||
|
||||
FindParameters& setScrobbler(Scrobbler _scrobbler, ScrobblingState _scrobblingState) { scrobbler = _scrobbler; scrobblingState = _scrobblingState; return *this; }
|
||||
FindParameters& setUser(UserId _user) {user = _user; return *this; }
|
||||
FindParameters& setRange(Range _range) {range = _range; return *this; }
|
||||
};
|
||||
FindParameters& setFeedbackBackend(FeedbackBackend _backend, SyncState _syncState) { backend = _backend; syncState = _syncState; return *this; }
|
||||
FindParameters& setUser(UserId _user) { user = _user; return *this; }
|
||||
FindParameters& setRange(Range _range) { range = _range; return *this; }
|
||||
};
|
||||
|
||||
// Search utility
|
||||
static std::size_t getCount(Session& session);
|
||||
static pointer find(Session& session, StarredTrackId id);
|
||||
static pointer find(Session& session, TrackId trackId, UserId userId, Scrobbler scrobbler);
|
||||
static RangeResults<StarredTrackId> find(Session& session, const FindParameters& findParams);
|
||||
// Search utility
|
||||
static std::size_t getCount(Session& session);
|
||||
static pointer find(Session& session, StarredTrackId id);
|
||||
static pointer find(Session& session, TrackId trackId, UserId userId, FeedbackBackend backend);
|
||||
static RangeResults<StarredTrackId> find(Session& session, const FindParameters& findParams);
|
||||
|
||||
// Accessors
|
||||
ObjectPtr<Track> getTrack() const { return _track; }
|
||||
ObjectPtr<User> getUser() const { return _user; }
|
||||
Scrobbler getScrobbler() const { return _scrobbler; }
|
||||
const Wt::WDateTime& getDateTime() const { return _dateTime; }
|
||||
ScrobblingState getScrobblingState() const { return _scrobblingState; }
|
||||
// Accessors
|
||||
ObjectPtr<Track> getTrack() const { return _track; }
|
||||
ObjectPtr<User> getUser() const { return _user; }
|
||||
FeedbackBackend getBackend() const { return _backend; }
|
||||
const Wt::WDateTime& getDateTime() const { return _dateTime; }
|
||||
SyncState getSyncState() const { return _syncState; }
|
||||
|
||||
// Setters
|
||||
void setDateTime(const Wt::WDateTime& dateTime);
|
||||
void setScrobblingState(ScrobblingState state) { _scrobblingState = state; }
|
||||
// Setters
|
||||
void setDateTime(const Wt::WDateTime& dateTime);
|
||||
void setSyncState(SyncState state) { _syncState = state; }
|
||||
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _scrobbler, "scrobbler");
|
||||
Wt::Dbo::field(a, _scrobblingState, "scrobbling_state");
|
||||
Wt::Dbo::field(a, _dateTime, "date_time");
|
||||
template<class Action>
|
||||
void persist(Action& a)
|
||||
{
|
||||
Wt::Dbo::field(a, _backend, "backend");
|
||||
Wt::Dbo::field(a, _syncState, "sync_state");
|
||||
Wt::Dbo::field(a, _dateTime, "date_time");
|
||||
|
||||
Wt::Dbo::belongsTo(a, _track, "track", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _user, "user", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
Wt::Dbo::belongsTo(a, _track, "track", Wt::Dbo::OnDeleteCascade);
|
||||
Wt::Dbo::belongsTo(a, _user, "user", Wt::Dbo::OnDeleteCascade);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Session;
|
||||
StarredTrack(ObjectPtr<Track> track, ObjectPtr<User> user, Scrobbler scrobbler);
|
||||
static pointer create(Session& session, ObjectPtr<Track> track, ObjectPtr<User> user, Scrobbler scrobbler);
|
||||
private:
|
||||
friend class Session;
|
||||
StarredTrack(ObjectPtr<Track> track, ObjectPtr<User> user, FeedbackBackend backend);
|
||||
static pointer create(Session& session, ObjectPtr<Track> track, ObjectPtr<User> user, FeedbackBackend backend);
|
||||
|
||||
Scrobbler _scrobbler; // for which scrobbler
|
||||
ScrobblingState _scrobblingState {ScrobblingState::PendingAdd};
|
||||
Wt::WDateTime _dateTime; // when it was starred
|
||||
FeedbackBackend _backend; // for which backend
|
||||
SyncState _syncState{ SyncState::PendingAdd };
|
||||
Wt::WDateTime _dateTime; // when it was starred
|
||||
|
||||
Wt::Dbo::ptr<Track> _track;
|
||||
Wt::Dbo::ptr<User> _user;
|
||||
};
|
||||
Wt::Dbo::ptr<Track> _track;
|
||||
Wt::Dbo::ptr<User> _user;
|
||||
};
|
||||
} // namespace Database
|
||||
|
||||
|
||||
@@ -61,23 +61,23 @@ class Track final : 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::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 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};
|
||||
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<FeedbackBackend> feedbackBackend; // and for this feedback backend
|
||||
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; }
|
||||
@@ -85,7 +85,7 @@ class Track final : public Object<Track, TrackId>
|
||||
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& setStarringUser(UserId _user, FeedbackBackend _feedbackBackend) { starringUser = _user; feedbackBackend = _feedbackBackend; 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; }
|
||||
|
||||
@@ -160,13 +160,19 @@ namespace Database
|
||||
void visitAllowedAudioBitrates(std::function<void(Bitrate)>);
|
||||
bool isAudioBitrateAllowed(Bitrate bitrate);
|
||||
|
||||
enum class Scrobbler
|
||||
enum class ScrobblingBackend
|
||||
{
|
||||
Internal = 0,
|
||||
ListenBrainz = 1,
|
||||
};
|
||||
|
||||
enum class ScrobblingState
|
||||
enum class FeedbackBackend
|
||||
{
|
||||
Internal = 0,
|
||||
ListenBrainz = 1,
|
||||
};
|
||||
|
||||
enum class SyncState
|
||||
{
|
||||
PendingAdd = 0,
|
||||
Synchronized = 1,
|
||||
|
||||
@@ -47,20 +47,23 @@ namespace Database {
|
||||
|
||||
struct FindParameters
|
||||
{
|
||||
std::optional<Scrobbler> scrobbler;
|
||||
Range range;
|
||||
std::optional<ScrobblingBackend> scrobblingBackend;
|
||||
std::optional<FeedbackBackend> feedbackBackend;
|
||||
Range range;
|
||||
|
||||
FindParameters& setScrobbler(Scrobbler _scrobbler) { scrobbler = _scrobbler; return *this; }
|
||||
FindParameters& setFeedbackBackend(FeedbackBackend _feedbackBackend) { feedbackBackend = _feedbackBackend; return *this; }
|
||||
FindParameters& setScrobblingBackend(ScrobblingBackend _scrobblingBackend) { scrobblingBackend = _scrobblingBackend; return *this; }
|
||||
FindParameters& setRange(Range _range) { range = _range; return *this; }
|
||||
};
|
||||
|
||||
static inline const std::size_t MinNameLength{ 3 };
|
||||
static inline const std::size_t MaxNameLength{ 15 };
|
||||
static inline const AudioFormat defaultSubsonicTranscodeFormat{ AudioFormat::OGG_OPUS };
|
||||
static inline const Bitrate defaultSubsonicTranscodeBitrate{ 128000 };
|
||||
static inline const UITheme defaultUITheme{ UITheme::Dark };
|
||||
static inline const SubsonicArtistListMode defaultSubsonicArtistListMode{ SubsonicArtistListMode::AllArtists };
|
||||
static inline const Scrobbler defaultScrobbler{ Scrobbler::Internal };
|
||||
static inline constexpr std::size_t MinNameLength{ 3 };
|
||||
static inline constexpr std::size_t MaxNameLength{ 15 };
|
||||
static inline constexpr AudioFormat defaultSubsonicTranscodeFormat{ AudioFormat::OGG_OPUS };
|
||||
static inline constexpr Bitrate defaultSubsonicTranscodeBitrate{ 128000 };
|
||||
static inline constexpr UITheme defaultUITheme{ UITheme::Dark };
|
||||
static inline constexpr SubsonicArtistListMode defaultSubsonicArtistListMode{ SubsonicArtistListMode::AllArtists };
|
||||
static inline constexpr ScrobblingBackend defaultScrobblingBackend{ ScrobblingBackend::Internal };
|
||||
static inline constexpr FeedbackBackend defaultFeedbackBackend{ FeedbackBackend::Internal };
|
||||
|
||||
User() = default;
|
||||
|
||||
@@ -88,7 +91,8 @@ namespace Database {
|
||||
void setUITheme(UITheme uiTheme) { _uiTheme = uiTheme; }
|
||||
void clearAuthTokens();
|
||||
void setSubsonicArtistListMode(SubsonicArtistListMode mode) { _subsonicArtistListMode = mode; }
|
||||
void setScrobbler(Scrobbler scrobbler) { _scrobbler = scrobbler; }
|
||||
void setFeedbackBackend(FeedbackBackend feedbackBackend) { _feedbackBackend = feedbackBackend; }
|
||||
void setScrobblingBackend(ScrobblingBackend scrobblingBackend) { _scrobblingBackend = scrobblingBackend; }
|
||||
void setListenBrainzToken(const std::optional<UUID>& MBID) { _listenbrainzToken = MBID ? MBID->getAsString() : ""; }
|
||||
|
||||
// read
|
||||
@@ -102,7 +106,8 @@ namespace Database {
|
||||
bool isRadioSet() const { return _radio; }
|
||||
UITheme getUITheme() const { return _uiTheme; }
|
||||
SubsonicArtistListMode getSubsonicArtistListMode() const { return _subsonicArtistListMode; }
|
||||
Scrobbler getScrobbler() const { return _scrobbler; }
|
||||
FeedbackBackend getFeedbackBackend() const { return _feedbackBackend; }
|
||||
ScrobblingBackend getScrobblingBackend() const { return _scrobblingBackend; }
|
||||
std::optional<UUID> getListenBrainzToken() const { return UUID::fromString(_listenbrainzToken); }
|
||||
|
||||
template<class Action>
|
||||
@@ -117,7 +122,8 @@ namespace Database {
|
||||
Wt::Dbo::field(a, _subsonicDefaultTranscodeBitrate, "subsonic_default_transcode_bitrate");
|
||||
Wt::Dbo::field(a, _subsonicArtistListMode, "subsonic_artist_list_mode");
|
||||
Wt::Dbo::field(a, _uiTheme, "ui_theme");
|
||||
Wt::Dbo::field(a, _scrobbler, "scrobbler");
|
||||
Wt::Dbo::field(a, _feedbackBackend, "feedback_backend");
|
||||
Wt::Dbo::field(a, _scrobblingBackend, "scrobbling_backend");
|
||||
Wt::Dbo::field(a, _listenbrainzToken, "listenbrainz_token");
|
||||
|
||||
// UI player settings
|
||||
@@ -138,7 +144,8 @@ namespace Database {
|
||||
std::string _passwordHash;
|
||||
Wt::WDateTime _lastLogin;
|
||||
UITheme _uiTheme{ defaultUITheme };
|
||||
Scrobbler _scrobbler{ defaultScrobbler };
|
||||
FeedbackBackend _feedbackBackend{ defaultFeedbackBackend };
|
||||
ScrobblingBackend _scrobblingBackend{ defaultScrobblingBackend };
|
||||
std::string _listenbrainzToken; // Musicbrainz Identifier
|
||||
|
||||
// Admin defined settings
|
||||
|
||||
@@ -35,7 +35,7 @@ TEST_F(DatabaseFixture, Listen_getAll)
|
||||
EXPECT_EQ(Listen::getCount(session), 0);
|
||||
}
|
||||
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 1}} };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 1}} };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
@@ -45,7 +45,7 @@ TEST_F(DatabaseFixture, Listen_getAll)
|
||||
|
||||
{
|
||||
auto transaction{ session.createUniqueTransaction() };
|
||||
ScopedListen listen2{ session, user.get(), track.get(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{13, 0, 1}} };
|
||||
ScopedListen listen2{ session, user.get(), track.get(), ScrobblingBackend::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{13, 0, 1}} };
|
||||
|
||||
EXPECT_EQ(Listen::getCount(session), 2);
|
||||
}
|
||||
@@ -61,12 +61,12 @@ TEST_F(DatabaseFixture, Listen_get)
|
||||
{
|
||||
ScopedTrack track{ session, "MyTrack" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 1}} };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 1}} };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobbler(Scrobbler::ListenBrainz)) };
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobblingBackend(ScrobblingBackend::ListenBrainz)) };
|
||||
EXPECT_EQ(listens.results.size(), 0);
|
||||
}
|
||||
|
||||
@@ -74,18 +74,18 @@ TEST_F(DatabaseFixture, Listen_get)
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
{
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobbler(Scrobbler::Internal)) };
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobblingBackend(ScrobblingBackend::Internal)) };
|
||||
EXPECT_EQ(listens.moreResults, false);
|
||||
ASSERT_EQ(listens.results.size(), 1);
|
||||
EXPECT_EQ(listens.results.front(), listen->getId());
|
||||
}
|
||||
|
||||
{
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobbler(Scrobbler::Internal).setScrobblingState(ScrobblingState::PendingAdd)) };
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobblingBackend(ScrobblingBackend::Internal).setSyncState(SyncState::PendingAdd)) };
|
||||
EXPECT_EQ(listens.results.size(), 1);
|
||||
}
|
||||
{
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobbler(Scrobbler::Internal).setScrobblingState(ScrobblingState::Synchronized)) };
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobblingBackend(ScrobblingBackend::Internal).setSyncState(SyncState::Synchronized)) };
|
||||
EXPECT_EQ(listens.results.size(), 0);
|
||||
}
|
||||
}
|
||||
@@ -95,14 +95,14 @@ TEST_F(DatabaseFixture, Listen_get_multi)
|
||||
{
|
||||
ScopedTrack track{ session, "MyTrack" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 3}} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 1}} };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 2}} };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 3}} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 1}} };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, Wt::WDateTime {Wt::WDate{2000, 1, 2}, Wt::WTime{12, 0, 2}} };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobbler(Scrobbler::Internal)) };
|
||||
auto listens{ Listen::find(session, Listen::FindParameters{}.setUser(user->getId()).setScrobblingBackend(ScrobblingBackend::Internal)) };
|
||||
ASSERT_EQ(listens.results.size(), 3);
|
||||
EXPECT_EQ(listens.results[0], listen1.getId());
|
||||
EXPECT_EQ(listens.results[1], listen2.getId());
|
||||
@@ -118,26 +118,26 @@ TEST_F(DatabaseFixture, Listen_get_byDateTime)
|
||||
const Wt::WDateTime dateTime2{ Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 2} };
|
||||
ASSERT_GT(dateTime2, dateTime1);
|
||||
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime1 };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime2 };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime1 };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime2 };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
{
|
||||
Listen::pointer listen{ Listen::find(session, user.getId(), track.getId(), Scrobbler::Internal, dateTime1) };
|
||||
Listen::pointer listen{ Listen::find(session, user.getId(), track.getId(), ScrobblingBackend::Internal, dateTime1) };
|
||||
ASSERT_TRUE(listen);
|
||||
EXPECT_EQ(listen->getId(), listen1.getId());
|
||||
}
|
||||
|
||||
{
|
||||
Listen::pointer listen{ Listen::find(session, user.getId(), track.getId(), Scrobbler::Internal, dateTime2) };
|
||||
Listen::pointer listen{ Listen::find(session, user.getId(), track.getId(), ScrobblingBackend::Internal, dateTime2) };
|
||||
ASSERT_TRUE(listen);
|
||||
EXPECT_EQ(listen->getId(), listen2.getId());
|
||||
}
|
||||
|
||||
{
|
||||
Listen::pointer listen{ Listen::find(session, user.getId(), track.getId(), Scrobbler::Internal, dateTime2.addSecs(56)) };
|
||||
Listen::pointer listen{ Listen::find(session, user.getId(), track.getId(), ScrobblingBackend::Internal, dateTime2.addSecs(56)) };
|
||||
EXPECT_FALSE(listen);
|
||||
}
|
||||
}
|
||||
@@ -148,19 +148,19 @@ TEST_F(DatabaseFixture, Listen_getTopArtists)
|
||||
ScopedTrack track1{ session, "MyTrack" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
const Wt::WDateTime dateTime1{ Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime1 };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime1 };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
EXPECT_EQ(artists.moreResults, false);
|
||||
}
|
||||
|
||||
ScopedTrack track2{ session, "MyTrack2" };
|
||||
ScopedArtist artist1{ session, "MyArtist1" };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime1.addSecs(1) };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime1.addSecs(1) };
|
||||
|
||||
{
|
||||
auto transaction{ session.createUniqueTransaction() };
|
||||
@@ -171,20 +171,20 @@ TEST_F(DatabaseFixture, Listen_getTopArtists)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 1);
|
||||
EXPECT_EQ(artists.results[0], artist1->getId());
|
||||
}
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::ListenBrainz, {}, std::nullopt) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::ListenBrainz, {}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, TrackArtistLinkType::Producer) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {}, TrackArtistLinkType::Producer) };
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
{
|
||||
@@ -194,7 +194,7 @@ TEST_F(DatabaseFixture, Listen_getTopArtists)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {cluster->getId()}, std::nullopt) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {cluster->getId()}, std::nullopt) };
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
}
|
||||
@@ -218,24 +218,24 @@ TEST_F(DatabaseFixture, Listen_getTopArtists_multi)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(1) };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(1) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 1);
|
||||
EXPECT_EQ(artists.results[0], artist1->getId());
|
||||
}
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(2) };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(3) };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(2) };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(3) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 2);
|
||||
EXPECT_EQ(artists.results[0], artist2->getId());
|
||||
EXPECT_EQ(artists.results[1], artist1->getId());
|
||||
@@ -243,7 +243,7 @@ TEST_F(DatabaseFixture, Listen_getTopArtists_multi)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt, Range {0, 1}) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt, Range {0, 1}) };
|
||||
ASSERT_EQ(artists.results.size(), 1);
|
||||
EXPECT_EQ(artists.moreResults, true);
|
||||
EXPECT_EQ(artists.results[0], artist2->getId());
|
||||
@@ -256,7 +256,7 @@ TEST_F(DatabaseFixture, Listen_getTopArtists_cluster)
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
ScopedArtist artist{ session, "MyArtist" };
|
||||
const Wt::WDateTime dateTime{ Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1} };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedClusterType clusterType{ session, "MyType" };
|
||||
ScopedCluster cluster{ session, clusterType.lockAndGet(), "MyCluster" };
|
||||
|
||||
@@ -268,7 +268,7 @@ TEST_F(DatabaseFixture, Listen_getTopArtists_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {cluster.getId()}, std::nullopt) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
{
|
||||
@@ -278,7 +278,7 @@ TEST_F(DatabaseFixture, Listen_getTopArtists_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), Scrobbler::Internal, {cluster.getId()}, std::nullopt) };
|
||||
auto artists{ Listen::getTopArtists(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 1);
|
||||
EXPECT_EQ(artists.results[0], artist.getId());
|
||||
}
|
||||
@@ -298,17 +298,17 @@ TEST_F(DatabaseFixture, Listen_getTopReleases)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 1);
|
||||
EXPECT_EQ(releases.results[0], release.getId());
|
||||
@@ -316,7 +316,7 @@ TEST_F(DatabaseFixture, Listen_getTopReleases)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), Scrobbler::ListenBrainz, {}) };
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), ScrobblingBackend::ListenBrainz, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
@@ -328,7 +328,7 @@ TEST_F(DatabaseFixture, Listen_getTopReleases_multi)
|
||||
ScopedTrack track2{ session, "MyTrack" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
const Wt::WDateTime dateTime{ Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedRelease release1{ session, "MyRelease1" };
|
||||
ScopedRelease release2{ session, "MyRelease2" };
|
||||
|
||||
@@ -341,28 +341,28 @@ TEST_F(DatabaseFixture, Listen_getTopReleases_multi)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 1);
|
||||
EXPECT_EQ(releases.results[0], release1.getId());
|
||||
}
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 2);
|
||||
EXPECT_EQ(releases.results[0], release2.getId());
|
||||
EXPECT_EQ(releases.results[1], release1.getId());
|
||||
}
|
||||
ScopedListen listen4{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen5{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen4{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedListen listen5{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 2);
|
||||
EXPECT_EQ(releases.results[0], release1.getId());
|
||||
@@ -375,7 +375,7 @@ TEST_F(DatabaseFixture, Listen_getTopReleases_cluster)
|
||||
ScopedTrack track{ session, "MyTrack" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
const Wt::WDateTime dateTime{ Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1} };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedClusterType clusterType{ session, "MyType" };
|
||||
ScopedCluster cluster{ session, clusterType.lockAndGet(), "MyCluster" };
|
||||
ScopedRelease release{ session, "MyRelease" };
|
||||
@@ -388,7 +388,7 @@ TEST_F(DatabaseFixture, Listen_getTopReleases_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()}) };
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}) };
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
{
|
||||
@@ -399,7 +399,7 @@ TEST_F(DatabaseFixture, Listen_getTopReleases_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()}) };
|
||||
auto releases{ Listen::getTopReleases(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}) };
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
EXPECT_EQ(releases.results[0], release.getId());
|
||||
}
|
||||
@@ -414,17 +414,17 @@ TEST_F(DatabaseFixture, Listen_getTopTracks)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 1);
|
||||
EXPECT_EQ(tracks.results[0], track.getId());
|
||||
@@ -432,7 +432,7 @@ TEST_F(DatabaseFixture, Listen_getTopTracks)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), Scrobbler::ListenBrainz, {}) };
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), ScrobblingBackend::ListenBrainz, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
@@ -444,33 +444,33 @@ TEST_F(DatabaseFixture, Listen_getTopTrack_multi)
|
||||
ScopedTrack track2{ session, "MyTrack2" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
const Wt::WDateTime dateTime{ Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 1);
|
||||
EXPECT_EQ(tracks.results[0], track1.getId());
|
||||
}
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 2);
|
||||
EXPECT_EQ(tracks.results[0], track2.getId());
|
||||
EXPECT_EQ(tracks.results[1], track1.getId());
|
||||
}
|
||||
ScopedListen listen4{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen5{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen4{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedListen listen5{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 2);
|
||||
EXPECT_EQ(tracks.results[0], track1.getId());
|
||||
@@ -483,14 +483,14 @@ TEST_F(DatabaseFixture, Listen_getTopTracks_cluster)
|
||||
ScopedTrack track{ session, "MyTrack" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
const Wt::WDateTime dateTime{ Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1} };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedClusterType clusterType{ session, "MyType" };
|
||||
ScopedCluster cluster{ session, clusterType.lockAndGet(), "MyCluster" };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {cluster.getId()}) };
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}) };
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
{
|
||||
@@ -501,7 +501,7 @@ TEST_F(DatabaseFixture, Listen_getTopTracks_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), Scrobbler::Internal, {cluster.getId()}) };
|
||||
auto tracks{ Listen::getTopTracks(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}) };
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
EXPECT_EQ(tracks.results[0], track.getId());
|
||||
}
|
||||
@@ -521,31 +521,31 @@ TEST_F(DatabaseFixture, Listen_getRecentArtists)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
EXPECT_EQ(artists.moreResults, false);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime{ Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 1);
|
||||
EXPECT_EQ(artists.results[0], artist->getId());
|
||||
}
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::ListenBrainz, {}, std::nullopt) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::ListenBrainz, {}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, TrackArtistLinkType::Producer) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {}, TrackArtistLinkType::Producer) };
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
{
|
||||
@@ -555,7 +555,7 @@ TEST_F(DatabaseFixture, Listen_getRecentArtists)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {cluster->getId()}, std::nullopt) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {cluster->getId()}, std::nullopt) };
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
}
|
||||
@@ -579,32 +579,32 @@ TEST_F(DatabaseFixture, Listen_getRecentArtists_multi)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(1) };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(1) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 1);
|
||||
EXPECT_EQ(artists.results[0], artist1->getId());
|
||||
}
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(2) };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(2) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 2);
|
||||
EXPECT_EQ(artists.results[0], artist2->getId());
|
||||
EXPECT_EQ(artists.results[1], artist1->getId());
|
||||
}
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(-1) };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(-1) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {}, std::nullopt, Range {0, 1}) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {}, std::nullopt, Range {0, 1}) };
|
||||
ASSERT_EQ(artists.results.size(), 1);
|
||||
EXPECT_EQ(artists.moreResults, true);
|
||||
EXPECT_EQ(artists.results[0], artist2->getId());
|
||||
@@ -617,7 +617,7 @@ TEST_F(DatabaseFixture, Listen_getRecentArtists_cluster)
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
ScopedArtist artist{ session, "MyArtist" };
|
||||
const Wt::WDateTime dateTime{ Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1} };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedClusterType clusterType{ session, "MyType" };
|
||||
ScopedCluster cluster{ session, clusterType.lockAndGet(), "MyCluster" };
|
||||
|
||||
@@ -629,7 +629,7 @@ TEST_F(DatabaseFixture, Listen_getRecentArtists_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {cluster.getId()}, std::nullopt) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
{
|
||||
@@ -639,7 +639,7 @@ TEST_F(DatabaseFixture, Listen_getRecentArtists_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), Scrobbler::Internal, {cluster.getId()}, std::nullopt) };
|
||||
auto artists{ Listen::getRecentArtists(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}, std::nullopt) };
|
||||
ASSERT_EQ(artists.results.size(), 1);
|
||||
EXPECT_EQ(artists.results[0], artist.getId());
|
||||
}
|
||||
@@ -659,18 +659,18 @@ TEST_F(DatabaseFixture, Listen_getRecentReleases)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime{ Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 1);
|
||||
EXPECT_EQ(releases.results[0], release.getId());
|
||||
@@ -678,7 +678,7 @@ TEST_F(DatabaseFixture, Listen_getRecentReleases)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::ListenBrainz, {}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::ListenBrainz, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
@@ -699,39 +699,39 @@ TEST_F(DatabaseFixture, Listen_getMostRecentRelease)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
const auto listen{ Listen::getMostRecentListen(session, user->getId(), Scrobbler::Internal, release.getId()) };
|
||||
const auto listen{ Listen::getMostRecentListen(session, user->getId(), ScrobblingBackend::Internal, release.getId()) };
|
||||
EXPECT_FALSE(listen);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime1{ Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime1 };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime1 };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
const auto listen{ Listen::getMostRecentListen(session, user->getId(), Scrobbler::Internal, release.getId()) };
|
||||
const auto listen{ Listen::getMostRecentListen(session, user->getId(), ScrobblingBackend::Internal, release.getId()) };
|
||||
EXPECT_TRUE(listen);
|
||||
EXPECT_EQ(listen->getDateTime(), dateTime1);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime2{ Wt::WDate {1999, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime2 };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime2 };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
const auto listen{ Listen::getMostRecentListen(session, user->getId(), Scrobbler::Internal, release.getId()) };
|
||||
const auto listen{ Listen::getMostRecentListen(session, user->getId(), ScrobblingBackend::Internal, release.getId()) };
|
||||
EXPECT_TRUE(listen);
|
||||
EXPECT_EQ(listen->getDateTime(), dateTime1);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime3{ Wt::WDate {2001, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime3 };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime3 };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
const auto listen{ Listen::getMostRecentListen(session, user->getId(), Scrobbler::Internal, release.getId()) };
|
||||
const auto listen{ Listen::getMostRecentListen(session, user->getId(), ScrobblingBackend::Internal, release.getId()) };
|
||||
EXPECT_TRUE(listen);
|
||||
EXPECT_EQ(listen->getDateTime(), dateTime3);
|
||||
}
|
||||
@@ -752,44 +752,44 @@ TEST_F(DatabaseFixture, Listen_getRecentReleases_multi)
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime{ Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 1);
|
||||
EXPECT_EQ(releases.results[0], release2.getId());
|
||||
}
|
||||
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(1) };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(1) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 2);
|
||||
EXPECT_EQ(releases.results[0], release1.getId());
|
||||
EXPECT_EQ(releases.results[1], release2.getId());
|
||||
}
|
||||
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(2) };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(2) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 2);
|
||||
EXPECT_EQ(releases.results[0], release2.getId());
|
||||
EXPECT_EQ(releases.results[1], release1.getId());
|
||||
}
|
||||
|
||||
ScopedListen listen4{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(-1) };
|
||||
ScopedListen listen4{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(-1) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(releases.moreResults, false);
|
||||
ASSERT_EQ(releases.results.size(), 2);
|
||||
EXPECT_EQ(releases.results[0], release2.getId());
|
||||
@@ -812,17 +812,17 @@ TEST_F(DatabaseFixture, Listen_getRecentReleases_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}) };
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime{ Wt::WDate{2000, 1, 2}, Wt::WTime{12,0, 1} };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}) };
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
|
||||
@@ -833,7 +833,7 @@ TEST_F(DatabaseFixture, Listen_getRecentReleases_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), Scrobbler::Internal, {cluster.getId()}) };
|
||||
auto releases{ Listen::getRecentReleases(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}) };
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
EXPECT_EQ(releases.results[0], release.getId());
|
||||
}
|
||||
@@ -847,18 +847,18 @@ TEST_F(DatabaseFixture, Listen_getRecentTracks)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime{ Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 1);
|
||||
EXPECT_EQ(tracks.results[0], track.getId());
|
||||
@@ -867,7 +867,7 @@ TEST_F(DatabaseFixture, Listen_getRecentTracks)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), Scrobbler::ListenBrainz, {}) };
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), ScrobblingBackend::ListenBrainz, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
@@ -881,39 +881,39 @@ TEST_F(DatabaseFixture, Listen_getMostRecentTrack)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto listen{ Listen::getMostRecentListen(session, user->getId(), Scrobbler::Internal, track.getId()) };
|
||||
auto listen{ Listen::getMostRecentListen(session, user->getId(), ScrobblingBackend::Internal, track.getId()) };
|
||||
EXPECT_FALSE(listen);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime1{ Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime1 };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime1 };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto listen{ Listen::getMostRecentListen(session, user->getId(), Scrobbler::Internal, track.getId()) };
|
||||
auto listen{ Listen::getMostRecentListen(session, user->getId(), ScrobblingBackend::Internal, track.getId()) };
|
||||
EXPECT_TRUE(listen);
|
||||
EXPECT_EQ(listen->getDateTime(), dateTime1);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime2{ Wt::WDate {1999, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime2 };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime2 };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto listen{ Listen::getMostRecentListen(session, user->getId(), Scrobbler::Internal, track.getId()) };
|
||||
auto listen{ Listen::getMostRecentListen(session, user->getId(), ScrobblingBackend::Internal, track.getId()) };
|
||||
EXPECT_TRUE(listen);
|
||||
EXPECT_EQ(listen->getDateTime(), dateTime1);
|
||||
}
|
||||
|
||||
const Wt::WDateTime dateTime3{ Wt::WDate {2001, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime3 };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime3 };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto listen{ Listen::getMostRecentListen(session, user->getId(), Scrobbler::Internal, track.getId()) };
|
||||
auto listen{ Listen::getMostRecentListen(session, user->getId(), ScrobblingBackend::Internal, track.getId()) };
|
||||
EXPECT_TRUE(listen);
|
||||
EXPECT_EQ(listen->getDateTime(), dateTime3);
|
||||
}
|
||||
@@ -926,44 +926,44 @@ TEST_F(DatabaseFixture, Listen_getRecentTracks_multi)
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
|
||||
const Wt::WDateTime dateTime{ Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen1{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 1);
|
||||
EXPECT_EQ(tracks.results[0], track2.getId());
|
||||
}
|
||||
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(1) };
|
||||
ScopedListen listen2{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(1) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 2);
|
||||
EXPECT_EQ(tracks.results[0], track1.getId());
|
||||
EXPECT_EQ(tracks.results[1], track2.getId());
|
||||
}
|
||||
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(2) };
|
||||
ScopedListen listen3{ session, user.lockAndGet(), track2.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(2) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 2);
|
||||
EXPECT_EQ(tracks.results[0], track2.getId());
|
||||
EXPECT_EQ(tracks.results[1], track1.getId());
|
||||
}
|
||||
|
||||
ScopedListen listen4{ session, user.lockAndGet(), track1.lockAndGet(), Scrobbler::Internal, dateTime.addSecs(-1) };
|
||||
ScopedListen listen4{ session, user.lockAndGet(), track1.lockAndGet(), ScrobblingBackend::Internal, dateTime.addSecs(-1) };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {}) };
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), ScrobblingBackend::Internal, {}) };
|
||||
EXPECT_EQ(tracks.moreResults, false);
|
||||
ASSERT_EQ(tracks.results.size(), 2);
|
||||
EXPECT_EQ(tracks.results[0], track2.getId());
|
||||
@@ -976,14 +976,14 @@ TEST_F(DatabaseFixture, Listen_getRecentTracks_cluster)
|
||||
ScopedTrack track{ session, "MyTrack" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
const Wt::WDateTime dateTime{ Wt::WDate {2000, 1, 2}, Wt::WTime {12,0, 1} };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), Scrobbler::Internal, dateTime };
|
||||
ScopedListen listen{ session, user.lockAndGet(), track.lockAndGet(), ScrobblingBackend::Internal, dateTime };
|
||||
ScopedClusterType clusterType{ session, "MyType" };
|
||||
ScopedCluster cluster{ session, clusterType.lockAndGet(), "MyCluster" };
|
||||
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {cluster.getId()}) };
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}) };
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
{
|
||||
@@ -994,7 +994,7 @@ TEST_F(DatabaseFixture, Listen_getRecentTracks_cluster)
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), Scrobbler::Internal, {cluster.getId()}) };
|
||||
auto tracks{ Listen::getRecentTracks(session, user->getId(), ScrobblingBackend::Internal, {cluster.getId()}) };
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
EXPECT_EQ(tracks.results[0], track.getId());
|
||||
}
|
||||
|
||||
@@ -26,102 +26,100 @@ using ScopedStarredArtist = ScopedEntity<Database::StarredArtist>;
|
||||
|
||||
TEST_F(DatabaseFixture, StarredArtist)
|
||||
{
|
||||
ScopedArtist artist {session, "MyArtist"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedUser user2 {session, "MyUser2"};
|
||||
ScopedArtist artist{ session, "MyArtist" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
ScopedUser user2{ session, "MyUser2" };
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto starredArtist {StarredArtist::find(session, artist->getId(), user->getId(), Scrobbler::Internal)};
|
||||
EXPECT_FALSE(starredArtist);
|
||||
EXPECT_EQ(StarredArtist::getCount(session), 0);
|
||||
auto starredArtist{ StarredArtist::find(session, artist->getId(), user->getId(), FeedbackBackend::Internal) };
|
||||
EXPECT_FALSE(starredArtist);
|
||||
EXPECT_EQ(StarredArtist::getCount(session), 0);
|
||||
|
||||
auto artists {Artist::find(session, Artist::FindParameters {})};
|
||||
EXPECT_EQ(artists.results.size(), 1);
|
||||
}
|
||||
auto artists{ Artist::find(session, Artist::FindParameters {}) };
|
||||
EXPECT_EQ(artists.results.size(), 1);
|
||||
}
|
||||
|
||||
ScopedStarredArtist starredArtist {session, artist.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
ScopedStarredArtist starredArtist{ session, artist.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto gotArtist {StarredArtist::find(session, artist->getId(), user->getId(), Scrobbler::Internal)};
|
||||
EXPECT_EQ(gotArtist->getId(), starredArtist->getId());
|
||||
EXPECT_EQ(StarredArtist::getCount(session), 1);
|
||||
}
|
||||
auto gotArtist{ StarredArtist::find(session, artist->getId(), user->getId(), FeedbackBackend::Internal) };
|
||||
EXPECT_EQ(gotArtist->getId(), starredArtist->getId());
|
||||
EXPECT_EQ(StarredArtist::getCount(session), 1);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists {Artist::find(session, Artist::FindParameters {})};
|
||||
EXPECT_EQ(artists.results.size(), 1);
|
||||
auto artists{ Artist::find(session, Artist::FindParameters {}) };
|
||||
EXPECT_EQ(artists.results.size(), 1);
|
||||
|
||||
artists = Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal));
|
||||
EXPECT_EQ(artists.results.size(), 1);
|
||||
artists = Artist::find(session, Artist::FindParameters{}.setStarringUser(user.getId(), FeedbackBackend::Internal));
|
||||
EXPECT_EQ(artists.results.size(), 1);
|
||||
|
||||
artists = Artist::find(session, Artist::FindParameters {}.setStarringUser(user2.getId(), Scrobbler::Internal));
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
artists = Artist::find(session, Artist::FindParameters{}.setStarringUser(user2.getId(), FeedbackBackend::Internal));
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, StarredArtist_PendingDestroy)
|
||||
{
|
||||
ScopedArtist artist {session, "MyArtist"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedStarredArtist starredArtist {session, artist.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
ScopedArtist artist{ session, "MyArtist" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
ScopedStarredArtist starredArtist{ session, artist.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal };
|
||||
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
{
|
||||
auto transaction{ session.createUniqueTransaction() };
|
||||
|
||||
auto artists {Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal))};
|
||||
EXPECT_EQ(artists.results.size(), 1);
|
||||
auto artists{ Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal)) };
|
||||
EXPECT_EQ(artists.results.size(), 1);
|
||||
|
||||
starredArtist.get().modify()->setScrobblingState(ScrobblingState::PendingRemove);
|
||||
artists = Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal));
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
starredArtist.get().modify()->setSyncState(SyncState::PendingRemove);
|
||||
artists = Artist::find(session, Artist::FindParameters{}.setStarringUser(user.getId(), FeedbackBackend::Internal));
|
||||
EXPECT_EQ(artists.results.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, StarredArtist_dateTime)
|
||||
{
|
||||
ScopedArtist artist1 {session, "MyArtist1"};
|
||||
ScopedArtist artist2 {session, "MyArtist2"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedArtist artist1{ session, "MyArtist1" };
|
||||
ScopedArtist artist2{ session, "MyArtist2" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
|
||||
ScopedStarredArtist starredArtist1 {session, artist1.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
ScopedStarredArtist starredArtist2 {session, artist2.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
ScopedStarredArtist starredArtist1{ session, artist1.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal };
|
||||
ScopedStarredArtist starredArtist2{ session, artist2.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal };
|
||||
|
||||
const Wt::WDateTime dateTime {Wt::WDate {1950, 1, 2}, Wt::WTime {12, 30, 1}};
|
||||
const Wt::WDateTime dateTime{ Wt::WDate {1950, 1, 2}, Wt::WTime {12, 30, 1} };
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto artists {Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal))};
|
||||
EXPECT_EQ(artists.results.size(), 2);
|
||||
}
|
||||
auto artists{ Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal)) };
|
||||
EXPECT_EQ(artists.results.size(), 2);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
{
|
||||
auto transaction{ session.createUniqueTransaction() };
|
||||
|
||||
starredArtist1.get().modify()->setDateTime(dateTime);
|
||||
starredArtist2.get().modify()->setDateTime(dateTime.addSecs(-1));
|
||||
starredArtist1.get().modify()->setDateTime(dateTime);
|
||||
starredArtist2.get().modify()->setDateTime(dateTime.addSecs(-1));
|
||||
|
||||
auto artists {Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
|
||||
.setSortMethod(ArtistSortMethod::StarredDateDesc))};
|
||||
ASSERT_EQ(artists.results.size(), 2);
|
||||
EXPECT_EQ(artists.results[0], starredArtist1->getArtist()->getId());
|
||||
EXPECT_EQ(artists.results[1], starredArtist2->getArtist()->getId());
|
||||
}
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
auto artists{ Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal).setSortMethod(ArtistSortMethod::StarredDateDesc)) };
|
||||
ASSERT_EQ(artists.results.size(), 2);
|
||||
EXPECT_EQ(artists.results[0], starredArtist1->getArtist()->getId());
|
||||
EXPECT_EQ(artists.results[1], starredArtist2->getArtist()->getId());
|
||||
}
|
||||
{
|
||||
auto transaction{ session.createUniqueTransaction() };
|
||||
|
||||
starredArtist1.get().modify()->setDateTime(dateTime);
|
||||
starredArtist2.get().modify()->setDateTime(dateTime.addSecs(1));
|
||||
starredArtist1.get().modify()->setDateTime(dateTime);
|
||||
starredArtist2.get().modify()->setDateTime(dateTime.addSecs(1));
|
||||
|
||||
auto artists {Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
|
||||
.setSortMethod(ArtistSortMethod::StarredDateDesc))};
|
||||
ASSERT_EQ(artists.results.size(), 2);
|
||||
EXPECT_EQ(artists.results[0], starredArtist2->getArtist()->getId());
|
||||
EXPECT_EQ(artists.results[1], starredArtist1->getArtist()->getId());
|
||||
}
|
||||
auto artists{ Artist::find(session, Artist::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal).setSortMethod(ArtistSortMethod::StarredDateDesc)) };
|
||||
ASSERT_EQ(artists.results.size(), 2);
|
||||
EXPECT_EQ(artists.results[0], starredArtist2->getArtist()->getId());
|
||||
EXPECT_EQ(artists.results[1], starredArtist1->getArtist()->getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,102 +26,100 @@ using ScopedStarredRelease = ScopedEntity<Database::StarredRelease>;
|
||||
|
||||
TEST_F(DatabaseFixture, StarredRelease)
|
||||
{
|
||||
ScopedRelease release {session, "MyRelease"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedUser user2 {session, "MyUser2"};
|
||||
ScopedRelease release{ session, "MyRelease" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
ScopedUser user2{ session, "MyUser2" };
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto starredRelease {StarredRelease::find(session, release->getId(), user->getId(), Scrobbler::Internal)};
|
||||
EXPECT_FALSE(starredRelease);
|
||||
EXPECT_EQ(StarredRelease::getCount(session), 0);
|
||||
auto starredRelease{ StarredRelease::find(session, release->getId(), user->getId(), FeedbackBackend::Internal) };
|
||||
EXPECT_FALSE(starredRelease);
|
||||
EXPECT_EQ(StarredRelease::getCount(session), 0);
|
||||
|
||||
auto releases {Release::find(session, Release::FindParameters {})};
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
}
|
||||
auto releases{ Release::find(session, Release::FindParameters {}) };
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
}
|
||||
|
||||
ScopedStarredRelease starredRelease {session, release.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
ScopedStarredRelease starredRelease{ session, release.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal };
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto gotRelease {StarredRelease::find(session, release->getId(), user->getId(), Scrobbler::Internal)};
|
||||
EXPECT_EQ(gotRelease->getId(), starredRelease->getId());
|
||||
EXPECT_EQ(StarredRelease::getCount(session), 1);
|
||||
}
|
||||
auto gotRelease{ StarredRelease::find(session, release->getId(), user->getId(), FeedbackBackend::Internal) };
|
||||
EXPECT_EQ(gotRelease->getId(), starredRelease->getId());
|
||||
EXPECT_EQ(StarredRelease::getCount(session), 1);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases {Release::find(session, Release::FindParameters {})};
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
auto releases{ Release::find(session, Release::FindParameters {}) };
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
|
||||
releases = Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal));
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
releases = Release::find(session, Release::FindParameters{}.setStarringUser(user.getId(), FeedbackBackend::Internal));
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
|
||||
releases = Release::find(session, Release::FindParameters {}.setStarringUser(user2.getId(), Scrobbler::Internal));
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
releases = Release::find(session, Release::FindParameters{}.setStarringUser(user2.getId(), FeedbackBackend::Internal));
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, Starredrelease_PendingDestroy)
|
||||
{
|
||||
ScopedRelease release {session, "MyRelease"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedStarredRelease starredRelease {session, release.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
ScopedRelease release{ session, "MyRelease" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
ScopedStarredRelease starredRelease{ session, release.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal };
|
||||
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
{
|
||||
auto transaction{ session.createUniqueTransaction() };
|
||||
|
||||
auto releases {Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal))};
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
auto releases{ Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal)) };
|
||||
EXPECT_EQ(releases.results.size(), 1);
|
||||
|
||||
starredRelease.get().modify()->setScrobblingState(ScrobblingState::PendingRemove);
|
||||
releases = Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal));
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
starredRelease.get().modify()->setSyncState(SyncState::PendingRemove);
|
||||
releases = Release::find(session, Release::FindParameters{}.setStarringUser(user.getId(), FeedbackBackend::Internal));
|
||||
EXPECT_EQ(releases.results.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, StarredRelease_dateTime)
|
||||
{
|
||||
ScopedRelease release1 {session, "MyRelease1"};
|
||||
ScopedRelease release2 {session, "MyRelease2"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedRelease release1{ session, "MyRelease1" };
|
||||
ScopedRelease release2{ session, "MyRelease2" };
|
||||
ScopedUser user{ session, "MyUser" };
|
||||
|
||||
ScopedStarredRelease starredRelease1 {session, release1.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
ScopedStarredRelease starredRelease2 {session, release2.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
ScopedStarredRelease starredRelease1{ session, release1.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal };
|
||||
ScopedStarredRelease starredRelease2{ session, release2.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal };
|
||||
|
||||
const Wt::WDateTime dateTime {Wt::WDate {1950, 1, 2}, Wt::WTime {12, 30, 1}};
|
||||
const Wt::WDateTime dateTime{ Wt::WDate {1950, 1, 2}, Wt::WTime {12, 30, 1} };
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
{
|
||||
auto transaction{ session.createSharedTransaction() };
|
||||
|
||||
auto releases {Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal))};
|
||||
EXPECT_EQ(releases.results.size(), 2);
|
||||
}
|
||||
auto releases{ Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal)) };
|
||||
EXPECT_EQ(releases.results.size(), 2);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
{
|
||||
auto transaction{ session.createUniqueTransaction() };
|
||||
|
||||
starredRelease1.get().modify()->setDateTime(dateTime);
|
||||
starredRelease2.get().modify()->setDateTime(dateTime.addSecs(-1));
|
||||
starredRelease1.get().modify()->setDateTime(dateTime);
|
||||
starredRelease2.get().modify()->setDateTime(dateTime.addSecs(-1));
|
||||
|
||||
auto releases {Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
|
||||
.setSortMethod(ReleaseSortMethod::StarredDateDesc))};
|
||||
ASSERT_EQ(releases.results.size(), 2);
|
||||
EXPECT_EQ(releases.results[0], starredRelease1->getRelease()->getId());
|
||||
EXPECT_EQ(releases.results[1], starredRelease2->getRelease()->getId());
|
||||
}
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
auto releases{ Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal).setSortMethod(ReleaseSortMethod::StarredDateDesc)) };
|
||||
ASSERT_EQ(releases.results.size(), 2);
|
||||
EXPECT_EQ(releases.results[0], starredRelease1->getRelease()->getId());
|
||||
EXPECT_EQ(releases.results[1], starredRelease2->getRelease()->getId());
|
||||
}
|
||||
{
|
||||
auto transaction{ session.createUniqueTransaction() };
|
||||
|
||||
starredRelease1.get().modify()->setDateTime(dateTime);
|
||||
starredRelease2.get().modify()->setDateTime(dateTime.addSecs(1));
|
||||
starredRelease1.get().modify()->setDateTime(dateTime);
|
||||
starredRelease2.get().modify()->setDateTime(dateTime.addSecs(1));
|
||||
|
||||
auto releases {Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
|
||||
.setSortMethod(ReleaseSortMethod::StarredDateDesc))};
|
||||
ASSERT_EQ(releases.results.size(), 2);
|
||||
EXPECT_EQ(releases.results[0], starredRelease2->getRelease()->getId());
|
||||
EXPECT_EQ(releases.results[1], starredRelease1->getRelease()->getId());
|
||||
}
|
||||
auto releases{ Release::find(session, Release::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal).setSortMethod(ReleaseSortMethod::StarredDateDesc)) };
|
||||
ASSERT_EQ(releases.results.size(), 2);
|
||||
EXPECT_EQ(releases.results[0], starredRelease2->getRelease()->getId());
|
||||
EXPECT_EQ(releases.results[1], starredRelease1->getRelease()->getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,102 +26,100 @@ using ScopedStarredTrack = ScopedEntity<Database::StarredTrack>;
|
||||
|
||||
TEST_F(DatabaseFixture, StarredTrack)
|
||||
{
|
||||
ScopedTrack track {session, "MyTrack"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedUser user2 {session, "MyUser2"};
|
||||
ScopedTrack track {session, "MyTrack"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedUser user2 {session, "MyUser2"};
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
|
||||
auto starredTrack {StarredTrack::find(session, track->getId(), user->getId(), Scrobbler::Internal)};
|
||||
EXPECT_FALSE(starredTrack);
|
||||
EXPECT_EQ(StarredTrack::getCount(session), 0);
|
||||
auto starredTrack {StarredTrack::find(session, track->getId(), user->getId(), FeedbackBackend::Internal)};
|
||||
EXPECT_FALSE(starredTrack);
|
||||
EXPECT_EQ(StarredTrack::getCount(session), 0);
|
||||
|
||||
auto tracks {Track::find(session, Track::FindParameters {})};
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
}
|
||||
auto tracks {Track::find(session, Track::FindParameters {})};
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
}
|
||||
|
||||
ScopedStarredTrack starredTrack {session, track.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
ScopedStarredTrack starredTrack {session, track.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal};
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
|
||||
auto gotTrack {StarredTrack::find(session, track->getId(), user->getId(), Scrobbler::Internal)};
|
||||
EXPECT_EQ(gotTrack->getId(), starredTrack->getId());
|
||||
EXPECT_EQ(StarredTrack::getCount(session), 1);
|
||||
}
|
||||
auto gotTrack {StarredTrack::find(session, track->getId(), user->getId(), FeedbackBackend::Internal)};
|
||||
EXPECT_EQ(gotTrack->getId(), starredTrack->getId());
|
||||
EXPECT_EQ(StarredTrack::getCount(session), 1);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
|
||||
auto tracks {Track::find(session, Track::FindParameters {})};
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
auto tracks {Track::find(session, Track::FindParameters {})};
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
|
||||
tracks = Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal));
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
tracks = Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal));
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
|
||||
tracks = Track::find(session, Track::FindParameters {}.setStarringUser(user2.getId(), Scrobbler::Internal));
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
tracks = Track::find(session, Track::FindParameters {}.setStarringUser(user2.getId(), FeedbackBackend::Internal));
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, Starredtrack_PendingDestroy)
|
||||
{
|
||||
ScopedTrack track {session, "MyTrack"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedStarredTrack starredTrack {session, track.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
ScopedTrack track {session, "MyTrack"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedStarredTrack starredTrack {session, track.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal};
|
||||
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
|
||||
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal))};
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal))};
|
||||
EXPECT_EQ(tracks.results.size(), 1);
|
||||
|
||||
starredTrack.get().modify()->setScrobblingState(ScrobblingState::PendingRemove);
|
||||
tracks = Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal));
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
starredTrack.get().modify()->setSyncState(SyncState::PendingRemove);
|
||||
tracks = Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal));
|
||||
EXPECT_EQ(tracks.results.size(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(DatabaseFixture, StarredTrack_dateTime)
|
||||
{
|
||||
ScopedTrack track1 {session, "MyTrack1"};
|
||||
ScopedTrack track2 {session, "MyTrack2"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
ScopedTrack track1 {session, "MyTrack1"};
|
||||
ScopedTrack track2 {session, "MyTrack2"};
|
||||
ScopedUser user {session, "MyUser"};
|
||||
|
||||
ScopedStarredTrack starredTrack1 {session, track1.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
ScopedStarredTrack starredTrack2 {session, track2.lockAndGet(), user.lockAndGet(), Scrobbler::Internal};
|
||||
ScopedStarredTrack starredTrack1 {session, track1.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal};
|
||||
ScopedStarredTrack starredTrack2 {session, track2.lockAndGet(), user.lockAndGet(), FeedbackBackend::Internal};
|
||||
|
||||
const Wt::WDateTime dateTime {Wt::WDate {1950, 1, 2}, Wt::WTime {12, 30, 1}};
|
||||
const Wt::WDateTime dateTime {Wt::WDate {1950, 1, 2}, Wt::WTime {12, 30, 1}};
|
||||
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
{
|
||||
auto transaction {session.createSharedTransaction()};
|
||||
|
||||
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal))};
|
||||
EXPECT_EQ(tracks.results.size(), 2);
|
||||
}
|
||||
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal))};
|
||||
EXPECT_EQ(tracks.results.size(), 2);
|
||||
}
|
||||
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
|
||||
starredTrack1.get().modify()->setDateTime(dateTime);
|
||||
starredTrack2.get().modify()->setDateTime(dateTime.addSecs(-1));
|
||||
starredTrack1.get().modify()->setDateTime(dateTime);
|
||||
starredTrack2.get().modify()->setDateTime(dateTime.addSecs(-1));
|
||||
|
||||
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
|
||||
.setSortMethod(TrackSortMethod::StarredDateDesc))};
|
||||
ASSERT_EQ(tracks.results.size(), 2);
|
||||
EXPECT_EQ(tracks.results[0], starredTrack1->getTrack()->getId());
|
||||
EXPECT_EQ(tracks.results[1], starredTrack2->getTrack()->getId());
|
||||
}
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal).setSortMethod(TrackSortMethod::StarredDateDesc))};
|
||||
ASSERT_EQ(tracks.results.size(), 2);
|
||||
EXPECT_EQ(tracks.results[0], starredTrack1->getTrack()->getId());
|
||||
EXPECT_EQ(tracks.results[1], starredTrack2->getTrack()->getId());
|
||||
}
|
||||
{
|
||||
auto transaction {session.createUniqueTransaction()};
|
||||
|
||||
starredTrack1.get().modify()->setDateTime(dateTime);
|
||||
starredTrack2.get().modify()->setDateTime(dateTime.addSecs(1));
|
||||
starredTrack1.get().modify()->setDateTime(dateTime);
|
||||
starredTrack2.get().modify()->setDateTime(dateTime.addSecs(1));
|
||||
|
||||
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), Scrobbler::Internal)
|
||||
.setSortMethod(TrackSortMethod::StarredDateDesc))};
|
||||
ASSERT_EQ(tracks.results.size(), 2);
|
||||
EXPECT_EQ(tracks.results[0], starredTrack2->getTrack()->getId());
|
||||
EXPECT_EQ(tracks.results[1], starredTrack1->getTrack()->getId());
|
||||
}
|
||||
auto tracks {Track::find(session, Track::FindParameters {}.setStarringUser(user.getId(), FeedbackBackend::Internal).setSortMethod(TrackSortMethod::StarredDateDesc))};
|
||||
ASSERT_EQ(tracks.results.size(), 2);
|
||||
EXPECT_EQ(tracks.results[0], starredTrack2->getTrack()->getId());
|
||||
EXPECT_EQ(tracks.results[1], starredTrack1->getTrack()->getId());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user