Store container and codec info in database

This commit is contained in:
emeric
2025-11-26 21:48:57 +01:00
parent 32177e0583
commit 37d603d72c
39 changed files with 618 additions and 306 deletions
+1 -1
View File
@@ -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
)
+90 -1
View File
@@ -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{};
@@ -17,9 +17,9 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "database/Types.hpp"
#include "database/objects/Types.hpp"
#include <set>
#include <unordered_set>
namespace lms::db
{
@@ -54,7 +54,7 @@ namespace lms::db
return "unknown";
}
static const std::set<Bitrate> allowedAudioBitrates{
static const std::unordered_set<Bitrate> allowedAudioBitrates{
64000,
96000,
128000,
@@ -21,14 +21,10 @@
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <functional>
#include <Wt/WDate.h>
#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<class ImageHash, std::uint64_t>;
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<void(Bitrate)>);
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
@@ -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
@@ -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
{
@@ -29,6 +29,7 @@
#include <Wt/Dbo/Field.h>
#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
{
@@ -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
@@ -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
{
@@ -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
{
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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<int> 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<std::size_t> bitsPerSample) { _bitsPerSample = bitsPerSample; }
void setReplayGain(std::optional<float> replayGain) { _replayGain = replayGain; }
// Metadata
void setTrackNumber(std::optional<int> 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<core::UUID>& 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<float> 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> artwork);
void setPreferredMediaArtwork(ObjectPtr<Artwork> artwork);
// Getters
std::size_t getScanVersion() const { return _scanVersion; }
std::optional<std::size_t> 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<std::size_t> getBitsPerSample() const { return _bitsPerSample; }
std::optional<float> getReplayGain() const { return _replayGain; }
// Metadata
std::optional<std::size_t> getTrackNumber() const { return _trackNumber; }
std::string getName() const { return _name; }
const core::PartialDateTime& getDate() const { return _date; }
std::optional<int> getYear() const;
const core::PartialDateTime& getOriginalDate() const { return _originalDate; }
std::optional<int> getOriginalYear() const;
const Wt::WDateTime& getLastWriteTime() const { return _fileLastWrite; }
const Wt::WDateTime& getAddedTime() const { return _fileAdded; }
bool hasLyrics() const;
std::optional<core::UUID> getTrackMBID() const { return core::UUID::fromString(_trackMBID); }
std::optional<core::UUID> getRecordingMBID() const { return core::UUID::fromString(_recordingMBID); }
std::optional<std::string> getCopyright() const;
std::optional<std::string> getCopyrightURL() const;
Advisory getAdvisory() const { return _advisory; }
std::optional<float> 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<ObjectPtr<Artist>> getArtists(core::EnumSet<TrackArtistLinkType> 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<int> _trackNumber;
std::string _name;
int _bitrate{}; // in bps
int _bitsPerSample{};
int _channelCount{};
std::chrono::duration<int, std::milli> _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<int, std::milli> _duration{};
ContainerType _container{ ContainerType::Unknown };
CodecType _codec{ CodecType::Unknown };
int _bitrate{}; // in bps
int _channelCount{};
int _sampleRate{};
std::optional<int> _bitsPerSample;
std::optional<float> _replayGain;
// Metadata
std::optional<int> _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<float> _replayGain;
std::string _artistDisplayName;
std::string _comment;
Advisory _advisory{ Advisory::UnSet };
Wt::Dbo::ptr<Medium> _medium;
Wt::Dbo::ptr<Release> _release;
Wt::Dbo::ptr<MediaLibrary> _mediaLibrary;
@@ -26,12 +26,14 @@
#include <Wt/Dbo/Field.h>
#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)
@@ -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
{
@@ -25,9 +25,9 @@
#include <Wt/Dbo/Field.h>
#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
{
@@ -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
@@ -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)
@@ -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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <Wt/WDate.h>
#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<class ImageHash, std::uint64_t>;
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<void(Bitrate)>);
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
@@ -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
@@ -22,7 +22,8 @@
#include <string>
#include "core/Exception.hpp"
#include "database/Types.hpp"
#include "database/objects/Types.hpp"
namespace lms::auth
{
@@ -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
@@ -22,8 +22,9 @@
#include <memory>
#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
@@ -23,10 +23,11 @@
#include <vector>
#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
@@ -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<db::TrackEmbeddedImageLink>(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());
@@ -26,7 +26,7 @@
#include <boost/asio/io_context_strand.hpp>
#include <boost/asio/steady_timer.hpp>
#include "database/Types.hpp"
#include "database/objects/Types.hpp"
#include "database/objects/UserId.hpp"
#include "services/scrobbling/Listen.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
+1 -1
View File
@@ -23,7 +23,7 @@
#include <vector>
#include "database/Object.hpp"
#include "database/Types.hpp"
#include "database/objects/Types.hpp"
#include "SubsonicResponse.hpp"
+1 -1
View File
@@ -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());
+1 -1
View File
@@ -26,7 +26,7 @@
#include <Wt/WApplication.h>
#include "database/Object.hpp"
#include "database/Types.hpp"
#include "database/objects/Types.hpp"
#include "database/objects/UserId.hpp"
#include "services/scanner/ScannerEvents.hpp"
+1 -1
View File
@@ -27,8 +27,8 @@
#include <Wt/WTemplate.h>
#include <Wt/WText.h>
#include "database/Types.hpp"
#include "database/objects/TrackId.hpp"
#include "database/objects/Types.hpp"
namespace lms::ui
{
+3 -2
View File
@@ -21,9 +21,10 @@
#include <optional>
#include "DatabaseCollectorBase.hpp"
#include "database/Types.hpp"
#include "database/objects/ArtistId.hpp"
#include "database/objects/Types.hpp"
#include "DatabaseCollectorBase.hpp"
namespace lms::db
{
+3 -2
View File
@@ -23,9 +23,10 @@
#include <Wt/WTemplate.h>
#include "common/ValueStringModel.hpp"
#include "database/Object.hpp"
#include "database/Types.hpp"
#include "database/objects/Types.hpp"
#include "common/ValueStringModel.hpp"
namespace lms::db
{
+2 -1
View File
@@ -27,10 +27,11 @@
#include <Wt/WWidget.h>
#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
{