From cb4014b0e5096c04b40068fae582a2a147afe577 Mon Sep 17 00:00:00 2001 From: emeric Date: Mon, 2 Sep 2024 08:06:17 +0200 Subject: [PATCH 01/23] Added support for record labels, fixes #502 --- SUBSONIC.md | 1 + src/libs/database/impl/Migration.cpp | 25 +++++++- src/libs/database/impl/Release.cpp | 57 +++++++++++++++++++ src/libs/database/impl/Session.cpp | 3 + .../database/include/database/LabelId.hpp | 24 ++++++++ .../database/include/database/Release.hpp | 40 ++++++++++++- src/libs/database/test/Migration.cpp | 2 + src/libs/database/test/Release.cpp | 18 ++++++ src/libs/metadata/impl/Parser.cpp | 2 +- src/libs/metadata/include/metadata/Types.hpp | 2 +- src/libs/metadata/test/Parser.cpp | 6 +- .../scanner/impl/ScanStepScanFiles.cpp | 16 ++++++ src/libs/subsonic/CMakeLists.txt | 1 + src/libs/subsonic/impl/responses/Album.cpp | 8 ++- .../subsonic/impl/responses/RecordLabel.cpp | 34 +++++++++++ .../subsonic/impl/responses/RecordLabel.hpp | 34 +++++++++++ src/tools/metadata/LmsMetadata.cpp | 6 +- 17 files changed, 267 insertions(+), 12 deletions(-) create mode 100644 src/libs/database/include/database/LabelId.hpp create mode 100644 src/libs/subsonic/impl/responses/RecordLabel.cpp create mode 100644 src/libs/subsonic/impl/responses/RecordLabel.hpp diff --git a/SUBSONIC.md b/SUBSONIC.md index 34a8053a..cc3a6d6f 100644 --- a/SUBSONIC.md +++ b/SUBSONIC.md @@ -24,6 +24,7 @@ The following extra fields are implemented: * `moods` * `musicBrainzId` * `originalReleaseDate` + * `recordLabels` * `releaseTypes` * `userRating` * `Child` response: diff --git a/src/libs/database/impl/Migration.cpp b/src/libs/database/impl/Migration.cpp index f9d8e431..59b9576b 100644 --- a/src/libs/database/impl/Migration.cpp +++ b/src/libs/database/impl/Migration.cpp @@ -35,7 +35,7 @@ namespace lms::db { namespace { - static constexpr Version LMS_DATABASE_VERSION{ 64 }; + static constexpr Version LMS_DATABASE_VERSION{ 65 }; } VersionInfo::VersionInfo() @@ -714,6 +714,28 @@ SELECT session.getDboSession()->execute("DROP INDEX IF EXISTS listen_user_backend_date_time"); } + void migrateFromV64(Session& session) + { + session.getDboSession()->execute(R"(CREATE TABLE IF NOT EXISTS "label" ( + "id" integer primary key autoincrement, + "version" integer not null, + "name" text not null +))"); + + session.getDboSession()->execute(R"(CREATE TABLE IF NOT EXISTS "release_label" ( + "label_id" bigint, + "release_id" bigint, + primary key ("label_id", "release_id"), + constraint "fk_release_label_key1" foreign key ("label_id") references "label" ("id") on delete cascade deferrable initially deferred, + constraint "fk_release_label_key2" foreign key ("release_id") references "release" ("id") on delete cascade deferrable initially deferred +))"); + session.getDboSession()->execute(R"(CREATE INDEX "release_label_label" on "release_label" ("label_id"))"); + session.getDboSession()->execute(R"(CREATE INDEX "release_label_release" on "release_label" ("release_id"))"); + + // Just increment the scan version of the settings to make the next scheduled scan rescan everything + session.getDboSession()->execute("UPDATE scan_settings SET scan_version = scan_version + 1"); + } + bool doDbMigration(Session& session) { static const std::string outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" }; @@ -754,6 +776,7 @@ SELECT { 61, migrateFromV61 }, { 62, migrateFromV62 }, { 63, migrateFromV63 }, + { 64, migrateFromV64 }, }; bool migrationPerformed{}; diff --git a/src/libs/database/impl/Release.cpp b/src/libs/database/impl/Release.cpp index baea5c02..bdb31e96 100644 --- a/src/libs/database/impl/Release.cpp +++ b/src/libs/database/impl/Release.cpp @@ -216,6 +216,36 @@ namespace lms::db } } // namespace + Label::Label(std::string_view name) + : _name{ name } + { + // As we use the name to uniquely identoify release type, we must throw (and not truncate) + if (name.size() > _maxNameLength) + throw Exception{ "Label name is too long: " + std::string{ name } + "'" }; + } + + Label::pointer Label::create(Session& session, std::string_view name) + { + return session.getDboSession()->add(std::unique_ptr