File indexing completed on 2024-04-21 04:48:57
0001 /* 0002 SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr> 0003 0004 SPDX-License-Identifier: LGPL-3.0-or-later 0005 */ 0006 0007 #ifndef DATABASEINTERFACE_H 0008 #define DATABASEINTERFACE_H 0009 0010 #include "elisaLib_export.h" 0011 0012 #include "elisautils.h" 0013 #include "datatypes.h" 0014 0015 #include <QObject> 0016 #include <QString> 0017 #include <QHash> 0018 #include <QList> 0019 #include <QUrl> 0020 #include <QDateTime> 0021 0022 #include <memory> 0023 #include <optional> 0024 0025 class DatabaseInterfacePrivate; 0026 class QSqlRecord; 0027 class QSqlQuery; 0028 0029 class ELISALIB_EXPORT DatabaseInterface : public QObject 0030 { 0031 Q_OBJECT 0032 0033 public: 0034 0035 enum DatabaseVersion { 0036 V9 = 9, 0037 V11 = 11, 0038 V12 = 12, 0039 V13 = 13, 0040 V14 = 14, 0041 V15 = 15, 0042 V16 = 16, 0043 V17 = 17, 0044 }; 0045 0046 explicit DatabaseInterface(QObject *parent = nullptr); 0047 0048 ~DatabaseInterface() override; 0049 0050 Q_INVOKABLE void init(const QString &dbName, const QString &databaseFileName = {}); 0051 0052 qulonglong albumIdFromTitleAndArtist(const QString &title, const QString &artist, const QString &albumPath); 0053 0054 DataTypes::ListTrackDataType allTracksData(); 0055 0056 DataTypes::ListRadioDataType allRadiosData(); 0057 0058 DataTypes::ListTrackDataType recentlyPlayedTracksData(int count); 0059 0060 DataTypes::ListTrackDataType frequentlyPlayedTracksData(int count); 0061 0062 DataTypes::ListAlbumDataType allAlbumsData(); 0063 0064 DataTypes::ListAlbumDataType allAlbumsDataByGenreAndArtist(const QString &genre, const QString &artist); 0065 0066 DataTypes::ListAlbumDataType allAlbumsDataByArtist(const QString &artist); 0067 0068 DataTypes::AlbumDataType albumDataFromDatabaseId(qulonglong id); 0069 0070 DataTypes::ListTrackDataType albumData(qulonglong databaseId); 0071 0072 DataTypes::ListArtistDataType allArtistsData(); 0073 0074 DataTypes::ListArtistDataType allArtistsDataByGenre(const QString &genre); 0075 0076 DataTypes::ArtistDataType artistDataFromDatabaseId(qulonglong id); 0077 0078 qulonglong artistIdFromName(const QString &name); 0079 0080 DataTypes::ListGenreDataType allGenresData(); 0081 0082 bool internalArtistMatchGenre(qulonglong databaseId, const QString &genre); 0083 0084 DataTypes::ListTrackDataType tracksDataFromAuthor(const QString &artistName); 0085 0086 DataTypes::ListTrackDataType tracksDataFromGenre(const QString &genre); 0087 0088 DataTypes::TrackDataType trackDataFromDatabaseId(qulonglong id); 0089 0090 DataTypes::TrackDataType trackDataFromDatabaseIdAndUrl(qulonglong id, const QUrl &trackUrl); 0091 0092 DataTypes::TrackDataType radioDataFromDatabaseId(qulonglong id); 0093 0094 qulonglong trackIdFromTitleAlbumTrackDiscNumber(const QString &title, const QString &artist, const std::optional<QString> &album, std::optional<int> trackNumber, std::optional<int> discNumber); 0095 0096 qulonglong trackIdFromFileName(const QUrl &fileName); 0097 0098 qulonglong radioIdFromFileName(const QUrl &fileName); 0099 0100 void applicationAboutToQuit(); 0101 0102 Q_SIGNALS: 0103 0104 void artistsAdded(const DataTypes::ListArtistDataType &newArtists); 0105 0106 void composersAdded(const DataTypes::ListArtistDataType &newComposers); 0107 0108 void lyricistsAdded(const DataTypes::ListArtistDataType &newLyricists); 0109 0110 void albumsAdded(const DataTypes::ListAlbumDataType &newAlbums); 0111 0112 void tracksAdded(const DataTypes::ListTrackDataType &allTracks); 0113 0114 void genresAdded(const DataTypes::ListGenreDataType &allGenres); 0115 0116 void artistRemoved(qulonglong removedArtistId); 0117 0118 void albumRemoved(qulonglong removedAlbumId); 0119 0120 void trackRemoved(qulonglong id); 0121 0122 void albumModified(const DataTypes::AlbumDataType &modifiedAlbum, qulonglong modifiedAlbumId); 0123 0124 void trackModified(const DataTypes::TrackDataType &modifiedTrack); 0125 0126 void requestsInitDone(); 0127 0128 void databaseError(); 0129 0130 void restoredTracks(const QHash<QUrl, QDateTime> &allFiles); 0131 0132 void cleanedDatabase(); 0133 0134 void finishInsertingTracksList(); 0135 0136 void finishRemovingTracksList(); 0137 0138 void radioAdded(const DataTypes::TrackDataType &radio); 0139 0140 void radioModified(const DataTypes::TrackDataType &radio); 0141 0142 void radioRemoved(qulonglong radioId); 0143 0144 public Q_SLOTS: 0145 0146 void insertTracksList(const DataTypes::ListTrackDataType &tracks, const QHash<QString, QUrl> &covers); 0147 0148 void removeTracksList(const QList<QUrl> &removedTracks); 0149 0150 void askRestoredTracks(); 0151 0152 void trackHasStartedPlaying(const QUrl &fileName, const QDateTime &time); 0153 0154 void trackHasFinishedPlaying(const QUrl &fileName, const QDateTime &time); 0155 0156 void clearData(); 0157 0158 void removeRadio(qulonglong radioId); 0159 0160 private: 0161 0162 enum class DatabaseState { 0163 GoodState, 0164 BadState, 0165 }; 0166 0167 /********* Init and upgrade methods *********/ 0168 0169 void initConnection(const QString &connectionName, const QString &databaseFileName); 0170 0171 bool initDatabase(); 0172 0173 void createDatabaseV9(); 0174 0175 void upgradeDatabaseV9(); 0176 0177 void upgradeDatabaseV11(); 0178 0179 void upgradeDatabaseV12(); 0180 0181 void upgradeDatabaseV13(); 0182 0183 void upgradeDatabaseV14(); 0184 0185 void upgradeDatabaseV15(); 0186 0187 void upgradeDatabaseV16(); 0188 0189 void upgradeDatabaseV17(); 0190 0191 [[nodiscard]] DatabaseState checkDatabaseSchema() const; 0192 0193 [[nodiscard]] DatabaseState checkTable(const QString &tableName, const QStringList &expectedColumns) const; 0194 0195 bool resetDatabase(); 0196 0197 DatabaseVersion currentDatabaseVersion(); 0198 0199 bool upgradeDatabaseToLatestVersion(); 0200 0201 void dropTable(const QString &table); 0202 0203 void setDatabaseVersionInTable(int version); 0204 0205 void createDatabaseVersionTable(); 0206 0207 void initDatabaseVersionQueries(); 0208 0209 void callUpgradeFunctionForVersion(DatabaseVersion databaseVersion); 0210 0211 /********* Data query methods *********/ 0212 0213 bool startTransaction(); 0214 0215 bool finishTransaction(); 0216 0217 bool rollBackTransaction(); 0218 0219 bool prepareQuery(QSqlQuery &query, const QString &queryText) const; 0220 0221 bool execQuery(QSqlQuery &query); 0222 0223 void initDataQueries(); 0224 0225 void initChangesTrackers(); 0226 0227 void recordModifiedTrack(qulonglong trackId); 0228 0229 void recordModifiedAlbum(qulonglong albumId); 0230 0231 QList<qulonglong> fetchTrackIds(qulonglong albumId); 0232 0233 qulonglong internalAlbumIdFromTitleAndArtist(const QString &title, const QString &artist, const QString &albumPath); 0234 0235 DataTypes::TrackDataType internalTrackFromDatabaseId(qulonglong id); 0236 0237 qulonglong internalTrackIdFromTitleAlbumTracDiscNumber(const QString &title, const QString &artist, const std::optional<QString> &album, 0238 std::optional<int> trackNumber, std::optional<int> discNumber); 0239 0240 qulonglong getDuplicateTrackIdFromTitleAlbumTrackDiscNumber(const QString &title, const QString &trackArtist, const QString &album, 0241 const QString &albumArtist, const QString &trackPath, int trackNumber, 0242 int discNumber, int priority); 0243 0244 qulonglong internalTrackIdFromFileName(const QUrl &fileName); 0245 0246 qulonglong internalRadioIdFromHttpAddress(const QString &httpAddress); 0247 0248 DataTypes::ListTrackDataType internalTracksFromAuthor(const QString &artistName); 0249 0250 DataTypes::ListTrackDataType internalTracksFromGenre(const QString &genre); 0251 0252 QList<qulonglong> internalAlbumIdsFromAuthor(const QString &artistName); 0253 0254 qulonglong insertAlbum(const QString &title, const QString &albumArtist, 0255 const QString &trackPath, const QUrl &albumArtURI); 0256 0257 bool updateAlbumFromId(qulonglong albumId, const QUrl &albumArtUri, 0258 const DataTypes::TrackDataType ¤tTrack, const QString &albumPath); 0259 0260 qulonglong insertArtist(const QString &name); 0261 0262 qulonglong internalArtistIdFromName(const QString &name); 0263 0264 qulonglong insertGenre(const QString &name); 0265 0266 void removeTrackInDatabase(qulonglong trackId); 0267 0268 void updateTrackInDatabase(const DataTypes::TrackDataType &oneTrack, const QString &albumPath); 0269 0270 void removeAlbumInDatabase(qulonglong albumId); 0271 0272 void removeArtistInDatabase(qulonglong artistId); 0273 0274 void reloadExistingDatabase(); 0275 0276 qulonglong genericInitialId(QSqlQuery &request); 0277 0278 void insertTrackOrigin(const QUrl &fileNameURI, const QDateTime &fileModifiedTime, const QDateTime &importDate); 0279 0280 void updateTrackOrigin(const QUrl &fileName, const QDateTime &fileModifiedTime); 0281 0282 qulonglong internalInsertTrack(const DataTypes::TrackDataType &oneModifiedTrack, 0283 const QHash<QString, QUrl> &covers, bool &isInserted); 0284 0285 [[nodiscard]] DataTypes::TrackDataType buildTrackDataFromDatabaseRecord(const QSqlRecord &trackRecord) const; 0286 0287 [[nodiscard]] DataTypes::TrackDataType buildRadioDataFromDatabaseRecord(const QSqlRecord &trackRecord) const; 0288 0289 void internalRemoveTracksList(const QList<QUrl> &removedTracks); 0290 0291 void internalRemoveTracksList(const QHash<QUrl, QDateTime> &removedTracks, qulonglong sourceId); 0292 0293 QUrl internalAlbumArtUriFromAlbumId(qulonglong albumId); 0294 0295 bool isValidArtist(qulonglong albumId); 0296 0297 qulonglong insertComposer(const QString &name); 0298 0299 qulonglong insertLyricist(const QString &name); 0300 0301 QHash<QUrl, QDateTime> internalAllFileName(); 0302 0303 bool internalGenericPartialData(QSqlQuery &query); 0304 0305 DataTypes::ListArtistDataType internalAllArtistsPartialData(QSqlQuery &artistsQuery); 0306 0307 DataTypes::ListAlbumDataType internalAllAlbumsPartialData(QSqlQuery &query); 0308 0309 DataTypes::ListTrackDataType internalOneAlbumData(qulonglong databaseId); 0310 0311 DataTypes::AlbumDataType internalOneAlbumPartialData(qulonglong databaseId); 0312 0313 DataTypes::ArtistDataType internalOneArtistPartialData(qulonglong databaseId); 0314 0315 DataTypes::ListTrackDataType internalAllTracksPartialData(); 0316 0317 DataTypes::ListRadioDataType internalAllRadiosPartialData(); 0318 0319 DataTypes::ListTrackDataType internalRecentlyPlayedTracksData(int count); 0320 0321 DataTypes::ListTrackDataType internalFrequentlyPlayedTracksData(int count); 0322 0323 DataTypes::TrackDataType internalOneTrackPartialData(qulonglong databaseId); 0324 0325 DataTypes::TrackDataType internalOneTrackPartialDataByIdAndUrl(qulonglong databaseId, const QUrl &trackUrl); 0326 0327 DataTypes::TrackDataType internalOneRadioPartialData(qulonglong databaseId); 0328 0329 DataTypes::ListGenreDataType internalAllGenresPartialData(); 0330 0331 DataTypes::ListArtistDataType internalAllComposersPartialData(); 0332 0333 DataTypes::ListArtistDataType internalAllLyricistsPartialData(); 0334 0335 void updateAlbumArtist(qulonglong albumId, const QString &title, const QString &albumPath, 0336 const QString &artistName); 0337 0338 bool updateAlbumCover(qulonglong albumId, const QUrl &albumArtUri); 0339 0340 QVariantList internalGetLatestFourCoversForArtist(const QString& artistName); 0341 0342 void updateTrackStartedStatistics(const QUrl &fileName, const QDateTime &time); 0343 0344 void updateTrackFinishedStatistics(const QUrl &fileName, const QDateTime &time); 0345 0346 void internalInsertOneTrack(const DataTypes::TrackDataType &oneTrack, const QHash<QString, QUrl> &covers); 0347 0348 void internalInsertOneRadio(const DataTypes::TrackDataType &oneTrack); 0349 0350 std::unique_ptr<DatabaseInterfacePrivate> d; 0351 0352 }; 0353 0354 #endif // DATABASEINTERFACE_H