diff --git a/src/libs/core/include/core/TaggedType.hpp b/src/libs/core/include/core/TaggedType.hpp
new file mode 100644
index 00000000..1963db33
--- /dev/null
+++ b/src/libs/core/include/core/TaggedType.hpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2025 Emeric Poupon
+ *
+ * This file is part of LMS.
+ *
+ * LMS is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LMS is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LMS. If not, see .
+ */
+
+#pragma once
+
+namespace lms::core
+{
+ template
+ class TaggedType
+ {
+ public:
+ using underlying_type = T;
+
+ explicit constexpr TaggedType() = default;
+ explicit constexpr TaggedType(T value)
+ : _value{ value } {}
+
+ constexpr T value() const { return _value; }
+
+ auto operator<=>(const TaggedType&) const = default;
+
+ private:
+ T _value{};
+ };
+} // namespace lms::core
\ No newline at end of file
diff --git a/src/libs/database/CMakeLists.txt b/src/libs/database/CMakeLists.txt
index a2aece03..12aee1b8 100644
--- a/src/libs/database/CMakeLists.txt
+++ b/src/libs/database/CMakeLists.txt
@@ -25,6 +25,8 @@ add_library(lmsdatabase STATIC
impl/SqlQuery.cpp
impl/Track.cpp
impl/TrackBookmark.cpp
+ impl/TrackEmbeddedImage.cpp
+ impl/TrackEmbeddedImageLink.cpp
impl/TrackLyrics.cpp
impl/Types.cpp
impl/UIState.cpp
diff --git a/src/libs/database/impl/Artist.cpp b/src/libs/database/impl/Artist.cpp
index 250f00c0..f0c5638f 100644
--- a/src/libs/database/impl/Artist.cpp
+++ b/src/libs/database/impl/Artist.cpp
@@ -29,9 +29,9 @@
#include "database/Track.hpp"
#include "database/User.hpp"
-#include "IdTypeTraits.hpp"
#include "SqlQuery.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/AuthToken.cpp b/src/libs/database/impl/AuthToken.cpp
index d963c653..8622975f 100644
--- a/src/libs/database/impl/AuthToken.cpp
+++ b/src/libs/database/impl/AuthToken.cpp
@@ -24,9 +24,9 @@
#include "database/Session.hpp"
#include "database/User.hpp"
-#include "IdTypeTraits.hpp"
-#include "StringViewTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
+#include "traits/StringViewTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/Cluster.cpp b/src/libs/database/impl/Cluster.cpp
index f59f9e59..44841f4f 100644
--- a/src/libs/database/impl/Cluster.cpp
+++ b/src/libs/database/impl/Cluster.cpp
@@ -27,10 +27,10 @@
#include "database/Session.hpp"
#include "database/Track.hpp"
-#include "IdTypeTraits.hpp"
#include "SqlQuery.hpp"
-#include "StringViewTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
+#include "traits/StringViewTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/Directory.cpp b/src/libs/database/impl/Directory.cpp
index d335cace..6f4f1778 100644
--- a/src/libs/database/impl/Directory.cpp
+++ b/src/libs/database/impl/Directory.cpp
@@ -23,9 +23,9 @@
#include "database/Session.hpp"
#include "database/Types.hpp"
-#include "IdTypeTraits.hpp"
-#include "PathTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
+#include "traits/PathTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/Image.cpp b/src/libs/database/impl/Image.cpp
index 0466f9a0..1b010d09 100644
--- a/src/libs/database/impl/Image.cpp
+++ b/src/libs/database/impl/Image.cpp
@@ -26,9 +26,9 @@
#include "database/Release.hpp"
#include "database/Session.hpp"
-#include "IdTypeTraits.hpp"
-#include "PathTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
+#include "traits/PathTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/Listen.cpp b/src/libs/database/impl/Listen.cpp
index be05082a..73e58490 100644
--- a/src/libs/database/impl/Listen.cpp
+++ b/src/libs/database/impl/Listen.cpp
@@ -22,9 +22,9 @@
#include "database/Track.hpp"
#include "database/User.hpp"
-#include "IdTypeTraits.hpp"
#include "SqlQuery.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/MediaLibrary.cpp b/src/libs/database/impl/MediaLibrary.cpp
index 81033c7b..cbbadaae 100644
--- a/src/libs/database/impl/MediaLibrary.cpp
+++ b/src/libs/database/impl/MediaLibrary.cpp
@@ -23,10 +23,10 @@
#include "database/Session.hpp"
#include "database/Track.hpp"
-#include "IdTypeTraits.hpp"
-#include "PathTraits.hpp"
-#include "StringViewTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
+#include "traits/PathTraits.hpp"
+#include "traits/StringViewTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/Migration.cpp b/src/libs/database/impl/Migration.cpp
index 31322d8e..1b0a857f 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{ 83 };
+ static constexpr Version LMS_DATABASE_VERSION{ 84 };
}
VersionInfo::VersionInfo()
@@ -1101,11 +1101,42 @@ FROM tracklist)");
void migrateFromV82(Session& session)
{
- // new setting to display inline artist relationships in the release view
+ // New setting to display inline artist relationships in the release view
utils::executeCommand(*session.getDboSession(), "ALTER TABLE user ADD COLUMN ui_enable_inline_artist_relationships BOOLEAN NOT NULL DEFAULT(false)");
utils::executeCommand(*session.getDboSession(), "ALTER TABLE user ADD COLUMN ui_inline_artist_relationships BIGINT NOT NULL DEFAULT(68)"); // Composer + Performer
}
+ void migrateFromV83(Session& session)
+ {
+ // New embedded track image handling
+ utils::executeCommand(*session.getDboSession(), "ALTER TABLE track DROP COLUMN has_cover");
+ utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "track_embedded_image" (
+ "id" integer primary key autoincrement,
+ "version" integer not null,
+ "hash" text not null,
+ "size" integer not null,
+ "width" integer not null,
+ "height" integer not null,
+ "mime_type" text not null
+))");
+
+ utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "track_embedded_image_link" (
+ "id" integer primary key autoincrement,
+ "version" integer not null,
+ "index" integer not null,
+ "is_preferred" boolean not null,
+ "type" integer not null,
+ "description" text not null,
+ "track_id" bigint,
+ "track_embedded_image_id" bigint,
+ constraint "fk_track_embedded_image_link_track" foreign key ("track_id") references "track" ("id") on delete cascade deferrable initially deferred,
+ constraint "fk_track_embedded_image_link_track_embedded_image" foreign key ("track_embedded_image_id") references "track_embedded_image" ("id") on delete cascade deferrable initially deferred
+ ))");
+
+ // Just increment the scan version of the settings to make the next scan rescan everything
+ utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET scan_version = scan_version + 1");
+ }
+
bool doDbMigration(Session& session)
{
constexpr std::string_view outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" };
@@ -1165,6 +1196,7 @@ FROM tracklist)");
{ 80, migrateFromV80 },
{ 81, migrateFromV81 },
{ 82, migrateFromV82 },
+ { 83, migrateFromV83 },
};
bool migrationPerformed{};
diff --git a/src/libs/database/impl/PlayListFile.cpp b/src/libs/database/impl/PlayListFile.cpp
index 776b1af4..8d60ed03 100644
--- a/src/libs/database/impl/PlayListFile.cpp
+++ b/src/libs/database/impl/PlayListFile.cpp
@@ -28,10 +28,10 @@
#include "database/TrackList.hpp"
#include "database/User.hpp"
-#include "IdTypeTraits.hpp"
-#include "PathTraits.hpp"
-#include "StringViewTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
+#include "traits/PathTraits.hpp"
+#include "traits/StringViewTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/PlayQueue.cpp b/src/libs/database/impl/PlayQueue.cpp
index e08efbab..cd1af8f3 100644
--- a/src/libs/database/impl/PlayQueue.cpp
+++ b/src/libs/database/impl/PlayQueue.cpp
@@ -28,9 +28,9 @@
#include "database/Track.hpp"
#include "database/User.hpp"
-#include "IdTypeTraits.hpp"
-#include "StringViewTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
+#include "traits/StringViewTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/RatedArtist.cpp b/src/libs/database/impl/RatedArtist.cpp
index f953c27a..3e480f1f 100644
--- a/src/libs/database/impl/RatedArtist.cpp
+++ b/src/libs/database/impl/RatedArtist.cpp
@@ -25,8 +25,8 @@
#include "database/Session.hpp"
#include "database/User.hpp"
-#include "IdTypeTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/RatedRelease.cpp b/src/libs/database/impl/RatedRelease.cpp
index 69cc51be..b7de0d78 100644
--- a/src/libs/database/impl/RatedRelease.cpp
+++ b/src/libs/database/impl/RatedRelease.cpp
@@ -25,8 +25,8 @@
#include "database/Session.hpp"
#include "database/User.hpp"
-#include "IdTypeTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/RatedTrack.cpp b/src/libs/database/impl/RatedTrack.cpp
index 5cf3bda5..0c0ec110 100644
--- a/src/libs/database/impl/RatedTrack.cpp
+++ b/src/libs/database/impl/RatedTrack.cpp
@@ -25,8 +25,8 @@
#include "database/Track.hpp"
#include "database/User.hpp"
-#include "IdTypeTraits.hpp"
#include "Utils.hpp"
+#include "traits/IdTypeTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/Release.cpp b/src/libs/database/impl/Release.cpp
index 574a9401..4c2575c1 100644
--- a/src/libs/database/impl/Release.cpp
+++ b/src/libs/database/impl/Release.cpp
@@ -31,12 +31,12 @@
#include "database/Types.hpp"
#include "database/User.hpp"
-#include "EnumSetTraits.hpp"
-#include "IdTypeTraits.hpp"
-#include "PartialDateTimeTraits.hpp"
#include "SqlQuery.hpp"
-#include "StringViewTraits.hpp"
#include "Utils.hpp"
+#include "traits/EnumSetTraits.hpp"
+#include "traits/IdTypeTraits.hpp"
+#include "traits/PartialDateTimeTraits.hpp"
+#include "traits/StringViewTraits.hpp"
namespace lms::db
{
diff --git a/src/libs/database/impl/Session.cpp b/src/libs/database/impl/Session.cpp
index 8eeb58ac..6c44db6e 100644
--- a/src/libs/database/impl/Session.cpp
+++ b/src/libs/database/impl/Session.cpp
@@ -43,6 +43,8 @@
#include "database/Track.hpp"
#include "database/TrackArtistLink.hpp"
#include "database/TrackBookmark.hpp"
+#include "database/TrackEmbeddedImage.hpp"
+#include "database/TrackEmbeddedImageLink.hpp"
#include "database/TrackFeatures.hpp"
#include "database/TrackList.hpp"
#include "database/TrackLyrics.hpp"
@@ -50,11 +52,12 @@
#include "database/UIState.hpp"
#include "database/User.hpp"
-#include "EnumSetTraits.hpp"
#include "Migration.hpp"
-#include "PartialDateTimeTraits.hpp"
-#include "PathTraits.hpp"
#include "Utils.hpp"
+#include "traits/EnumSetTraits.hpp"
+#include "traits/ImageHashTypeTraits.hpp"
+#include "traits/PartialDateTimeTraits.hpp"
+#include "traits/PathTraits.hpp"
namespace lms::db
{
@@ -122,6 +125,8 @@ namespace lms::db
_session.mapClass