Tried to factorize some db code
This commit is contained in:
@@ -204,114 +204,6 @@ Artist::find(Session& session, const FindParameters& params)
|
||||
return execQuery(query, params.range);
|
||||
}
|
||||
|
||||
RangeResults<ReleaseId>
|
||||
Artist::getReleases(Range range, const std::vector<ClusterId>& clusterIds) const
|
||||
{
|
||||
assert(session());
|
||||
|
||||
WhereClause where;
|
||||
|
||||
std::ostringstream oss;
|
||||
|
||||
oss << "SELECT DISTINCT r.id FROM release r INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id INNER JOIN track t ON t.release_id = r.id";
|
||||
|
||||
if (!clusterIds.empty())
|
||||
{
|
||||
oss << " INNER JOIN cluster c ON c.id = t_c.cluster_id INNER JOIN track_cluster t_c ON t_c.track_id = t.id";
|
||||
|
||||
WhereClause clusterClause;
|
||||
|
||||
for (auto id : clusterIds)
|
||||
clusterClause.Or(WhereClause("c.id = ?")).bind(id.toString());
|
||||
|
||||
where.And(clusterClause);
|
||||
}
|
||||
|
||||
where.And(WhereClause("a.id = ?")).bind(getId().toString());
|
||||
|
||||
oss << " " << where.get();
|
||||
|
||||
if (!clusterIds.empty())
|
||||
oss << " GROUP BY t.id HAVING COUNT(DISTINCT c.id) = " << clusterIds.size();
|
||||
|
||||
oss << " ORDER BY t.date DESC, r.name COLLATE NOCASE";
|
||||
|
||||
auto query {session()->query<ReleaseId>(oss.str())};
|
||||
|
||||
for (const std::string& bindArg : where.getBindArgs())
|
||||
query.bind(bindArg);
|
||||
|
||||
return execQuery(query, range);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
Artist::getReleaseCount() const
|
||||
{
|
||||
assert(session());
|
||||
|
||||
int res = session()->query<int>("SELECT COUNT(DISTINCT r.id) FROM release r INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id INNER JOIN track t ON t.release_id = r.id")
|
||||
.where("a.id = ?").bind(getId());
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<Track::pointer>
|
||||
Artist::getTracks(std::optional<TrackArtistLinkType> linkType) const
|
||||
{
|
||||
assert(session());
|
||||
|
||||
auto query {session()->query<Wt::Dbo::ptr<Track>>("SELECT DISTINCT t FROM track t INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id")
|
||||
.where("a.id = ?").bind(getId())
|
||||
.orderBy("t.date DESC,t.release_id,t.disc_number,t.track_number")};
|
||||
|
||||
if (linkType)
|
||||
query.where("t_a_l.type = ?").bind(*linkType);
|
||||
|
||||
auto tracks {query.resultList()};
|
||||
return std::vector<Track::pointer>(tracks.begin(), tracks.end());
|
||||
}
|
||||
|
||||
RangeResults<Track::pointer>
|
||||
Artist::getNonReleaseTracks(std::optional<TrackArtistLinkType> linkType, Range range) const
|
||||
{
|
||||
assert(session());
|
||||
|
||||
auto query {session()->query<Wt::Dbo::ptr<Track>>("SELECT t FROM track t INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id")
|
||||
.where("a.id = ?").bind(getId())
|
||||
.where("t.release_id is NULL")
|
||||
.orderBy("t.name")};
|
||||
if (linkType)
|
||||
query.where("t_a_l.type = ?").bind(*linkType);
|
||||
|
||||
return execQuery(query, range);
|
||||
}
|
||||
|
||||
bool
|
||||
Artist::hasNonReleaseTracks(std::optional<TrackArtistLinkType> linkType) const
|
||||
{
|
||||
auto query {session()->query<Wt::Dbo::ptr<Track>>("SELECT t FROM track t INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id")
|
||||
.where("a.id = ?").bind(getId())
|
||||
.where("t.release_id is NULL")
|
||||
.orderBy("t.name")};
|
||||
|
||||
if (linkType)
|
||||
query.where("t_a_l.type = ?").bind(*linkType);
|
||||
|
||||
return !query.resultList().empty();
|
||||
}
|
||||
|
||||
std::vector<Track::pointer>
|
||||
Artist::getRandomTracks(std::optional<std::size_t> count) const
|
||||
{
|
||||
assert(session());
|
||||
|
||||
Wt::Dbo::collection<Wt::Dbo::ptr<Track>> tracks {session()->query<Wt::Dbo::ptr<Track>>("SELECT t from track t INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id")
|
||||
.where("a.id = ?").bind(getId())
|
||||
.orderBy("RANDOM()")
|
||||
.limit(count ? static_cast<int>(*count) : -1)};
|
||||
|
||||
return std::vector<Track::pointer>(tracks.begin(), tracks.end());
|
||||
}
|
||||
|
||||
RangeResults<ArtistId>
|
||||
Artist::findSimilarArtists(EnumSet<TrackArtistLinkType> artistLinkTypes, Range range) const
|
||||
{
|
||||
|
||||
@@ -549,6 +549,28 @@ CREATE TABLE "listen" (
|
||||
ScanSettings::get(session).modify()->addAudioFileExtension(".wv");
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
migrateFromV33(Session& session)
|
||||
{
|
||||
// remove name from track_artist_link
|
||||
// Drop Auth mode
|
||||
session.getDboSession().execute(R"(
|
||||
CREATE TABLE IF NOT EXISTS "track_artist_link_backup" (
|
||||
"id" integer primary key autoincrement,
|
||||
"version" integer not null,
|
||||
"type" integer not null,
|
||||
"track_id" bigint,
|
||||
"artist_id" bigint,
|
||||
constraint "fk_track_artist_link_track" foreign key ("track_id") references "track" ("id") on delete cascade deferrable initially deferred,
|
||||
constraint "fk_track_artist_link_artist" foreign key ("artist_id") references "artist" ("id") on delete cascade deferrable initially deferred
|
||||
);
|
||||
))");
|
||||
session.getDboSession().execute("INSERT INTO track_artist_link_backup SELECT id, version, type, track_id, artist_id FROM track_artist_link");
|
||||
session.getDboSession().execute("DROP TABLE track_artist_link");
|
||||
session.getDboSession().execute("ALTER TABLE track_artist_link_backup RENAME TO track_artist_link");
|
||||
}
|
||||
|
||||
void
|
||||
doDbMigration(Session& session)
|
||||
{
|
||||
@@ -588,6 +610,7 @@ CREATE TABLE "listen" (
|
||||
{30, migrateFromV30},
|
||||
{31, migrateFromV31},
|
||||
{32, migrateFromV32},
|
||||
{33, migrateFromV33},
|
||||
};
|
||||
|
||||
while (1)
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Database
|
||||
class Session;
|
||||
|
||||
using Version = std::size_t;
|
||||
static constexpr Version LMS_DATABASE_VERSION {33};
|
||||
static constexpr Version LMS_DATABASE_VERSION {34};
|
||||
class VersionInfo
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -43,7 +43,7 @@ createQuery(Session& session, const Track::FindParameters& params)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto query {session.getDboSession().query<TrackId>("SELECT t.id from track t")};
|
||||
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) + "%");
|
||||
@@ -79,6 +79,33 @@ createQuery(Session& session, const Track::FindParameters& params)
|
||||
query.where(oss.str());
|
||||
}
|
||||
|
||||
if (params.artist.isValid())
|
||||
{
|
||||
query.join("artist a ON a.id = t_a_l.artist_id")
|
||||
.join("track_artist_link t_a_l ON t_a_l.track_id = t.id")
|
||||
.where("a.id = ?").bind(params.artist);
|
||||
|
||||
if (!params.trackArtistLinkTypes.empty())
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
bool first {true};
|
||||
for (TrackArtistLinkType linkType : params.trackArtistLinkTypes)
|
||||
{
|
||||
if (!first)
|
||||
oss << " OR ";
|
||||
oss << "t_a_l.type = ?";
|
||||
query.bind(linkType);
|
||||
|
||||
first = false;
|
||||
}
|
||||
query.where(oss.str());
|
||||
}
|
||||
}
|
||||
|
||||
if (params.nonRelease)
|
||||
query.where("t.release_id IS NULL");
|
||||
|
||||
switch (params.sortMethod)
|
||||
{
|
||||
case TrackSortMethod::None:
|
||||
@@ -93,6 +120,12 @@ createQuery(Session& session, const Track::FindParameters& params)
|
||||
assert(params.starringUser.isValid());
|
||||
query.orderBy("s_t.date_time DESC");
|
||||
break;
|
||||
case TrackSortMethod::Name:
|
||||
query.orderBy("t.name COLLATE NOCASE");
|
||||
break;
|
||||
case TrackSortMethod::DateDescAndRelease:
|
||||
query.orderBy("t.date DESC,t.release_id,t.disc_number,t.track_number");
|
||||
break;
|
||||
}
|
||||
|
||||
return query;
|
||||
|
||||
Reference in New Issue
Block a user