Dedicated view for tracklist
This commit is contained in:
@@ -40,6 +40,12 @@ _MBID {MBID ? MBID->getAsString() : ""}
|
||||
{
|
||||
}
|
||||
|
||||
Artist::pointer
|
||||
Artist::create(Session& session, const std::string& name, const std::optional<UUID>& MBID)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<Artist> {new Artist {name, MBID}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
Artist::getCount(Session& session)
|
||||
{
|
||||
@@ -81,17 +87,6 @@ Artist::exists(Session& session, ArtistId id)
|
||||
return session.getDboSession().query<int>("SELECT 1 FROM artist").where("id = ?").bind(id).resultValue() == 1;
|
||||
}
|
||||
|
||||
Artist::pointer
|
||||
Artist::create(Session& session, const std::string& name, const std::optional<UUID>& MBID)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
Artist::pointer res {session.getDboSession().add(std::make_unique<Artist>(name, MBID))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static
|
||||
Wt::Dbo::Query<ArtistId>
|
||||
createQuery(Session& session, const Artist::FindParameters& params)
|
||||
@@ -119,13 +114,13 @@ createQuery(Session& session, const Artist::FindParameters& params)
|
||||
for (std::string_view keyword : params.keywords)
|
||||
{
|
||||
clauses.push_back("a.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
||||
query.bind("%" + escapeLikeKeyword(keyword) + "%");
|
||||
query.bind("%" + Utils::escapeLikeKeyword(keyword) + "%");
|
||||
}
|
||||
|
||||
for (std::string_view keyword : params.keywords)
|
||||
{
|
||||
sortClauses.push_back("a.sort_name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'");
|
||||
query.bind("%" + escapeLikeKeyword(keyword) + "%");
|
||||
query.bind("%" + Utils::escapeLikeKeyword(keyword) + "%");
|
||||
}
|
||||
|
||||
query.where("(" + StringUtils::joinStrings(clauses, " AND ") + ") OR (" + StringUtils::joinStrings(sortClauses, " AND ") + ")");
|
||||
@@ -193,7 +188,7 @@ Artist::findAllOrphans(Session& session, Range range)
|
||||
session.checkSharedLocked();
|
||||
auto query {session.getDboSession().query<ArtistId>("SELECT DISTINCT a.id FROM artist a WHERE NOT EXISTS(SELECT 1 FROM track t INNER JOIN track_artist_link t_a_l ON t_a_l.artist_id = a.id WHERE t.id = t_a_l.track_id)")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ArtistId>
|
||||
@@ -202,7 +197,7 @@ Artist::find(Session& session, const FindParameters& params)
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto query {createQuery(session, params)};
|
||||
return execQuery(query, params.range);
|
||||
return Utils::execQuery(query, params.range);
|
||||
}
|
||||
|
||||
RangeResults<ArtistId>
|
||||
@@ -246,10 +241,11 @@ Artist::findSimilarArtists(EnumSet<TrackArtistLinkType> artistLinkTypes, Range r
|
||||
.bind(getId())
|
||||
.groupBy("a.id")
|
||||
.orderBy("COUNT(*) DESC, RANDOM()")};
|
||||
|
||||
for (TrackArtistLinkType type : artistLinkTypes)
|
||||
query.bind(type);
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
std::vector<std::vector<Cluster::pointer>>
|
||||
|
||||
@@ -38,12 +38,7 @@ namespace Database
|
||||
AuthToken::pointer
|
||||
AuthToken::create(Session& session, std::string_view value, const Wt::WDateTime& expiry, ObjectPtr<User> user)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
AuthToken::pointer res {session.getDboSession().add(std::make_unique<AuthToken>(value, expiry, user))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
return session.getDboSession().add(std::unique_ptr<AuthToken> {new AuthToken {value, expiry, user}});
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -36,6 +36,12 @@ Cluster::Cluster(ObjectPtr<ClusterType> type, std::string_view name)
|
||||
{
|
||||
}
|
||||
|
||||
Cluster::pointer
|
||||
Cluster::create(Session& session, ObjectPtr<ClusterType> type, std::string_view name)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<Cluster> {new Cluster {type, name}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
Cluster::getCount(Session& session)
|
||||
{
|
||||
@@ -44,24 +50,13 @@ Cluster::getCount(Session& session)
|
||||
return session.getDboSession().query<int>("SELECT COUNT(*) FROM cluster");
|
||||
}
|
||||
|
||||
Cluster::pointer
|
||||
Cluster::create(Session& session, ObjectPtr<ClusterType> type, std::string_view name)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
Cluster::pointer res {session.getDboSession().add(std::make_unique<Cluster>(type, name))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
RangeResults<ClusterId>
|
||||
Cluster::find(Session& session, Range range)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
auto query {session.getDboSession().query<ClusterId>("SELECT id FROM cluster")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ClusterId>
|
||||
@@ -70,7 +65,7 @@ Cluster::findOrphans(Session& session, Range range)
|
||||
session.checkSharedLocked();
|
||||
auto query {session.getDboSession().query<ClusterId>("SELECT DISTINCT c.id FROM cluster c WHERE NOT EXISTS(SELECT 1 FROM track_cluster t_c WHERE t_c.cluster_id = c.id)")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
Cluster::pointer
|
||||
@@ -95,7 +90,7 @@ Cluster::getTracks(Range range) const
|
||||
auto query {session()->query<TrackId>("SELECT t.id FROM track t INNER JOIN cluster c ON c.id = t_c.cluster_id INNER JOIN track_cluster t_c ON t_c.track_id = t.id")
|
||||
.where("c.id = ?").bind(getId())};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
@@ -113,6 +108,12 @@ ClusterType::ClusterType(std::string_view name)
|
||||
{
|
||||
}
|
||||
|
||||
ClusterType::pointer
|
||||
ClusterType::create(Session& session, const std::string& name)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<ClusterType> {new ClusterType {name}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
ClusterType::getCount(Session& session)
|
||||
{
|
||||
@@ -132,7 +133,7 @@ ClusterType::findOrphans(Session& session, Range range)
|
||||
" LEFT OUTER JOIN cluster c ON c_t.id = c.cluster_type_id")
|
||||
.where("c.id IS NULL")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ClusterTypeId>
|
||||
@@ -144,7 +145,7 @@ ClusterType::findUsed(Session& session, Range range)
|
||||
"SELECT DISTINCT c_t.id from cluster_type c_t")
|
||||
.join("cluster c ON c_t.id = c.cluster_type_id")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
ClusterType::pointer
|
||||
@@ -170,18 +171,7 @@ ClusterType::find(Session& session, Range range)
|
||||
|
||||
auto query {session.getDboSession().query<ClusterTypeId>("SELECT id from cluster_type")};
|
||||
|
||||
return execQuery(query, range);
|
||||
}
|
||||
|
||||
ClusterType::pointer
|
||||
ClusterType::create(Session& session, const std::string& name)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
ClusterType::pointer res {session.getDboSession().add(std::make_unique<ClusterType>(name))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
Cluster::pointer
|
||||
|
||||
@@ -141,6 +141,12 @@ namespace Database
|
||||
, _track {getDboPtr(track)}
|
||||
{}
|
||||
|
||||
Listen::pointer
|
||||
Listen::create(Session& session, ObjectPtr<User> user, ObjectPtr<Track> track, Scrobbler scrobbler, const Wt::WDateTime& dateTime)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<Listen> {new Listen {user, track, scrobbler, dateTime}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
Listen::getCount(Session& session)
|
||||
{
|
||||
@@ -172,7 +178,7 @@ namespace Database
|
||||
if (parameters.scrobblingState)
|
||||
query.where("scrobbling_state = ?").bind(*parameters.scrobblingState);
|
||||
|
||||
return execQuery(query, parameters.range);
|
||||
return Utils::execQuery(query, parameters.range);
|
||||
}
|
||||
|
||||
Listen::pointer
|
||||
@@ -188,17 +194,6 @@ namespace Database
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
Listen::pointer
|
||||
Listen::create(Session& session, ObjectPtr<User> user, ObjectPtr<Track> track, Scrobbler scrobbler, const Wt::WDateTime& dateTime)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
Listen::pointer res {session.getDboSession().add(std::make_unique<Listen>(user, track, scrobbler, dateTime))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
RangeResults<ArtistId>
|
||||
Listen::getTopArtists(Session& session,
|
||||
UserId userId,
|
||||
@@ -213,7 +208,7 @@ namespace Database
|
||||
.orderBy("COUNT(a.id) DESC")
|
||||
.groupBy("a.id")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ReleaseId>
|
||||
@@ -227,7 +222,7 @@ namespace Database
|
||||
.orderBy("COUNT(r.id) DESC")
|
||||
.groupBy("r.id")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<TrackId>
|
||||
@@ -241,7 +236,7 @@ namespace Database
|
||||
.orderBy("COUNT(t.id) DESC")
|
||||
.groupBy("t.id")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ArtistId>
|
||||
@@ -256,7 +251,7 @@ namespace Database
|
||||
.groupBy("a.id").having("l.date_time = MAX(l.date_time)")
|
||||
.orderBy("l.date_time DESC")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ReleaseId>
|
||||
@@ -270,7 +265,7 @@ namespace Database
|
||||
.groupBy("r.id").having("l.date_time = MAX(l.date_time)")
|
||||
.orderBy("l.date_time DESC")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<TrackId>
|
||||
@@ -284,7 +279,7 @@ namespace Database
|
||||
.groupBy("t.id").having("l.date_time = MAX(l.date_time)")
|
||||
.orderBy("l.date_time DESC")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -576,12 +576,21 @@ CREATE TABLE IF NOT EXISTS "track_artist_link_backup" (
|
||||
migrateFromV34(Session& session)
|
||||
{
|
||||
// Add scrobbling state
|
||||
// By default, everythin needs to be sent
|
||||
// By default, everything needs to be sent
|
||||
session.getDboSession().execute("ALTER TABLE starred_artist ADD scrobbling_state INTEGER NOT NULL DEFAULT(" + std::to_string(static_cast<int>(/*ScrobblingState::PendingAdd*/0)) + ")");
|
||||
session.getDboSession().execute("ALTER TABLE starred_release ADD scrobbling_state INTEGER NOT NULL DEFAULT(" + std::to_string(static_cast<int>(/*ScrobblingState::PendingAdd*/0)) + ")");
|
||||
session.getDboSession().execute("ALTER TABLE starred_track ADD scrobbling_state INTEGER NOT NULL DEFAULT(" + std::to_string(static_cast<int>(/*ScrobblingState::PendingAdd*/0)) + ")");
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
migrateFromV35(Session& session)
|
||||
{
|
||||
// Add creattion/last modif date time for tracklists
|
||||
session.getDboSession().execute("ALTER TABLE tracklist ADD creation_date_time TEXT");
|
||||
session.getDboSession().execute("ALTER TABLE tracklist ADD last_modified_date_time TEXT");
|
||||
}
|
||||
|
||||
void
|
||||
doDbMigration(Session& session)
|
||||
{
|
||||
@@ -623,6 +632,7 @@ CREATE TABLE IF NOT EXISTS "track_artist_link_backup" (
|
||||
{32, migrateFromV32},
|
||||
{33, migrateFromV33},
|
||||
{34, migrateFromV34},
|
||||
{35, migrateFromV35},
|
||||
};
|
||||
|
||||
while (1)
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Database
|
||||
class Session;
|
||||
|
||||
using Version = std::size_t;
|
||||
static constexpr Version LMS_DATABASE_VERSION {35};
|
||||
static constexpr Version LMS_DATABASE_VERSION {36};
|
||||
class VersionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -57,7 +57,7 @@ createQuery(Session& session, const Release::FindParameters& params)
|
||||
}
|
||||
|
||||
for (std::string_view keyword : params.keywords)
|
||||
query.where("r.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + escapeLikeKeyword(keyword) + "%");
|
||||
query.where("r.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + Utils::escapeLikeKeyword(keyword) + "%");
|
||||
|
||||
if (params.starringUser.isValid())
|
||||
{
|
||||
@@ -172,6 +172,12 @@ _MBID {MBID ? MBID->getAsString() : ""}
|
||||
{
|
||||
}
|
||||
|
||||
Release::pointer
|
||||
Release::create(Session& session, const std::string& name, const std::optional<UUID>& MBID)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<Release> {new Release {name, MBID}});
|
||||
}
|
||||
|
||||
std::vector<Release::pointer>
|
||||
Release::find(Session& session, const std::string& name)
|
||||
{
|
||||
@@ -214,17 +220,6 @@ Release::exists(Session& session, ReleaseId id)
|
||||
return session.getDboSession().query<int>("SELECT 1 FROM release").where("id = ?").bind(id).resultValue() == 1;
|
||||
}
|
||||
|
||||
Release::pointer
|
||||
Release::create(Session& session, const std::string& name, const std::optional<UUID>& MBID)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
Release::pointer res {session.getDboSession().add(std::make_unique<Release>(name, MBID))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::size_t
|
||||
Release::getCount(Session& session)
|
||||
{
|
||||
@@ -238,7 +233,7 @@ Release::findOrderedByArtist(Session& session, Range range)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
// TODO merge with execQuery
|
||||
// TODO merge with find
|
||||
auto query {session.getDboSession().query<ReleaseId>(
|
||||
"SELECT DISTINCT r.id FROM release r"
|
||||
" INNER JOIN track t ON r.id = t.release_id"
|
||||
@@ -246,7 +241,7 @@ Release::findOrderedByArtist(Session& session, Range range)
|
||||
" INNER JOIN artist a ON t_a_l.artist_id = a.id")
|
||||
.orderBy("a.name COLLATE NOCASE, r.name COLLATE NOCASE")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ReleaseId>
|
||||
@@ -255,7 +250,7 @@ Release::findOrphans(Session& session, Range range)
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto query {session.getDboSession().query<ReleaseId>("select r.id from release r LEFT OUTER JOIN Track t ON r.id = t.release_id WHERE t.id IS NULL")};
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<ReleaseId>
|
||||
@@ -265,7 +260,7 @@ Release::find(Session& session, const FindParameters& params)
|
||||
|
||||
auto query {createQuery(session, params)};
|
||||
|
||||
return execQuery(query, params.range);
|
||||
return Utils::execQuery(query, params.range);
|
||||
}
|
||||
|
||||
std::optional<std::size_t>
|
||||
|
||||
@@ -120,7 +120,7 @@ ScanSettings::setClusterTypes(Session& session, const std::set<std::string>& clu
|
||||
if (!clusterType)
|
||||
{
|
||||
LMS_LOG(DB, INFO) << "Creating cluster type " << clusterTypeName;
|
||||
clusterType = ClusterType::create(session, clusterTypeName);
|
||||
clusterType = session.create<ClusterType>(clusterTypeName);
|
||||
_clusterTypes.insert(getDboPtr(clusterType));
|
||||
|
||||
needRescan = true;
|
||||
|
||||
@@ -36,6 +36,12 @@ namespace Database
|
||||
{
|
||||
}
|
||||
|
||||
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}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
StarredArtist::getCount(Session& session)
|
||||
{
|
||||
@@ -61,20 +67,9 @@ namespace Database
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
StarredArtist::pointer
|
||||
StarredArtist::create(Session& session, ObjectPtr<Artist> artist, ObjectPtr<User> user, Scrobbler scrobbler)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
StarredArtist::pointer res {session.getDboSession().add(std::make_unique<StarredArtist>(artist, user, scrobbler))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
StarredArtist::setDateTime(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
_dateTime = normalizeDateTime(dateTime);
|
||||
_dateTime = Utils::normalizeDateTime(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,12 @@ namespace Database
|
||||
{
|
||||
}
|
||||
|
||||
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}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
StarredRelease::getCount(Session& session)
|
||||
{
|
||||
@@ -61,20 +67,9 @@ namespace Database
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
StarredRelease::pointer
|
||||
StarredRelease::create(Session& session, ObjectPtr<Release> release, ObjectPtr<User> user, Scrobbler scrobbler)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
StarredRelease::pointer res {session.getDboSession().add(std::make_unique<StarredRelease>(release, user, scrobbler))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
StarredRelease::setDateTime(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
_dateTime = normalizeDateTime(dateTime);
|
||||
_dateTime = Utils::normalizeDateTime(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,12 @@ namespace Database
|
||||
{
|
||||
}
|
||||
|
||||
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}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
StarredTrack::getCount(Session& session)
|
||||
{
|
||||
@@ -75,23 +81,12 @@ namespace Database
|
||||
if (params.user.isValid())
|
||||
query.where("s_t.user_id = ?").bind(params.user);
|
||||
|
||||
return execQuery(query, params.range);
|
||||
}
|
||||
|
||||
StarredTrack::pointer
|
||||
StarredTrack::create(Session& session, ObjectPtr<Track> track, ObjectPtr<User> user, Scrobbler scrobbler)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
StarredTrack::pointer res {session.getDboSession().add(std::make_unique<StarredTrack>(track, user, scrobbler))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
return Utils::execQuery(query, params.range);
|
||||
}
|
||||
|
||||
void
|
||||
StarredTrack::setDateTime(const Wt::WDateTime& dateTime)
|
||||
{
|
||||
_dateTime = normalizeDateTime(dateTime);
|
||||
_dateTime = Utils::normalizeDateTime(dateTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ createQuery(Session& session, const Track::FindParameters& params)
|
||||
auto query {session.getDboSession().query<TrackId>("SELECT DISTINCT t.id from track t")};
|
||||
|
||||
for (std::string_view keyword : params.keywords)
|
||||
query.where("t.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + escapeLikeKeyword(keyword) + "%");
|
||||
query.where("t.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + Utils::escapeLikeKeyword(keyword) + "%");
|
||||
|
||||
if (params.writtenAfter.isValid())
|
||||
query.where("t.file_last_write > ?").bind(params.writtenAfter);
|
||||
@@ -156,12 +156,7 @@ Track::Track(const std::filesystem::path& p)
|
||||
Track::pointer
|
||||
Track::create(Session& session, const std::filesystem::path& p)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
Track::pointer res {session.getDboSession().add(std::make_unique<Track>(p))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
return session.getDboSession().add(std::unique_ptr<Track> {new Track {p}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
@@ -219,7 +214,7 @@ Track::findPaths(Session& session, Range range)
|
||||
// TODO Dbo traits on filesystem
|
||||
auto query {session.getDboSession().query<QueryResultType>("SELECT id, file_path FROM track")};
|
||||
|
||||
RangeResults<QueryResultType> queryResults {execQuery(query, range)};
|
||||
RangeResults<QueryResultType> queryResults {Utils::execQuery(query, range)};
|
||||
|
||||
RangeResults<PathResult> res;
|
||||
res.range = queryResults.range;
|
||||
@@ -243,7 +238,7 @@ Track::findRecordingMBIDDuplicates(Session& session, Range range)
|
||||
auto query {session.getDboSession().query<TrackId>( "SELECT track.id FROM track WHERE recording_mbid in (SELECT recording_mbid FROM track WHERE recording_mbid <> '' GROUP BY recording_mbid HAVING COUNT (*) > 1)")
|
||||
.orderBy("track.release_id,track.disc_number,track.track_number,track.recording_mbid")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
RangeResults<TrackId>
|
||||
@@ -255,7 +250,7 @@ Track::findWithRecordingMBIDAndMissingFeatures(Session& session, Range range)
|
||||
.where("LENGTH(t.recording_mbid) > 0")
|
||||
.where("NOT EXISTS (SELECT * FROM track_features t_f WHERE t_f.track_id = t.id)")};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
std::vector<Cluster::pointer>
|
||||
@@ -284,7 +279,7 @@ Track::find(Session& session, const FindParameters& parameters)
|
||||
|
||||
auto query {createQuery(session, parameters)};
|
||||
|
||||
return execQuery(query, parameters.range);
|
||||
return Utils::execQuery(query, parameters.range);
|
||||
}
|
||||
|
||||
RangeResults<TrackId>
|
||||
@@ -297,7 +292,7 @@ Track::findByNameAndReleaseName(Session& session, std::string_view trackName, st
|
||||
.where("t.name = ?").bind(trackName)
|
||||
.where("r.name = ?").bind(releaseName)};
|
||||
|
||||
return execQuery(query, Range {});
|
||||
return Utils::execQuery(query, Range {});
|
||||
}
|
||||
|
||||
RangeResults<TrackId>
|
||||
@@ -328,7 +323,7 @@ Track::findSimilarTracks(Session& session, const std::vector<TrackId>& tracks, R
|
||||
for (TrackId trackId : tracks)
|
||||
query.bind(trackId);
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -33,6 +33,12 @@ _track {getDboPtr(track)}
|
||||
{
|
||||
}
|
||||
|
||||
TrackBookmark::pointer
|
||||
TrackBookmark::create(Session& session, ObjectPtr<User> user, ObjectPtr<Track> track)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<TrackBookmark> {new TrackBookmark {user, track}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
TrackBookmark::getCount(Session& session)
|
||||
{
|
||||
@@ -41,18 +47,6 @@ TrackBookmark::getCount(Session& session)
|
||||
return session.getDboSession().query<int>("SELECT COUNT(*) FROM track_bookmark");
|
||||
}
|
||||
|
||||
|
||||
TrackBookmark::pointer
|
||||
TrackBookmark::create(Session& session, ObjectPtr<User> user, ObjectPtr<Track> track)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
TrackBookmark::pointer res {session.getDboSession().add(std::make_unique<TrackBookmark>(user, track))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
RangeResults<TrackBookmarkId>
|
||||
TrackBookmark::find(Session& session, UserId userId, Range range)
|
||||
{
|
||||
@@ -61,7 +55,7 @@ TrackBookmark::find(Session& session, UserId userId, Range range)
|
||||
auto query {session.getDboSession().query<TrackBookmarkId>("SELECT id from track_bookmark")
|
||||
.where("user_id = ?").bind(userId)};
|
||||
|
||||
return execQuery(query, range);
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
TrackBookmark::pointer
|
||||
|
||||
@@ -36,6 +36,12 @@ _track {getDboPtr(track)}
|
||||
{
|
||||
}
|
||||
|
||||
TrackFeatures::pointer
|
||||
TrackFeatures::create(Session& session, ObjectPtr<Track> track, const std::string& jsonEncodedFeatures)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<TrackFeatures> {new TrackFeatures {track, jsonEncodedFeatures}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
TrackFeatures::getCount(Session& session)
|
||||
{
|
||||
@@ -71,18 +77,7 @@ TrackFeatures::find(Session& session, Range range)
|
||||
|
||||
auto query {session.getDboSession().query<TrackFeaturesId>("SELECT id from track_features")};
|
||||
|
||||
return execQuery(query, range);
|
||||
}
|
||||
|
||||
TrackFeatures::pointer
|
||||
TrackFeatures::create(Session& session, ObjectPtr<Track> track, const std::string& jsonEncodedFeatures)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
TrackFeatures::pointer res {session.getDboSession().add(std::make_unique<TrackFeatures>(track, jsonEncodedFeatures))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
return Utils::execQuery(query, range);
|
||||
}
|
||||
|
||||
FeatureValues
|
||||
|
||||
@@ -36,23 +36,20 @@
|
||||
namespace Database {
|
||||
|
||||
TrackList::TrackList(std::string_view name, TrackListType type, bool isPublic, ObjectPtr<User> user)
|
||||
: _name {name},
|
||||
_type {type},
|
||||
_isPublic {isPublic},
|
||||
_user {getDboPtr(user)}
|
||||
: _name {name}
|
||||
, _type {type}
|
||||
, _isPublic {isPublic}
|
||||
, _creationDateTime {Wt::WDateTime::currentDateTime()}
|
||||
, _lastModifiedDateTime {Wt::WDateTime::currentDateTime()}
|
||||
, _user {getDboPtr(user)}
|
||||
{
|
||||
assert(user);
|
||||
}
|
||||
|
||||
TrackList::pointer
|
||||
TrackList::create(Session& session, std::string_view name, TrackListType type, bool isPublic, ObjectPtr<User> user)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
assert(user);
|
||||
|
||||
TrackList::pointer res {session.getDboSession().add( std::make_unique<TrackList>(name, type, isPublic, user) )};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return res;
|
||||
return session.getDboSession().add(std::unique_ptr<TrackList> {new TrackList {name, type, isPublic, user}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
@@ -112,9 +109,19 @@ TrackList::find(Session& session, const FindParameters& params)
|
||||
query.where(oss.str());
|
||||
}
|
||||
|
||||
query.orderBy("t_l.name COLLATE NOCASE");
|
||||
switch (params.sortMethod)
|
||||
{
|
||||
case TrackListSortMethod::None:
|
||||
break;
|
||||
case TrackListSortMethod::Name:
|
||||
query.orderBy("t_l.name COLLATE NOCASE");
|
||||
break;
|
||||
case TrackListSortMethod::LastModifiedDesc:
|
||||
query.orderBy("t_l.last_modified_date_time DESC");
|
||||
break;
|
||||
}
|
||||
|
||||
return execQuery(query, params.range);
|
||||
return Utils::execQuery(query, params.range);
|
||||
}
|
||||
|
||||
TrackList::pointer
|
||||
@@ -173,7 +180,7 @@ TrackList::getEntryByTrackAndDateTime(ObjectPtr<Track> track, const Wt::WDateTim
|
||||
return session()->find<TrackListEntry>()
|
||||
.where("tracklist_id = ?").bind(getId())
|
||||
.where("track_id = ?").bind(track->getId())
|
||||
.where("date_time = ?").bind(normalizeDateTime(dateTime))
|
||||
.where("date_time = ?").bind(Utils::normalizeDateTime(dateTime))
|
||||
.resultValue();
|
||||
}
|
||||
|
||||
@@ -596,23 +603,30 @@ TrackList::getTopTracks(const std::vector<ClusterId>& clusterIds, std::optional<
|
||||
}
|
||||
|
||||
TrackListEntry::TrackListEntry(ObjectPtr<Track> track, ObjectPtr<TrackList> tracklist, const Wt::WDateTime& dateTime)
|
||||
: _dateTime {normalizeDateTime(dateTime)}
|
||||
: _dateTime {Utils::normalizeDateTime(dateTime)}
|
||||
, _track {getDboPtr(track)}
|
||||
, _tracklist {getDboPtr(tracklist)}
|
||||
{
|
||||
assert(track);
|
||||
assert(tracklist);
|
||||
}
|
||||
|
||||
TrackListEntry::pointer
|
||||
TrackListEntry::create(Session& session, ObjectPtr<Track> track, ObjectPtr<TrackList> tracklist, const Wt::WDateTime& dateTime)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
assert(track);
|
||||
assert(tracklist);
|
||||
return session.getDboSession().add(std::unique_ptr<TrackListEntry>( new TrackListEntry {track, tracklist, dateTime}));
|
||||
}
|
||||
|
||||
auto res = session.getDboSession().add(std::make_unique<TrackListEntry>( track, tracklist, dateTime));
|
||||
session.getDboSession().flush();
|
||||
void
|
||||
TrackListEntry::onPostCreated()
|
||||
{
|
||||
_tracklist.modify()->setLastModifiedDateTime(Wt::WDateTime::currentDateTime());
|
||||
}
|
||||
|
||||
return res;
|
||||
void
|
||||
TrackListEntry::onPreRemove()
|
||||
{
|
||||
_tracklist.modify()->setLastModifiedDateTime(Wt::WDateTime::currentDateTime());
|
||||
}
|
||||
|
||||
TrackListEntry::pointer
|
||||
|
||||
@@ -35,6 +35,12 @@ User::User(std::string_view loginName)
|
||||
{
|
||||
}
|
||||
|
||||
User::pointer
|
||||
User::create(Session& session, std::string_view loginName)
|
||||
{
|
||||
return session.getDboSession().add(std::unique_ptr<User> {new User {loginName}});
|
||||
}
|
||||
|
||||
std::size_t
|
||||
User::getCount(Session& session)
|
||||
{
|
||||
@@ -53,7 +59,7 @@ User::find(Session& session, const FindParameters& params)
|
||||
if (params.scrobbler)
|
||||
query.where("scrobbler = ?").bind(*params.scrobbler);
|
||||
|
||||
return execQuery(query, params.range);
|
||||
return Utils::execQuery(query, params.range);
|
||||
}
|
||||
|
||||
User::pointer
|
||||
@@ -64,17 +70,6 @@ User::findDemoUser(Session& session)
|
||||
return session.getDboSession().find<User>().where("type = ?").bind(UserType::DEMO).resultValue();
|
||||
}
|
||||
|
||||
User::pointer
|
||||
User::create(Session& session, std::string_view loginName)
|
||||
{
|
||||
session.checkUniqueLocked();
|
||||
|
||||
User::pointer user {session.getDboSession().add(std::make_unique<User>(loginName))};
|
||||
session.getDboSession().flush();
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
User::pointer
|
||||
User::find(Session& session, UserId id)
|
||||
{
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "utils/String.hpp"
|
||||
|
||||
namespace Database
|
||||
namespace Database::Utils
|
||||
{
|
||||
std::string
|
||||
escapeLikeKeyword(std::string_view keyword)
|
||||
@@ -35,6 +35,5 @@ namespace Database
|
||||
// force second resolution
|
||||
return Wt::WDateTime::fromTime_t(dateTime.toTime_t());
|
||||
}
|
||||
|
||||
} // namespace Database
|
||||
} // namespace Database::Utils
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "services/database/Types.hpp"
|
||||
|
||||
namespace Database
|
||||
namespace Database::Utils
|
||||
{
|
||||
#define ESCAPE_CHAR_STR "\\"
|
||||
static inline constexpr char escapeChar {'\\'};
|
||||
@@ -82,5 +82,5 @@ namespace Database
|
||||
}
|
||||
|
||||
Wt::WDateTime normalizeDateTime(const Wt::WDateTime& dateTime);
|
||||
} // namespace Database
|
||||
} // namespace Database::Utils
|
||||
|
||||
|
||||
Reference in New Issue
Block a user