1 /* 2 * Copyright (C) 2015 Emeric Poupon 3 * 4 * This file is part of LMS. 5 * 6 * LMS is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * LMS is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with LMS. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #pragma once 21 22 #include <optional> 23 #include <string> 24 #include <unordered_set> 25 #include <vector> 26 27 #include <Wt/WDateTime.h> 28 #include <Wt/Dbo/Dbo.h> 29 30 #include "utils/EnumSet.hpp" 31 #include "utils/UUID.hpp" 32 33 #include "Types.hpp" 34 35 namespace Database 36 { 37 38 class Cluster; 39 class ClusterType; 40 class Release; 41 class Session; 42 class Track; 43 class TrackArtistLink; 44 class User; 45 46 class Artist : public Wt::Dbo::Dbo<Artist> 47 { 48 public: 49 50 enum class SortMethod 51 { 52 None, 53 ByName, 54 BySortName, 55 }; 56 57 using pointer = Wt::Dbo::ptr<Artist>; 58 Artist()59 Artist() {} 60 Artist(const std::string& name, const std::optional<UUID>& MBID = {}); 61 62 // Accessors 63 static pointer getByMBID(Session& session, const UUID& MBID); 64 static pointer getById(Session& session, IdType id); 65 static std::vector<pointer> getByName(Session& session, const std::string& name); // exact match on name field 66 static std::vector<pointer> getByClusters(Session& session, 67 const std::set<IdType>& clusters, // at least one track that belongs to these clusters 68 SortMethod sortMethod 69 ); 70 static std::vector<pointer> getByFilter(Session& session, 71 const std::set<IdType>& clusters, // if non empty, at least one artist that belongs to these clusters 72 const std::vector<std::string>& keywords, // if non empty, name must match all of these keywords (name + sort name fields) 73 std::optional<TrackArtistLinkType> linkType, // if set, only artists that have produced at least one track with this link type 74 SortMethod sortMethod, 75 std::optional<Range> range, 76 bool& moreExpected); 77 78 static std::vector<pointer> getAll(Session& session); 79 static std::vector<pointer> getAll(Session& session, SortMethod sortMethod); 80 static std::vector<pointer> getAll(Session& session, SortMethod sortMethod, std::optional<Range> range, bool& moreResults); 81 static std::vector<IdType> getAllIds(Session& session); 82 static std::vector<IdType> getAllIdsRandom(Session& session, const std::set<IdType>& clusters, std::optional<TrackArtistLinkType> linkType, std::optional<std::size_t> size = {}); 83 static std::vector<pointer> getAllOrphans(Session& session); // No track related 84 static std::vector<pointer> getLastWritten(Session& session, 85 std::optional<Wt::WDateTime> after, 86 const std::set<IdType>& clusters, 87 std::optional<TrackArtistLinkType> linkType, // if set, only artists that have produced at least one track with this link type 88 std::optional<Range>, 89 bool& moreResults); 90 static std::vector<IdType> getAllIdsWithClusters(Session& session, std::optional<std::size_t> limit = {}); 91 static std::vector<pointer> getStarred(Session& session, 92 Wt::Dbo::ptr<User> user, 93 const std::set<IdType>& clusters, 94 std::optional<TrackArtistLinkType> linkType, // if set, only artists that have produced at least one track with this link type 95 SortMethod sortMethod, 96 std::optional<Range>, bool& moreResults); 97 98 // Accessors getName() const99 const std::string& getName() const { return _name; } getSortName() const100 const std::string& getSortName() const { return _sortName; } getMBID() const101 std::optional<UUID> getMBID() const { return UUID::fromString(_MBID); } 102 103 std::vector<Wt::Dbo::ptr<Release>> getReleases(const std::set<IdType>& clusterIds = {}) const; // if non empty, get the releases that match all these clusters 104 std::size_t getReleaseCount() const; 105 std::vector<Wt::Dbo::ptr<Track>> getTracks(std::optional<TrackArtistLinkType> linkType = {}) const; 106 std::vector<Wt::Dbo::ptr<Track>> getTracksWithRelease(std::optional<TrackArtistLinkType> linkType = {}) const; 107 std::vector<Wt::Dbo::ptr<Track>> getRandomTracks(std::optional<std::size_t> count) const; 108 109 // No artistLinkTypes means get them all 110 std::vector<pointer> getSimilarArtists(EnumSet<TrackArtistLinkType> artistLinkTypes = {}, std::optional<Range> range = std::nullopt) const; 111 112 // Get the cluster of the tracks made by this artist 113 // Each clusters are grouped by cluster type, sorted by the number of occurence 114 // size is the max number of cluster per cluster type 115 std::vector<std::vector<Wt::Dbo::ptr<Cluster>>> getClusterGroups(std::vector<Wt::Dbo::ptr<ClusterType>> clusterTypes, std::size_t size) const; 116 setName(std::string_view name)117 void setName(std::string_view name) { _name = name; } setMBID(const std::optional<UUID> & mbid)118 void setMBID(const std::optional<UUID>& mbid) { _MBID = mbid ? mbid->getAsString() : ""; } 119 void setSortName(const std::string& sortName); 120 121 // Create 122 static pointer create(Session& session, const std::string& name, const std::optional<UUID>& UUID = {}); 123 124 template<class Action> persist(Action & a)125 void persist(Action& a) 126 { 127 Wt::Dbo::field(a, _name, "name"); 128 Wt::Dbo::field(a, _sortName, "sort_name"); 129 Wt::Dbo::field(a, _MBID, "mbid"); 130 131 Wt::Dbo::hasMany(a, _trackArtistLinks, Wt::Dbo::ManyToOne, "artist"); 132 Wt::Dbo::hasMany(a, _starringUsers, Wt::Dbo::ManyToMany, "user_release_starred", "", Wt::Dbo::OnDeleteCascade); 133 } 134 135 private: 136 137 static const std::size_t _maxNameLength = 128; 138 139 std::string _name; 140 std::string _sortName; 141 std::string _MBID; // Musicbrainz Identifier 142 143 Wt::Dbo::collection<Wt::Dbo::ptr<TrackArtistLink>> _trackArtistLinks; // Tracks involving this artist 144 Wt::Dbo::collection<Wt::Dbo::ptr<User>> _starringUsers; // Users that starred this artist 145 }; 146 147 } // namespace Database 148 149