UI: added away to filter all the views by music library

This commit is contained in:
emeric
2024-04-28 23:37:59 +02:00
parent 83c71ee90c
commit 391d859272
35 changed files with 558 additions and 305 deletions
+23 -4
View File
@@ -43,17 +43,19 @@ namespace lms::db
query.groupBy("c.id");
if (params.track.isValid() || params.release.isValid())
{
query.join("track_cluster t_c ON t_c.cluster_id = c.id");
query.join("track t ON t.id = t_c.track_id");
}
if (!params.clusterTypeName.empty())
query.join("cluster_type c_t ON c_t.id = c.cluster_type_id");
if (params.track.isValid())
query.where("t.id = ?").bind(params.track);
query.where("t_c.track_id = ?").bind(params.track);
if (params.release.isValid())
{
query.join("track t ON t.id = t_c.track_id");
query.where("t.release_id = ?").bind(params.release);
}
assert(!params.clusterType.isValid() || params.clusterTypeName.empty());
if (params.clusterType.isValid())
@@ -61,6 +63,17 @@ namespace lms::db
else if (!params.clusterTypeName.empty())
query.where("c_t.name = ?").bind(params.clusterTypeName);
switch (params.sortMethod)
{
case ClusterSortMethod::None:
break;
case ClusterSortMethod::Name:
query.orderBy("c.name COLLATE NOCASE");
break;
}
query.groupBy("c.id");
return query;
}
@@ -208,6 +221,12 @@ namespace lms::db
return utils::execRangeQuery<ClusterTypeId>(query, range);
}
void ClusterType::find(Session& session, const std::function<void(const pointer&)>& func)
{
auto query{ session.getDboSession()->find<ClusterType>() };
return utils::forEachQueryResult(query, func);
}
ClusterType::pointer ClusterType::find(Session& session, std::string_view name)
{
session.checkReadTransaction();
+9 -2
View File
@@ -34,7 +34,7 @@ namespace lms::db
{
namespace
{
static constexpr Version LMS_DATABASE_VERSION{ 57 };
static constexpr Version LMS_DATABASE_VERSION{ 58 };
}
VersionInfo::VersionInfo()
@@ -455,11 +455,17 @@ SELECT
void migrateFromV56(Session& session)
{
// Make sure we remove all the previoulsy created index, the createIndexesIfNeeded will recreate them all
std::vector<std::string> indexeNames{ utils::fetchQueryResults(session.getDboSession()->query<std::string>(R"(SELECT name FROM sqlite_master WHERE type = 'index' AND name LIKE '%_idx')")) };
std::vector<std::string> indexeNames{ utils::fetchQueryResults(session.getDboSession()->query<std::string>(R"(SELECT name FROM sqlite_master WHERE type = 'index' AND name LIKE '%_idx')")) };
for (const auto& indexName : indexeNames)
session.getDboSession()->execute("DROP INDEX " + indexName);
}
void migrateFromV57(Session& session)
{
// useless index
session.getDboSession()->execute("DROP INDEX cluster_name_idx");
}
bool doDbMigration(Session& session)
{
static const std::string outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" };
@@ -494,6 +500,7 @@ SELECT
{54, migrateFromV54},
{55, migrateFromV55},
{56, migrateFromV56},
{57, migrateFromV57},
};
bool migrationPerformed{};
-1
View File
@@ -172,7 +172,6 @@ namespace lms::db
_session.execute("CREATE INDEX IF NOT EXISTS auth_token_value_idx ON auth_token(value)");
_session.execute("CREATE INDEX IF NOT EXISTS cluster_cluster_type_idx ON cluster(cluster_type_id)");
_session.execute("CREATE INDEX IF NOT EXISTS cluster_name_idx ON cluster(name)");
_session.execute("CREATE INDEX IF NOT EXISTS cluster_type_name_idx ON cluster_type(name)");
_session.execute("CREATE INDEX IF NOT EXISTS listen_backend_idx ON listen(backend)");
+81 -45
View File
@@ -35,6 +35,79 @@
namespace lms::db
{
namespace
{
template <typename ResultType>
Wt::Dbo::Query<ResultType> createQuery(Session& session, std::string_view itemToSelect, const TrackList::FindParameters& params)
{
auto query{ session.getDboSession()->query<ResultType>("SELECT DISTINCT " + std::string{ itemToSelect } + " FROM tracklist t_l") };
if (!params.clusters.empty() || params.mediaLibrary.isValid())
query.join("tracklist_entry t_l_e ON t_l_e.tracklist_id = t_l.id");
if (params.mediaLibrary.isValid())
query.join("track t ON t.id = t_l_e.track_id");
if (params.mediaLibrary.isValid())
query.where("t.media_library_id = ?").bind(params.mediaLibrary);
if (params.user.isValid())
query.where("t_l.user_id = ?").bind(params.user);
if (params.type)
query.where("t_l.type = ?").bind(*params.type);
if (!params.clusters.empty())
{
std::ostringstream oss;
oss << "t_l_e.track_id IN (SELECT DISTINCT t.id FROM track t"
" INNER JOIN track_cluster t_c ON t_c.track_id = t.id"
" INNER JOIN cluster c ON c.id = t_c.cluster_id";
WhereClause clusterClause;
for (const ClusterId clusterId : params.clusters)
{
clusterClause.Or(WhereClause("c.id = ?"));
query.bind(clusterId);
}
oss << " " << clusterClause.get();
oss << " GROUP BY t.id HAVING COUNT(*) = " << params.clusters.size() << ")";
query.where(oss.str());
}
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 query;
}
template <typename ResultType>
Wt::Dbo::Query<ResultType> createQuery(Session& session, const TrackList::FindParameters& params)
{
std::string_view itemToSelect;
if constexpr (std::is_same_v<ResultType, TrackListId>)
itemToSelect = "t_l.id";
else if constexpr (std::is_same_v<ResultType, Wt::Dbo::ptr<TrackList>>)
itemToSelect = "t_l";
else
static_assert("Unhandled type");
return createQuery<ResultType>(session, itemToSelect, params);
}
}
TrackList::TrackList(std::string_view name, TrackListType type, bool isPublic, ObjectPtr<User> user)
: _name{ name }
, _type{ type }
@@ -58,7 +131,6 @@ namespace lms::db
return utils::fetchQuerySingleResult(session.getDboSession()->query<int>("SELECT COUNT(*) FROM tracklist"));
}
TrackList::pointer TrackList::find(Session& session, std::string_view name, TrackListType type, UserId userId)
{
session.checkReadTransaction();
@@ -73,53 +145,17 @@ namespace lms::db
RangeResults<TrackListId> TrackList::find(Session& session, const FindParameters& params)
{
session.checkReadTransaction();
auto query{ session.getDboSession()->query<TrackListId>("SELECT DISTINCT t_l.id FROM tracklist t_l") };
if (params.user.isValid())
query.where("t_l.user_id = ?").bind(params.user);
if (params.type)
query.where("t_l.type = ?").bind(*params.type);
if (!params.clusters.empty())
{
query.join("tracklist_entry t_l_e ON t_l_e.tracklist_id = t_l.id");
query.join("track t ON t.id = t_l_e.track_id");
std::ostringstream oss;
oss << "t.id IN (SELECT DISTINCT t.id FROM track t"
" INNER JOIN track_cluster t_c ON t_c.track_id = t.id"
" INNER JOIN cluster c ON c.id = t_c.cluster_id";
WhereClause clusterClause;
for (const ClusterId clusterId : params.clusters)
{
clusterClause.Or(WhereClause("c.id = ?"));
query.bind(clusterId);
}
oss << " " << clusterClause.get();
oss << " GROUP BY t.id HAVING COUNT(*) = " << params.clusters.size() << ")";
query.where(oss.str());
}
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;
}
auto query{ createQuery<TrackListId>(session, params) };
return utils::execRangeQuery<TrackListId>(query, params.range);
}
void TrackList::find(Session& session, const FindParameters& params, const std::function<void(const TrackList::pointer&)>& func)
{
session.checkReadTransaction();
auto query{ createQuery<Wt::Dbo::ptr<TrackList>>(session, params) };
utils::forEachQueryRangeResult(query, params.range, func);
}
TrackList::pointer TrackList::find(Session& session, TrackListId id)
{
session.checkReadTransaction();