summaryrefslogtreecommitdiffstats
path: root/src/library/dao/trackdao.h
blob: 18582cc967b820bac06582cf61cb13feff2e4f1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#pragma once

#include <QFileInfo>
#include <QObject>
#include <QSet>
#include <QList>
#include <QSqlDatabase>
#include <QString>

#include "preferences/usersettings.h"
#include "library/dao/dao.h"
#include "library/relocatedtrack.h"
#include "track/globaltrackcache.h"
#include "util/class.h"
#include "util/memory.h"

class SqlTransaction;
class PlaylistDAO;
class AnalysisDao;
class CueDAO;
class LibraryHashDAO;

class TrackDAO : public QObject, public virtual DAO, public virtual GlobalTrackCacheRelocator {
    Q_OBJECT
  public:

    enum class ResolveTrackIdFlag : int {
        ResolveOnly = 0,
        UnhideHidden = 1,
        AddMissing = 2
    };
    Q_DECLARE_FLAGS(ResolveTrackIdFlags, ResolveTrackIdFlag)

    // The 'config object' is necessary because users decide ID3 tags get
    // synchronized on track metadata change
    TrackDAO(
            CueDAO& cueDao,
            PlaylistDAO& playlistDao,
            AnalysisDao& analysisDao,
            LibraryHashDAO& libraryHashDao,
            UserSettingsPointer pConfig);
    ~TrackDAO() override;

    void finish();

    QList<TrackId> resolveTrackIds(
            const QList<TrackFile> &trackFiles,
            ResolveTrackIdFlags flags = ResolveTrackIdFlag::ResolveOnly);

    TrackId getTrackIdByRef(
            const TrackRef& trackRef) const;
    QList<TrackRef> getAllTrackRefs(
            const QDir& rootDir) const;

    TrackPointer getTrackByRef(
            const TrackRef& trackRef) const;

    // Returns a set of all track locations in the library.
    QSet<QString> getAllTrackLocations() const;
    QString getTrackLocation(TrackId trackId) const;

    // Only used by friend class LibraryScanner, but public for testing!
    bool detectMovedTracks(
            QList<RelocatedTrack>* pRelocatedTracks,
            const QStringList& addedTracks,
            volatile const bool* pCancel) const;

    // Only used by friend class TrackCollection, but public for testing!
    void saveTrack(Track* pTrack) const;

  signals:
    // Forwarded from Track object
    void trackDirty(TrackId trackId);
    void trackClean(TrackId trackId);

    // Multiple tracks
    void tracksAdded(const QSet<TrackId>& trackIds);
    void tracksChanged(const QSet<TrackId>& trackIds);
    void tracksRemoved(const QSet<TrackId>& trackIds);

    void progressVerifyTracksOutside(const QString& path);
    void progressCoverArt(const QString& file);
    void forceModelUpdate();

  public slots:
    // Slots to inform the TrackDAO about changes that
    // have been applied directly to the database.
    void slotDatabaseTracksChanged(
            const QSet<TrackId>& changedTrackIds);
    void slotDatabaseTracksRelocated(
            const QList<RelocatedTrack>& relocatedTracks);

  private:
    friend class LibraryScanner;
    friend class TrackCollection;

    TrackId getTrackIdByLocation(
            const QString& location) const;
    TrackPointer getTrackById(
            TrackId trackId) const;

    // Loads a track from the database (by id if available, otherwise by location)
    // or adds it if not found in case the location is known. The (optional) out
    // parameter is set if the track has been found (-> true) or added (-> false).
    // Asynchronously imports cover art for newly added tracks. On failure a nullptr
    // is returned and pAlreadyInLibrary is left untouched.
    TrackPointer getOrAddTrack(
            const TrackRef& trackRef,
            bool* pAlreadyInLibrary = nullptr);

    void addTracksPrepare();
    TrackId addTracksAddTrack(
            const TrackPointer& pTrack,
            bool unremove);
    TrackPointer addTracksAddFile(
            const TrackFile& trackFile,
            bool unremove);
    void addTracksFinish(bool rollback = false);

    bool updateTrack(Track* pTrack) const;

    void hideAllTracks(const QDir& rootDir) const;

    bool hideTracks(
            const QList<TrackId>& trackIds) const;
    void afterHidingTracks(
            const QList<TrackId>& trackIds);

    bool unhideTracks(
            const QList<TrackId>& trackIds) const;
    void afterUnhidingTracks(
            const QList<TrackId>& trackIds);

    bool onPurgingTracks(
            const QList<TrackId>& trackIds) const;
    void afterPurgingTracks(
            const QList<TrackId>& trackIds);

    // Scanning related calls.
    void markTrackLocationsAsVerified(const QStringList& locations) const;
    void markTracksInDirectoriesAsVerified(const QStringList& directories) const;
    void invalidateTrackLocationsInLibrary() const;
    void markUnverifiedTracksAsDeleted();

    bool verifyRemainingTracks(
            const QStringList& libraryRootDirs,
            volatile const bool* pCancel);

    void detectCoverArtForTracksWithoutCover(volatile const bool* pCancel,
                                        QSet<TrackId>* pTracksChanged);

    // Callback for GlobalTrackCache
    TrackFile relocateCachedTrack(
            TrackId trackId,
            TrackFile fileInfo) override;

    CueDAO& m_cueDao;
    PlaylistDAO& m_playlistDao;
    AnalysisDao& m_analysisDao;
    LibraryHashDAO& m_libraryHashDao;

    UserSettingsPointer m_pConfig;

    std::unique_ptr<QSqlQuery> m_pQueryTrackLocationInsert;
    std::unique_ptr<QSqlQuery> m_pQueryTrackLocationSelect;
    std::unique_ptr<QSqlQuery> m_pQueryLibraryInsert;
    std::unique_ptr<QSqlQuery> m_pQueryLibraryUpdate;
    std::unique_ptr<QSqlQuery> m_pQueryLibrarySelect;
    std::unique_ptr<SqlTransaction> m_pTransaction;
    int m_trackLocationIdColumn;
    int m_queryLibraryIdColumn;
    int m_queryLibraryMixxxDeletedColumn;

    QSet<TrackId> m_tracksAddedSet;

    DISALLOW_COPY_AND_ASSIGN(TrackDAO);
};

Q_DECLARE_OPERATORS_FOR_FLAGS(TrackDAO::ResolveTrackIdFlags)