diff --git a/src/libs/database/CMakeLists.txt b/src/libs/database/CMakeLists.txt index 4e79b43a..c896269e 100644 --- a/src/libs/database/CMakeLists.txt +++ b/src/libs/database/CMakeLists.txt @@ -29,6 +29,7 @@ add_library(lmsdatabase STATIC impl/objects/TrackEmbeddedImage.cpp impl/objects/TrackEmbeddedImageLink.cpp impl/objects/TrackLyrics.cpp + impl/objects/Types.cpp impl/objects/UIState.cpp impl/objects/User.cpp impl/Db.cpp @@ -39,7 +40,6 @@ add_library(lmsdatabase STATIC impl/Session.cpp impl/SqlQuery.cpp impl/Transaction.cpp - impl/Types.cpp impl/Utils.cpp ) diff --git a/src/libs/database/impl/Migration.cpp b/src/libs/database/impl/Migration.cpp index cda0492a..f8eca7ac 100644 --- a/src/libs/database/impl/Migration.cpp +++ b/src/libs/database/impl/Migration.cpp @@ -34,7 +34,7 @@ namespace lms::db { namespace { - static constexpr Version LMS_DATABASE_VERSION{ 100 }; + static constexpr Version LMS_DATABASE_VERSION{ 101 }; } VersionInfo::VersionInfo() @@ -1581,6 +1581,94 @@ FROM track)"); constraint "fk_podcast_episode_podcast" foreign key ("podcast_id") references "podcast" ("id") on delete cascade deferrable initially deferred))"); } + void migrateFromV100(Session& session) + { + // Add container and codec to track table + made bits_per_sample optional + + utils::executeCommand(*session.getDboSession(), R"(CREATE TABLE IF NOT EXISTS "track_backup" ( + "id" integer primary key autoincrement, + "version" integer not null, + "scan_version" integer not null, + "absolute_file_path" text not null, + "file_size" bigint not null, + "file_last_write" text, + "file_added" text, + "duration" integer, + "container" integer not null, + "codec" integer not null, + "bitrate" integer not null, + "channel_count" integer not null, + "sample_rate" integer not null, + "bits_per_sample" integer, + "replay_gain" real, + "track_number" integer, + "name" text not null, + "date" text, + "original_date" text, + "mbid" text not null, + "recording_mbid" text not null, + "copyright" text not null, + "copyright_url" text not null, + "artist_display_name" text not null, + "comment" text not null, + "advisory" integer not null, + "medium_id" bigint, + "release_id" bigint, + "media_library_id" bigint, + "directory_id" bigint, + "preferred_artwork_id" bigint, + "preferred_media_artwork_id" bigint, + constraint "fk_track_medium" foreign key ("medium_id") references "medium" ("id") on delete cascade deferrable initially deferred, + constraint "fk_track_release" foreign key ("release_id") references "release" ("id") on delete cascade deferrable initially deferred, + constraint "fk_track_media_library" foreign key ("media_library_id") references "media_library" ("id") on delete set null deferrable initially deferred, + constraint "fk_track_directory" foreign key ("directory_id") references "directory" ("id") on delete cascade deferrable initially deferred, + constraint "fk_track_preferred_artwork" foreign key ("preferred_artwork_id") references "artwork" ("id") on delete set null deferrable initially deferred, + constraint "fk_track_preferred_media_artwork" foreign key ("preferred_media_artwork_id") references "artwork" ("id") on delete set null deferrable initially deferred))"); + + // Copy data from track to track_backup + utils::executeCommand(*session.getDboSession(), R"(INSERT INTO track_backup + SELECT + id, + version, + scan_version, + absolute_file_path, + file_size, + file_last_write, + file_added, + duration, + 0 as container, + 0 as codec, + bitrate, + channel_count, + sample_rate, + CASE WHEN bits_per_sample = 0 THEN NULL ELSE bits_per_sample END as bits_per_sample, + replay_gain, + track_number, + name, + date, + original_date, + mbid, + recording_mbid, + copyright, + copyright_url, + artist_display_name, + comment, + advisory, + medium_id, + release_id, + media_library_id, + directory_id, + preferred_artwork_id, + preferred_media_artwork_id + FROM track)"); + + utils::executeCommand(*session.getDboSession(), "DROP TABLE track"); + utils::executeCommand(*session.getDboSession(), "ALTER TABLE track_backup RENAME TO track"); + + // Just increment the scan version of the settings to make the next scan rescan all audio files + utils::executeCommand(*session.getDboSession(), "UPDATE scan_settings SET audio_scan_version = audio_scan_version + 1"); + } + bool doDbMigration(Session& session) { constexpr std::string_view outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" }; @@ -1657,6 +1745,7 @@ FROM track)"); { 97, migrateFromV97 }, { 98, migrateFromV98 }, { 99, migrateFromV99 }, + { 100, migrateFromV100 }, }; bool migrationPerformed{}; diff --git a/src/libs/database/impl/Types.cpp b/src/libs/database/impl/objects/Types.cpp similarity index 94% rename from src/libs/database/impl/Types.cpp rename to src/libs/database/impl/objects/Types.cpp index f07a30fd..df159c91 100644 --- a/src/libs/database/impl/Types.cpp +++ b/src/libs/database/impl/objects/Types.cpp @@ -17,9 +17,9 @@ * along with LMS. If not, see . */ -#include "database/Types.hpp" +#include "database/objects/Types.hpp" -#include +#include namespace lms::db { @@ -54,7 +54,7 @@ namespace lms::db return "unknown"; } - static const std::set allowedAudioBitrates{ + static const std::unordered_set allowedAudioBitrates{ 64000, 96000, 128000, diff --git a/src/libs/database/include/database/Types.hpp b/src/libs/database/include/database/Types.hpp index 37bfcfa4..46c1661d 100644 --- a/src/libs/database/include/database/Types.hpp +++ b/src/libs/database/include/database/Types.hpp @@ -21,14 +21,10 @@ #include #include -#include -#include #include #include "core/Exception.hpp" -#include "core/LiteralString.hpp" -#include "core/TaggedType.hpp" namespace lms::db { @@ -113,243 +109,4 @@ namespace lms::db std::size_t getTotalFileCount() const { return trackCount + imageCount + trackLyricsCount + playListCount + artistInfoCount; } }; - - struct YearRange - { - int begin{}; - int end{}; - }; - - struct FileInfo - { - Wt::WDateTime lastWrittenTime; - std::size_t scanVersion{}; - }; - - enum class ArtistSortMethod - { - None, - Id, - Name, - SortName, - Random, - LastWrittenDesc, - AddedDesc, - StarredDateDesc, - }; - - enum class ClusterSortMethod - { - None, - Name, - }; - - enum class DirectorySortMethod - { - None, - Name, - }; - - using ImageHashType = core::TaggedType; - - enum class LabelSortMethod - { - None, - Name, - }; - - enum class MediumSortMethod - { - None, - PositionAsc, - }; - - enum class PodcastEpisodeSortMode - { - None, - PubDateAsc, - PubDateDesc, - }; - - enum class ReleaseSortMethod - { - None, - Id, - Name, - SortName, - ArtistNameThenName, - DateAsc, - DateDesc, - OriginalDate, - OriginalDateDesc, - Random, - LastWrittenDesc, - AddedDesc, - StarredDateDesc, - }; - - enum class ReleaseTypeSortMethod - { - None, - Name, - }; - - enum class TrackArtistLinkSortMethod - { - None, - OriginalDateDesc, - }; - - enum class TrackEmbeddedImageSortMethod - { - None, - SizeDesc, - TrackNumberThenSizeDesc, - DiscNumberThenTrackNumberThenSizeDesc, - TrackListIndexAscThenSizeDesc, - }; - - enum class TrackListSortMethod - { - None, - Name, - LastModifiedDesc, - }; - - enum class TrackSortMethod - { - None, - Id, - Random, - LastWrittenDesc, - AddedDesc, - StarredDateDesc, - AbsoluteFilePath, - Name, - DateDescAndRelease, - OriginalDateDescAndRelease, - Release, // order by disc/track number - TrackList, // order by asc order in tracklist - TrackNumber, - }; - - enum class TrackLyricsSortMethod - { - None, - ExternalFirst, - EmbeddedFirst, - }; - - enum class ImageType - { - Unknown = 0, - Other = 1, - FileIcon = 2, - OtherFileIcon = 3, - FrontCover = 4, - BackCover = 5, - LeafletPage = 6, - Media = 7, - LeadArtist = 8, - Artist = 9, - Conductor = 10, - Band = 11, - Composer = 12, - Lyricist = 13, - RecordingLocation = 14, - DuringRecording = 15, - DuringPerformance = 16, - MovieScreenCapture = 17, - ColouredFish = 18, - Illustration = 19, - BandLogo = 20, - PublisherLogo = 21 - }; - - enum class TrackArtistLinkType - { - Artist = 0, // regular track artist - Arranger = 1, - Composer = 2, - Conductor = 3, - Lyricist = 4, - Mixer = 5, - Performer = 6, - Producer = 7, - ReleaseArtist = 8, - Remixer = 9, - Writer = 10, - }; - - core::LiteralString trackArtistLinkTypeToString(TrackArtistLinkType type); - - // User selectable transcoding output formats - enum class TranscodingOutputFormat - { - MP3 = 1, - OGG_OPUS = 2, - OGG_VORBIS = 3, - WEBM_VORBIS = 4, - MATROSKA_OPUS = 5, - }; - - using Bitrate = std::uint32_t; - // Do not remove values! - void visitAllowedAudioBitrates(std::function); - bool isAudioBitrateAllowed(Bitrate bitrate); - - using Rating = int; - - enum class ScrobblingBackend - { - Internal = 0, - ListenBrainz = 1, - }; - - enum class FeedbackBackend - { - Internal = 0, - ListenBrainz = 1, - }; - - enum class SyncState - { - PendingAdd = 0, - Synchronized = 1, - PendingRemove = 2, - }; - - enum class UserType - { - REGULAR = 0, - ADMIN = 1, - DEMO = 2, - }; - - enum class UITheme - { - Light = 0, - Dark = 1, - }; - - enum class SubsonicArtistListMode - { - AllArtists = 0, - ReleaseArtists = 1, - TrackArtists = 2, - }; - - enum class TrackListType - { - PlayList = 0, // user controlled playlists - Internal = 1, // internal usage (current playqueue, history, ...) - }; - - enum class Advisory - { - UnSet = 0, - Unknown = 1, - Clean = 2, - Explicit = 3, - }; } // namespace lms::db diff --git a/src/libs/database/include/database/objects/Artist.hpp b/src/libs/database/include/database/objects/Artist.hpp index 7cae8afd..21d9e96e 100644 --- a/src/libs/database/include/database/objects/Artist.hpp +++ b/src/libs/database/include/database/objects/Artist.hpp @@ -41,6 +41,7 @@ #include "database/objects/MediaLibraryId.hpp" #include "database/objects/ReleaseId.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/Cluster.hpp b/src/libs/database/include/database/objects/Cluster.hpp index f30e343d..01a60648 100644 --- a/src/libs/database/include/database/objects/Cluster.hpp +++ b/src/libs/database/include/database/objects/Cluster.hpp @@ -33,6 +33,7 @@ #include "database/objects/ClusterId.hpp" #include "database/objects/Release.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" namespace lms::db { diff --git a/src/libs/database/include/database/objects/Directory.hpp b/src/libs/database/include/database/objects/Directory.hpp index 3174f235..dd8ac918 100644 --- a/src/libs/database/include/database/objects/Directory.hpp +++ b/src/libs/database/include/database/objects/Directory.hpp @@ -29,6 +29,7 @@ #include #include "core/EnumSet.hpp" + #include "database/Object.hpp" #include "database/Types.hpp" #include "database/objects/ArtistId.hpp" @@ -36,6 +37,7 @@ #include "database/objects/MediaLibraryId.hpp" #include "database/objects/MediumId.hpp" #include "database/objects/ReleaseId.hpp" +#include "database/objects/Types.hpp" namespace lms::db { diff --git a/src/libs/database/include/database/objects/Listen.hpp b/src/libs/database/include/database/objects/Listen.hpp index b6882fa2..13d6f77a 100644 --- a/src/libs/database/include/database/objects/Listen.hpp +++ b/src/libs/database/include/database/objects/Listen.hpp @@ -31,6 +31,7 @@ #include "database/objects/ListenId.hpp" #include "database/objects/ReleaseId.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/Medium.hpp b/src/libs/database/include/database/objects/Medium.hpp index 97e8a64e..55c3dff5 100644 --- a/src/libs/database/include/database/objects/Medium.hpp +++ b/src/libs/database/include/database/objects/Medium.hpp @@ -33,6 +33,7 @@ #include "database/objects/ArtworkId.hpp" #include "database/objects/MediumId.hpp" #include "database/objects/ReleaseId.hpp" +#include "database/objects/Types.hpp" namespace lms::db { diff --git a/src/libs/database/include/database/objects/PodcastEpisode.hpp b/src/libs/database/include/database/objects/PodcastEpisode.hpp index 40389793..8db9c541 100644 --- a/src/libs/database/include/database/objects/PodcastEpisode.hpp +++ b/src/libs/database/include/database/objects/PodcastEpisode.hpp @@ -34,6 +34,7 @@ #include "database/objects/ArtworkId.hpp" #include "database/objects/PodcastEpisodeId.hpp" #include "database/objects/PodcastId.hpp" +#include "database/objects/Types.hpp" namespace lms::db { diff --git a/src/libs/database/include/database/objects/RatedArtist.hpp b/src/libs/database/include/database/objects/RatedArtist.hpp index 0a336d08..f007c493 100644 --- a/src/libs/database/include/database/objects/RatedArtist.hpp +++ b/src/libs/database/include/database/objects/RatedArtist.hpp @@ -28,6 +28,7 @@ #include "database/Types.hpp" #include "database/objects/ArtistId.hpp" #include "database/objects/RatedArtistId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/RatedRelease.hpp b/src/libs/database/include/database/objects/RatedRelease.hpp index 4096f380..3b0cf162 100644 --- a/src/libs/database/include/database/objects/RatedRelease.hpp +++ b/src/libs/database/include/database/objects/RatedRelease.hpp @@ -28,6 +28,7 @@ #include "database/Types.hpp" #include "database/objects/RatedReleaseId.hpp" #include "database/objects/ReleaseId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/RatedTrack.hpp b/src/libs/database/include/database/objects/RatedTrack.hpp index de944e5b..878b935f 100644 --- a/src/libs/database/include/database/objects/RatedTrack.hpp +++ b/src/libs/database/include/database/objects/RatedTrack.hpp @@ -28,6 +28,7 @@ #include "database/Types.hpp" #include "database/objects/RatedTrackId.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/Release.hpp b/src/libs/database/include/database/objects/Release.hpp index 7fe7c4c2..18999963 100644 --- a/src/libs/database/include/database/objects/Release.hpp +++ b/src/libs/database/include/database/objects/Release.hpp @@ -31,6 +31,7 @@ #include "core/EnumSet.hpp" #include "core/PartialDateTime.hpp" #include "core/UUID.hpp" + #include "database/IdRange.hpp" #include "database/Object.hpp" #include "database/Types.hpp" @@ -43,6 +44,7 @@ #include "database/objects/MediaLibraryId.hpp" #include "database/objects/ReleaseId.hpp" #include "database/objects/ReleaseTypeId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/StarredArtist.hpp b/src/libs/database/include/database/objects/StarredArtist.hpp index 3bca8939..3b91942a 100644 --- a/src/libs/database/include/database/objects/StarredArtist.hpp +++ b/src/libs/database/include/database/objects/StarredArtist.hpp @@ -26,6 +26,7 @@ #include "database/Types.hpp" #include "database/objects/ArtistId.hpp" #include "database/objects/StarredArtistId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/StarredRelease.hpp b/src/libs/database/include/database/objects/StarredRelease.hpp index 6f172d38..3f81c8de 100644 --- a/src/libs/database/include/database/objects/StarredRelease.hpp +++ b/src/libs/database/include/database/objects/StarredRelease.hpp @@ -26,6 +26,7 @@ #include "database/Types.hpp" #include "database/objects/ReleaseId.hpp" #include "database/objects/StarredReleaseId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/StarredTrack.hpp b/src/libs/database/include/database/objects/StarredTrack.hpp index 352b1ba7..9a6b1c58 100644 --- a/src/libs/database/include/database/objects/StarredTrack.hpp +++ b/src/libs/database/include/database/objects/StarredTrack.hpp @@ -28,6 +28,7 @@ #include "database/Types.hpp" #include "database/objects/StarredTrackId.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/Track.hpp b/src/libs/database/include/database/objects/Track.hpp index 1e410d7d..88f7e95f 100644 --- a/src/libs/database/include/database/objects/Track.hpp +++ b/src/libs/database/include/database/objects/Track.hpp @@ -34,6 +34,7 @@ #include "core/EnumSet.hpp" #include "core/PartialDateTime.hpp" #include "core/UUID.hpp" + #include "database/IdRange.hpp" #include "database/Object.hpp" #include "database/Types.hpp" @@ -48,6 +49,7 @@ #include "database/objects/TrackEmbeddedImageId.hpp" #include "database/objects/TrackId.hpp" #include "database/objects/TrackListId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db @@ -216,19 +218,28 @@ namespace lms::db static void updatePreferredArtwork(Session& session, TrackId trackId, ArtworkId artworkId); static void updatePreferredMediaArtwork(Session& session, TrackId trackId, ArtworkId artworkId); - // Accessors + // Setters void setScanVersion(std::size_t version) { _scanVersion = version; } - void setTrackNumber(std::optional num) { _trackNumber = num; } - void setName(std::string_view name); + + // File properties void setAbsoluteFilePath(const std::filesystem::path& filePath); void setFileSize(std::size_t fileSize) { _fileSize = fileSize; } void setLastWriteTime(const Wt::WDateTime& time) { _fileLastWrite = time; } void setAddedTime(const Wt::WDateTime& time) { _fileAdded = time; } - void setBitrate(std::size_t bitrate) { _bitrate = bitrate; } - void setBitsPerSample(std::size_t bitsPerSample) { _bitsPerSample = bitsPerSample; } + + // Audio properties void setDuration(std::chrono::milliseconds duration) { _duration = duration; } + void setContainer(ContainerType container) { _container = container; } + void setCodec(CodecType codec) { _codec = codec; } + void setBitrate(std::size_t bitrate) { _bitrate = bitrate; } void setChannelCount(std::size_t channelCount) { _channelCount = channelCount; } - void setSampleRate(std::size_t channelCount) { _sampleRate = channelCount; } + void setSampleRate(std::size_t sampleRate) { _sampleRate = sampleRate; } + void setBitsPerSample(std::optional bitsPerSample) { _bitsPerSample = bitsPerSample; } + void setReplayGain(std::optional replayGain) { _replayGain = replayGain; } + + // Metadata + void setTrackNumber(std::optional num) { _trackNumber = num; } + void setName(std::string_view name); void setDate(const core::PartialDateTime& date) { _date = date; } void setOriginalDate(const core::PartialDateTime& date) { _originalDate = date; } void setTrackMBID(const std::optional& MBID) { _trackMBID = MBID ? MBID->getAsString() : ""; } @@ -236,7 +247,6 @@ namespace lms::db void setCopyright(std::string_view copyright); void setCopyrightURL(std::string_view copyrightURL); void setAdvisory(Advisory advisory) { _advisory = advisory; } - void setReplayGain(std::optional replayGain) { _replayGain = replayGain; } void setArtistDisplayName(std::string_view name) { _artistDisplayName = name; } void setComment(std::string_view comment) { _comment = comment; } void clearArtistLinks(); @@ -254,32 +264,41 @@ namespace lms::db void setPreferredArtwork(ObjectPtr artwork); void setPreferredMediaArtwork(ObjectPtr artwork); + // Getters std::size_t getScanVersion() const { return _scanVersion; } - std::optional getTrackNumber() const { return _trackNumber; } - std::string getName() const { return _name; } + + // File properties const std::filesystem::path& getAbsoluteFilePath() const { return _absoluteFilePath; } long long getFileSize() const { return _fileSize; } - std::size_t getBitrate() const { return _bitrate; } - std::size_t getBitsPerSample() const { return _bitsPerSample; } - std::size_t getChannelCount() const { return _channelCount; } - std::chrono::milliseconds getDuration() const { return _duration; } - std::size_t getSampleRate() const { return _sampleRate; } const Wt::WDateTime& getLastWritten() const { return _fileLastWrite; } + const Wt::WDateTime& getAddedTime() const { return _fileAdded; } + + // Audio properties + std::chrono::milliseconds getDuration() const { return _duration; } + ContainerType getContainer() const { return _container; } + CodecType getCodec() const { return _codec; } + std::size_t getBitrate() const { return _bitrate; } + std::size_t getChannelCount() const { return _channelCount; } + std::size_t getSampleRate() const { return _sampleRate; } + std::optional getBitsPerSample() const { return _bitsPerSample; } + std::optional getReplayGain() const { return _replayGain; } + + // Metadata + std::optional getTrackNumber() const { return _trackNumber; } + std::string getName() const { return _name; } const core::PartialDateTime& getDate() const { return _date; } std::optional getYear() const; const core::PartialDateTime& getOriginalDate() const { return _originalDate; } std::optional getOriginalYear() const; const Wt::WDateTime& getLastWriteTime() const { return _fileLastWrite; } - const Wt::WDateTime& getAddedTime() const { return _fileAdded; } bool hasLyrics() const; std::optional getTrackMBID() const { return core::UUID::fromString(_trackMBID); } std::optional getRecordingMBID() const { return core::UUID::fromString(_recordingMBID); } std::optional getCopyright() const; std::optional getCopyrightURL() const; - Advisory getAdvisory() const { return _advisory; } - std::optional getReplayGain() const { return _replayGain; } std::string_view getArtistDisplayName() const { return _artistDisplayName; } std::string_view getComment() const { return _comment; } + Advisory getAdvisory() const { return _advisory; } // no artistLinkTypes means get all std::vector> getArtists(core::EnumSet artistLinkTypes) const; // no type means all @@ -304,27 +323,32 @@ namespace lms::db void persist(Action& a) { Wt::Dbo::field(a, _scanVersion, "scan_version"); - Wt::Dbo::field(a, _trackNumber, "track_number"); - Wt::Dbo::field(a, _name, "name"); - Wt::Dbo::field(a, _duration, "duration"); - Wt::Dbo::field(a, _bitrate, "bitrate"); - Wt::Dbo::field(a, _bitsPerSample, "bits_per_sample"); - Wt::Dbo::field(a, _channelCount, "channel_count"); - Wt::Dbo::field(a, _sampleRate, "sample_rate"); - Wt::Dbo::field(a, _date, "date"); - Wt::Dbo::field(a, _originalDate, "original_date"); + Wt::Dbo::field(a, _absoluteFilePath, "absolute_file_path"); Wt::Dbo::field(a, _fileSize, "file_size"); Wt::Dbo::field(a, _fileLastWrite, "file_last_write"); Wt::Dbo::field(a, _fileAdded, "file_added"); + + Wt::Dbo::field(a, _duration, "duration"); + Wt::Dbo::field(a, _container, "container"); + Wt::Dbo::field(a, _codec, "codec"); + Wt::Dbo::field(a, _bitrate, "bitrate"); + Wt::Dbo::field(a, _channelCount, "channel_count"); + Wt::Dbo::field(a, _sampleRate, "sample_rate"); + Wt::Dbo::field(a, _bitsPerSample, "bits_per_sample"); + Wt::Dbo::field(a, _replayGain, "replay_gain"); + + Wt::Dbo::field(a, _trackNumber, "track_number"); + Wt::Dbo::field(a, _name, "name"); + Wt::Dbo::field(a, _date, "date"); + Wt::Dbo::field(a, _originalDate, "original_date"); Wt::Dbo::field(a, _trackMBID, "mbid"); Wt::Dbo::field(a, _recordingMBID, "recording_mbid"); Wt::Dbo::field(a, _copyright, "copyright"); Wt::Dbo::field(a, _copyrightURL, "copyright_url"); - Wt::Dbo::field(a, _advisory, "advisory"); - Wt::Dbo::field(a, _replayGain, "replay_gain"); Wt::Dbo::field(a, _artistDisplayName, "artist_display_name"); Wt::Dbo::field(a, _comment, "comment"); // TODO: move in a dedicated table + Wt::Dbo::field(a, _advisory, "advisory"); Wt::Dbo::belongsTo(a, _medium, "medium", Wt::Dbo::OnDeleteCascade); Wt::Dbo::belongsTo(a, _release, "release", Wt::Dbo::OnDeleteCascade); @@ -347,27 +371,36 @@ namespace lms::db static constexpr std::size_t _maxCopyrightURLLength{ 512 }; int _scanVersion{}; - std::optional _trackNumber; - std::string _name; - int _bitrate{}; // in bps - int _bitsPerSample{}; - int _channelCount{}; - std::chrono::duration _duration{}; - int _sampleRate{}; - core::PartialDateTime _date; - core::PartialDateTime _originalDate; + + // File information std::filesystem::path _absoluteFilePath; // full path long long _fileSize{}; Wt::WDateTime _fileLastWrite; Wt::WDateTime _fileAdded; + + // Audio properties + std::chrono::duration _duration{}; + ContainerType _container{ ContainerType::Unknown }; + CodecType _codec{ CodecType::Unknown }; + int _bitrate{}; // in bps + int _channelCount{}; + int _sampleRate{}; + std::optional _bitsPerSample; + std::optional _replayGain; + + // Metadata + std::optional _trackNumber; + std::string _name; + core::PartialDateTime _date; + core::PartialDateTime _originalDate; std::string _trackMBID; std::string _recordingMBID; std::string _copyright; std::string _copyrightURL; - Advisory _advisory{ Advisory::UnSet }; - std::optional _replayGain; std::string _artistDisplayName; std::string _comment; + Advisory _advisory{ Advisory::UnSet }; + Wt::Dbo::ptr _medium; Wt::Dbo::ptr _release; Wt::Dbo::ptr _mediaLibrary; diff --git a/src/libs/database/include/database/objects/TrackArtistLink.hpp b/src/libs/database/include/database/objects/TrackArtistLink.hpp index f4e8406d..e10ec355 100644 --- a/src/libs/database/include/database/objects/TrackArtistLink.hpp +++ b/src/libs/database/include/database/objects/TrackArtistLink.hpp @@ -26,12 +26,14 @@ #include #include "core/EnumSet.hpp" + #include "database/IdType.hpp" #include "database/Object.hpp" #include "database/Types.hpp" #include "database/objects/ArtistId.hpp" #include "database/objects/ReleaseId.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" LMS_DECLARE_IDTYPE(TrackArtistLinkId) diff --git a/src/libs/database/include/database/objects/TrackEmbeddedImage.hpp b/src/libs/database/include/database/objects/TrackEmbeddedImage.hpp index 48d472cd..4237ec84 100644 --- a/src/libs/database/include/database/objects/TrackEmbeddedImage.hpp +++ b/src/libs/database/include/database/objects/TrackEmbeddedImage.hpp @@ -33,6 +33,7 @@ #include "database/objects/TrackEmbeddedImageId.hpp" #include "database/objects/TrackId.hpp" #include "database/objects/TrackListId.hpp" +#include "database/objects/Types.hpp" namespace lms::db { diff --git a/src/libs/database/include/database/objects/TrackEmbeddedImageLink.hpp b/src/libs/database/include/database/objects/TrackEmbeddedImageLink.hpp index ea670888..8334616c 100644 --- a/src/libs/database/include/database/objects/TrackEmbeddedImageLink.hpp +++ b/src/libs/database/include/database/objects/TrackEmbeddedImageLink.hpp @@ -25,9 +25,9 @@ #include #include "database/Object.hpp" -#include "database/Types.hpp" #include "database/objects/TrackEmbeddedImageId.hpp" #include "database/objects/TrackEmbeddedImageLinkId.hpp" +#include "database/objects/Types.hpp" namespace lms::db { diff --git a/src/libs/database/include/database/objects/TrackList.hpp b/src/libs/database/include/database/objects/TrackList.hpp index 37647203..81b712da 100644 --- a/src/libs/database/include/database/objects/TrackList.hpp +++ b/src/libs/database/include/database/objects/TrackList.hpp @@ -33,6 +33,7 @@ #include "database/objects/Filters.hpp" #include "database/objects/TrackId.hpp" #include "database/objects/TrackListId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/database/include/database/objects/TrackLyrics.hpp b/src/libs/database/include/database/objects/TrackLyrics.hpp index dd7c5c9c..ee7e35bf 100644 --- a/src/libs/database/include/database/objects/TrackLyrics.hpp +++ b/src/libs/database/include/database/objects/TrackLyrics.hpp @@ -32,6 +32,7 @@ #include "database/Object.hpp" #include "database/Types.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" LMS_DECLARE_IDTYPE(TrackLyricsId) diff --git a/src/libs/database/include/database/objects/Types.hpp b/src/libs/database/include/database/objects/Types.hpp new file mode 100644 index 00000000..966083be --- /dev/null +++ b/src/libs/database/include/database/objects/Types.hpp @@ -0,0 +1,315 @@ +/* + * Copyright (C) 2015 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 + +#include + +#include "core/LiteralString.hpp" +#include "core/TaggedType.hpp" + +namespace lms::db +{ + // For enums that have explicit values, never change enum values as they are stored in database. + // => only add new values or remove unused values, do not recycle values. + + struct YearRange + { + int begin{}; + int end{}; + }; + + struct FileInfo + { + Wt::WDateTime lastWrittenTime; + std::size_t scanVersion{}; + }; + + enum class ArtistSortMethod + { + None, + Id, + Name, + SortName, + Random, + LastWrittenDesc, + AddedDesc, + StarredDateDesc, + }; + + enum class ClusterSortMethod + { + None, + Name, + }; + + enum class DirectorySortMethod + { + None, + Name, + }; + + using ImageHashType = core::TaggedType; + + enum class LabelSortMethod + { + None, + Name, + }; + + enum class MediumSortMethod + { + None, + PositionAsc, + }; + + enum class PodcastEpisodeSortMode + { + None, + PubDateAsc, + PubDateDesc, + }; + + enum class ReleaseSortMethod + { + None, + Id, + Name, + SortName, + ArtistNameThenName, + DateAsc, + DateDesc, + OriginalDate, + OriginalDateDesc, + Random, + LastWrittenDesc, + AddedDesc, + StarredDateDesc, + }; + + enum class ReleaseTypeSortMethod + { + None, + Name, + }; + + enum class TrackArtistLinkSortMethod + { + None, + OriginalDateDesc, + }; + + enum class TrackEmbeddedImageSortMethod + { + None, + SizeDesc, + TrackNumberThenSizeDesc, + DiscNumberThenTrackNumberThenSizeDesc, + TrackListIndexAscThenSizeDesc, + }; + + enum class TrackListSortMethod + { + None, + Name, + LastModifiedDesc, + }; + + enum class TrackSortMethod + { + None, + Id, + Random, + LastWrittenDesc, + AddedDesc, + StarredDateDesc, + AbsoluteFilePath, + Name, + DateDescAndRelease, + OriginalDateDescAndRelease, + Release, // order by disc/track number + TrackList, // order by asc order in tracklist + TrackNumber, + }; + + enum class TrackLyricsSortMethod + { + None, + ExternalFirst, + EmbeddedFirst, + }; + + enum class ImageType + { + Unknown = 0, + Other = 1, + FileIcon = 2, + OtherFileIcon = 3, + FrontCover = 4, + BackCover = 5, + LeafletPage = 6, + Media = 7, + LeadArtist = 8, + Artist = 9, + Conductor = 10, + Band = 11, + Composer = 12, + Lyricist = 13, + RecordingLocation = 14, + DuringRecording = 15, + DuringPerformance = 16, + MovieScreenCapture = 17, + ColouredFish = 18, + Illustration = 19, + BandLogo = 20, + PublisherLogo = 21 + }; + + enum class TrackArtistLinkType + { + Artist = 0, // regular track artist + Arranger = 1, + Composer = 2, + Conductor = 3, + Lyricist = 4, + Mixer = 5, + Performer = 6, + Producer = 7, + ReleaseArtist = 8, + Remixer = 9, + Writer = 10, + }; + + core::LiteralString trackArtistLinkTypeToString(TrackArtistLinkType type); + + // User selectable transcoding output formats + enum class TranscodingOutputFormat + { + MP3 = 1, + OGG_OPUS = 2, + OGG_VORBIS = 3, + WEBM_VORBIS = 4, + MATROSKA_OPUS = 5, + }; + + using Bitrate = std::uint32_t; + void visitAllowedAudioBitrates(std::function); + bool isAudioBitrateAllowed(Bitrate bitrate); + + using Rating = int; + + enum class ScrobblingBackend + { + Internal = 0, + ListenBrainz = 1, + }; + + enum class FeedbackBackend + { + Internal = 0, + ListenBrainz = 1, + }; + + enum class SyncState + { + PendingAdd = 0, + Synchronized = 1, + PendingRemove = 2, + }; + + enum class UserType + { + REGULAR = 0, + ADMIN = 1, + DEMO = 2, + }; + + enum class UITheme + { + Light = 0, + Dark = 1, + }; + + enum class SubsonicArtistListMode + { + AllArtists = 0, + ReleaseArtists = 1, + TrackArtists = 2, + }; + + enum class TrackListType + { + PlayList = 0, // user controlled playlists + Internal = 1, // internal usage (current playqueue, history, ...) + }; + + enum class Advisory + { + UnSet = 0, + Unknown = 1, + Clean = 2, + Explicit = 3, + }; + + enum class ContainerType + { + Unknown = 0, + + AIFF = 1, + APE = 2, + ASF = 3, + DSF = 4, + FLAC = 5, + MP4 = 6, + MPC = 7, + MPEG = 8, + Ogg = 9, + Shorten = 10, + TrueAudio = 11, + WAV = 12, + WavPack = 13, + }; + + enum class CodecType + { + Unknown = 0, + + AAC = 1, + AC3 = 2, + ALAC = 3, + APE = 4, + DSD = 5, + EAC3 = 6, + FLAC = 7, + MP3 = 8, + MP4ALS = 9, + MPC7 = 10, + MPC8 = 11, + Opus = 12, + PCM = 13, + Shorten = 14, + TrueAudio = 15, + Vorbis = 16, + WavPack = 17, + WMA1 = 18, + WMA2 = 19, + WMA9Pro = 20, + WMA9Lossless = 21, + }; +} // namespace lms::db diff --git a/src/libs/database/include/database/objects/User.hpp b/src/libs/database/include/database/objects/User.hpp index ba731886..88dd21c0 100644 --- a/src/libs/database/include/database/objects/User.hpp +++ b/src/libs/database/include/database/objects/User.hpp @@ -28,8 +28,10 @@ #include "core/EnumSet.hpp" #include "core/UUID.hpp" + #include "database/Object.hpp" #include "database/Types.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/services/auth/include/services/auth/Types.hpp b/src/libs/services/auth/include/services/auth/Types.hpp index 4122b2d2..d1a4027e 100644 --- a/src/libs/services/auth/include/services/auth/Types.hpp +++ b/src/libs/services/auth/include/services/auth/Types.hpp @@ -22,7 +22,8 @@ #include #include "core/Exception.hpp" -#include "database/Types.hpp" + +#include "database/objects/Types.hpp" namespace lms::auth { diff --git a/src/libs/services/feedback/include/services/feedback/IFeedbackService.hpp b/src/libs/services/feedback/include/services/feedback/IFeedbackService.hpp index e1353b4a..f54858e2 100644 --- a/src/libs/services/feedback/include/services/feedback/IFeedbackService.hpp +++ b/src/libs/services/feedback/include/services/feedback/IFeedbackService.hpp @@ -30,6 +30,7 @@ #include "database/objects/Filters.hpp" #include "database/objects/ReleaseId.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" namespace lms::db diff --git a/src/libs/services/recommendation/impl/IEngine.hpp b/src/libs/services/recommendation/impl/IEngine.hpp index a072fba4..bdf48f7b 100644 --- a/src/libs/services/recommendation/impl/IEngine.hpp +++ b/src/libs/services/recommendation/impl/IEngine.hpp @@ -22,8 +22,9 @@ #include #include "core/EnumSet.hpp" -#include "database/Types.hpp" + #include "database/objects/TrackListId.hpp" +#include "database/objects/Types.hpp" #include "services/recommendation/Types.hpp" namespace lms::db diff --git a/src/libs/services/recommendation/include/services/recommendation/IRecommendationService.hpp b/src/libs/services/recommendation/include/services/recommendation/IRecommendationService.hpp index fabb9a0d..b0520482 100644 --- a/src/libs/services/recommendation/include/services/recommendation/IRecommendationService.hpp +++ b/src/libs/services/recommendation/include/services/recommendation/IRecommendationService.hpp @@ -23,10 +23,11 @@ #include #include "core/EnumSet.hpp" -#include "database/Types.hpp" + #include "database/objects/ArtistId.hpp" #include "database/objects/ReleaseId.hpp" #include "database/objects/TrackListId.hpp" +#include "database/objects/Types.hpp" #include "services/recommendation/Types.hpp" namespace lms::db diff --git a/src/libs/services/scanner/impl/scanners/audiofile/AudioFileScanOperation.cpp b/src/libs/services/scanner/impl/scanners/audiofile/AudioFileScanOperation.cpp index 502d14ab..b189e793 100644 --- a/src/libs/services/scanner/impl/scanners/audiofile/AudioFileScanOperation.cpp +++ b/src/libs/services/scanner/impl/scanners/audiofile/AudioFileScanOperation.cpp @@ -296,7 +296,7 @@ namespace lms::scanner return dbLyrics; } - db::ImageType convertImageType(audio::Image::Type type) + db::ImageType audioImageTypeToDbImageType(audio::Image::Type type) { switch (type) { @@ -349,6 +349,92 @@ namespace lms::scanner return db::ImageType::Unknown; } + db::ContainerType audioContainerToDbContainer(audio::ContainerType type) + { + switch (type) + { + case audio::ContainerType::AIFF: + return db::ContainerType::AIFF; + case audio::ContainerType::APE: + return db::ContainerType::APE; + case audio::ContainerType::ASF: + return db::ContainerType::ASF; + case audio::ContainerType::DSF: + return db::ContainerType::DSF; + case audio::ContainerType::FLAC: + return db::ContainerType::FLAC; + case audio::ContainerType::MP4: + return db::ContainerType::MP4; + case audio::ContainerType::MPC: + return db::ContainerType::MPC; + case audio::ContainerType::MPEG: + return db::ContainerType::MPEG; + case audio::ContainerType::Shorten: + return db::ContainerType::Shorten; + case audio::ContainerType::Ogg: + return db::ContainerType::Ogg; + case audio::ContainerType::TrueAudio: + return db::ContainerType::TrueAudio; + case audio::ContainerType::WAV: + return db::ContainerType::WAV; + case audio::ContainerType::WavPack: + return db::ContainerType::WavPack; + } + + return db::ContainerType::Unknown; + } + + db::CodecType audioCodecToDbCodec(audio::CodecType type) + { + switch (type) + { + case audio::CodecType::AAC: + return db::CodecType::AAC; + case audio::CodecType::AC3: + return db::CodecType::AC3; + case audio::CodecType::ALAC: + return db::CodecType::ALAC; + case audio::CodecType::APE: + return db::CodecType::APE; + case audio::CodecType::DSD: + return db::CodecType::DSD; + case audio::CodecType::EAC3: + return db::CodecType::EAC3; + case audio::CodecType::FLAC: + return db::CodecType::FLAC; + case audio::CodecType::MP3: + return db::CodecType::MP3; + case audio::CodecType::MP4ALS: + return db::CodecType::MP4ALS; + case audio::CodecType::MPC7: + return db::CodecType::MPC7; + case audio::CodecType::MPC8: + return db::CodecType::MPC8; + case audio::CodecType::Opus: + return db::CodecType::Opus; + case audio::CodecType::PCM: + return db::CodecType::PCM; + case audio::CodecType::Shorten: + return db::CodecType::Shorten; + case audio::CodecType::TrueAudio: + return db::CodecType::TrueAudio; + case audio::CodecType::Vorbis: + return db::CodecType::Vorbis; + case audio::CodecType::WavPack: + return db::CodecType::WavPack; + case audio::CodecType::WMA1: + return db::CodecType::WMA1; + case audio::CodecType::WMA2: + return db::CodecType::WMA2; + case audio::CodecType::WMA9Pro: + return db::CodecType::WMA9Pro; + case audio::CodecType::WMA9Lossless: + return db::CodecType::WMA9Lossless; + } + + return db::CodecType::Unknown; + } + db::TrackEmbeddedImage::pointer getOrCreateTrackEmbeddedImage(db::Session& session, const ImageInfo& imageInfo) { db::TrackEmbeddedImage::pointer image{ db::TrackEmbeddedImage::find(session, imageInfo.size, db::ImageHashType{ imageInfo.hash }) }; @@ -372,7 +458,7 @@ namespace lms::scanner const db::TrackEmbeddedImage::pointer image{ getOrCreateTrackEmbeddedImage(session, imageInfo) }; db::TrackEmbeddedImageLink::pointer imageLink{ session.create(dbTrack, image) }; imageLink.modify()->setIndex(imageInfo.index); - imageLink.modify()->setType(convertImageType(imageInfo.type)); + imageLink.modify()->setType(audioImageTypeToDbImageType(imageInfo.type)); imageLink.modify()->setDescription(imageInfo.description); return imageLink; @@ -695,11 +781,13 @@ namespace lms::scanner track.modify()->setScanVersion(getScannerSettings().audioScanVersion); // Audio properties - track.modify()->setBitrate(_file->audioProperties.bitrate); - track.modify()->setBitsPerSample(_file->audioProperties.bitsPerSample ? *_file->audioProperties.bitsPerSample : 0); - track.modify()->setChannelCount(_file->audioProperties.channelCount); track.modify()->setDuration(_file->audioProperties.duration); + track.modify()->setContainer(audioContainerToDbContainer(_file->audioProperties.container)); + track.modify()->setCodec(audioCodecToDbCodec(_file->audioProperties.codec)); + track.modify()->setBitrate(_file->audioProperties.bitrate); + track.modify()->setChannelCount(_file->audioProperties.channelCount); track.modify()->setSampleRate(_file->audioProperties.sampleRate); + track.modify()->setBitsPerSample(_file->audioProperties.bitsPerSample); track.modify()->setFileSize(getFileSize()); track.modify()->setLastWriteTime(getLastWriteTime()); diff --git a/src/libs/services/scrobbling/impl/listenbrainz/ListensSynchronizer.hpp b/src/libs/services/scrobbling/impl/listenbrainz/ListensSynchronizer.hpp index 25523e3b..3bd41c2f 100644 --- a/src/libs/services/scrobbling/impl/listenbrainz/ListensSynchronizer.hpp +++ b/src/libs/services/scrobbling/impl/listenbrainz/ListensSynchronizer.hpp @@ -26,7 +26,7 @@ #include #include -#include "database/Types.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" #include "services/scrobbling/Listen.hpp" diff --git a/src/libs/services/scrobbling/include/services/scrobbling/IScrobblingService.hpp b/src/libs/services/scrobbling/include/services/scrobbling/IScrobblingService.hpp index 3d0b2e09..ff5c016f 100644 --- a/src/libs/services/scrobbling/include/services/scrobbling/IScrobblingService.hpp +++ b/src/libs/services/scrobbling/include/services/scrobbling/IScrobblingService.hpp @@ -31,6 +31,7 @@ #include "database/objects/Filters.hpp" #include "database/objects/ReleaseId.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" #include "services/scrobbling/Listen.hpp" namespace lms::db diff --git a/src/libs/subsonic/impl/responses/Artist.hpp b/src/libs/subsonic/impl/responses/Artist.hpp index 3420d38b..89547fc5 100644 --- a/src/libs/subsonic/impl/responses/Artist.hpp +++ b/src/libs/subsonic/impl/responses/Artist.hpp @@ -23,7 +23,7 @@ #include #include "database/Object.hpp" -#include "database/Types.hpp" +#include "database/objects/Types.hpp" #include "SubsonicResponse.hpp" diff --git a/src/libs/subsonic/impl/responses/Song.cpp b/src/libs/subsonic/impl/responses/Song.cpp index 87a0d753..2a23f26b 100644 --- a/src/libs/subsonic/impl/responses/Song.cpp +++ b/src/libs/subsonic/impl/responses/Song.cpp @@ -183,7 +183,7 @@ namespace lms::api::subsonic return trackResponse; trackResponse.setAttribute("comment", track->getComment()); - trackResponse.setAttribute("bitDepth", track->getBitsPerSample()); + trackResponse.setAttribute("bitDepth", track->getBitsPerSample() ? *track->getBitsPerSample() : 0); trackResponse.setAttribute("samplingRate", track->getSampleRate()); trackResponse.setAttribute("channelCount", track->getChannelCount()); diff --git a/src/lms/ui/LmsApplication.hpp b/src/lms/ui/LmsApplication.hpp index 75dfee52..a7776097 100644 --- a/src/lms/ui/LmsApplication.hpp +++ b/src/lms/ui/LmsApplication.hpp @@ -26,7 +26,7 @@ #include #include "database/Object.hpp" -#include "database/Types.hpp" +#include "database/objects/Types.hpp" #include "database/objects/UserId.hpp" #include "services/scanner/ScannerEvents.hpp" diff --git a/src/lms/ui/MediaPlayer.hpp b/src/lms/ui/MediaPlayer.hpp index ea5472ac..b335d065 100644 --- a/src/lms/ui/MediaPlayer.hpp +++ b/src/lms/ui/MediaPlayer.hpp @@ -27,8 +27,8 @@ #include #include -#include "database/Types.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" namespace lms::ui { diff --git a/src/lms/ui/explore/ArtistCollector.hpp b/src/lms/ui/explore/ArtistCollector.hpp index 7d09cdb1..6d96602b 100644 --- a/src/lms/ui/explore/ArtistCollector.hpp +++ b/src/lms/ui/explore/ArtistCollector.hpp @@ -21,9 +21,10 @@ #include -#include "DatabaseCollectorBase.hpp" -#include "database/Types.hpp" #include "database/objects/ArtistId.hpp" +#include "database/objects/Types.hpp" + +#include "DatabaseCollectorBase.hpp" namespace lms::db { diff --git a/src/lms/ui/explore/ArtistListHelpers.hpp b/src/lms/ui/explore/ArtistListHelpers.hpp index 55a7fd0c..edde480a 100644 --- a/src/lms/ui/explore/ArtistListHelpers.hpp +++ b/src/lms/ui/explore/ArtistListHelpers.hpp @@ -23,9 +23,10 @@ #include -#include "common/ValueStringModel.hpp" #include "database/Object.hpp" -#include "database/Types.hpp" +#include "database/objects/Types.hpp" + +#include "common/ValueStringModel.hpp" namespace lms::db { diff --git a/src/lms/ui/explore/TrackListHelpers.hpp b/src/lms/ui/explore/TrackListHelpers.hpp index 3dbae791..ef4c0c36 100644 --- a/src/lms/ui/explore/TrackListHelpers.hpp +++ b/src/lms/ui/explore/TrackListHelpers.hpp @@ -27,10 +27,11 @@ #include #include "core/EnumSet.hpp" + #include "database/Object.hpp" -#include "database/Types.hpp" #include "database/objects/ArtistId.hpp" #include "database/objects/TrackId.hpp" +#include "database/objects/Types.hpp" namespace lms::db {