Added a way to filter by release type

This commit is contained in:
emeric
2025-02-09 21:11:45 +01:00
parent b4bce77877
commit 639629fbb3
16 changed files with 156 additions and 19 deletions
+10 -2
View File
@@ -51,7 +51,8 @@ namespace lms::db
|| params.release.isValid()
|| params.filters.clusters.size() == 1
|| params.filters.mediaLibrary.isValid()
|| params.filters.label.isValid())
|| params.filters.label.isValid()
|| params.filters.releaseType.isValid())
{
query.join("track_artist_link t_a_l ON t_a_l.artist_id = a.id");
}
@@ -61,7 +62,8 @@ namespace lms::db
|| params.writtenAfter.isValid()
|| params.release.isValid()
|| params.filters.mediaLibrary.isValid()
|| params.filters.label.isValid())
|| params.filters.label.isValid()
|| params.filters.releaseType.isValid())
{
query.join("track t ON t.id = t_a_l.track_id");
@@ -79,6 +81,12 @@ namespace lms::db
query.join("release_label r_l ON r_l.release_id = t.release_id");
query.where("r_l.label_id = ?").bind(params.filters.label);
}
if (params.filters.releaseType.isValid())
{
query.join("release_release_type r_r_t ON r_r_t.release_id = t.release_id");
query.where("r_r_t.release_type_id = ?").bind(params.filters.releaseType);
}
}
if (params.linkType)
+28 -8
View File
@@ -42,18 +42,26 @@ namespace lms::db
assert(!params.artist.isValid()); // poor check
if (params.filters.mediaLibrary.isValid() || params.filters.label.isValid())
if (params.filters.mediaLibrary.isValid()
|| params.filters.label.isValid()
|| params.filters.releaseType.isValid())
{
query.join("track t ON t.id = t_a_l.track_id");
}
if (params.filters.mediaLibrary.isValid())
query.where("t.media_library_id = ?").bind(params.filters.mediaLibrary);
if (params.filters.mediaLibrary.isValid())
query.where("t.media_library_id = ?").bind(params.filters.mediaLibrary);
if (params.filters.label.isValid())
{
query.join("release_label r_l ON t.release_id = r_l.release_id");
query.where("r_l.label_id = ?").bind(params.filters.label);
if (params.filters.label.isValid())
{
query.join("release_label r_l ON r_l.release_id = t.release_id");
query.where("r_l.label_id = ?").bind(params.filters.label);
}
if (params.filters.releaseType.isValid())
{
query.join("release_release_type r_r_t ON r_r_t.release_id = t.release_id");
query.where("r_r_t.release_type_id = ?").bind(params.filters.releaseType);
}
}
if (params.linkType)
@@ -127,6 +135,12 @@ namespace lms::db
query.where("r_l.label_id = ?").bind(params.filters.label);
}
if (params.filters.releaseType.isValid())
{
query.join("release_release_type r_r_t ON r_r_t.release_id = r.id");
query.where("r_r_t.release_type_id = ?").bind(params.filters.releaseType);
}
if (!params.filters.clusters.empty())
{
std::ostringstream oss;
@@ -180,6 +194,12 @@ namespace lms::db
query.where("r_l.label_id = ?").bind(params.filters.label);
}
if (params.filters.releaseType.isValid())
{
query.join("release_release_type r_r_t ON r_r_t.release_id = t.release_id");
query.where("r_r_t.release_type_id = ?").bind(params.filters.releaseType);
}
if (!params.filters.clusters.empty())
{
std::ostringstream oss;
+24
View File
@@ -83,6 +83,12 @@ namespace lms::db
query.where("r_l.label_id = ?").bind(params.filters.label);
}
if (params.filters.releaseType.isValid())
{
query.join("release_release_type r_r_t ON r_r_t.release_id = r.id");
query.where("r_r_t.release_type_id = ?").bind(params.filters.releaseType);
}
if (params.directory.isValid())
query.where("t.directory_id = ?").bind(params.directory);
@@ -401,6 +407,24 @@ namespace lms::db
return utils::fetchQuerySingleResult(session.getDboSession()->query<Wt::Dbo::ptr<ReleaseType>>("SELECT r_t from release_type r_t").where("r_t.name = ?").bind(name));
}
void ReleaseType::find(Session& session, ReleaseTypeSortMethod sortMethod, std::function<void(const ReleaseType::pointer& releaseType)> func)
{
session.checkReadTransaction();
auto query{ session.getDboSession()->find<ReleaseType>() };
switch (sortMethod)
{
case ReleaseTypeSortMethod::None:
break;
case ReleaseTypeSortMethod::Name:
query.orderBy("name COLLATE NOCASE");
}
utils::forEachQueryResult(query, [&](const ReleaseType::pointer& releaseType) {
func(releaseType);
});
}
RangeResults<ReleaseTypeId> ReleaseType::findOrphanIds(Session& session, std::optional<Range> range)
{
session.checkReadTransaction();
+3 -1
View File
@@ -238,7 +238,9 @@ namespace lms::db
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_mbid_idx ON release(mbid)");
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_name_idx ON release(name)");
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_name_nocase_idx ON release(name COLLATE NOCASE)");
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_type_name_idx ON release_type(name)");
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_type_id_idx ON release_type(id)");
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS release_type_name_idx ON release_type(name COLLATE NOCASE)");
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_id_idx ON track(id)");
utils::executeCommand(_session, "CREATE INDEX IF NOT EXISTS track_absolute_path_idx ON track(absolute_file_path)");
+6
View File
@@ -168,6 +168,12 @@ namespace lms::db
query.where("r_l.label_id = ?").bind(params.filters.label);
}
if (params.filters.releaseType.isValid())
{
query.join("release_release_type r_r_t ON r_r_t.release_id = t.release_id");
query.where("r_r_t.release_type_id = ?").bind(params.filters.releaseType);
}
if (params.directory.isValid())
query.where("t.directory_id = ?").bind(params.directory);
+8 -1
View File
@@ -54,7 +54,8 @@ namespace lms::db
query.where("t_l.name LIKE ? ESCAPE '" ESCAPE_CHAR_STR "'").bind("%" + utils::escapeLikeKeyword(keyword) + "%");
if (params.filters.mediaLibrary.isValid()
|| params.filters.label.isValid())
|| params.filters.label.isValid()
|| params.filters.releaseType.isValid())
{
query.join("track t ON t.id = t_l_e.track_id");
@@ -66,6 +67,12 @@ namespace lms::db
query.join("release_label r_l ON r_l.release_id = t.release_id");
query.where("r_l.label_id = ?").bind(params.filters.label);
}
if (params.filters.releaseType.isValid())
{
query.join("release_release_type r_r_t ON r_r_t.release_id = t.release_id");
query.where("r_r_t.release_type_id = ?").bind(params.filters.releaseType);
}
}
if (params.user.isValid())
@@ -24,6 +24,7 @@
#include "database/ClusterId.hpp"
#include "database/LabelId.hpp"
#include "database/MediaLibraryId.hpp"
#include "database/ReleaseTypeId.hpp"
namespace lms::db
{
@@ -32,6 +33,7 @@ namespace lms::db
MediaLibraryId mediaLibrary; // tracks that belongs to this library
std::vector<ClusterId> clusters; // tracks that belong to all these clusters
LabelId label; // tracks which release has this label
ReleaseTypeId releaseType; // tracks which release has this type
Filters& setClusters(std::span<const ClusterId> _clusters)
{
@@ -48,5 +50,10 @@ namespace lms::db
label = _label;
return *this;
}
Filters& setReleaseType(ReleaseTypeId _releaseType)
{
releaseType = _releaseType;
return *this;
}
};
} // namespace lms::db
@@ -124,6 +124,7 @@ namespace lms::db
static std::size_t getCount(Session& session);
static pointer find(Session& session, ReleaseTypeId id);
static pointer find(Session& session, std::string_view name);
static void find(Session& session, ReleaseTypeSortMethod sortMethod, std::function<void(const ReleaseType::pointer& releaseType)> func);
static RangeResults<ReleaseTypeId> findOrphanIds(Session& session, std::optional<Range> range = std::nullopt);
// Accessors
@@ -158,6 +158,12 @@ namespace lms::db
StarredDateDesc,
};
enum class ReleaseTypeSortMethod
{
None,
Name,
};
enum class TrackListSortMethod
{
None,
+56 -4
View File
@@ -30,6 +30,7 @@
#include "database/LabelId.hpp"
#include "database/MediaLibrary.hpp"
#include "database/Release.hpp"
#include "database/ReleaseTypeId.hpp"
#include "database/Session.hpp"
#include "LmsApplication.hpp"
@@ -50,7 +51,11 @@ namespace lms::ui
{
};
using TypeVariant = std::variant<db::ClusterTypeId, MediaLibraryTag, LabelTag>;
struct ReleaseTypeTag
{
};
using TypeVariant = std::variant<db::ClusterTypeId, MediaLibraryTag, LabelTag, ReleaseTypeTag>;
using TypeModel = ValueStringModel<TypeVariant>;
std::unique_ptr<TypeModel> createTypeModel()
@@ -66,11 +71,12 @@ namespace lms::ui
typeModel->add(Wt::WString::tr("Lms.Explore.media-library"), MediaLibraryTag{});
typeModel->add(Wt::WString::tr("Lms.Explore.label"), LabelTag{});
typeModel->add(Wt::WString::tr("Lms.Explore.release-type"), ReleaseTypeTag{});
return typeModel;
}
using ValueVariant = std::variant<db::ClusterId, db::MediaLibraryId, db::LabelId>;
using ValueVariant = std::variant<db::ClusterId, db::MediaLibraryId, db::LabelId, db::ReleaseTypeId>;
using ValueModel = ValueStringModel<ValueVariant>;
std::unique_ptr<ValueModel> createValueModel(TypeVariant type)
@@ -93,6 +99,12 @@ namespace lms::ui
valueModel->add(Wt::WString::fromUTF8(std::string{ label->getName() }), label->getId());
});
}
else if (std::holds_alternative<ReleaseTypeTag>(type))
{
db::ReleaseType::find(session, db::ReleaseTypeSortMethod::Name, [&](const db::ReleaseType::pointer& releaseType) {
valueModel->add(Wt::WString::fromUTF8(std::string{ releaseType->getName() }), releaseType->getId());
});
}
else if (const db::ClusterTypeId * clusterTypeId{ std::get_if<db::ClusterTypeId>(&type) })
{
db::Cluster::FindParameters params;
@@ -136,6 +148,11 @@ namespace lms::ui
set(*labelId);
state::writeValue<db::LabelId::ValueType>("filters_label_id", labelId->getValue());
}
else if (const db::ReleaseTypeId * releaseTypeId{ std::get_if<db::ReleaseTypeId>(&value) })
{
set(*releaseTypeId);
state::writeValue<db::ReleaseTypeId::ValueType>("filters_release_type_id", releaseTypeId->getValue());
}
else if (const db::ClusterId * clusterId{ std::get_if<db::ClusterId>(&value) })
{
add(*clusterId);
@@ -176,8 +193,10 @@ namespace lms::ui
if (const std::optional<db::MediaLibraryId::ValueType> mediaLibraryId{ state::readValue<db::MediaLibraryId::ValueType>("filters_media_library_id") })
set(db::MediaLibraryId{ *mediaLibraryId });
if (const std::optional<db::LabelId::ValueType> mediaLibraryId{ state::readValue<db::LabelId::ValueType>("filters_label_id") })
set(db::LabelId{ *mediaLibraryId });
if (const std::optional<db::LabelId::ValueType> labelId{ state::readValue<db::LabelId::ValueType>("filters_label_id") })
set(db::LabelId{ *labelId });
if (const std::optional<db::ReleaseTypeId::ValueType> releaseTypeId{ state::readValue<db::ReleaseTypeId::ValueType>("filters_release_type_id") })
set(db::ReleaseTypeId{ *releaseTypeId });
}
void Filters::add(db::ClusterId clusterId)
@@ -272,6 +291,39 @@ namespace lms::ui
emitFilterAddedNotification();
}
void Filters::set(db::ReleaseTypeId releaseTypeId)
{
if (_releaseTypeFilter)
{
_filters->removeWidget(_releaseTypeFilter);
_releaseTypeFilter = nullptr;
_dbFilters.releaseType = db::ReleaseTypeId{};
}
std::string name;
{
auto transaction{ LmsApp->getDbSession().createReadTransaction() };
const auto releaseType{ db::ReleaseType::find(LmsApp->getDbSession(), releaseTypeId) };
if (!releaseType)
return;
name = releaseType->getName();
}
_dbFilters.releaseType = releaseTypeId;
_releaseTypeFilter = _filters->addWidget(utils::createFilter(Wt::WString::fromUTF8(name), Wt::WString::tr("Lms.Explore.release-type"), "bg-dark", true));
_releaseTypeFilter->clicked().connect(_releaseTypeFilter, [this] {
_filters->removeWidget(_releaseTypeFilter);
_dbFilters.releaseType = db::ReleaseTypeId{};
_releaseTypeFilter = nullptr;
_sigUpdated.emit();
state::writeValue<db::LabelId::ValueType>("filters_release_type_id", std::nullopt);
});
emitFilterAddedNotification();
}
void Filters::emitFilterAddedNotification()
{
LmsApp->notifyMsg(Notification::Type::Info,
+2 -3
View File
@@ -19,9 +19,6 @@
#pragma once
#include <span>
#include <vector>
#include <Wt/WContainerWidget.h>
#include <Wt/WSignal.h>
#include <Wt/WTemplate.h>
@@ -45,11 +42,13 @@ namespace lms::ui
void showDialog();
void set(db::LabelId labelId);
void set(db::MediaLibraryId mediaLibraryId);
void set(db::ReleaseTypeId releaseTypeId);
void emitFilterAddedNotification();
Wt::WContainerWidget* _filters{};
Wt::WInteractWidget* _mediaLibraryFilter{};
Wt::WInteractWidget* _labelFilter{};
Wt::WInteractWidget* _releaseTypeFilter{};
Wt::Signal<> _sigUpdated;