/* * 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 #include #include #include #include #include #include #include "core/EnumSet.hpp" #include "core/UUID.hpp" #include "database/ArtistId.hpp" #include "database/ClusterId.hpp" #include "database/DirectoryId.hpp" #include "database/LabelId.hpp" #include "database/MediaLibraryId.hpp" #include "database/Object.hpp" #include "database/ReleaseId.hpp" #include "database/ReleaseTypeId.hpp" #include "database/Types.hpp" #include "database/UserId.hpp" namespace lms::db { class Artist; class Cluster; class ClusterType; class Image; class Release; class Session; class Track; class User; class Label final : public Object { public: Label() = default; static std::size_t getCount(Session& session); static pointer find(Session& session, LabelId id); static pointer find(Session& session, std::string_view name); static RangeResults findOrphanIds(Session& session, std::optional range = std::nullopt); // Accessors std::string_view getName() const { return _name; } template void persist(Action& a) { Wt::Dbo::field(a, _name, "name"); Wt::Dbo::hasMany(a, _releases, Wt::Dbo::ManyToMany, "release_label", "", Wt::Dbo::OnDeleteCascade); } private: static constexpr std::size_t _maxNameLength{ 512 }; friend class Session; Label(std::string_view name); static pointer create(Session& session, std::string_view name); std::string _name; Wt::Dbo::collection> _releases; // releases that match this label }; class ReleaseType final : public Object { public: ReleaseType() = default; static std::size_t getCount(Session& session); static pointer find(Session& session, ReleaseTypeId id); static pointer find(Session& session, std::string_view name); static RangeResults findOrphanIds(Session& session, std::optional range = std::nullopt); // Accessors std::string_view getName() const { return _name; } template void persist(Action& a) { Wt::Dbo::field(a, _name, "name"); Wt::Dbo::hasMany(a, _releases, Wt::Dbo::ManyToMany, "release_release_type", "", Wt::Dbo::OnDeleteCascade); } private: static constexpr std::size_t _maxNameLength{ 512 }; friend class Session; ReleaseType(std::string_view name); static pointer create(Session& session, std::string_view name); std::string _name; Wt::Dbo::collection> _releases; // releases that match this type }; class Release final : public Object { public: struct FindParameters { std::vector clusters; // if non empty, releases that belong to these clusters std::vector keywords; // if non empty, name must match all of these keywords (cannot be set with keywords) std::string name; // must match this name (cannot be set with keywords) ReleaseSortMethod sortMethod{ ReleaseSortMethod::None }; std::optional range; Wt::WDateTime writtenAfter; std::optional dateRange; UserId starringUser; // only releases starred by this user std::optional feedbackBackend; // and for this backend ArtistId artist; // only releases that involved this user core::EnumSet trackArtistLinkTypes; // and for these link types core::EnumSet excludedTrackArtistLinkTypes; // but not for these link types std::string releaseType; // If set, albums that has this release type MediaLibraryId mediaLibrary; // If set, releases that has at least a track in this library DirectoryId directory; // if set, releases in this directory (cannot be set with parent directory) DirectoryId parentDirectory; // if set, releases in this parent directory (cannot be set with directory) FindParameters& setClusters(std::span _clusters) { clusters.assign(std::cbegin(_clusters), std::cend(_clusters)); return *this; } FindParameters& setKeywords(const std::vector& _keywords) { keywords = _keywords; return *this; } FindParameters& setName(std::string_view _name) { name = _name; return *this; } FindParameters& setSortMethod(ReleaseSortMethod _sortMethod) { sortMethod = _sortMethod; return *this; } FindParameters& setRange(std::optional _range) { range = _range; return *this; } FindParameters& setWrittenAfter(const Wt::WDateTime& _after) { writtenAfter = _after; return *this; } FindParameters& setDateRange(const std::optional& _dateRange) { dateRange = _dateRange; return *this; } FindParameters& setStarringUser(UserId _user, FeedbackBackend _feedbackBackend) { starringUser = _user; feedbackBackend = _feedbackBackend; return *this; } FindParameters& setArtist(ArtistId _artist, core::EnumSet _trackArtistLinkTypes = {}, core::EnumSet _excludedTrackArtistLinkTypes = {}) { artist = _artist; trackArtistLinkTypes = _trackArtistLinkTypes; excludedTrackArtistLinkTypes = _excludedTrackArtistLinkTypes; return *this; } FindParameters& setReleaseType(std::string_view _releaseType) { releaseType = _releaseType; return *this; } FindParameters& setMediaLibrary(MediaLibraryId _mediaLibrary) { mediaLibrary = _mediaLibrary; return *this; } FindParameters& setDirectory(DirectoryId _directory) { directory = _directory; return *this; } FindParameters& setParentDirectory(DirectoryId _parentDirectory) { parentDirectory = _parentDirectory; return *this; } }; Release() = default; // Accessors static std::size_t getCount(Session& session); static bool exists(Session& session, ReleaseId id); static pointer find(Session& session, const core::UUID& MBID); static pointer find(Session& session, ReleaseId id); static void find(Session& session, ReleaseId& lastRetrievedRelease, std::size_t count, const std::function& func, MediaLibraryId library = {}); static RangeResults find(Session& session, const FindParameters& parameters); static void find(Session& session, const FindParameters& parameters, const std::function& func); static RangeResults findIds(Session& session, const FindParameters& parameters); static std::size_t getCount(Session& session, const FindParameters& parameters); static RangeResults findOrphanIds(Session& session, std::optional range = std::nullopt); // not track related // Get the cluster of the tracks that belong to this release // Each clusters are grouped by cluster type, sorted by the number of occurence (max to min) // size is the max number of cluster per cluster type std::vector>> getClusterGroups(const std::vector& clusterTypeIds, std::size_t size) const; // Utility functions (if all tracks have the same values, which is legit to not be the case) Wt::WDate getDate() const; std::optional getYear() const; Wt::WDate getOriginalDate() const; std::optional getOriginalYear() const; std::optional getCopyright() const; std::optional getCopyrightURL() const; std::size_t getMeanBitrate() const; // Accessors std::string_view getName() const { return _name; } std::string_view getSortName() const { return _sortName; } std::optional getMBID() const { return core::UUID::fromString(_MBID); } std::optional getGroupMBID() const { return core::UUID::fromString(_groupMBID); } std::optional getTotalDisc() const { return _totalDisc; } std::size_t getDiscCount() const; // may not be total disc (if incomplete for example) std::vector getDiscs() const; std::chrono::milliseconds getDuration() const; Wt::WDateTime getLastWritten() const; std::string_view getArtistDisplayName() const { return _artistDisplayName; } bool isCompilation() const { return _isCompilation; } std::size_t getTrackCount() const; std::vector> getReleaseTypes() const; std::vector getLabelNames() const; std::vector getReleaseTypeNames() const; void visitLabels(const std::function& _func) const; std::string_view getBarcode() const { return _barcode; } ObjectPtr getImage() const; // Setters void setName(std::string_view name) { _name = name; } void setSortName(std::string_view sortName) { _sortName = sortName; } void setMBID(const std::optional& mbid) { _MBID = mbid ? mbid->getAsString() : ""; } void setGroupMBID(const std::optional& mbid) { _groupMBID = mbid ? mbid->getAsString() : ""; } void setTotalDisc(std::optional totalDisc) { _totalDisc = totalDisc; } void setArtistDisplayName(std::string_view name) { _artistDisplayName = name; } void setCompilation(bool value) { _isCompilation = value; } void clearLabels(); void clearReleaseTypes(); void addLabel(ObjectPtr