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