1 #pragma once
2 
3 #include <QHash>
4 #include <QObject>
5 #include <QSqlDatabase>
6 #include <QSet>
7 
8 #include "library/dao/dao.h"
9 #include "track/trackid.h"
10 #include "util/class.h"
11 
12 #define PLAYLIST_TABLE "Playlists"
13 #define PLAYLIST_TRACKS_TABLE "PlaylistTracks"
14 
15 const QString PLAYLISTTABLE_ID = QStringLiteral("id");
16 const QString PLAYLISTTABLE_NAME = QStringLiteral("name");
17 const QString PLAYLISTTABLE_POSITION = QStringLiteral("position");
18 const QString PLAYLISTTABLE_HIDDEN = QStringLiteral("hidden");
19 const QString PLAYLISTTABLE_DATECREATED = QStringLiteral("date_created");
20 const QString PLAYLISTTABLE_DATEMODIFIED = QStringLiteral("date_modified");
21 
22 const QString PLAYLISTTRACKSTABLE_TRACKID = QStringLiteral("track_id");
23 const QString PLAYLISTTRACKSTABLE_POSITION = QStringLiteral("position");
24 const QString PLAYLISTTRACKSTABLE_PLAYLISTID = QStringLiteral("playlist_id");
25 const QString PLAYLISTTRACKSTABLE_DATETIMEADDED = QStringLiteral("pl_datetime_added");
26 
27 #define AUTODJ_TABLE "Auto DJ"
28 
29 class AutoDJProcessor;
30 
31 class PlaylistDAO : public QObject, public virtual DAO {
32     Q_OBJECT
33   public:
34     enum HiddenType {
35         PLHT_NOT_HIDDEN = 0,
36         PLHT_AUTO_DJ = 1,
37         PLHT_SET_LOG = 2,
38         PLHT_UNKNOWN = -1
39     };
40 
41     enum class AutoDJSendLoc {
42         TOP,
43         BOTTOM,
44         REPLACE,
45     };
46 
47     PlaylistDAO();
48     ~PlaylistDAO() override = default;
49 
50     void initialize(const QSqlDatabase& database) override;
51 
52     // Create a playlist, fails with -1 if already exists
53     int createPlaylist(const QString& name, const HiddenType type = PLHT_NOT_HIDDEN);
54     // Create a playlist, appends "(n)" if already exists, name becomes the new name
55     int createUniquePlaylist(QString* pName, const HiddenType type = PLHT_NOT_HIDDEN);
56     // Delete a playlist
57     void deletePlaylist(const int playlistId);
58     // Rename a playlist
59     void renamePlaylist(const int playlistId, const QString& newName);
60     // Lock or unlock a playlist
61     bool setPlaylistLocked(const int playlistId, const bool locked);
62     // Find out the state of a playlist lock
63     bool isPlaylistLocked(const int playlistId) const;
64     // Append a list of tracks to a playlist
65     bool appendTracksToPlaylist(const QList<TrackId>& trackIds, const int playlistId);
66     // Append a track to a playlist
67     bool appendTrackToPlaylist(TrackId trackId, const int playlistId);
68     // Find out how many playlists exist.
69     unsigned int playlistCount() const;
70     // Find out the name of the playlist at the given Id
71     QString getPlaylistName(const int playlistId) const;
72     // Get the playlist id by its name
73     int getPlaylistIdFromName(const QString& name) const;
74     // Get the id of the playlist at index. Note that the index is the natural
75     // position in the database table, not the display order position column
76     // stored in the database.
77     int getPlaylistId(const int index) const;
78     QList<TrackId> getTrackIds(const int playlistId) const;
79     // Returns true if the playlist with playlistId is hidden
80     bool isHidden(const int playlistId) const;
81     // Returns the HiddenType of playlistId
82     HiddenType getHiddenType(const int playlistId) const;
83     // Returns the maximum position of the given playlist
84     int getMaxPosition(const int playlistId) const;
85     // Remove a track from all playlists
86     void removeTracksFromPlaylists(const QList<TrackId>& trackIds);
87     // removes all hidden and purged Tracks from the playlist
88     void removeHiddenTracks(const int playlistId);
89     // Remove a track from a playlist
90     void removeTrackFromPlaylist(int playlistId, int position);
91     void removeTracksFromPlaylist(int playlistId, const QList<int>& positions);
92     void removeTracksFromPlaylistById(int playlistId, TrackId trackId);
93     // Insert a track into a specific position in a playlist
94     bool insertTrackIntoPlaylist(TrackId trackId, int playlistId, int position);
95     // Inserts a list of tracks into playlist
96     int insertTracksIntoPlaylist(const QList<TrackId>& trackIds, const int playlistId, int position);
97     // Add a playlist to the Auto-DJ Queue
98     void addPlaylistToAutoDJQueue(const int playlistId, AutoDJSendLoc loc);
99     // Add a list of tracks to the Auto-DJ Queue
100     void addTracksToAutoDJQueue(const QList<TrackId>& trackIds, AutoDJSendLoc loc);
101     // Get the preceding playlist of currentPlaylistId with the HiddenType
102     // hidden. Returns -1 if no such playlist exists.
103     int getPreviousPlaylist(const int currentPlaylistId, HiddenType hidden) const;
104     // Append all the tracks in the source playlist to the target playlist.
105     bool copyPlaylistTracks(const int sourcePlaylistID, const int targetPlaylistID);
106     // Returns the number of tracks in the given playlist.
107     int tracksInPlaylist(const int playlistId) const;
108     // moved Track to a new position
109     void moveTrack(const int playlistId,
110             const int oldPosition, const int newPosition);
111     // shuffles all tracks in the position List
112     void shuffleTracks(const int playlistId, const QList<int>& positions, const QHash<int,TrackId>& allIds);
113     bool isTrackInPlaylist(TrackId trackId, const int playlistId) const;
114 
115     void getPlaylistsTrackIsIn(TrackId trackId, QSet<int>* playlistSet) const;
116 
117     void setAutoDJProcessor(AutoDJProcessor* pAutoDJProcessor);
118 
119   signals:
120     void added(int playlistId);
121     void deleted(int playlistId);
122     void renamed(int playlistId, const QString& newName);
123     void lockChanged(int playlistId);
124     void trackAdded(int playlistId, TrackId trackId, int position);
125     void trackRemoved(int playlistId, TrackId trackId, int position);
126     void tracksChanged(const QSet<int>& playlistIds); // added/removed/reordered
127 
128   private:
129     bool removeTracksFromPlaylist(int playlistId, int startIndex);
130     void removeTracksFromPlaylistInner(int playlistId, int position);
131     void removeTracksFromPlaylistByIdInner(int playlistId, TrackId trackId);
132     void searchForDuplicateTrack(const int fromPosition,
133                                  const int toPosition,
134                                  TrackId trackID,
135                                  const int excludePosition,
136                                  const int otherTrackPosition,
137                                  const QHash<int,TrackId>* pTrackPositionIds,
138                                  int* pTrackDistance);
139     void populatePlaylistMembershipCache();
140 
141     QMultiHash<TrackId, int> m_playlistsTrackIsIn;
142     AutoDJProcessor* m_pAutoDJProcessor;
143     DISALLOW_COPY_AND_ASSIGN(PlaylistDAO);
144 };
145