File indexing completed on 2024-03-24 04:51:41
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 #include "databaseinterface.h" 0008 0009 #include "databaseLogging.h" 0010 0011 #include <KLocalizedString> 0012 0013 #include <QCoreApplication> 0014 0015 #include <QSqlDatabase> 0016 #include <QSqlDriver> 0017 #include <QSqlQuery> 0018 #include <QSqlRecord> 0019 #include <QSqlError> 0020 0021 #include <QFile> 0022 #include <QMutex> 0023 #include <QVariant> 0024 #include <QAtomicInt> 0025 #include <QElapsedTimer> 0026 #include <QDebug> 0027 0028 #include <algorithm> 0029 0030 class DatabaseInterfacePrivate 0031 { 0032 public: 0033 0034 enum TrackRecordColumns 0035 { 0036 TrackId, 0037 TrackTitle, 0038 TrackAlbumId, 0039 TrackArtistName, 0040 TrackArtistsCount, 0041 TrackAllArtists, 0042 TrackAlbumArtistName, 0043 TrackFileName, 0044 TrackFileModifiedTime, 0045 TrackNumber, 0046 TrackDiscNumber, 0047 TrackDuration, 0048 TrackAlbumTitle, 0049 TrackRating, 0050 TrackCoverFileName, 0051 TrackIsSingleDiscAlbum, 0052 TrackGenreName, 0053 TrackComposerName, 0054 TrackLyricistName, 0055 TrackComment, 0056 TrackYear, 0057 TrackChannelsCount, 0058 TrackBitRate, 0059 TrackSamplerate, 0060 TrackHasEmbeddedCover, 0061 TrackImportDate, 0062 TrackFirstPlayDate, 0063 TrackLastPlayDate, 0064 TrackPlayCounter, 0065 TrackEmbeddedCover, 0066 }; 0067 0068 enum RadioRecordColumns 0069 { 0070 RadioId, 0071 RadioTitle, 0072 RadioHttpAddress, 0073 RadioImageAddress, 0074 RadioRating, 0075 RadioGenreName, 0076 RadioComment, 0077 }; 0078 0079 enum AlbumsRecordColumns 0080 { 0081 AlbumsId, 0082 AlbumsTitle, 0083 AlbumsSecondaryText, 0084 AlbumsCoverFileName, 0085 AlbumsArtistName, 0086 AlbumsYear, 0087 AlbumsArtistsCount, 0088 AlbumsAllArtists, 0089 AlbumsHighestRating, 0090 AlbumsAllGenres, 0091 AlbumsIsSingleDiscAlbum, 0092 AlbumsEmbeddedCover, 0093 }; 0094 0095 enum SingleAlbumRecordColumns 0096 { 0097 SingleAlbumId, 0098 SingleAlbumTitle, 0099 SingleAlbumArtistName, 0100 SingleAlbumPath, 0101 SingleAlbumCoverFileName, 0102 SingleAlbumTracksCount, 0103 SingleAlbumIsSingleDiscAlbum, 0104 SingleAlbumArtistsCount, 0105 SingleAlbumAllArtists, 0106 SingleAlbumHighestRating, 0107 SingleAlbumAllGenres, 0108 SingleAlbumEmbeddedCover, 0109 }; 0110 0111 DatabaseInterfacePrivate(const QSqlDatabase &tracksDatabase, const QString &connectionName, const QString &databaseFileName) 0112 : mTracksDatabase(tracksDatabase), mConnectionName(connectionName), 0113 mDatabaseFileName(databaseFileName), mSelectAlbumQuery(mTracksDatabase), 0114 mSelectTrackQuery(mTracksDatabase), mSelectAlbumIdFromTitleQuery(mTracksDatabase), 0115 mInsertAlbumQuery(mTracksDatabase), mSelectTrackIdFromTitleAlbumIdArtistQuery(mTracksDatabase), 0116 mInsertTrackQuery(mTracksDatabase), mSelectTracksFromArtist(mTracksDatabase), 0117 mSelectTracksFromGenre(mTracksDatabase), 0118 mSelectTrackFromIdQuery(mTracksDatabase), mSelectRadioFromIdQuery(mTracksDatabase), 0119 mSelectCountAlbumsForArtistQuery(mTracksDatabase), 0120 mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery(mTracksDatabase), 0121 mSelectAllAlbumsFromArtistQuery(mTracksDatabase), mSelectAllArtistsQuery(mTracksDatabase), 0122 mInsertArtistsQuery(mTracksDatabase), mSelectArtistByNameQuery(mTracksDatabase), 0123 mSelectArtistQuery(mTracksDatabase), 0124 mUpdateTrackStartedStatistics(mTracksDatabase), mUpdateTrackFinishedStatistics(mTracksDatabase), 0125 mRemoveTrackQuery(mTracksDatabase), mRemoveAlbumQuery(mTracksDatabase), 0126 mRemoveArtistQuery(mTracksDatabase), mSelectAllTracksQuery(mTracksDatabase), 0127 mSelectAllRadiosQuery(mTracksDatabase), 0128 mInsertTrackMapping(mTracksDatabase), mUpdateTrackFirstPlayStatistics(mTracksDatabase), 0129 mInsertMusicSource(mTracksDatabase), mSelectMusicSource(mTracksDatabase), 0130 mUpdateTrackPriority(mTracksDatabase), mUpdateTrackFileModifiedTime(mTracksDatabase), 0131 mSelectTracksMapping(mTracksDatabase), mSelectTracksMappingPriority(mTracksDatabase), 0132 mSelectRadioIdFromHttpAddress(mTracksDatabase), 0133 mUpdateAlbumArtUriFromAlbumIdQuery(mTracksDatabase), 0134 mSelectUpToFourLatestCoversFromArtistNameQuery(mTracksDatabase), 0135 mSelectTracksMappingPriorityByTrackId(mTracksDatabase), 0136 mSelectAlbumIdsFromArtist(mTracksDatabase), mSelectAllTrackFilesQuery(mTracksDatabase), 0137 mRemoveTracksMappingFromSource(mTracksDatabase), mRemoveTracksMapping(mTracksDatabase), 0138 mSelectTracksWithoutMappingQuery(mTracksDatabase), mSelectAlbumIdFromTitleAndArtistQuery(mTracksDatabase), 0139 mSelectAlbumIdFromTitleWithoutArtistQuery(mTracksDatabase), 0140 mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery(mTracksDatabase), mSelectAlbumArtUriFromAlbumIdQuery(mTracksDatabase), 0141 mInsertComposerQuery(mTracksDatabase), mSelectComposerByNameQuery(mTracksDatabase), 0142 mSelectComposerQuery(mTracksDatabase), mInsertLyricistQuery(mTracksDatabase), 0143 mSelectLyricistByNameQuery(mTracksDatabase), mSelectLyricistQuery(mTracksDatabase), 0144 mInsertGenreQuery(mTracksDatabase), mSelectGenreByNameQuery(mTracksDatabase), 0145 mSelectGenreQuery(mTracksDatabase), mSelectAllTracksShortQuery(mTracksDatabase), 0146 mSelectAllAlbumsShortQuery(mTracksDatabase), mSelectAllComposersQuery(mTracksDatabase), 0147 mSelectAllLyricistsQuery(mTracksDatabase), mSelectCountAlbumsForComposerQuery(mTracksDatabase), 0148 mSelectCountAlbumsForLyricistQuery(mTracksDatabase), mSelectAllGenresQuery(mTracksDatabase), 0149 mSelectGenreForArtistQuery(mTracksDatabase), mSelectGenreForAlbumQuery(mTracksDatabase), 0150 mUpdateTrackQuery(mTracksDatabase), mUpdateAlbumArtistQuery(mTracksDatabase), 0151 mUpdateRadioQuery(mTracksDatabase), 0152 mUpdateAlbumArtistInTracksQuery(mTracksDatabase), mQueryMaximumTrackIdQuery(mTracksDatabase), 0153 mQueryMaximumAlbumIdQuery(mTracksDatabase), mQueryMaximumArtistIdQuery(mTracksDatabase), 0154 mQueryMaximumLyricistIdQuery(mTracksDatabase), mQueryMaximumComposerIdQuery(mTracksDatabase), 0155 mQueryMaximumGenreIdQuery(mTracksDatabase), mSelectAllArtistsWithGenreFilterQuery(mTracksDatabase), 0156 mSelectAllAlbumsShortWithGenreArtistFilterQuery(mTracksDatabase), mSelectAllAlbumsShortWithArtistFilterQuery(mTracksDatabase), 0157 mSelectAllRecentlyPlayedTracksQuery(mTracksDatabase), mSelectAllFrequentlyPlayedTracksQuery(mTracksDatabase), 0158 mClearTracksDataTable(mTracksDatabase), mClearTracksTable(mTracksDatabase), 0159 mClearAlbumsTable(mTracksDatabase), mClearArtistsTable(mTracksDatabase), 0160 mClearComposerTable(mTracksDatabase), mClearGenreTable(mTracksDatabase), mClearLyricistTable(mTracksDatabase), 0161 mArtistMatchGenreQuery(mTracksDatabase), mSelectTrackIdQuery(mTracksDatabase), 0162 mInsertRadioQuery(mTracksDatabase), mDeleteRadioQuery(mTracksDatabase), 0163 mSelectTrackFromIdAndUrlQuery(mTracksDatabase), 0164 mUpdateDatabaseVersionQuery(mTracksDatabase), mSelectDatabaseVersionQuery(mTracksDatabase) 0165 { 0166 } 0167 0168 QSqlDatabase mTracksDatabase; 0169 0170 const QString mConnectionName; 0171 0172 const QString mDatabaseFileName; 0173 0174 QSqlQuery mSelectAlbumQuery; 0175 0176 QSqlQuery mSelectTrackQuery; 0177 0178 QSqlQuery mSelectAlbumIdFromTitleQuery; 0179 0180 QSqlQuery mInsertAlbumQuery; 0181 0182 QSqlQuery mSelectTrackIdFromTitleAlbumIdArtistQuery; 0183 0184 QSqlQuery mInsertTrackQuery; 0185 0186 QSqlQuery mSelectTracksFromArtist; 0187 0188 QSqlQuery mSelectTracksFromGenre; 0189 0190 QSqlQuery mSelectTrackFromIdQuery; 0191 0192 QSqlQuery mSelectRadioFromIdQuery; 0193 0194 QSqlQuery mSelectCountAlbumsForArtistQuery; 0195 0196 QSqlQuery mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery; 0197 0198 QSqlQuery mSelectAllAlbumsFromArtistQuery; 0199 0200 QSqlQuery mSelectAllArtistsQuery; 0201 0202 QSqlQuery mInsertArtistsQuery; 0203 0204 QSqlQuery mSelectArtistByNameQuery; 0205 0206 QSqlQuery mSelectArtistQuery; 0207 0208 QSqlQuery mUpdateTrackStartedStatistics; 0209 0210 QSqlQuery mUpdateTrackFinishedStatistics; 0211 0212 QSqlQuery mRemoveTrackQuery; 0213 0214 QSqlQuery mRemoveAlbumQuery; 0215 0216 QSqlQuery mRemoveArtistQuery; 0217 0218 QSqlQuery mSelectAllTracksQuery; 0219 0220 QSqlQuery mSelectAllRadiosQuery; 0221 0222 QSqlQuery mInsertTrackMapping; 0223 0224 QSqlQuery mUpdateTrackFirstPlayStatistics; 0225 0226 QSqlQuery mInsertMusicSource; 0227 0228 QSqlQuery mSelectMusicSource; 0229 0230 QSqlQuery mUpdateTrackPriority; 0231 0232 QSqlQuery mUpdateTrackFileModifiedTime; 0233 0234 QSqlQuery mSelectTracksMapping; 0235 0236 QSqlQuery mSelectTracksMappingPriority; 0237 0238 QSqlQuery mSelectRadioIdFromHttpAddress; 0239 0240 QSqlQuery mUpdateAlbumArtUriFromAlbumIdQuery; 0241 0242 QSqlQuery mSelectUpToFourLatestCoversFromArtistNameQuery; 0243 0244 QSqlQuery mSelectTracksMappingPriorityByTrackId; 0245 0246 QSqlQuery mSelectAlbumIdsFromArtist; 0247 0248 QSqlQuery mSelectAllTrackFilesQuery; 0249 0250 QSqlQuery mRemoveTracksMappingFromSource; 0251 0252 QSqlQuery mRemoveTracksMapping; 0253 0254 QSqlQuery mSelectTracksWithoutMappingQuery; 0255 0256 QSqlQuery mSelectAlbumIdFromTitleAndArtistQuery; 0257 0258 QSqlQuery mSelectAlbumIdFromTitleWithoutArtistQuery; 0259 0260 QSqlQuery mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery; 0261 0262 QSqlQuery mSelectAlbumArtUriFromAlbumIdQuery; 0263 0264 QSqlQuery mInsertComposerQuery; 0265 0266 QSqlQuery mSelectComposerByNameQuery; 0267 0268 QSqlQuery mSelectComposerQuery; 0269 0270 QSqlQuery mInsertLyricistQuery; 0271 0272 QSqlQuery mSelectLyricistByNameQuery; 0273 0274 QSqlQuery mSelectLyricistQuery; 0275 0276 QSqlQuery mInsertGenreQuery; 0277 0278 QSqlQuery mSelectGenreByNameQuery; 0279 0280 QSqlQuery mSelectGenreQuery; 0281 0282 QSqlQuery mSelectAllTracksShortQuery; 0283 0284 QSqlQuery mSelectAllAlbumsShortQuery; 0285 0286 QSqlQuery mSelectAllComposersQuery; 0287 0288 QSqlQuery mSelectAllLyricistsQuery; 0289 0290 QSqlQuery mSelectCountAlbumsForComposerQuery; 0291 0292 QSqlQuery mSelectCountAlbumsForLyricistQuery; 0293 0294 QSqlQuery mSelectAllGenresQuery; 0295 0296 QSqlQuery mSelectGenreForArtistQuery; 0297 0298 QSqlQuery mSelectGenreForAlbumQuery; 0299 0300 QSqlQuery mUpdateTrackQuery; 0301 0302 QSqlQuery mUpdateAlbumArtistQuery; 0303 0304 QSqlQuery mUpdateRadioQuery; 0305 0306 QSqlQuery mUpdateAlbumArtistInTracksQuery; 0307 0308 QSqlQuery mQueryMaximumTrackIdQuery; 0309 0310 QSqlQuery mQueryMaximumAlbumIdQuery; 0311 0312 QSqlQuery mQueryMaximumArtistIdQuery; 0313 0314 QSqlQuery mQueryMaximumLyricistIdQuery; 0315 0316 QSqlQuery mQueryMaximumComposerIdQuery; 0317 0318 QSqlQuery mQueryMaximumGenreIdQuery; 0319 0320 QSqlQuery mSelectAllArtistsWithGenreFilterQuery; 0321 0322 QSqlQuery mSelectAllAlbumsShortWithGenreArtistFilterQuery; 0323 0324 QSqlQuery mSelectAllAlbumsShortWithArtistFilterQuery; 0325 0326 QSqlQuery mSelectAllRecentlyPlayedTracksQuery; 0327 0328 QSqlQuery mSelectAllFrequentlyPlayedTracksQuery; 0329 0330 QSqlQuery mClearTracksDataTable; 0331 0332 QSqlQuery mClearTracksTable; 0333 0334 QSqlQuery mClearAlbumsTable; 0335 0336 QSqlQuery mClearArtistsTable; 0337 0338 QSqlQuery mClearComposerTable; 0339 0340 QSqlQuery mClearGenreTable; 0341 0342 QSqlQuery mClearLyricistTable; 0343 0344 QSqlQuery mArtistMatchGenreQuery; 0345 0346 QSqlQuery mSelectTrackIdQuery; 0347 0348 QSqlQuery mInsertRadioQuery; 0349 0350 QSqlQuery mDeleteRadioQuery; 0351 0352 QSqlQuery mSelectTrackFromIdAndUrlQuery; 0353 0354 QSqlQuery mUpdateDatabaseVersionQuery; 0355 0356 QSqlQuery mSelectDatabaseVersionQuery; 0357 0358 QSet<qulonglong> mModifiedTrackIds; 0359 0360 QSet<qulonglong> mModifiedAlbumIds; 0361 0362 QSet<qulonglong> mModifiedArtistIds; 0363 0364 QSet<qulonglong> mInsertedTracks; 0365 0366 QSet<qulonglong> mInsertedAlbums; 0367 0368 QSet<qulonglong> mInsertedArtists; 0369 0370 qulonglong mAlbumId = 1; 0371 0372 qulonglong mArtistId = 1; 0373 0374 qulonglong mComposerId = 1; 0375 0376 qulonglong mLyricistId = 1; 0377 0378 qulonglong mGenreId = 1; 0379 0380 qulonglong mTrackId = 1; 0381 0382 QAtomicInt mStopRequest = 0; 0383 0384 bool mInitFinished = false; 0385 0386 const DatabaseInterface::DatabaseVersion mLatestDatabaseVersion = DatabaseInterface::V17; 0387 0388 struct TableSchema { 0389 QString name; 0390 QStringList fields; 0391 }; 0392 0393 const QList<TableSchema> mExpectedTableNamesAndFields { 0394 {QStringLiteral("Albums"), { 0395 QStringLiteral("ID"), QStringLiteral("Title"), 0396 QStringLiteral("ArtistName"), QStringLiteral("AlbumPath"), 0397 QStringLiteral("CoverFileName")}}, 0398 0399 {QStringLiteral("Artists"), { 0400 QStringLiteral("ID"), QStringLiteral("Name")}}, 0401 0402 {QStringLiteral("Composer"), { 0403 QStringLiteral("ID"), QStringLiteral("Name")}}, 0404 0405 {QStringLiteral("Genre"), { 0406 QStringLiteral("ID"), QStringLiteral("Name")}}, 0407 0408 {QStringLiteral("Lyricist"), { 0409 QStringLiteral("ID"), QStringLiteral("Name")}}, 0410 0411 {QStringLiteral("Radios"), { 0412 QStringLiteral("ID"), QStringLiteral("HttpAddress"), 0413 QStringLiteral("ImageAddress"), QStringLiteral("Title"), 0414 QStringLiteral("Rating"), QStringLiteral("Genre"), 0415 QStringLiteral("Comment")}}, 0416 0417 {QStringLiteral("Tracks"), { 0418 QStringLiteral("ID"), QStringLiteral("FileName"), 0419 QStringLiteral("Priority"), QStringLiteral("Title"), 0420 QStringLiteral("ArtistName"), QStringLiteral("AlbumTitle"), 0421 QStringLiteral("AlbumArtistName"), QStringLiteral("AlbumPath"), 0422 QStringLiteral("TrackNumber"), QStringLiteral("DiscNumber"), 0423 QStringLiteral("Duration"), QStringLiteral("Rating"), 0424 QStringLiteral("Genre"), QStringLiteral("Composer"), 0425 QStringLiteral("Lyricist"), QStringLiteral("Comment"), 0426 QStringLiteral("Year"), QStringLiteral("Channels"), 0427 QStringLiteral("BitRate"), QStringLiteral("SampleRate"), 0428 QStringLiteral("HasEmbeddedCover")}}, 0429 0430 {QStringLiteral("TracksData"), { 0431 QStringLiteral("FileName"), QStringLiteral("FileModifiedTime"), 0432 QStringLiteral("ImportDate"), QStringLiteral("FirstPlayDate"), 0433 QStringLiteral("LastPlayDate"), QStringLiteral("PlayCounter")}}, 0434 }; 0435 }; 0436 0437 DatabaseInterface::DatabaseInterface(QObject *parent) : QObject(parent), d(nullptr) 0438 { 0439 } 0440 0441 DatabaseInterface::~DatabaseInterface() 0442 { 0443 if (d) { 0444 d->mTracksDatabase.close(); 0445 } 0446 } 0447 0448 void DatabaseInterface::init(const QString &dbName, const QString &databaseFileName) 0449 { 0450 initConnection(dbName, databaseFileName); 0451 0452 if (!initDatabase()) { 0453 if (!resetDatabase() || !initDatabase()) { 0454 qCCritical(orgKdeElisaDatabase()) << "Database cannot be initialized"; 0455 return; 0456 } 0457 } 0458 initDataQueries(); 0459 0460 if (!databaseFileName.isEmpty()) { 0461 reloadExistingDatabase(); 0462 } 0463 } 0464 0465 qulonglong DatabaseInterface::albumIdFromTitleAndArtist(const QString &title, const QString &artist, const QString &albumPath) 0466 { 0467 auto result = qulonglong{0}; 0468 0469 auto transactionResult = startTransaction(); 0470 if (!transactionResult) { 0471 return result; 0472 } 0473 0474 result = internalAlbumIdFromTitleAndArtist(title, artist, albumPath); 0475 0476 transactionResult = finishTransaction(); 0477 if (!transactionResult) { 0478 return result; 0479 } 0480 0481 return result; 0482 } 0483 0484 DataTypes::ListTrackDataType DatabaseInterface::allTracksData() 0485 { 0486 auto result = DataTypes::ListTrackDataType{}; 0487 0488 if (!d) { 0489 return result; 0490 } 0491 0492 auto transactionResult = startTransaction(); 0493 if (!transactionResult) { 0494 return result; 0495 } 0496 0497 result = internalAllTracksPartialData(); 0498 0499 transactionResult = finishTransaction(); 0500 if (!transactionResult) { 0501 return result; 0502 } 0503 0504 return result; 0505 } 0506 0507 DataTypes::ListRadioDataType DatabaseInterface::allRadiosData() 0508 { 0509 auto result = DataTypes::ListRadioDataType{}; 0510 0511 if (!d) { 0512 return result; 0513 } 0514 0515 auto transactionResult = startTransaction(); 0516 if (!transactionResult) { 0517 return result; 0518 } 0519 0520 result = internalAllRadiosPartialData(); 0521 0522 transactionResult = finishTransaction(); 0523 if (!transactionResult) { 0524 return result; 0525 } 0526 0527 return result; 0528 } 0529 0530 DataTypes::ListTrackDataType DatabaseInterface::recentlyPlayedTracksData(int count) 0531 { 0532 auto result = DataTypes::ListTrackDataType{}; 0533 0534 if (!d) { 0535 return result; 0536 } 0537 0538 auto transactionResult = startTransaction(); 0539 if (!transactionResult) { 0540 return result; 0541 } 0542 0543 result = internalRecentlyPlayedTracksData(count); 0544 0545 transactionResult = finishTransaction(); 0546 if (!transactionResult) { 0547 return result; 0548 } 0549 0550 return result; 0551 } 0552 0553 DataTypes::ListTrackDataType DatabaseInterface::frequentlyPlayedTracksData(int count) 0554 { 0555 auto result = DataTypes::ListTrackDataType{}; 0556 0557 if (!d) { 0558 return result; 0559 } 0560 0561 auto transactionResult = startTransaction(); 0562 if (!transactionResult) { 0563 return result; 0564 } 0565 0566 result = internalFrequentlyPlayedTracksData(count); 0567 0568 transactionResult = finishTransaction(); 0569 if (!transactionResult) { 0570 return result; 0571 } 0572 0573 return result; 0574 } 0575 0576 DataTypes::ListAlbumDataType DatabaseInterface::allAlbumsData() 0577 { 0578 auto result = DataTypes::ListAlbumDataType{}; 0579 0580 if (!d) { 0581 return result; 0582 } 0583 0584 auto transactionResult = startTransaction(); 0585 if (!transactionResult) { 0586 return result; 0587 } 0588 0589 result = internalAllAlbumsPartialData(d->mSelectAllAlbumsShortQuery); 0590 0591 transactionResult = finishTransaction(); 0592 if (!transactionResult) { 0593 return result; 0594 } 0595 0596 return result; 0597 } 0598 0599 DataTypes::ListAlbumDataType DatabaseInterface::allAlbumsDataByGenreAndArtist(const QString &genre, const QString &artist) 0600 { 0601 auto result = DataTypes::ListAlbumDataType{}; 0602 0603 if (!d) { 0604 return result; 0605 } 0606 0607 auto transactionResult = startTransaction(); 0608 if (!transactionResult) { 0609 return result; 0610 } 0611 0612 d->mSelectAllAlbumsShortWithGenreArtistFilterQuery.bindValue(QStringLiteral(":artistFilter"), artist); 0613 d->mSelectAllAlbumsShortWithGenreArtistFilterQuery.bindValue(QStringLiteral(":genreFilter"), genre); 0614 0615 result = internalAllAlbumsPartialData(d->mSelectAllAlbumsShortWithGenreArtistFilterQuery); 0616 0617 transactionResult = finishTransaction(); 0618 if (!transactionResult) { 0619 return result; 0620 } 0621 0622 return result; 0623 } 0624 0625 DataTypes::ListAlbumDataType DatabaseInterface::allAlbumsDataByArtist(const QString &artist) 0626 { 0627 auto result = DataTypes::ListAlbumDataType{}; 0628 0629 if (!d) { 0630 return result; 0631 } 0632 0633 auto transactionResult = startTransaction(); 0634 if (!transactionResult) { 0635 return result; 0636 } 0637 0638 d->mSelectAllAlbumsShortWithArtistFilterQuery.bindValue(QStringLiteral(":artistFilter"), artist); 0639 0640 result = internalAllAlbumsPartialData(d->mSelectAllAlbumsShortWithArtistFilterQuery); 0641 0642 transactionResult = finishTransaction(); 0643 if (!transactionResult) { 0644 return result; 0645 } 0646 0647 return result; 0648 } 0649 0650 DataTypes::AlbumDataType DatabaseInterface::albumDataFromDatabaseId(qulonglong id) 0651 { 0652 auto result = DataTypes::AlbumDataType{}; 0653 0654 if (!d) { 0655 return result; 0656 } 0657 0658 auto transactionResult = startTransaction(); 0659 if (!transactionResult) { 0660 return result; 0661 } 0662 0663 result = internalOneAlbumPartialData(id); 0664 0665 transactionResult = finishTransaction(); 0666 if (!transactionResult) { 0667 return result; 0668 } 0669 0670 return result; 0671 } 0672 0673 DataTypes::ListTrackDataType DatabaseInterface::albumData(qulonglong databaseId) 0674 { 0675 auto result = DataTypes::ListTrackDataType{}; 0676 0677 if (!d) { 0678 return result; 0679 } 0680 0681 auto transactionResult = startTransaction(); 0682 if (!transactionResult) { 0683 return result; 0684 } 0685 0686 result = internalOneAlbumData(databaseId); 0687 0688 transactionResult = finishTransaction(); 0689 if (!transactionResult) { 0690 return result; 0691 } 0692 0693 return result; 0694 } 0695 0696 DataTypes::ListArtistDataType DatabaseInterface::allArtistsData() 0697 { 0698 auto result = DataTypes::ListArtistDataType{}; 0699 0700 if (!d) { 0701 return result; 0702 } 0703 0704 auto transactionResult = startTransaction(); 0705 if (!transactionResult) { 0706 return result; 0707 } 0708 0709 result = internalAllArtistsPartialData(d->mSelectAllArtistsQuery); 0710 0711 transactionResult = finishTransaction(); 0712 if (!transactionResult) { 0713 return result; 0714 } 0715 0716 return result; 0717 } 0718 0719 DataTypes::ListArtistDataType DatabaseInterface::allArtistsDataByGenre(const QString &genre) 0720 { 0721 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::allArtistsDataByGenre" << genre; 0722 0723 auto result = DataTypes::ListArtistDataType{}; 0724 0725 if (!d) { 0726 return result; 0727 } 0728 0729 auto transactionResult = startTransaction(); 0730 if (!transactionResult) { 0731 return result; 0732 } 0733 0734 d->mSelectAllArtistsWithGenreFilterQuery.bindValue(QStringLiteral(":genreFilter"), genre); 0735 0736 result = internalAllArtistsPartialData(d->mSelectAllArtistsWithGenreFilterQuery); 0737 0738 transactionResult = finishTransaction(); 0739 if (!transactionResult) { 0740 return result; 0741 } 0742 0743 return result; 0744 } 0745 0746 DataTypes::ArtistDataType DatabaseInterface::artistDataFromDatabaseId(qulonglong id) 0747 { 0748 auto result = DataTypes::ArtistDataType{}; 0749 0750 if (!d) { 0751 return result; 0752 } 0753 0754 auto transactionResult = startTransaction(); 0755 if (!transactionResult) { 0756 return result; 0757 } 0758 0759 result = internalOneArtistPartialData(id); 0760 0761 transactionResult = finishTransaction(); 0762 if (!transactionResult) { 0763 return result; 0764 } 0765 0766 return result; 0767 } 0768 0769 qulonglong DatabaseInterface::artistIdFromName(const QString &name) 0770 { 0771 auto result = qulonglong{0}; 0772 0773 auto transactionResult = startTransaction(); 0774 if (!transactionResult) { 0775 return result; 0776 } 0777 0778 result = internalArtistIdFromName(name); 0779 0780 transactionResult = finishTransaction(); 0781 if (!transactionResult) { 0782 return result; 0783 } 0784 0785 return result; 0786 } 0787 0788 DataTypes::ListGenreDataType DatabaseInterface::allGenresData() 0789 { 0790 auto result = DataTypes::ListGenreDataType{}; 0791 0792 if (!d) { 0793 return result; 0794 } 0795 0796 auto transactionResult = startTransaction(); 0797 if (!transactionResult) { 0798 return result; 0799 } 0800 0801 result = internalAllGenresPartialData(); 0802 0803 transactionResult = finishTransaction(); 0804 if (!transactionResult) { 0805 return result; 0806 } 0807 0808 return result; 0809 } 0810 0811 bool DatabaseInterface::internalArtistMatchGenre(qulonglong databaseId, const QString &genre) 0812 { 0813 auto result = true; 0814 0815 if (!d) { 0816 return result; 0817 } 0818 0819 d->mArtistMatchGenreQuery.bindValue(QStringLiteral(":databaseId"), databaseId); 0820 d->mArtistMatchGenreQuery.bindValue(QStringLiteral(":genreFilter"), genre); 0821 0822 auto queryResult = execQuery(d->mArtistMatchGenreQuery); 0823 0824 if (!queryResult || !d->mArtistMatchGenreQuery.isSelect() || !d->mArtistMatchGenreQuery.isActive()) { 0825 Q_EMIT databaseError(); 0826 0827 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::artistMatchGenre" << d->mArtistMatchGenreQuery.lastQuery(); 0828 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::artistMatchGenre" << d->mArtistMatchGenreQuery.boundValues(); 0829 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::artistMatchGenre" << d->mArtistMatchGenreQuery.lastError(); 0830 0831 d->mArtistMatchGenreQuery.finish(); 0832 0833 auto transactionResult = finishTransaction(); 0834 if (!transactionResult) { 0835 return result; 0836 } 0837 0838 return result; 0839 } 0840 0841 result = d->mArtistMatchGenreQuery.next(); 0842 0843 d->mArtistMatchGenreQuery.finish(); 0844 0845 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalArtistMatchGenre" << databaseId << (result ? "match" : "does not match"); 0846 0847 return result; 0848 } 0849 0850 DataTypes::ListTrackDataType DatabaseInterface::tracksDataFromAuthor(const QString &ArtistName) 0851 { 0852 auto allTracks = DataTypes::ListTrackDataType{}; 0853 0854 auto transactionResult = startTransaction(); 0855 if (!transactionResult) { 0856 return allTracks; 0857 } 0858 0859 allTracks = internalTracksFromAuthor(ArtistName); 0860 0861 transactionResult = finishTransaction(); 0862 if (!transactionResult) { 0863 return allTracks; 0864 } 0865 0866 return allTracks; 0867 } 0868 0869 DataTypes::ListTrackDataType DatabaseInterface::tracksDataFromGenre(const QString &genre) 0870 { 0871 auto allTracks = DataTypes::ListTrackDataType{}; 0872 0873 auto transactionResult = startTransaction(); 0874 if (!transactionResult) { 0875 return allTracks; 0876 } 0877 0878 allTracks = internalTracksFromGenre(genre); 0879 0880 transactionResult = finishTransaction(); 0881 if (!transactionResult) { 0882 return allTracks; 0883 } 0884 0885 return allTracks; 0886 } 0887 DataTypes::TrackDataType DatabaseInterface::trackDataFromDatabaseId(qulonglong id) 0888 { 0889 auto result = DataTypes::TrackDataType(); 0890 0891 if (!d) { 0892 return result; 0893 } 0894 0895 auto transactionResult = startTransaction(); 0896 if (!transactionResult) { 0897 return result; 0898 } 0899 0900 result = internalOneTrackPartialData(id); 0901 0902 transactionResult = finishTransaction(); 0903 if (!transactionResult) { 0904 return result; 0905 } 0906 0907 return result; 0908 } 0909 0910 DataTypes::TrackDataType DatabaseInterface::trackDataFromDatabaseIdAndUrl(qulonglong id, const QUrl &trackUrl) 0911 { 0912 auto result = DataTypes::TrackDataType(); 0913 0914 if (!d) { 0915 return result; 0916 } 0917 0918 auto transactionResult = startTransaction(); 0919 if (!transactionResult) { 0920 return result; 0921 } 0922 0923 result = internalOneTrackPartialDataByIdAndUrl(id, trackUrl); 0924 0925 transactionResult = finishTransaction(); 0926 if (!transactionResult) { 0927 return result; 0928 } 0929 0930 return result; 0931 } 0932 0933 DataTypes::TrackDataType DatabaseInterface::radioDataFromDatabaseId(qulonglong id) 0934 { 0935 auto result = DataTypes::TrackDataType(); 0936 0937 if (!d) { 0938 return result; 0939 } 0940 0941 auto transactionResult = startTransaction(); 0942 if (!transactionResult) { 0943 return result; 0944 } 0945 0946 result = internalOneRadioPartialData(id); 0947 0948 transactionResult = finishTransaction(); 0949 if (!transactionResult) { 0950 return result; 0951 } 0952 0953 return result; 0954 } 0955 0956 qulonglong DatabaseInterface::trackIdFromTitleAlbumTrackDiscNumber(const QString &title, const QString &artist, const std::optional<QString> &album, 0957 std::optional<int> trackNumber, std::optional<int> discNumber) 0958 { 0959 auto result = qulonglong(0); 0960 0961 if (!d) { 0962 return result; 0963 } 0964 0965 auto transactionResult = startTransaction(); 0966 if (!transactionResult) { 0967 return result; 0968 } 0969 0970 result = internalTrackIdFromTitleAlbumTracDiscNumber(title, artist, album, trackNumber, discNumber); 0971 0972 transactionResult = finishTransaction(); 0973 if (!transactionResult) { 0974 return result; 0975 } 0976 0977 return result; 0978 } 0979 0980 qulonglong DatabaseInterface::trackIdFromFileName(const QUrl &fileName) 0981 { 0982 auto result = qulonglong(0); 0983 0984 if (!d) { 0985 return result; 0986 } 0987 0988 auto transactionResult = startTransaction(); 0989 if (!transactionResult) { 0990 return result; 0991 } 0992 0993 result = internalTrackIdFromFileName(fileName); 0994 0995 transactionResult = finishTransaction(); 0996 if (!transactionResult) { 0997 return result; 0998 } 0999 1000 return result; 1001 } 1002 1003 qulonglong DatabaseInterface::radioIdFromFileName(const QUrl &fileName) 1004 { 1005 auto result = qulonglong(0); 1006 1007 if (!d) { 1008 return result; 1009 } 1010 1011 auto transactionResult = startTransaction(); 1012 if (!transactionResult) { 1013 return result; 1014 } 1015 1016 result = internalRadioIdFromHttpAddress(fileName.toString()); 1017 1018 transactionResult = finishTransaction(); 1019 if (!transactionResult) { 1020 return result; 1021 } 1022 1023 return result; 1024 } 1025 1026 void DatabaseInterface::applicationAboutToQuit() 1027 { 1028 d->mStopRequest = 1; 1029 } 1030 1031 void DatabaseInterface::insertTracksList(const DataTypes::ListTrackDataType &tracks, const QHash<QString, QUrl> &covers) 1032 { 1033 qCDebug(orgKdeElisaDatabase()) << "DatabaseInterface::insertTracksList" << tracks.count(); 1034 if (d->mStopRequest == 1) { 1035 Q_EMIT finishInsertingTracksList(); 1036 return; 1037 } 1038 1039 auto transactionResult = startTransaction(); 1040 if (!transactionResult) { 1041 Q_EMIT finishInsertingTracksList(); 1042 return; 1043 } 1044 1045 initChangesTrackers(); 1046 1047 for(const auto &oneTrack : tracks) { 1048 switch (oneTrack.elementType()) 1049 { 1050 case ElisaUtils::Track: 1051 { 1052 qCDebug(orgKdeElisaDatabase()) << "DatabaseInterface::insertTracksList" << "insert one track"; 1053 internalInsertOneTrack(oneTrack, covers); 1054 break; 1055 } 1056 case ElisaUtils::Radio: 1057 { 1058 qCDebug(orgKdeElisaDatabase()) << "DatabaseInterface::insertTracksList" << "insert one radio"; 1059 internalInsertOneRadio(oneTrack); 1060 break; 1061 } 1062 case ElisaUtils::Album: 1063 case ElisaUtils::Artist: 1064 case ElisaUtils::Composer: 1065 case ElisaUtils::Container: 1066 case ElisaUtils::FileName: 1067 case ElisaUtils::Genre: 1068 case ElisaUtils::Lyricist: 1069 case ElisaUtils::Unknown: 1070 case ElisaUtils::PlayList: 1071 qCDebug(orgKdeElisaDatabase()) << "DatabaseInterface::insertTracksList" << "invalid track data"; 1072 break; 1073 } 1074 1075 if (d->mStopRequest == 1) { 1076 transactionResult = finishTransaction(); 1077 if (!transactionResult) { 1078 Q_EMIT finishInsertingTracksList(); 1079 return; 1080 } 1081 Q_EMIT finishInsertingTracksList(); 1082 return; 1083 } 1084 } 1085 1086 if (!d->mInsertedArtists.isEmpty()) { 1087 DataTypes::ListArtistDataType newArtists; 1088 1089 for (auto newArtistId : std::as_const(d->mInsertedArtists)) { 1090 newArtists.push_back(internalOneArtistPartialData(newArtistId)); 1091 } 1092 1093 qCInfo(orgKdeElisaDatabase) << "artistsAdded" << newArtists.size(); 1094 Q_EMIT artistsAdded(newArtists); 1095 } 1096 1097 if (!d->mInsertedAlbums.isEmpty()) { 1098 DataTypes::ListAlbumDataType newAlbums; 1099 1100 for (auto albumId : std::as_const(d->mInsertedAlbums)) { 1101 d->mModifiedAlbumIds.remove(albumId); 1102 newAlbums.push_back(internalOneAlbumPartialData(albumId)); 1103 } 1104 1105 qCInfo(orgKdeElisaDatabase) << "albumsAdded" << newAlbums.size(); 1106 Q_EMIT albumsAdded(newAlbums); 1107 } 1108 1109 for (auto albumId : std::as_const(d->mModifiedAlbumIds)) { 1110 Q_EMIT albumModified({{DataTypes::DatabaseIdRole, albumId}}, albumId); 1111 } 1112 1113 if (!d->mInsertedTracks.isEmpty()) { 1114 DataTypes::ListTrackDataType newTracks; 1115 1116 for (auto trackId : std::as_const(d->mInsertedTracks)) { 1117 newTracks.push_back(internalOneTrackPartialData(trackId)); 1118 d->mModifiedTrackIds.remove(trackId); 1119 } 1120 1121 qCInfo(orgKdeElisaDatabase) << "tracksAdded" << newTracks.size(); 1122 Q_EMIT tracksAdded(newTracks); 1123 } 1124 1125 for (auto trackId : std::as_const(d->mModifiedTrackIds)) { 1126 Q_EMIT trackModified(internalOneTrackPartialData(trackId)); 1127 } 1128 1129 transactionResult = finishTransaction(); 1130 if (!transactionResult) { 1131 Q_EMIT finishInsertingTracksList(); 1132 return; 1133 } 1134 Q_EMIT finishInsertingTracksList(); 1135 } 1136 1137 void DatabaseInterface::removeTracksList(const QList<QUrl> &removedTracks) 1138 { 1139 auto transactionResult = startTransaction(); 1140 if (!transactionResult) { 1141 Q_EMIT finishRemovingTracksList(); 1142 return; 1143 } 1144 1145 initChangesTrackers(); 1146 1147 internalRemoveTracksList(removedTracks); 1148 1149 transactionResult = finishTransaction(); 1150 if (!transactionResult) { 1151 Q_EMIT finishRemovingTracksList(); 1152 return; 1153 } 1154 1155 if (!d->mInsertedArtists.isEmpty()) { 1156 DataTypes::ListArtistDataType newArtists; 1157 for (auto newArtistId : std::as_const(d->mInsertedArtists)) { 1158 newArtists.push_back(internalOneArtistPartialData(newArtistId)); 1159 } 1160 Q_EMIT artistsAdded(newArtists); 1161 } 1162 1163 Q_EMIT finishRemovingTracksList(); 1164 } 1165 1166 void DatabaseInterface::askRestoredTracks() 1167 { 1168 auto transactionResult = startTransaction(); 1169 if (!transactionResult) { 1170 return; 1171 } 1172 1173 auto result = internalAllFileName(); 1174 1175 Q_EMIT restoredTracks(result); 1176 1177 transactionResult = finishTransaction(); 1178 if (!transactionResult) { 1179 return; 1180 } 1181 } 1182 1183 void DatabaseInterface::trackHasStartedPlaying(const QUrl &fileName, const QDateTime &time) 1184 { 1185 auto transactionResult = startTransaction(); 1186 if (!transactionResult) { 1187 return; 1188 } 1189 1190 updateTrackStartedStatistics(fileName, time); 1191 1192 transactionResult = finishTransaction(); 1193 if (!transactionResult) { 1194 return; 1195 } 1196 } 1197 1198 void DatabaseInterface::trackHasFinishedPlaying(const QUrl &fileName, const QDateTime &time) 1199 { 1200 auto transactionResult = startTransaction(); 1201 if (!transactionResult) { 1202 return; 1203 } 1204 1205 updateTrackFinishedStatistics(fileName, time); 1206 1207 transactionResult = finishTransaction(); 1208 if (!transactionResult) { 1209 return; 1210 } 1211 } 1212 1213 void DatabaseInterface::clearData() 1214 { 1215 auto transactionResult = startTransaction(); 1216 if (!transactionResult) { 1217 return; 1218 } 1219 1220 auto queryResult = execQuery(d->mClearTracksTable); 1221 1222 if (!queryResult || !d->mClearTracksTable.isActive()) { 1223 Q_EMIT databaseError(); 1224 1225 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearTracksTable.lastQuery(); 1226 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearTracksTable.boundValues(); 1227 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearTracksTable.lastError(); 1228 } 1229 1230 d->mClearTracksTable.finish(); 1231 1232 queryResult = execQuery(d->mClearTracksDataTable); 1233 1234 if (!queryResult || !d->mClearTracksDataTable.isActive()) { 1235 Q_EMIT databaseError(); 1236 1237 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearTracksDataTable.lastQuery(); 1238 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearTracksDataTable.boundValues(); 1239 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearTracksDataTable.lastError(); 1240 } 1241 1242 d->mClearTracksDataTable.finish(); 1243 1244 queryResult = execQuery(d->mClearAlbumsTable); 1245 1246 if (!queryResult || !d->mClearAlbumsTable.isActive()) { 1247 Q_EMIT databaseError(); 1248 1249 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearAlbumsTable.lastQuery(); 1250 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearAlbumsTable.boundValues(); 1251 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearAlbumsTable.lastError(); 1252 } 1253 1254 d->mClearAlbumsTable.finish(); 1255 1256 queryResult = execQuery(d->mClearComposerTable); 1257 1258 if (!queryResult || !d->mClearComposerTable.isActive()) { 1259 Q_EMIT databaseError(); 1260 1261 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearComposerTable.lastQuery(); 1262 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearComposerTable.boundValues(); 1263 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearComposerTable.lastError(); 1264 } 1265 1266 d->mClearComposerTable.finish(); 1267 1268 queryResult = execQuery(d->mClearLyricistTable); 1269 1270 if (!queryResult || !d->mClearLyricistTable.isActive()) { 1271 Q_EMIT databaseError(); 1272 1273 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearLyricistTable.lastQuery(); 1274 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearLyricistTable.boundValues(); 1275 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearLyricistTable.lastError(); 1276 } 1277 1278 d->mClearLyricistTable.finish(); 1279 1280 queryResult = execQuery(d->mClearGenreTable); 1281 1282 if (!queryResult || !d->mClearGenreTable.isActive()) { 1283 Q_EMIT databaseError(); 1284 1285 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearGenreTable.lastQuery(); 1286 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearGenreTable.boundValues(); 1287 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearGenreTable.lastError(); 1288 } 1289 1290 d->mClearGenreTable.finish(); 1291 1292 queryResult = execQuery(d->mClearArtistsTable); 1293 1294 if (!queryResult || !d->mClearArtistsTable.isActive()) { 1295 Q_EMIT databaseError(); 1296 1297 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearArtistsTable.lastQuery(); 1298 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearArtistsTable.boundValues(); 1299 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::clearData" << d->mClearArtistsTable.lastError(); 1300 } 1301 1302 d->mClearArtistsTable.finish(); 1303 1304 transactionResult = finishTransaction(); 1305 if (!transactionResult) { 1306 return; 1307 } 1308 1309 Q_EMIT cleanedDatabase(); 1310 } 1311 1312 /********* Init and upgrade methods *********/ 1313 1314 void DatabaseInterface::initConnection(const QString &connectionName, const QString &databaseFileName) 1315 { 1316 QSqlDatabase tracksDatabase = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), connectionName); 1317 1318 if (!databaseFileName.isEmpty()) { 1319 tracksDatabase.setDatabaseName(QStringLiteral("file:") + databaseFileName); 1320 } else { 1321 tracksDatabase.setDatabaseName(QStringLiteral("file:memdb1?mode=memory")); 1322 } 1323 tracksDatabase.setConnectOptions(QStringLiteral("foreign_keys = ON;locking_mode = EXCLUSIVE;QSQLITE_OPEN_URI;QSQLITE_BUSY_TIMEOUT=500000")); 1324 1325 auto result = tracksDatabase.open(); 1326 if (result) { 1327 qCDebug(orgKdeElisaDatabase) << "database open"; 1328 } else { 1329 qCDebug(orgKdeElisaDatabase) << "database not open"; 1330 } 1331 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::init" << (tracksDatabase.driver()->hasFeature(QSqlDriver::Transactions) ? "yes" : "no"); 1332 1333 tracksDatabase.exec(QStringLiteral("PRAGMA foreign_keys = ON;")); 1334 1335 d = std::make_unique<DatabaseInterfacePrivate>(tracksDatabase, connectionName, databaseFileName); 1336 } 1337 1338 bool DatabaseInterface::initDatabase() 1339 { 1340 auto listTables = d->mTracksDatabase.tables(); 1341 1342 if (listTables.contains(QLatin1String("DatabaseVersionV2")) || 1343 listTables.contains(QLatin1String("DatabaseVersionV3")) || 1344 listTables.contains(QLatin1String("DatabaseVersionV4")) || 1345 listTables.contains(QLatin1String("DatabaseVersionV6")) || 1346 listTables.contains(QLatin1String("DatabaseVersionV7")) || 1347 listTables.contains(QLatin1String("DatabaseVersionV8")) || 1348 listTables.contains(QLatin1String("DatabaseVersionV10"))) { 1349 1350 qCDebug(orgKdeElisaDatabase()) << "Old database schema unsupported: delete and start from scratch"; 1351 qCDebug(orgKdeElisaDatabase()) << "list of old tables" << d->mTracksDatabase.tables(); 1352 1353 auto oldTables = QStringList{ 1354 QStringLiteral("DatabaseVersionV2"), 1355 QStringLiteral("DatabaseVersionV3"), 1356 QStringLiteral("DatabaseVersionV4"), 1357 QStringLiteral("DatabaseVersionV5"), 1358 QStringLiteral("DatabaseVersionV6"), 1359 QStringLiteral("DatabaseVersionV7"), 1360 QStringLiteral("DatabaseVersionV8"), 1361 QStringLiteral("DatabaseVersionV10"), 1362 QStringLiteral("AlbumsArtists"), 1363 QStringLiteral("TracksArtists"), 1364 QStringLiteral("TracksMapping"), 1365 QStringLiteral("Tracks"), 1366 QStringLiteral("Composer"), 1367 QStringLiteral("Genre"), 1368 QStringLiteral("Lyricist"), 1369 QStringLiteral("Albums"), 1370 QStringLiteral("DiscoverSource"), 1371 QStringLiteral("Artists"),}; 1372 for (const auto &oneTable : oldTables) { 1373 if (listTables.indexOf(oneTable) == -1) { 1374 continue; 1375 } 1376 1377 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1378 1379 auto result = createSchemaQuery.exec(QLatin1String("DROP TABLE ") + oneTable); 1380 1381 if (!result) { 1382 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDatabase" << createSchemaQuery.lastQuery(); 1383 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDatabase" << createSchemaQuery.lastError(); 1384 1385 Q_EMIT databaseError(); 1386 } 1387 } 1388 } 1389 1390 return upgradeDatabaseToLatestVersion(); 1391 } 1392 1393 void DatabaseInterface::createDatabaseV9() 1394 { 1395 qCInfo(orgKdeElisaDatabase) << "begin creation of v9 database schema"; 1396 1397 { 1398 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1399 1400 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV9` (`Version` INTEGER PRIMARY KEY NOT NULL)")); 1401 1402 if (!result) { 1403 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); 1404 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); 1405 1406 Q_EMIT databaseError(); 1407 } 1408 } 1409 1410 { 1411 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1412 1413 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DiscoverSource` (`ID` INTEGER PRIMARY KEY NOT NULL, " 1414 "`Name` VARCHAR(55) NOT NULL, " 1415 "UNIQUE (`Name`))")); 1416 1417 if (!result) { 1418 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); 1419 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); 1420 1421 Q_EMIT databaseError(); 1422 } 1423 } 1424 1425 { 1426 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1427 1428 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Artists` (`ID` INTEGER PRIMARY KEY NOT NULL, " 1429 "`Name` VARCHAR(55) NOT NULL, " 1430 "UNIQUE (`Name`))")); 1431 1432 if (!result) { 1433 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); 1434 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); 1435 1436 Q_EMIT databaseError(); 1437 } 1438 } 1439 1440 { 1441 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1442 1443 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Composer` (`ID` INTEGER PRIMARY KEY NOT NULL, " 1444 "`Name` VARCHAR(55) NOT NULL, " 1445 "UNIQUE (`Name`))")); 1446 1447 if (!result) { 1448 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); 1449 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); 1450 1451 Q_EMIT databaseError(); 1452 } 1453 } 1454 1455 { 1456 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1457 1458 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Genre` (`ID` INTEGER PRIMARY KEY NOT NULL, " 1459 "`Name` VARCHAR(85) NOT NULL, " 1460 "UNIQUE (`Name`))")); 1461 1462 if (!result) { 1463 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); 1464 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); 1465 1466 Q_EMIT databaseError(); 1467 } 1468 } 1469 1470 { 1471 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1472 1473 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Lyricist` (`ID` INTEGER PRIMARY KEY NOT NULL, " 1474 "`Name` VARCHAR(55) NOT NULL, " 1475 "UNIQUE (`Name`))")); 1476 1477 if (!result) { 1478 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); 1479 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); 1480 1481 Q_EMIT databaseError(); 1482 } 1483 } 1484 1485 { 1486 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1487 1488 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Albums` (" 1489 "`ID` INTEGER PRIMARY KEY NOT NULL, " 1490 "`Title` VARCHAR(55) NOT NULL, " 1491 "`ArtistName` VARCHAR(55), " 1492 "`AlbumPath` VARCHAR(255) NOT NULL, " 1493 "`CoverFileName` VARCHAR(255) NOT NULL, " 1494 "UNIQUE (`Title`, `ArtistName`, `AlbumPath`), " 1495 "CONSTRAINT fk_artists FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`) " 1496 "ON DELETE CASCADE)")); 1497 1498 if (!result) { 1499 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); 1500 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); 1501 } 1502 } 1503 1504 { 1505 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1506 1507 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Tracks` (" 1508 "`ID` INTEGER PRIMARY KEY NOT NULL, " 1509 "`Title` VARCHAR(85) NOT NULL, " 1510 "`ArtistName` VARCHAR(55), " 1511 "`AlbumTitle` VARCHAR(55), " 1512 "`AlbumArtistName` VARCHAR(55), " 1513 "`AlbumPath` VARCHAR(255), " 1514 "`TrackNumber` INTEGER DEFAULT -1, " 1515 "`DiscNumber` INTEGER DEFAULT -1, " 1516 "`Duration` INTEGER NOT NULL, " 1517 "`Rating` INTEGER NOT NULL DEFAULT 0, " 1518 "`Genre` VARCHAR(55), " 1519 "`Composer` VARCHAR(55), " 1520 "`Lyricist` VARCHAR(55), " 1521 "`Comment` VARCHAR(255) DEFAULT '', " 1522 "`Year` INTEGER DEFAULT 0, " 1523 "`Channels` INTEGER DEFAULT -1, " 1524 "`BitRate` INTEGER DEFAULT -1, " 1525 "`SampleRate` INTEGER DEFAULT -1, " 1526 "`HasEmbeddedCover` BOOLEAN NOT NULL, " 1527 "`ImportDate` INTEGER NOT NULL, " 1528 "`FirstPlayDate` INTEGER, " 1529 "`LastPlayDate` INTEGER, " 1530 "`PlayCounter` INTEGER NOT NULL, " 1531 "UNIQUE (" 1532 "`Title`, `AlbumTitle`, `AlbumArtistName`, " 1533 "`AlbumPath`, `TrackNumber`, `DiscNumber`" 1534 "), " 1535 "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " 1536 "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " 1537 "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " 1538 "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " 1539 "CONSTRAINT fk_tracks_album FOREIGN KEY (" 1540 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" 1541 "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); 1542 1543 if (!result) { 1544 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); 1545 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); 1546 1547 Q_EMIT databaseError(); 1548 } 1549 } 1550 1551 { 1552 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1553 1554 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `TracksMapping` (" 1555 "`TrackID` INTEGER NULL, " 1556 "`DiscoverID` INTEGER NOT NULL, " 1557 "`FileName` VARCHAR(255) NOT NULL, " 1558 "`Priority` INTEGER NOT NULL, " 1559 "`FileModifiedTime` DATETIME NOT NULL, " 1560 "PRIMARY KEY (`FileName`), " 1561 "CONSTRAINT TracksUnique UNIQUE (`TrackID`, `Priority`), " 1562 "CONSTRAINT fk_tracksmapping_trackID FOREIGN KEY (`TrackID`) REFERENCES `Tracks`(`ID`) ON DELETE CASCADE, " 1563 "CONSTRAINT fk_tracksmapping_discoverID FOREIGN KEY (`DiscoverID`) REFERENCES `DiscoverSource`(`ID`))")); 1564 1565 if (!result) { 1566 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastQuery(); 1567 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createSchemaQuery.lastError(); 1568 } 1569 } 1570 1571 { 1572 QSqlQuery createTrackIndex(d->mTracksDatabase); 1573 1574 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 1575 "IF NOT EXISTS " 1576 "`TitleAlbumsIndex` ON `Albums` " 1577 "(`Title`)")); 1578 1579 if (!result) { 1580 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); 1581 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); 1582 1583 Q_EMIT databaseError(); 1584 } 1585 } 1586 1587 { 1588 QSqlQuery createTrackIndex(d->mTracksDatabase); 1589 1590 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 1591 "IF NOT EXISTS " 1592 "`ArtistNameAlbumsIndex` ON `Albums` " 1593 "(`ArtistName`)")); 1594 1595 if (!result) { 1596 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); 1597 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); 1598 1599 Q_EMIT databaseError(); 1600 } 1601 } 1602 1603 { 1604 QSqlQuery createTrackIndex(d->mTracksDatabase); 1605 1606 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 1607 "IF NOT EXISTS " 1608 "`TracksAlbumIndex` ON `Tracks` " 1609 "(`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); 1610 1611 if (!result) { 1612 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); 1613 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); 1614 1615 Q_EMIT databaseError(); 1616 } 1617 } 1618 1619 { 1620 QSqlQuery createTrackIndex(d->mTracksDatabase); 1621 1622 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 1623 "IF NOT EXISTS " 1624 "`ArtistNameIndex` ON `Tracks` " 1625 "(`ArtistName`)")); 1626 1627 if (!result) { 1628 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); 1629 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); 1630 1631 Q_EMIT databaseError(); 1632 } 1633 } 1634 1635 { 1636 QSqlQuery createTrackIndex(d->mTracksDatabase); 1637 1638 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 1639 "IF NOT EXISTS " 1640 "`AlbumArtistNameIndex` ON `Tracks` " 1641 "(`AlbumArtistName`)")); 1642 1643 if (!result) { 1644 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); 1645 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); 1646 1647 Q_EMIT databaseError(); 1648 } 1649 } 1650 1651 { 1652 QSqlQuery createTrackIndex(d->mTracksDatabase); 1653 1654 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 1655 "IF NOT EXISTS " 1656 "`TracksFileNameIndex` ON `TracksMapping` " 1657 "(`FileName`)")); 1658 1659 if (!result) { 1660 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastQuery(); 1661 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseV9" << createTrackIndex.lastError(); 1662 1663 Q_EMIT databaseError(); 1664 } 1665 } 1666 1667 qCInfo(orgKdeElisaDatabase) << "end creation of v9 database schema"; 1668 } 1669 1670 void DatabaseInterface::upgradeDatabaseV9() 1671 { 1672 qCInfo(orgKdeElisaDatabase) << "begin update to v9 of database schema"; 1673 1674 { 1675 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1676 1677 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV9` (`Version` INTEGER PRIMARY KEY NOT NULL)")); 1678 1679 if (!result) { 1680 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); 1681 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); 1682 1683 Q_EMIT databaseError(); 1684 } 1685 } 1686 1687 { 1688 QSqlQuery disableForeignKeys(d->mTracksDatabase); 1689 1690 auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); 1691 1692 if (!result) { 1693 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << disableForeignKeys.lastQuery(); 1694 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << disableForeignKeys.lastError(); 1695 1696 Q_EMIT databaseError(); 1697 } 1698 } 1699 1700 d->mTracksDatabase.transaction(); 1701 1702 { 1703 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1704 1705 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewAlbums` (" 1706 "`ID` INTEGER PRIMARY KEY NOT NULL, " 1707 "`Title` VARCHAR(55) NOT NULL, " 1708 "`ArtistName` VARCHAR(55), " 1709 "`AlbumPath` VARCHAR(255) NOT NULL, " 1710 "`CoverFileName` VARCHAR(255) NOT NULL, " 1711 "UNIQUE (`Title`, `ArtistName`, `AlbumPath`), " 1712 "CONSTRAINT fk_artists FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`) " 1713 "ON DELETE CASCADE)")); 1714 1715 if (!result) { 1716 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); 1717 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); 1718 } 1719 } 1720 1721 { 1722 QSqlQuery copyDataQuery(d->mTracksDatabase); 1723 1724 auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewAlbums` " 1725 "SELECT " 1726 "album.`ID`, " 1727 "album.`Title`, " 1728 "artist.`Name`, " 1729 "album.`AlbumPath`, " 1730 "album.`CoverFileName` " 1731 "FROM " 1732 "`Albums` album, " 1733 "`AlbumsArtists` albumArtistMapping, " 1734 "`Artists` artist " 1735 "WHERE " 1736 "album.`ID` = albumArtistMapping.`AlbumID` AND " 1737 "albumArtistMapping.`ArtistID` = artist.`ID`")); 1738 1739 if (!result) { 1740 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << copyDataQuery.lastQuery(); 1741 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << copyDataQuery.lastError(); 1742 1743 Q_EMIT databaseError(); 1744 } 1745 } 1746 1747 { 1748 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1749 1750 auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Albums`")); 1751 1752 if (!result) { 1753 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); 1754 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); 1755 1756 Q_EMIT databaseError(); 1757 } 1758 } 1759 1760 { 1761 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1762 1763 auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `AlbumsArtists`")); 1764 1765 if (!result) { 1766 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); 1767 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); 1768 1769 Q_EMIT databaseError(); 1770 } 1771 } 1772 1773 { 1774 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1775 1776 auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewAlbums` RENAME TO `Albums`")); 1777 1778 if (!result) { 1779 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); 1780 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); 1781 1782 Q_EMIT databaseError(); 1783 } 1784 } 1785 1786 { 1787 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1788 1789 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracks` (" 1790 "`ID` INTEGER PRIMARY KEY NOT NULL, " 1791 "`Title` VARCHAR(85) NOT NULL, " 1792 "`ArtistName` VARCHAR(55), " 1793 "`AlbumTitle` VARCHAR(55), " 1794 "`AlbumArtistName` VARCHAR(55), " 1795 "`AlbumPath` VARCHAR(255), " 1796 "`TrackNumber` INTEGER DEFAULT -1, " 1797 "`DiscNumber` INTEGER DEFAULT -1, " 1798 "`Duration` INTEGER NOT NULL, " 1799 "`Rating` INTEGER NOT NULL DEFAULT 0, " 1800 "`Genre` VARCHAR(55), " 1801 "`Composer` VARCHAR(55), " 1802 "`Lyricist` VARCHAR(55), " 1803 "`Comment` VARCHAR(255) DEFAULT '', " 1804 "`Year` INTEGER DEFAULT 0, " 1805 "`Channels` INTEGER DEFAULT -1, " 1806 "`BitRate` INTEGER DEFAULT -1, " 1807 "`SampleRate` INTEGER DEFAULT -1, " 1808 "`HasEmbeddedCover` BOOLEAN NOT NULL, " 1809 "`ImportDate` INTEGER NOT NULL, " 1810 "`FirstPlayDate` INTEGER, " 1811 "`LastPlayDate` INTEGER, " 1812 "`PlayCounter` INTEGER NOT NULL, " 1813 "UNIQUE (" 1814 "`Title`, `AlbumTitle`, `AlbumArtistName`, " 1815 "`AlbumPath`, `TrackNumber`, `DiscNumber`" 1816 "), " 1817 "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " 1818 "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " 1819 "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " 1820 "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " 1821 "CONSTRAINT fk_tracks_album FOREIGN KEY (" 1822 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" 1823 "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); 1824 1825 if (!result) { 1826 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); 1827 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); 1828 1829 Q_EMIT databaseError(); 1830 } 1831 } 1832 1833 { 1834 QSqlQuery copyDataQuery(d->mTracksDatabase); 1835 1836 auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewTracks` " 1837 "(`ID`, `Title`, `ArtistName`, " 1838 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`, " 1839 "`TrackNumber`, `DiscNumber`, `Duration`, " 1840 "`Rating`, `Genre`, `Composer`, " 1841 "`Lyricist`, `Comment`, `Year`, " 1842 "`Channels`, `BitRate`, `SampleRate`, " 1843 "`HasEmbeddedCover`, `ImportDate`, `PlayCounter`) " 1844 "SELECT " 1845 "track.`ID`, " 1846 "track.`Title`, " 1847 "artist.`Name`, " 1848 "album.`Title`, " 1849 "album.`ArtistName`, " 1850 "album.`AlbumPath`, " 1851 "track.`TrackNumber`, " 1852 "track.`DiscNumber`, " 1853 "track.`Duration`, " 1854 "track.`Rating`, " 1855 "genre.`Name`, " 1856 "composer.`Name`, " 1857 "lyricist.`Name`, " 1858 "track.`Comment`, " 1859 "track.`Year`, " 1860 "track.`Channels`, " 1861 "track.`BitRate`, " 1862 "track.`SampleRate`, " 1863 "FALSE, " 1864 "strftime('%s', 'now'), " 1865 "0 " 1866 "FROM " 1867 "`Tracks` track, " 1868 "`TracksArtists` trackArtistMapping, " 1869 "`Artists` artist, " 1870 "`Albums` album " 1871 "left join " 1872 "`Genre` genre " 1873 "on track.`GenreID` = genre.`ID` " 1874 "left join " 1875 "`Composer` composer " 1876 "on track.`ComposerID` = composer.`ID` " 1877 "left join " 1878 "`Lyricist` lyricist " 1879 "on track.`LyricistID` = lyricist.`ID` " 1880 "WHERE " 1881 "track.`ID` = trackArtistMapping.`TrackID` AND " 1882 "trackArtistMapping.`ArtistID` = artist.`ID` AND " 1883 "track.`AlbumID` = album.`ID`")); 1884 1885 if (!result) { 1886 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << copyDataQuery.lastQuery(); 1887 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << copyDataQuery.lastError(); 1888 1889 Q_EMIT databaseError(); 1890 } 1891 } 1892 1893 { 1894 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1895 1896 auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Tracks`")); 1897 1898 if (!result) { 1899 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); 1900 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); 1901 1902 Q_EMIT databaseError(); 1903 } 1904 } 1905 1906 { 1907 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1908 1909 auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `TracksArtists`")); 1910 1911 if (!result) { 1912 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); 1913 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); 1914 1915 Q_EMIT databaseError(); 1916 } 1917 } 1918 1919 { 1920 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1921 1922 auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracks` RENAME TO `Tracks`")); 1923 1924 if (!result) { 1925 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastQuery(); 1926 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << createSchemaQuery.lastError(); 1927 1928 Q_EMIT databaseError(); 1929 } 1930 } 1931 1932 d->mTracksDatabase.commit(); 1933 1934 { 1935 QSqlQuery enableForeignKeys(d->mTracksDatabase); 1936 1937 auto result = enableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=ON")); 1938 1939 if (!result) { 1940 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << enableForeignKeys.lastQuery(); 1941 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV9" << enableForeignKeys.lastError(); 1942 1943 Q_EMIT databaseError(); 1944 } 1945 } 1946 1947 qCInfo(orgKdeElisaDatabase) << "finished update to v9 of database schema"; 1948 } 1949 1950 void DatabaseInterface::upgradeDatabaseV11() 1951 { 1952 qCInfo(orgKdeElisaDatabase) << "begin update to v11 of database schema"; 1953 1954 { 1955 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1956 1957 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV11` (`Version` INTEGER PRIMARY KEY NOT NULL)")); 1958 1959 if (!result) { 1960 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); 1961 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); 1962 1963 Q_EMIT databaseError(); 1964 } 1965 } 1966 1967 { 1968 QSqlQuery disableForeignKeys(d->mTracksDatabase); 1969 1970 auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); 1971 1972 if (!result) { 1973 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << disableForeignKeys.lastQuery(); 1974 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << disableForeignKeys.lastError(); 1975 1976 Q_EMIT databaseError(); 1977 } 1978 } 1979 1980 d->mTracksDatabase.transaction(); 1981 1982 { 1983 QSqlQuery createSchemaQuery(d->mTracksDatabase); 1984 1985 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `TracksData` (" 1986 "`DiscoverID` INTEGER NOT NULL, " 1987 "`FileName` VARCHAR(255) NOT NULL, " 1988 "`FileModifiedTime` DATETIME NOT NULL, " 1989 "`ImportDate` INTEGER NOT NULL, " 1990 "`FirstPlayDate` INTEGER, " 1991 "`LastPlayDate` INTEGER, " 1992 "`PlayCounter` INTEGER NOT NULL, " 1993 "PRIMARY KEY (`FileName`, `DiscoverID`), " 1994 "CONSTRAINT fk_tracksmapping_discoverID FOREIGN KEY (`DiscoverID`) REFERENCES `DiscoverSource`(`ID`))")); 1995 1996 if (!result) { 1997 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); 1998 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); 1999 } 2000 } 2001 2002 { 2003 QSqlQuery copyDataQuery(d->mTracksDatabase); 2004 2005 auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `TracksData` " 2006 "SELECT " 2007 "m.`DiscoverID`, " 2008 "m.`FileName`, " 2009 "m.`FileModifiedTime`, " 2010 "t.`ImportDate`, " 2011 "t.`FirstPlayDate`, " 2012 "t.`LastPlayDate`, " 2013 "t.`PlayCounter` " 2014 "FROM " 2015 "`Tracks` t, " 2016 "`TracksMapping` m " 2017 "WHERE " 2018 "t.`ID` = m.`TrackID`")); 2019 2020 if (!result) { 2021 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << copyDataQuery.lastQuery(); 2022 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << copyDataQuery.lastError(); 2023 2024 Q_EMIT databaseError(); 2025 } 2026 } 2027 2028 { 2029 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2030 2031 auto result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracks` (" 2032 "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " 2033 "`DiscoverID` INTEGER NOT NULL, " 2034 "`FileName` VARCHAR(255) NOT NULL, " 2035 "`Priority` INTEGER NOT NULL, " 2036 "`Title` VARCHAR(85) NOT NULL, " 2037 "`ArtistName` VARCHAR(55), " 2038 "`AlbumTitle` VARCHAR(55), " 2039 "`AlbumArtistName` VARCHAR(55), " 2040 "`AlbumPath` VARCHAR(255), " 2041 "`TrackNumber` INTEGER, " 2042 "`DiscNumber` INTEGER, " 2043 "`Duration` INTEGER NOT NULL, " 2044 "`Rating` INTEGER NOT NULL DEFAULT 0, " 2045 "`Genre` VARCHAR(55), " 2046 "`Composer` VARCHAR(55), " 2047 "`Lyricist` VARCHAR(55), " 2048 "`Comment` VARCHAR(255), " 2049 "`Year` INTEGER, " 2050 "`Channels` INTEGER, " 2051 "`BitRate` INTEGER, " 2052 "`SampleRate` INTEGER, " 2053 "`HasEmbeddedCover` BOOLEAN NOT NULL, " 2054 "UNIQUE (" 2055 "`FileName`" 2056 "), " 2057 "UNIQUE (" 2058 "`Priority`, `Title`, `ArtistName`, " 2059 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`" 2060 "), " 2061 "CONSTRAINT fk_fileName FOREIGN KEY (`FileName`, `DiscoverID`) " 2062 "REFERENCES `TracksData`(`FileName`, `DiscoverID`) ON DELETE CASCADE, " 2063 "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " 2064 "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " 2065 "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " 2066 "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " 2067 "CONSTRAINT fk_tracks_discoverID FOREIGN KEY (`DiscoverID`) REFERENCES `DiscoverSource`(`ID`)" 2068 "CONSTRAINT fk_tracks_album FOREIGN KEY (" 2069 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" 2070 "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); 2071 2072 if (!result) { 2073 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); 2074 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); 2075 2076 Q_EMIT databaseError(); 2077 } 2078 } 2079 2080 { 2081 QSqlQuery copyDataQuery(d->mTracksDatabase); 2082 2083 auto result = copyDataQuery.exec(QStringLiteral("INSERT OR IGNORE INTO `NewTracks` " 2084 "(" 2085 "`DiscoverID`, " 2086 "`FileName`, " 2087 "`Priority`, " 2088 "`Title`, " 2089 "`ArtistName`, " 2090 "`AlbumTitle`, " 2091 "`AlbumArtistName`, " 2092 "`AlbumPath`, " 2093 "`TrackNumber`, " 2094 "`DiscNumber`, " 2095 "`Duration`, " 2096 "`Rating`, " 2097 "`Genre`, " 2098 "`Composer`, " 2099 "`Lyricist`, " 2100 "`Comment`, " 2101 "`Year`, " 2102 "`Channels`, " 2103 "`BitRate`, " 2104 "`SampleRate`, " 2105 "`HasEmbeddedCover`" 2106 ") " 2107 "SELECT " 2108 "m.`DiscoverID`, " 2109 "m.`FileName`, " 2110 "m.`Priority`, " 2111 "t.`Title`, " 2112 "t.`ArtistName`, " 2113 "t.`AlbumTitle`, " 2114 "t.`AlbumArtistName`, " 2115 "t.`AlbumPath`, " 2116 "t.`TrackNumber`, " 2117 "t.`DiscNumber`, " 2118 "t.`Duration`, " 2119 "t.`Rating`, " 2120 "t.`Genre`, " 2121 "t.`Composer`, " 2122 "t.`Lyricist`, " 2123 "t.`Comment`, " 2124 "t.`Year`, " 2125 "t.`Channels`, " 2126 "t.`BitRate`, " 2127 "t.`SampleRate`, " 2128 "t.`HasEmbeddedCover` " 2129 "FROM " 2130 "`Tracks` t, " 2131 "`TracksMapping` m " 2132 "WHERE " 2133 "t.`ID` = m.`TrackID`")); 2134 2135 if (!result) { 2136 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << copyDataQuery.lastQuery(); 2137 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << copyDataQuery.lastError(); 2138 2139 Q_EMIT databaseError(); 2140 } 2141 } 2142 2143 { 2144 QSqlQuery updateDataQuery(d->mTracksDatabase); 2145 2146 auto result = updateDataQuery.exec(QStringLiteral("UPDATE `NewTracks` " 2147 "SET " 2148 "`TrackNumber` = NULL " 2149 "WHERE " 2150 "`TrackNumber` = -1")); 2151 2152 if (!result) { 2153 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastQuery(); 2154 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastError(); 2155 2156 Q_EMIT databaseError(); 2157 } 2158 } 2159 2160 { 2161 QSqlQuery updateDataQuery(d->mTracksDatabase); 2162 2163 auto result = updateDataQuery.exec(QStringLiteral("UPDATE `NewTracks` " 2164 "SET " 2165 "`Channels` = NULL " 2166 "WHERE " 2167 "`Channels` = -1")); 2168 2169 if (!result) { 2170 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastQuery(); 2171 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastError(); 2172 2173 Q_EMIT databaseError(); 2174 } 2175 } 2176 2177 { 2178 QSqlQuery updateDataQuery(d->mTracksDatabase); 2179 2180 auto result = updateDataQuery.exec(QStringLiteral("UPDATE `NewTracks` " 2181 "SET " 2182 "`BitRate` = NULL " 2183 "WHERE " 2184 "`BitRate` = -1")); 2185 2186 if (!result) { 2187 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastQuery(); 2188 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastError(); 2189 2190 Q_EMIT databaseError(); 2191 } 2192 } 2193 2194 { 2195 QSqlQuery updateDataQuery(d->mTracksDatabase); 2196 2197 auto result = updateDataQuery.exec(QStringLiteral("UPDATE `NewTracks` " 2198 "SET " 2199 "`SampleRate` = NULL " 2200 "WHERE " 2201 "`SampleRate` = -1")); 2202 2203 if (!result) { 2204 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastQuery(); 2205 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << updateDataQuery.lastError(); 2206 2207 Q_EMIT databaseError(); 2208 } 2209 } 2210 2211 { 2212 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2213 2214 auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Tracks`")); 2215 2216 if (!result) { 2217 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); 2218 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); 2219 2220 Q_EMIT databaseError(); 2221 } 2222 } 2223 2224 { 2225 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2226 2227 auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `TracksMapping`")); 2228 2229 if (!result) { 2230 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); 2231 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); 2232 2233 Q_EMIT databaseError(); 2234 } 2235 } 2236 2237 { 2238 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2239 2240 auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracks` RENAME TO `Tracks`")); 2241 2242 if (!result) { 2243 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastQuery(); 2244 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createSchemaQuery.lastError(); 2245 2246 Q_EMIT databaseError(); 2247 } 2248 } 2249 2250 d->mTracksDatabase.commit(); 2251 2252 { 2253 QSqlQuery enableForeignKeys(d->mTracksDatabase); 2254 2255 auto result = enableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=ON")); 2256 2257 if (!result) { 2258 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << enableForeignKeys.lastQuery(); 2259 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << enableForeignKeys.lastError(); 2260 2261 Q_EMIT databaseError(); 2262 } 2263 } 2264 2265 { 2266 QSqlQuery createTrackIndex(d->mTracksDatabase); 2267 2268 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2269 "IF NOT EXISTS " 2270 "`TracksAlbumIndex` ON `Tracks` " 2271 "(`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); 2272 2273 if (!result) { 2274 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); 2275 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); 2276 2277 Q_EMIT databaseError(); 2278 } 2279 } 2280 2281 { 2282 QSqlQuery createTrackIndex(d->mTracksDatabase); 2283 2284 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2285 "IF NOT EXISTS " 2286 "`ArtistNameIndex` ON `Tracks` " 2287 "(`ArtistName`)")); 2288 2289 if (!result) { 2290 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); 2291 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); 2292 2293 Q_EMIT databaseError(); 2294 } 2295 } 2296 2297 { 2298 QSqlQuery createTrackIndex(d->mTracksDatabase); 2299 2300 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2301 "IF NOT EXISTS " 2302 "`AlbumArtistNameIndex` ON `Tracks` " 2303 "(`AlbumArtistName`)")); 2304 2305 if (!result) { 2306 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); 2307 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); 2308 2309 Q_EMIT databaseError(); 2310 } 2311 } 2312 2313 { 2314 QSqlQuery createTrackIndex(d->mTracksDatabase); 2315 2316 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2317 "IF NOT EXISTS " 2318 "`TracksUniqueData` ON `Tracks` " 2319 "(`Title`, `ArtistName`, " 2320 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); 2321 2322 if (!result) { 2323 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); 2324 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); 2325 2326 Q_EMIT databaseError(); 2327 } 2328 } 2329 2330 { 2331 QSqlQuery createTrackIndex(d->mTracksDatabase); 2332 2333 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2334 "IF NOT EXISTS " 2335 "`TracksUniqueDataPriority` ON `Tracks` " 2336 "(`Priority`, `Title`, `ArtistName`, " 2337 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); 2338 2339 if (!result) { 2340 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); 2341 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); 2342 2343 Q_EMIT databaseError(); 2344 } 2345 } 2346 2347 { 2348 QSqlQuery createTrackIndex(d->mTracksDatabase); 2349 2350 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2351 "IF NOT EXISTS " 2352 "`TracksFileNameIndex` ON `Tracks` " 2353 "(`FileName`)")); 2354 2355 if (!result) { 2356 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastQuery(); 2357 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV11" << createTrackIndex.lastError(); 2358 2359 Q_EMIT databaseError(); 2360 } 2361 } 2362 2363 qCInfo(orgKdeElisaDatabase) << "finished update to v11 of database schema"; 2364 } 2365 2366 void DatabaseInterface::upgradeDatabaseV12() 2367 { 2368 qCInfo(orgKdeElisaDatabase) << "begin update to v12 of database schema"; 2369 2370 { 2371 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2372 2373 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV12` (`Version` INTEGER PRIMARY KEY NOT NULL)")); 2374 2375 if (!result) { 2376 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); 2377 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); 2378 2379 Q_EMIT databaseError(); 2380 } 2381 } 2382 2383 { 2384 QSqlQuery disableForeignKeys(d->mTracksDatabase); 2385 2386 auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); 2387 2388 if (!result) { 2389 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << disableForeignKeys.lastQuery(); 2390 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << disableForeignKeys.lastError(); 2391 2392 Q_EMIT databaseError(); 2393 } 2394 } 2395 2396 d->mTracksDatabase.transaction(); 2397 2398 { 2399 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2400 2401 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracks` (" 2402 "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " 2403 "`FileName` VARCHAR(255) NOT NULL, " 2404 "`Priority` INTEGER NOT NULL, " 2405 "`Title` VARCHAR(85) NOT NULL, " 2406 "`ArtistName` VARCHAR(55), " 2407 "`AlbumTitle` VARCHAR(55), " 2408 "`AlbumArtistName` VARCHAR(55), " 2409 "`AlbumPath` VARCHAR(255), " 2410 "`TrackNumber` INTEGER, " 2411 "`DiscNumber` INTEGER, " 2412 "`Duration` INTEGER NOT NULL, " 2413 "`Rating` INTEGER NOT NULL DEFAULT 0, " 2414 "`Genre` VARCHAR(55), " 2415 "`Composer` VARCHAR(55), " 2416 "`Lyricist` VARCHAR(55), " 2417 "`Comment` VARCHAR(255), " 2418 "`Year` INTEGER, " 2419 "`Channels` INTEGER, " 2420 "`BitRate` INTEGER, " 2421 "`SampleRate` INTEGER, " 2422 "`HasEmbeddedCover` BOOLEAN NOT NULL, " 2423 "UNIQUE (" 2424 "`FileName`" 2425 "), " 2426 "UNIQUE (" 2427 "`Priority`, `Title`, `ArtistName`, " 2428 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`" 2429 "), " 2430 "CONSTRAINT fk_fileName FOREIGN KEY (`FileName`) " 2431 "REFERENCES `TracksData`(`FileName`) ON DELETE CASCADE, " 2432 "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " 2433 "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " 2434 "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " 2435 "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " 2436 "CONSTRAINT fk_tracks_album FOREIGN KEY (" 2437 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" 2438 "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); 2439 2440 if (!result) { 2441 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); 2442 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); 2443 } 2444 } 2445 2446 { 2447 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2448 2449 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracksData` (" 2450 "`FileName` VARCHAR(255) NOT NULL, " 2451 "`FileModifiedTime` DATETIME NOT NULL, " 2452 "`ImportDate` INTEGER NOT NULL, " 2453 "`FirstPlayDate` INTEGER, " 2454 "`LastPlayDate` INTEGER, " 2455 "`PlayCounter` INTEGER NOT NULL, " 2456 "PRIMARY KEY (`FileName`))")); 2457 2458 if (!result) { 2459 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); 2460 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); 2461 } 2462 } 2463 2464 { 2465 QSqlQuery copyDataQuery(d->mTracksDatabase); 2466 2467 auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewTracksData` " 2468 "SELECT " 2469 "td.`FileName`, " 2470 "td.`FileModifiedTime`, " 2471 "td.`ImportDate`, " 2472 "td.`FirstPlayDate`, " 2473 "td.`LastPlayDate`, " 2474 "td.`PlayCounter` " 2475 "FROM " 2476 "`TracksData` td")); 2477 2478 if (!result) { 2479 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << copyDataQuery.lastQuery(); 2480 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << copyDataQuery.lastError(); 2481 2482 Q_EMIT databaseError(); 2483 } 2484 } 2485 2486 { 2487 QSqlQuery copyDataQuery(d->mTracksDatabase); 2488 2489 auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewTracks` " 2490 "SELECT " 2491 "t.`ID`, " 2492 "t.`FileName`, " 2493 "t.`Priority`, " 2494 "t.`Title`, " 2495 "t.`ArtistName`, " 2496 "t.`AlbumTitle`, " 2497 "t.`AlbumArtistName`, " 2498 "t.`AlbumPath`, " 2499 "t.`TrackNumber`, " 2500 "t.`DiscNumber`, " 2501 "t.`Duration`, " 2502 "t.`Rating`, " 2503 "t.`Genre`, " 2504 "t.`Composer`, " 2505 "t.`Lyricist`, " 2506 "t.`Comment`, " 2507 "t.`Year`, " 2508 "t.`Channels`, " 2509 "t.`BitRate`, " 2510 "t.`SampleRate`, " 2511 "t.`HasEmbeddedCover` " 2512 "FROM " 2513 "`Tracks` t")); 2514 2515 if (!result) { 2516 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << copyDataQuery.lastQuery(); 2517 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << copyDataQuery.lastError(); 2518 2519 Q_EMIT databaseError(); 2520 } 2521 } 2522 2523 { 2524 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2525 2526 auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `TracksData`")); 2527 2528 if (!result) { 2529 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); 2530 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); 2531 2532 Q_EMIT databaseError(); 2533 } 2534 } 2535 2536 { 2537 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2538 2539 auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Tracks`")); 2540 2541 if (!result) { 2542 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); 2543 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); 2544 2545 Q_EMIT databaseError(); 2546 } 2547 } 2548 2549 { 2550 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2551 2552 auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracksData` RENAME TO `TracksData`")); 2553 2554 if (!result) { 2555 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); 2556 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); 2557 2558 Q_EMIT databaseError(); 2559 } 2560 } 2561 2562 { 2563 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2564 2565 auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracks` RENAME TO `Tracks`")); 2566 2567 if (!result) { 2568 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastQuery(); 2569 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createSchemaQuery.lastError(); 2570 2571 Q_EMIT databaseError(); 2572 } 2573 } 2574 2575 d->mTracksDatabase.commit(); 2576 2577 { 2578 QSqlQuery enableForeignKeys(d->mTracksDatabase); 2579 2580 auto result = enableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=ON")); 2581 2582 if (!result) { 2583 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << enableForeignKeys.lastQuery(); 2584 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << enableForeignKeys.lastError(); 2585 2586 Q_EMIT databaseError(); 2587 } 2588 } 2589 2590 { 2591 QSqlQuery createTrackIndex(d->mTracksDatabase); 2592 2593 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2594 "IF NOT EXISTS " 2595 "`TracksAlbumIndex` ON `Tracks` " 2596 "(`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); 2597 2598 if (!result) { 2599 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); 2600 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); 2601 2602 Q_EMIT databaseError(); 2603 } 2604 } 2605 2606 { 2607 QSqlQuery createTrackIndex(d->mTracksDatabase); 2608 2609 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2610 "IF NOT EXISTS " 2611 "`ArtistNameIndex` ON `Tracks` " 2612 "(`ArtistName`)")); 2613 2614 if (!result) { 2615 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); 2616 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); 2617 2618 Q_EMIT databaseError(); 2619 } 2620 } 2621 2622 { 2623 QSqlQuery createTrackIndex(d->mTracksDatabase); 2624 2625 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2626 "IF NOT EXISTS " 2627 "`AlbumArtistNameIndex` ON `Tracks` " 2628 "(`AlbumArtistName`)")); 2629 2630 if (!result) { 2631 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); 2632 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); 2633 2634 Q_EMIT databaseError(); 2635 } 2636 } 2637 2638 { 2639 QSqlQuery createTrackIndex(d->mTracksDatabase); 2640 2641 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2642 "IF NOT EXISTS " 2643 "`TracksUniqueData` ON `Tracks` " 2644 "(`Title`, `ArtistName`, " 2645 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); 2646 2647 if (!result) { 2648 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); 2649 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); 2650 2651 Q_EMIT databaseError(); 2652 } 2653 } 2654 2655 { 2656 QSqlQuery createTrackIndex(d->mTracksDatabase); 2657 2658 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2659 "IF NOT EXISTS " 2660 "`TracksUniqueDataPriority` ON `Tracks` " 2661 "(`Priority`, `Title`, `ArtistName`, " 2662 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); 2663 2664 if (!result) { 2665 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); 2666 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); 2667 2668 Q_EMIT databaseError(); 2669 } 2670 } 2671 2672 { 2673 QSqlQuery createTrackIndex(d->mTracksDatabase); 2674 2675 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2676 "IF NOT EXISTS " 2677 "`TracksFileNameIndex` ON `Tracks` " 2678 "(`FileName`)")); 2679 2680 if (!result) { 2681 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastQuery(); 2682 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV12" << createTrackIndex.lastError(); 2683 2684 Q_EMIT databaseError(); 2685 } 2686 } 2687 2688 qCInfo(orgKdeElisaDatabase) << "finished update to v12 of database schema"; 2689 } 2690 2691 void DatabaseInterface::upgradeDatabaseV13() 2692 { 2693 qCInfo(orgKdeElisaDatabase) << "begin update to v13 of database schema"; 2694 2695 { 2696 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2697 2698 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV13` (`Version` INTEGER PRIMARY KEY NOT NULL)")); 2699 2700 if (!result) { 2701 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastQuery(); 2702 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastError(); 2703 2704 Q_EMIT databaseError(); 2705 } 2706 } 2707 2708 { 2709 QSqlQuery disableForeignKeys(d->mTracksDatabase); 2710 2711 auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); 2712 2713 if (!result) { 2714 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << disableForeignKeys.lastQuery(); 2715 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << disableForeignKeys.lastError(); 2716 2717 Q_EMIT databaseError(); 2718 } 2719 } 2720 2721 d->mTracksDatabase.transaction(); 2722 2723 { 2724 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2725 2726 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `NewTracks` (" 2727 "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " 2728 "`FileName` VARCHAR(255) NOT NULL, " 2729 "`Priority` INTEGER NOT NULL, " 2730 "`Title` VARCHAR(85) NOT NULL, " 2731 "`ArtistName` VARCHAR(55), " 2732 "`AlbumTitle` VARCHAR(55), " 2733 "`AlbumArtistName` VARCHAR(55), " 2734 "`AlbumPath` VARCHAR(255), " 2735 "`TrackNumber` INTEGER, " 2736 "`DiscNumber` INTEGER, " 2737 "`Duration` INTEGER NOT NULL, " 2738 "`Rating` INTEGER NOT NULL DEFAULT 0, " 2739 "`Genre` VARCHAR(55), " 2740 "`Composer` VARCHAR(55), " 2741 "`Lyricist` VARCHAR(55), " 2742 "`Comment` VARCHAR(255), " 2743 "`Year` INTEGER, " 2744 "`Channels` INTEGER, " 2745 "`BitRate` INTEGER, " 2746 "`SampleRate` INTEGER, " 2747 "`HasEmbeddedCover` BOOLEAN NOT NULL, " 2748 "UNIQUE (" 2749 "`FileName`" 2750 "), " 2751 "UNIQUE (" 2752 "`Priority`, `Title`, `ArtistName`, " 2753 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`, " 2754 "`TrackNumber`, `DiscNumber`" 2755 "), " 2756 "CONSTRAINT fk_fileName FOREIGN KEY (`FileName`) " 2757 "REFERENCES `TracksData`(`FileName`) ON DELETE CASCADE, " 2758 "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " 2759 "CONSTRAINT fk_tracks_composer FOREIGN KEY (`Composer`) REFERENCES `Composer`(`Name`), " 2760 "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`Lyricist`) REFERENCES `Lyricist`(`Name`), " 2761 "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`), " 2762 "CONSTRAINT fk_tracks_album FOREIGN KEY (" 2763 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" 2764 "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); 2765 2766 if (!result) { 2767 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastQuery(); 2768 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastError(); 2769 } 2770 } 2771 2772 { 2773 QSqlQuery copyDataQuery(d->mTracksDatabase); 2774 2775 auto result = copyDataQuery.exec(QStringLiteral("INSERT INTO `NewTracks` " 2776 "SELECT " 2777 "t.`ID`, " 2778 "t.`FileName`, " 2779 "t.`Priority`, " 2780 "t.`Title`, " 2781 "t.`ArtistName`, " 2782 "t.`AlbumTitle`, " 2783 "t.`AlbumArtistName`, " 2784 "t.`AlbumPath`, " 2785 "t.`TrackNumber`, " 2786 "t.`DiscNumber`, " 2787 "t.`Duration`, " 2788 "t.`Rating`, " 2789 "t.`Genre`, " 2790 "t.`Composer`, " 2791 "t.`Lyricist`, " 2792 "t.`Comment`, " 2793 "t.`Year`, " 2794 "t.`Channels`, " 2795 "t.`BitRate`, " 2796 "t.`SampleRate`, " 2797 "t.`HasEmbeddedCover` " 2798 "FROM " 2799 "`Tracks` t")); 2800 2801 if (!result) { 2802 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << copyDataQuery.lastQuery(); 2803 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << copyDataQuery.lastError(); 2804 2805 Q_EMIT databaseError(); 2806 } 2807 } 2808 2809 { 2810 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2811 2812 auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Tracks`")); 2813 2814 if (!result) { 2815 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastQuery(); 2816 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastError(); 2817 2818 Q_EMIT databaseError(); 2819 } 2820 } 2821 2822 { 2823 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2824 2825 auto result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `NewTracks` RENAME TO `Tracks`")); 2826 2827 if (!result) { 2828 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastQuery(); 2829 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createSchemaQuery.lastError(); 2830 2831 Q_EMIT databaseError(); 2832 } 2833 } 2834 2835 d->mTracksDatabase.commit(); 2836 2837 { 2838 QSqlQuery enableForeignKeys(d->mTracksDatabase); 2839 2840 auto result = enableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=ON")); 2841 2842 if (!result) { 2843 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << enableForeignKeys.lastQuery(); 2844 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << enableForeignKeys.lastError(); 2845 2846 Q_EMIT databaseError(); 2847 } 2848 } 2849 2850 { 2851 QSqlQuery createTrackIndex(d->mTracksDatabase); 2852 2853 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2854 "IF NOT EXISTS " 2855 "`TracksAlbumIndex` ON `Tracks` " 2856 "(`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); 2857 2858 if (!result) { 2859 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); 2860 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); 2861 2862 Q_EMIT databaseError(); 2863 } 2864 } 2865 2866 { 2867 QSqlQuery createTrackIndex(d->mTracksDatabase); 2868 2869 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2870 "IF NOT EXISTS " 2871 "`ArtistNameIndex` ON `Tracks` " 2872 "(`ArtistName`)")); 2873 2874 if (!result) { 2875 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); 2876 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); 2877 2878 Q_EMIT databaseError(); 2879 } 2880 } 2881 2882 { 2883 QSqlQuery createTrackIndex(d->mTracksDatabase); 2884 2885 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2886 "IF NOT EXISTS " 2887 "`AlbumArtistNameIndex` ON `Tracks` " 2888 "(`AlbumArtistName`)")); 2889 2890 if (!result) { 2891 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); 2892 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); 2893 2894 Q_EMIT databaseError(); 2895 } 2896 } 2897 2898 { 2899 QSqlQuery createTrackIndex(d->mTracksDatabase); 2900 2901 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2902 "IF NOT EXISTS " 2903 "`TracksUniqueData` ON `Tracks` " 2904 "(`Title`, `ArtistName`, " 2905 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`, " 2906 "`TrackNumber`, `DiscNumber`)")); 2907 2908 if (!result) { 2909 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); 2910 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); 2911 2912 Q_EMIT databaseError(); 2913 } 2914 } 2915 2916 { 2917 QSqlQuery createTrackIndex(d->mTracksDatabase); 2918 2919 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2920 "IF NOT EXISTS " 2921 "`TracksUniqueDataPriority` ON `Tracks` " 2922 "(`Priority`, `Title`, `ArtistName`, " 2923 "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`, " 2924 "`TrackNumber`, `DiscNumber`)")); 2925 2926 if (!result) { 2927 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); 2928 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); 2929 2930 Q_EMIT databaseError(); 2931 } 2932 } 2933 2934 { 2935 QSqlQuery createTrackIndex(d->mTracksDatabase); 2936 2937 const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " 2938 "IF NOT EXISTS " 2939 "`TracksFileNameIndex` ON `Tracks` " 2940 "(`FileName`)")); 2941 2942 if (!result) { 2943 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastQuery(); 2944 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV13" << createTrackIndex.lastError(); 2945 2946 Q_EMIT databaseError(); 2947 } 2948 } 2949 2950 qCInfo(orgKdeElisaDatabase) << "finished update to v13 of database schema"; 2951 } 2952 2953 void DatabaseInterface::upgradeDatabaseV14() 2954 { 2955 qCInfo(orgKdeElisaDatabase) << "begin update to v14 of database schema"; 2956 2957 { 2958 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2959 2960 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV14` (`Version` INTEGER PRIMARY KEY NOT NULL)")); 2961 2962 if (!result) { 2963 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastQuery(); 2964 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastError(); 2965 2966 Q_EMIT databaseError(); 2967 } 2968 } 2969 2970 { 2971 QSqlQuery disableForeignKeys(d->mTracksDatabase); 2972 2973 auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); 2974 2975 if (!result) { 2976 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << disableForeignKeys.lastQuery(); 2977 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << disableForeignKeys.lastError(); 2978 2979 Q_EMIT databaseError(); 2980 } 2981 } 2982 2983 d->mTracksDatabase.transaction(); 2984 2985 { 2986 QSqlQuery createSchemaQuery(d->mTracksDatabase); 2987 2988 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Radios` (" 2989 "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " 2990 "`HttpAddress` VARCHAR(255) NOT NULL, " 2991 "`Priority` INTEGER NOT NULL, " 2992 "`Title` VARCHAR(85) NOT NULL, " 2993 "`Rating` INTEGER NOT NULL DEFAULT 0, " 2994 "`Genre` VARCHAR(55), " 2995 "`Comment` VARCHAR(255), " 2996 "UNIQUE (" 2997 "`HttpAddress`" 2998 "), " 2999 "UNIQUE (" 3000 "`Priority`, `Title`, `HttpAddress`" 3001 ") " 3002 "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`))" 3003 )); 3004 3005 if (!result) { 3006 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastQuery(); 3007 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastError(); 3008 3009 Q_EMIT databaseError(); 3010 } 3011 } 3012 3013 { 3014 QSqlQuery createSchemaQuery(d->mTracksDatabase); 3015 3016 //Find webradios (french): https://doc.ubuntu-fr.org/liste_radio_france 3017 //English: https://www.radio.fr/language/english (to get the link play a radio and look for streamUrl in the html elements page). 3018 const auto &result = createSchemaQuery.exec(QStringLiteral("INSERT INTO `Radios` (`HttpAddress`, `Priority`, `Title`) " 3019 "SELECT 'http://classicrock.stream.ouifm.fr/ouifm3.mp3', 1, 'OuiFM_Classic_Rock' UNION ALL " 3020 "SELECT 'http://rock70s.stream.ouifm.fr/ouifmseventies.mp3', 1, 'OuiFM_70s' UNION ALL " 3021 "SELECT 'http://jazzradio.ice.infomaniak.ch/jazzradio-high.mp3', 2 , 'Jazz_Radio' UNION ALL " 3022 "SELECT 'http://cdn.nrjaudio.fm/audio1/fr/30601/mp3_128.mp3?origine=playerweb', 1, 'Nostalgie' UNION ALL " 3023 "SELECT 'https://scdn.nrjaudio.fm/audio1/fr/30713/aac_64.mp3?origine=playerweb', 1, 'Nostalgie Johnny' UNION ALL " 3024 "SELECT 'http://sc-classrock.1.fm:8200', 1, 'Classic rock replay' UNION ALL " 3025 "SELECT 'http://agnes.torontocast.com:8151/stream', 1, 'Instrumentals Forever' UNION ALL " 3026 "SELECT 'https://stream.laut.fm/jahfari', 1, 'Jahfari'" 3027 )); 3028 if (!result) { 3029 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastQuery(); 3030 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << createSchemaQuery.lastError(); 3031 3032 Q_EMIT databaseError(); 3033 } 3034 } 3035 3036 d->mTracksDatabase.commit(); 3037 3038 { 3039 QSqlQuery enableForeignKeys(d->mTracksDatabase); 3040 3041 auto result = enableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=ON")); 3042 3043 if (!result) { 3044 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << enableForeignKeys.lastQuery(); 3045 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV14" << enableForeignKeys.lastError(); 3046 3047 Q_EMIT databaseError(); 3048 } 3049 } 3050 3051 qCInfo(orgKdeElisaDatabase) << "finished update to v14 of database schema"; 3052 } 3053 3054 void DatabaseInterface::upgradeDatabaseV15() 3055 { 3056 qCInfo(orgKdeElisaDatabase) << "begin update to v15 of database schema"; 3057 3058 { 3059 QSqlQuery createSchemaQuery(d->mTracksDatabase); 3060 3061 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV15` (`Version` INTEGER PRIMARY KEY NOT NULL)")); 3062 3063 if (!result) { 3064 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery(); 3065 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError(); 3066 3067 Q_EMIT databaseError(); 3068 } 3069 } 3070 3071 { 3072 QSqlQuery disableForeignKeys(d->mTracksDatabase); 3073 3074 auto result = disableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=OFF")); 3075 3076 if (!result) { 3077 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << disableForeignKeys.lastQuery(); 3078 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << disableForeignKeys.lastError(); 3079 3080 Q_EMIT databaseError(); 3081 } 3082 } 3083 3084 d->mTracksDatabase.transaction(); 3085 3086 { 3087 QSqlQuery createSchemaQuery(d->mTracksDatabase); 3088 3089 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `RadiosNew` (" 3090 "`ID` INTEGER PRIMARY KEY AUTOINCREMENT, " 3091 "`HttpAddress` VARCHAR(255) NOT NULL, " 3092 "`ImageAddress` VARCHAR(255) NOT NULL, " 3093 "`Title` VARCHAR(85) NOT NULL, " 3094 "`Rating` INTEGER NOT NULL DEFAULT 0, " 3095 "`Genre` VARCHAR(55), " 3096 "`Comment` VARCHAR(255), " 3097 "UNIQUE (" 3098 "`HttpAddress`" 3099 "), " 3100 "UNIQUE (" 3101 "`Title`, `HttpAddress`" 3102 ") " 3103 "CONSTRAINT fk_tracks_genre FOREIGN KEY (`Genre`) REFERENCES `Genre`(`Name`))" 3104 )); 3105 3106 if (!result) { 3107 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery(); 3108 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError(); 3109 3110 Q_EMIT databaseError(); 3111 } 3112 } 3113 3114 { 3115 QSqlQuery createSchemaQuery(d->mTracksDatabase); 3116 3117 const auto &result = createSchemaQuery.exec(QStringLiteral("INSERT INTO RadiosNew SELECT ID, HttpAddress, '', Title, Rating, Genre, Comment FROM Radios")); 3118 3119 if (!result) { 3120 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery(); 3121 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError(); 3122 3123 Q_EMIT databaseError(); 3124 } 3125 } 3126 3127 { 3128 QSqlQuery createSchemaQuery(d->mTracksDatabase); 3129 3130 const auto &result = createSchemaQuery.exec(QStringLiteral("DROP TABLE `Radios`")); 3131 3132 if (!result) { 3133 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery(); 3134 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError(); 3135 3136 Q_EMIT databaseError(); 3137 } 3138 } 3139 3140 { 3141 QSqlQuery createSchemaQuery(d->mTracksDatabase); 3142 3143 const auto &result = createSchemaQuery.exec(QStringLiteral("ALTER TABLE `RadiosNew` RENAME TO `Radios`")); 3144 3145 if (!result) { 3146 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery(); 3147 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError(); 3148 3149 Q_EMIT databaseError(); 3150 } 3151 } 3152 3153 { 3154 QSqlQuery createSchemaQuery(d->mTracksDatabase); 3155 const auto &result = createSchemaQuery.exec(QStringLiteral("INSERT INTO `Radios` (`HttpAddress`, `ImageAddress`, `Title`) " 3156 "VALUES ('https://ice1.somafm.com/groovesalad-256.mp3', 'https://somafm.com/img/groovesalad120.png', 'SomaFM - Groove Salad')," 3157 " ('https://ice1.somafm.com/dronezone-256.mp3', 'https://somafm.com/img/dronezone120.jpg', 'SomaFM - Drone Zone')," 3158 " ('https://ice1.somafm.com/deepspaceone-128.mp3', 'https://somafm.com/img/deepspaceone120.gif', 'SomaFM - Deep Space One')," 3159 " ('https://ice1.somafm.com/u80s-256-mp3', 'https://somafm.com/img/u80s-120.png', 'SomaFM - Underground 80s')," 3160 " ('https://ice1.somafm.com/synphaera-256-mp3', 'https://somafm.com/img3/synphaera120.jpg', 'SomaFM - Synphaera Radio')," 3161 " ('https://ice1.somafm.com/defcon-256-mp3', 'https://somafm.com/img/defcon120.png', 'SomaFM - DEF CON Radio')," 3162 " ('https://ice1.somafm.com/dubstep-256-mp3', 'https://somafm.com/img/dubstep120.png', 'SomaFM - Dub Step Beyond')," 3163 " ('https://ice1.somafm.com/vaporwaves-128-mp3', 'https://somafm.com/img/vaporwaves120.jpg', 'SomaFM - Vaporwaves')," 3164 " ('https://ice1.somafm.com/missioncontrol-128-mp3', 'https://somafm.com/img/missioncontrol120.jpg', 'SomaFM - Mission Control')," 3165 " ('http://ams1.reliastream.com:8054/stream', 'https://c64radio.com/images/coollogo_com-24210747.png', 'c64radio.com - The SID Station')," 3166 " ('http://relay1.slayradio.org:8000/', 'https://www.slayradio.org/styles/default/images/SLAY_Radio_top_log_metal.png', 'slayradio.org - SLAYRadio')," 3167 " ('https://chai5she.cdn.dvmr.fr/francemusique-lofi.mp3', 'https://static.radio.fr/images/broadcasts/07/f7/3366/c44.png', 'France Musique')" 3168 )); 3169 if (!result) { 3170 qCInfo(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastQuery(); 3171 qCInfo(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << createSchemaQuery.lastError(); 3172 3173 Q_EMIT databaseError(); 3174 } 3175 } 3176 3177 d->mTracksDatabase.commit(); 3178 3179 { 3180 QSqlQuery enableForeignKeys(d->mTracksDatabase); 3181 3182 auto result = enableForeignKeys.exec(QStringLiteral(" PRAGMA foreign_keys=ON")); 3183 3184 if (!result) { 3185 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << enableForeignKeys.lastQuery(); 3186 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseV15" << enableForeignKeys.lastError(); 3187 3188 Q_EMIT databaseError(); 3189 } 3190 } 3191 3192 qCInfo(orgKdeElisaDatabase) << "finished update to v15 of database schema"; 3193 } 3194 3195 void DatabaseInterface::upgradeDatabaseV16() 3196 { 3197 qCInfo(orgKdeElisaDatabase) << __FUNCTION__ << "begin update to v16 of database schema"; 3198 3199 { 3200 QSqlQuery sqlQuery(d->mTracksDatabase); 3201 3202 bool resultOfSqlQuery = sqlQuery.exec(QStringLiteral("DELETE FROM Radios WHERE Title='Nostalgie' OR Title='Nostalgie Johnny'")); 3203 3204 if (!resultOfSqlQuery) { 3205 qCWarning(orgKdeElisaDatabase) << __FUNCTION__ << sqlQuery.lastQuery(); 3206 qCWarning(orgKdeElisaDatabase) << __FUNCTION__ << sqlQuery.lastError(); 3207 3208 Q_EMIT databaseError(); 3209 } 3210 } 3211 3212 { 3213 QSqlQuery sqlQuery(d->mTracksDatabase); 3214 3215 QStringList sqlUpdates = QStringLiteral( 3216 "UPDATE Radios SET HttpAddress='https://ouifm.ice.infomaniak.ch/ouifm-high.mp3' WHERE HttpAddress='http://classicrock.stream.ouifm.fr/ouifm3.mp3'; " 3217 "UPDATE Radios SET HttpAddress='https://ouifmrock70s.ice.infomaniak.ch/ouifmseventies.mp3' WHERE HttpAddress='http://rock70s.stream.ouifm.fr/ouifmseventies.mp3'; " 3218 "UPDATE Radios SET HttpAddress='https://jazzradio.ice.infomaniak.ch/jazzradio-high.mp3' WHERE HttpAddress='http://jazzradio.ice.infomaniak.ch/jazzradio-high.mp3'; " 3219 "UPDATE Radios SET HttpAddress='https://quincy.torontocast.com:1925/stream' WHERE HttpAddress='http://agnes.torontocast.com:8151/stream'; " 3220 "UPDATE Radios SET HttpAddress='https://icecast.radiofrance.fr/francemusique-lofi.mp3' WHERE HttpAddress='https://chai5she.cdn.dvmr.fr/francemusique-lofi.mp3'").split(QStringLiteral(";")); 3221 3222 for (const QString& oneSqlUpdate : sqlUpdates) 3223 { 3224 if (!sqlQuery.exec(oneSqlUpdate)) { 3225 qCWarning(orgKdeElisaDatabase) << __FUNCTION__ << sqlQuery.lastQuery(); 3226 qCWarning(orgKdeElisaDatabase) << __FUNCTION__ << sqlQuery.lastError(); 3227 3228 Q_EMIT databaseError(); 3229 } 3230 } 3231 } 3232 3233 qCInfo(orgKdeElisaDatabase) << __FUNCTION__ << "finished update to v16 of database schema"; 3234 } 3235 3236 void DatabaseInterface::upgradeDatabaseV17() 3237 { 3238 } 3239 3240 DatabaseInterface::DatabaseState DatabaseInterface::checkDatabaseSchema() const 3241 { 3242 const auto tables = d->mExpectedTableNamesAndFields; 3243 const bool isInBadState = std::any_of(tables.cbegin(), tables.cend(), [this](const auto &table) { 3244 return checkTable(table.name, table.fields) == DatabaseState::BadState; 3245 }); 3246 return isInBadState ? DatabaseState::BadState : DatabaseState::GoodState; 3247 } 3248 3249 DatabaseInterface::DatabaseState DatabaseInterface::checkTable(const QString &tableName, const QStringList &expectedColumns) const 3250 { 3251 const auto columnsList = d->mTracksDatabase.record(tableName); 3252 3253 if (columnsList.count() != expectedColumns.count()) { 3254 qCInfo(orgKdeElisaDatabase()) << tableName << "table has wrong number of columns" << columnsList.count() << "expected" << expectedColumns.count(); 3255 return DatabaseState::BadState; 3256 } 3257 3258 for (const auto &oneField : expectedColumns) { 3259 if (!columnsList.contains(oneField)) { 3260 qCInfo(orgKdeElisaDatabase()) << tableName << "table has missing column" << oneField; 3261 return DatabaseState::BadState; 3262 } 3263 } 3264 3265 return DatabaseState::GoodState; 3266 } 3267 3268 bool DatabaseInterface::resetDatabase() 3269 { 3270 qCInfo(orgKdeElisaDatabase()) << "Full reset of database due to corrupted database"; 3271 3272 const auto connectionName = d->mConnectionName; 3273 const auto databaseFileName = d->mDatabaseFileName; 3274 3275 d->mTracksDatabase.close(); 3276 d.reset(); 3277 3278 auto dbFile = QFile(databaseFileName); 3279 if (!dbFile.remove()) { 3280 qCCritical(orgKdeElisaDatabase()) << "Database file could not be deleted" << dbFile.errorString(); 3281 return false; 3282 } 3283 3284 initConnection(connectionName, databaseFileName); 3285 return true; 3286 } 3287 3288 DatabaseInterface::DatabaseVersion DatabaseInterface::currentDatabaseVersion() 3289 { 3290 int version = 0; 3291 3292 auto listTables = d->mTracksDatabase.tables(); 3293 3294 if (listTables.contains(QLatin1String("DatabaseVersion"))) { 3295 initDatabaseVersionQueries(); 3296 3297 auto queryResult = execQuery(d->mSelectDatabaseVersionQuery); 3298 if (!queryResult) { 3299 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseToLatestVersion" << d->mUpdateDatabaseVersionQuery.lastQuery(); 3300 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::upgradeDatabaseToLatestVersion" << d->mUpdateDatabaseVersionQuery.lastError(); 3301 3302 Q_EMIT databaseError(); 3303 } 3304 3305 if(d->mSelectDatabaseVersionQuery.next()) { 3306 const auto ¤tRecord = d->mSelectDatabaseVersionQuery.record(); 3307 3308 version = currentRecord.value(0).toInt(); 3309 } 3310 } else if (listTables.contains(QLatin1String("DatabaseVersionV5")) && 3311 !listTables.contains(QLatin1String("DatabaseVersionV9"))) { 3312 version = DatabaseInterface::V9; 3313 } else { 3314 createDatabaseVersionTable(); 3315 initDatabaseVersionQueries(); 3316 3317 if(listTables.contains(QLatin1String("DatabaseVersionV9"))) { 3318 if (!listTables.contains(QLatin1String("DatabaseVersionV11"))) { 3319 version = DatabaseInterface::V11; 3320 } else if (!listTables.contains(QLatin1String("DatabaseVersionV12"))) { 3321 version = DatabaseInterface::V12; 3322 } else if (!listTables.contains(QLatin1String("DatabaseVersionV13"))) { 3323 version = DatabaseInterface::V13; 3324 } else if (!listTables.contains(QLatin1String("DatabaseVersionV14"))) { 3325 version = DatabaseInterface::V14; 3326 } else { 3327 version = DatabaseInterface::V15; 3328 } 3329 } else { 3330 createDatabaseV9(); 3331 version = DatabaseInterface::V11; 3332 } 3333 } 3334 3335 return static_cast<DatabaseVersion>(version); 3336 } 3337 3338 bool DatabaseInterface::upgradeDatabaseToLatestVersion() 3339 { 3340 auto versionBegin = currentDatabaseVersion(); 3341 3342 int version = versionBegin; 3343 for (; version-1 != d->mLatestDatabaseVersion; version++) { 3344 callUpgradeFunctionForVersion(static_cast<DatabaseVersion>(version)); 3345 } 3346 3347 if (version-1 != versionBegin) { 3348 dropTable(QStringLiteral("DROP TABLE DatabaseVersionV9")); 3349 dropTable(QStringLiteral("DROP TABLE DatabaseVersionV11")); 3350 dropTable(QStringLiteral("DROP TABLE DatabaseVersionV12")); 3351 dropTable(QStringLiteral("DROP TABLE DatabaseVersionV13")); 3352 dropTable(QStringLiteral("DROP TABLE DatabaseVersionV14")); 3353 } 3354 3355 setDatabaseVersionInTable(d->mLatestDatabaseVersion); 3356 3357 if (checkDatabaseSchema() == DatabaseState::BadState) { 3358 Q_EMIT databaseError(); 3359 return false; 3360 } 3361 return true; 3362 } 3363 3364 void DatabaseInterface::dropTable(const QString &query) 3365 { 3366 QSqlQuery dropQueryQuery(d->mTracksDatabase); 3367 3368 const auto &result = dropQueryQuery.exec(query); 3369 3370 if (!result) { 3371 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::dropTable" << dropQueryQuery.lastQuery(); 3372 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::dropTable" << dropQueryQuery.lastError(); 3373 3374 Q_EMIT databaseError(); 3375 } 3376 } 3377 3378 void DatabaseInterface::setDatabaseVersionInTable(int version) 3379 { 3380 d->mUpdateDatabaseVersionQuery.bindValue(QStringLiteral(":version"), version); 3381 3382 auto queryResult = execQuery(d->mUpdateDatabaseVersionQuery); 3383 3384 if (!queryResult) { 3385 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::setDatabaseVersionInTable" << d->mUpdateDatabaseVersionQuery.lastQuery(); 3386 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::setDatabaseVersionInTable" << d->mUpdateDatabaseVersionQuery.lastError(); 3387 3388 Q_EMIT databaseError(); 3389 } 3390 } 3391 3392 void DatabaseInterface::createDatabaseVersionTable() 3393 { 3394 qCInfo(orgKdeElisaDatabase) << "begin creation of DatabaseVersion table"; 3395 QSqlQuery createSchemaQuery(d->mTracksDatabase); 3396 3397 const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersion` (`Version` INTEGER PRIMARY KEY NOT NULL default 0)")); 3398 3399 if (!result) { 3400 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseVersionTable" << createSchemaQuery.lastQuery(); 3401 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseVersionTable" << createSchemaQuery.lastError(); 3402 3403 Q_EMIT databaseError(); 3404 } 3405 3406 const auto resultInsert = createSchemaQuery.exec(QStringLiteral("INSERT INTO `DatabaseVersion` VALUES (0)")); 3407 if (!resultInsert) { 3408 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseVersionTable" << createSchemaQuery.lastQuery(); 3409 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::createDatabaseVersionTable" << createSchemaQuery.lastError(); 3410 3411 Q_EMIT databaseError(); 3412 } 3413 } 3414 3415 void DatabaseInterface::initDatabaseVersionQueries() 3416 { 3417 { 3418 auto initDatabaseVersionQuery = QStringLiteral("UPDATE `DatabaseVersion` set `Version` = :version "); 3419 3420 auto result = prepareQuery(d->mUpdateDatabaseVersionQuery, initDatabaseVersionQuery); 3421 3422 if (!result) { 3423 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDatabaseVersionQueries" << d->mUpdateDatabaseVersionQuery.lastQuery(); 3424 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDatabaseVersionQueries" << d->mUpdateDatabaseVersionQuery.lastError(); 3425 3426 Q_EMIT databaseError(); 3427 } 3428 } 3429 3430 { 3431 auto selectDatabaseVersionQuery = QStringLiteral("SELECT versionTable.`Version` FROM `DatabaseVersion` versionTable"); 3432 3433 auto result = prepareQuery(d->mSelectDatabaseVersionQuery, selectDatabaseVersionQuery); 3434 3435 if (!result) { 3436 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDatabaseVersionQueries" << d->mSelectDatabaseVersionQuery.lastQuery(); 3437 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDatabaseVersionQueries" << d->mSelectDatabaseVersionQuery.lastError(); 3438 3439 Q_EMIT databaseError(); 3440 } 3441 } 3442 } 3443 3444 void DatabaseInterface::callUpgradeFunctionForVersion(DatabaseVersion databaseVersion) 3445 { 3446 switch(databaseVersion) 3447 { 3448 case DatabaseInterface::V9: 3449 upgradeDatabaseV9(); 3450 break; 3451 case DatabaseInterface::V11: 3452 upgradeDatabaseV11(); 3453 break; 3454 case DatabaseInterface::V12: 3455 upgradeDatabaseV12(); 3456 break; 3457 case DatabaseInterface::V13: 3458 upgradeDatabaseV13(); 3459 break; 3460 case DatabaseInterface::V14: 3461 upgradeDatabaseV14(); 3462 break; 3463 case DatabaseInterface::V15: 3464 upgradeDatabaseV15(); 3465 break; 3466 case DatabaseInterface::V16: 3467 upgradeDatabaseV16(); 3468 break; 3469 case DatabaseInterface::V17: 3470 upgradeDatabaseV17(); 3471 break; 3472 } 3473 } 3474 3475 /********* Data query methods *********/ 3476 3477 bool DatabaseInterface::startTransaction() 3478 { 3479 auto result = false; 3480 3481 auto transactionResult = d->mTracksDatabase.transaction(); 3482 if (!transactionResult) { 3483 qCDebug(orgKdeElisaDatabase) << "transaction failed" << d->mTracksDatabase.lastError() << d->mTracksDatabase.lastError().driverText(); 3484 3485 return result; 3486 } 3487 3488 result = true; 3489 3490 return result; 3491 } 3492 3493 bool DatabaseInterface::finishTransaction() 3494 { 3495 auto result = false; 3496 3497 auto transactionResult = d->mTracksDatabase.commit(); 3498 3499 if (!transactionResult) { 3500 qCDebug(orgKdeElisaDatabase) << "commit failed" << d->mTracksDatabase.lastError() << d->mTracksDatabase.lastError().nativeErrorCode(); 3501 3502 return result; 3503 } 3504 3505 result = true; 3506 3507 return result; 3508 } 3509 3510 bool DatabaseInterface::rollBackTransaction() 3511 { 3512 auto result = false; 3513 3514 auto transactionResult = d->mTracksDatabase.rollback(); 3515 3516 if (!transactionResult) { 3517 qCDebug(orgKdeElisaDatabase) << "commit failed" << d->mTracksDatabase.lastError() << d->mTracksDatabase.lastError().nativeErrorCode(); 3518 3519 return result; 3520 } 3521 3522 result = true; 3523 3524 return result; 3525 } 3526 3527 bool DatabaseInterface::prepareQuery(QSqlQuery &query, const QString &queryText) const 3528 { 3529 query.setForwardOnly(true); 3530 return query.prepare(queryText); 3531 } 3532 3533 bool DatabaseInterface::execQuery(QSqlQuery &query) 3534 { 3535 #if !defined NDEBUG 3536 auto timer = QElapsedTimer{}; 3537 timer.start(); 3538 #endif 3539 3540 auto result = query.exec(); 3541 3542 #if !defined NDEBUG 3543 if (timer.nsecsElapsed() > 10000000) { 3544 qCDebug(orgKdeElisaDatabase) << "[[" << timer.nsecsElapsed() << "]]" << query.lastQuery(); 3545 } 3546 #endif 3547 3548 return result; 3549 } 3550 3551 void DatabaseInterface::initDataQueries() 3552 { 3553 auto transactionResult = startTransaction(); 3554 if (!transactionResult) { 3555 return; 3556 } 3557 3558 { 3559 auto selectAlbumQueryText = QStringLiteral("SELECT " 3560 "album.`ID`, " 3561 "album.`Title`, " 3562 "album.`ArtistName`, " 3563 "album.`AlbumPath`, " 3564 "album.`CoverFileName`, " 3565 "(" 3566 "SELECT " 3567 "COUNT(*) " 3568 "FROM " 3569 "`Tracks` tracks3 " 3570 "WHERE " 3571 "tracks3.`AlbumTitle` = album.`Title` AND " 3572 "(tracks3.`AlbumArtistName` = album.`ArtistName` OR " 3573 "(tracks3.`AlbumArtistName` IS NULL AND " 3574 "album.`ArtistName` IS NULL" 3575 ")" 3576 ") AND " 3577 "tracks3.`AlbumPath` = album.`AlbumPath` " 3578 ") as `TracksCount`, " 3579 "(" 3580 "SELECT " 3581 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 3582 "FROM " 3583 "`Tracks` tracks2 " 3584 "WHERE " 3585 "tracks2.`AlbumTitle` = album.`Title` AND " 3586 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 3587 "(tracks2.`AlbumArtistName` IS NULL AND " 3588 "album.`ArtistName` IS NULL" 3589 ")" 3590 ") AND " 3591 "tracks2.`AlbumPath` = album.`AlbumPath` " 3592 ") as `IsSingleDiscAlbum`, " 3593 "COUNT(DISTINCT tracks.`ArtistName`) as ArtistsCount, " 3594 "GROUP_CONCAT(tracks.`ArtistName`, ', ') as AllArtists, " 3595 "MAX(tracks.`Rating`) as HighestRating, " 3596 "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres, " 3597 "( " 3598 "SELECT tracksCover.`FileName` " 3599 "FROM " 3600 "`Tracks` tracksCover " 3601 "WHERE " 3602 "tracksCover.`HasEmbeddedCover` = 1 AND " 3603 "tracksCover.`AlbumTitle` = album.`Title` AND " 3604 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 3605 "(tracksCover.`AlbumArtistName` IS NULL AND " 3606 "album.`ArtistName` IS NULL " 3607 ") " 3608 ") AND " 3609 "tracksCover.`AlbumPath` = album.`AlbumPath` " 3610 ") as EmbeddedCover " 3611 "FROM " 3612 "`Albums` album LEFT JOIN " 3613 "`Tracks` tracks ON " 3614 "tracks.`AlbumTitle` = album.`Title` AND " 3615 "(" 3616 "tracks.`AlbumArtistName` = album.`ArtistName` OR " 3617 "(" 3618 "tracks.`AlbumArtistName` IS NULL AND " 3619 "album.`ArtistName` IS NULL" 3620 ")" 3621 ") AND " 3622 "tracks.`AlbumPath` = album.`AlbumPath`" 3623 "LEFT JOIN " 3624 "`Genre` genres ON tracks.`Genre` = genres.`Name` " 3625 "WHERE " 3626 "album.`ID` = :albumId " 3627 "GROUP BY album.`ID`"); 3628 3629 auto result = prepareQuery(d->mSelectAlbumQuery, selectAlbumQueryText); 3630 3631 if (!result) { 3632 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumQuery.lastQuery(); 3633 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumQuery.lastError(); 3634 3635 Q_EMIT databaseError(); 3636 } 3637 } 3638 3639 { 3640 auto selectAllGenresText = QStringLiteral("SELECT " 3641 "genre.`ID`, " 3642 "genre.`Name` " 3643 "FROM `Genre` genre " 3644 "ORDER BY genre.`Name` COLLATE NOCASE"); 3645 3646 auto result = prepareQuery(d->mSelectAllGenresQuery, selectAllGenresText); 3647 3648 if (!result) { 3649 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllGenresQuery.lastQuery(); 3650 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllGenresQuery.lastError(); 3651 3652 Q_EMIT databaseError(); 3653 } 3654 } 3655 3656 { 3657 auto selectAllAlbumsText = QStringLiteral("SELECT " 3658 "album.`ID`, " 3659 "album.`Title`, " 3660 "album.`ArtistName` as SecondaryText, " 3661 "album.`CoverFileName`, " 3662 "album.`ArtistName`, " 3663 "GROUP_CONCAT(tracks.`Year`, ', ') as Year, " 3664 "COUNT(DISTINCT tracks.`ArtistName`) as ArtistsCount, " 3665 "GROUP_CONCAT(tracks.`ArtistName`, ', ') as AllArtists, " 3666 "MAX(tracks.`Rating`) as HighestRating, " 3667 "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres, " 3668 "(" 3669 "SELECT " 3670 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 3671 "FROM " 3672 "`Tracks` tracks2 " 3673 "WHERE " 3674 "tracks2.`AlbumTitle` = album.`Title` AND " 3675 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 3676 "(tracks2.`AlbumArtistName` IS NULL AND " 3677 "album.`ArtistName` IS NULL" 3678 ")" 3679 ") AND " 3680 "tracks2.`AlbumPath` = album.`AlbumPath` " 3681 ") as `IsSingleDiscAlbum`, " 3682 "( " 3683 "SELECT tracksCover.`FileName` " 3684 "FROM " 3685 "`Tracks` tracksCover " 3686 "WHERE " 3687 "tracksCover.`HasEmbeddedCover` = 1 AND " 3688 "tracksCover.`AlbumTitle` = album.`Title` AND " 3689 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 3690 "(tracksCover.`AlbumArtistName` IS NULL AND " 3691 "album.`ArtistName` IS NULL " 3692 ") " 3693 ") AND " 3694 "tracksCover.`AlbumPath` = album.`AlbumPath` " 3695 ") as EmbeddedCover " 3696 "FROM " 3697 "`Albums` album, " 3698 "`Tracks` tracks LEFT JOIN " 3699 "`Genre` genres ON tracks.`Genre` = genres.`Name` " 3700 "WHERE " 3701 "tracks.`AlbumTitle` = album.`Title` AND " 3702 "(tracks.`AlbumArtistName` = album.`ArtistName` OR " 3703 "(tracks.`AlbumArtistName` IS NULL AND " 3704 "album.`ArtistName` IS NULL" 3705 ") " 3706 ") AND " 3707 "tracks.`AlbumPath` = album.`AlbumPath` " 3708 "GROUP BY album.`ID`, album.`Title`, album.`AlbumPath` " 3709 "ORDER BY album.`Title` COLLATE NOCASE"); 3710 3711 auto result = prepareQuery(d->mSelectAllAlbumsShortQuery, selectAllAlbumsText); 3712 3713 if (!result) { 3714 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllAlbumsShortQuery.lastQuery(); 3715 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllAlbumsShortQuery.lastError(); 3716 3717 Q_EMIT databaseError(); 3718 } 3719 } 3720 3721 { 3722 auto selectAllAlbumsText = QStringLiteral("SELECT " 3723 "album.`ID`, " 3724 "album.`Title`, " 3725 "album.`ArtistName` as SecondaryText, " 3726 "album.`CoverFileName`, " 3727 "album.`ArtistName`, " 3728 "GROUP_CONCAT(tracks.`Year`, ', ') as Year, " 3729 "COUNT(DISTINCT tracks.`ArtistName`) as ArtistsCount, " 3730 "GROUP_CONCAT(tracks.`ArtistName`, ', ') as AllArtists, " 3731 "MAX(tracks.`Rating`) as HighestRating, " 3732 "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres, " 3733 "(" 3734 "SELECT " 3735 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 3736 "FROM " 3737 "`Tracks` tracks2 " 3738 "WHERE " 3739 "tracks2.`AlbumTitle` = album.`Title` AND " 3740 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 3741 "(tracks2.`AlbumArtistName` IS NULL AND " 3742 "album.`ArtistName` IS NULL" 3743 ")" 3744 ") AND " 3745 "tracks2.`AlbumPath` = album.`AlbumPath` " 3746 ") as `IsSingleDiscAlbum`, " 3747 "( " 3748 "SELECT tracksCover.`FileName` " 3749 "FROM " 3750 "`Tracks` tracksCover " 3751 "WHERE " 3752 "tracksCover.`HasEmbeddedCover` = 1 AND " 3753 "tracksCover.`AlbumTitle` = album.`Title` AND " 3754 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 3755 "(tracksCover.`AlbumArtistName` IS NULL AND " 3756 "album.`ArtistName` IS NULL " 3757 ") " 3758 ") AND " 3759 "tracksCover.`AlbumPath` = album.`AlbumPath` " 3760 ") as EmbeddedCover " 3761 "FROM " 3762 "`Albums` album, " 3763 "`Tracks` tracks LEFT JOIN " 3764 "`Genre` genres ON tracks.`Genre` = genres.`Name` " 3765 "WHERE " 3766 "tracks.`AlbumTitle` = album.`Title` AND " 3767 "(tracks.`AlbumArtistName` = album.`ArtistName` OR " 3768 "(tracks.`AlbumArtistName` IS NULL AND " 3769 "album.`ArtistName` IS NULL" 3770 ")" 3771 ") AND " 3772 "tracks.`AlbumPath` = album.`AlbumPath` AND " 3773 "EXISTS (" 3774 " SELECT tracks2.`Genre` " 3775 " FROM " 3776 " `Tracks` tracks2, " 3777 " `Genre` genre2 " 3778 " WHERE " 3779 " tracks2.`AlbumTitle` = album.`Title` AND " 3780 " (tracks2.`AlbumArtistName` = album.`ArtistName` OR " 3781 " (tracks2.`AlbumArtistName` IS NULL AND " 3782 " album.`ArtistName` IS NULL" 3783 " )" 3784 " ) AND " 3785 " tracks2.`Genre` = genre2.`Name` AND " 3786 " genre2.`Name` = :genreFilter AND " 3787 " (tracks2.`ArtistName` = :artistFilter OR tracks2.`AlbumArtistName` = :artistFilter) " 3788 ") " 3789 "GROUP BY album.`ID`, album.`Title`, album.`AlbumPath` " 3790 "ORDER BY album.`Title` COLLATE NOCASE"); 3791 3792 auto result = prepareQuery(d->mSelectAllAlbumsShortWithGenreArtistFilterQuery, selectAllAlbumsText); 3793 3794 if (!result) { 3795 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllAlbumsShortWithGenreArtistFilterQuery.lastQuery(); 3796 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllAlbumsShortWithGenreArtistFilterQuery.lastError(); 3797 3798 Q_EMIT databaseError(); 3799 } 3800 } 3801 3802 { 3803 auto selectAllAlbumsText = QStringLiteral("SELECT " 3804 "album.`ID`, " 3805 "album.`Title`, " 3806 "album.`ArtistName` as SecondaryText, " 3807 "album.`CoverFileName`, " 3808 "album.`ArtistName`, " 3809 "GROUP_CONCAT(tracks.`Year`, ', ') as Year, " 3810 "COUNT(DISTINCT tracks.`ArtistName`) as ArtistsCount, " 3811 "GROUP_CONCAT(tracks.`ArtistName`, ', ') as AllArtists, " 3812 "MAX(tracks.`Rating`) as HighestRating, " 3813 "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres, " 3814 "(" 3815 "SELECT " 3816 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 3817 "FROM " 3818 "`Tracks` tracks2 " 3819 "WHERE " 3820 "tracks2.`AlbumTitle` = album.`Title` AND " 3821 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 3822 "(tracks2.`AlbumArtistName` IS NULL AND " 3823 "album.`ArtistName` IS NULL" 3824 ")" 3825 ") AND " 3826 "tracks2.`AlbumPath` = album.`AlbumPath` " 3827 ") as `IsSingleDiscAlbum`, " 3828 "( " 3829 "SELECT tracksCover.`FileName` " 3830 "FROM " 3831 "`Tracks` tracksCover " 3832 "WHERE " 3833 "tracksCover.`HasEmbeddedCover` = 1 AND " 3834 "tracksCover.`AlbumTitle` = album.`Title` AND " 3835 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 3836 "(tracksCover.`AlbumArtistName` IS NULL AND " 3837 "album.`ArtistName` IS NULL " 3838 ") " 3839 ") AND " 3840 "tracksCover.`AlbumPath` = album.`AlbumPath` " 3841 ") as EmbeddedCover " 3842 "FROM " 3843 "`Albums` album, " 3844 "`Tracks` tracks LEFT JOIN " 3845 "`Genre` genres ON tracks.`Genre` = genres.`Name` " 3846 "WHERE " 3847 "tracks.`AlbumTitle` = album.`Title` AND " 3848 "(tracks.`AlbumArtistName` = album.`ArtistName` OR " 3849 "(tracks.`AlbumArtistName` IS NULL AND " 3850 "album.`ArtistName` IS NULL" 3851 ")" 3852 ") AND " 3853 "tracks.`AlbumPath` = album.`AlbumPath` AND " 3854 "EXISTS (" 3855 " SELECT tracks2.`Genre` " 3856 " FROM " 3857 " `Tracks` tracks2 " 3858 " WHERE " 3859 " tracks2.`AlbumTitle` = album.`Title` AND " 3860 " ( " 3861 " tracks2.`AlbumArtistName` = album.`ArtistName` OR " 3862 " ( " 3863 " tracks2.`AlbumArtistName` IS NULL AND " 3864 " album.`ArtistName` IS NULL " 3865 " )" 3866 " ) AND " 3867 " (tracks2.`ArtistName` = :artistFilter OR tracks2.`AlbumArtistName` = :artistFilter) " 3868 ") " 3869 "GROUP BY album.`ID`, album.`Title`, album.`AlbumPath` " 3870 "ORDER BY album.`Title` COLLATE NOCASE"); 3871 3872 auto result = prepareQuery(d->mSelectAllAlbumsShortWithArtistFilterQuery, selectAllAlbumsText); 3873 3874 if (!result) { 3875 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllAlbumsShortWithArtistFilterQuery.lastQuery(); 3876 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllAlbumsShortWithArtistFilterQuery.lastError(); 3877 3878 Q_EMIT databaseError(); 3879 } 3880 } 3881 3882 { 3883 auto selectAllArtistsWithFilterText = QStringLiteral("SELECT artists.`ID`, " 3884 "artists.`Name`, " 3885 "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres " 3886 "FROM `Artists` artists LEFT JOIN " 3887 "`Tracks` tracks ON artists.`Name` = tracks.`ArtistName` LEFT JOIN " 3888 "`Genre` genres ON tracks.`Genre` = genres.`Name` " 3889 "GROUP BY artists.`ID` " 3890 "ORDER BY artists.`Name` COLLATE NOCASE"); 3891 3892 auto result = prepareQuery(d->mSelectAllArtistsQuery, selectAllArtistsWithFilterText); 3893 3894 if (!result) { 3895 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllArtistsQuery.lastQuery(); 3896 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllArtistsQuery.lastError(); 3897 3898 Q_EMIT databaseError(); 3899 } 3900 } 3901 3902 { 3903 auto selectAllArtistsWithGenreFilterText = QStringLiteral("SELECT artists.`ID`, " 3904 "artists.`Name`, " 3905 "GROUP_CONCAT(genres.`Name`, ', ') as AllGenres " 3906 "FROM `Artists` artists LEFT JOIN " 3907 "`Tracks` tracks ON (tracks.`ArtistName` = artists.`Name` OR tracks.`AlbumArtistName` = artists.`Name`) LEFT JOIN " 3908 "`Genre` genres ON tracks.`Genre` = genres.`Name` " 3909 "WHERE " 3910 "EXISTS (" 3911 " SELECT tracks2.`Genre` " 3912 " FROM " 3913 " `Tracks` tracks2, " 3914 " `Genre` genre2 " 3915 " WHERE " 3916 " (tracks2.`ArtistName` = artists.`Name` OR tracks2.`AlbumArtistName` = artists.`Name`) AND " 3917 " tracks2.`Genre` = genre2.`Name` AND " 3918 " genre2.`Name` = :genreFilter " 3919 ") " 3920 "GROUP BY artists.`ID` " 3921 "ORDER BY artists.`Name` COLLATE NOCASE"); 3922 3923 auto result = prepareQuery(d->mSelectAllArtistsWithGenreFilterQuery, selectAllArtistsWithGenreFilterText); 3924 3925 if (!result) { 3926 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllArtistsWithGenreFilterQuery.lastQuery(); 3927 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllArtistsWithGenreFilterQuery.lastError(); 3928 3929 Q_EMIT databaseError(); 3930 } 3931 } 3932 3933 { 3934 auto artistMatchGenreText = QStringLiteral("SELECT artists.`ID` " 3935 "FROM `Artists` artists LEFT JOIN " 3936 "`Tracks` tracks ON (tracks.`ArtistName` = artists.`Name` OR tracks.`AlbumArtistName` = artists.`Name`) LEFT JOIN " 3937 "`Genre` genres ON tracks.`Genre` = genres.`Name` " 3938 "WHERE " 3939 "EXISTS (" 3940 " SELECT tracks2.`Genre` " 3941 " FROM " 3942 " `Tracks` tracks2, " 3943 " `Genre` genre2 " 3944 " WHERE " 3945 " (tracks2.`ArtistName` = artists.`Name` OR tracks2.`AlbumArtistName` = artists.`Name`) AND " 3946 " tracks2.`Genre` = genre2.`Name` AND " 3947 " genre2.`Name` = :genreFilter " 3948 ") AND " 3949 "artists.`ID` = :databaseId"); 3950 3951 auto result = prepareQuery(d->mArtistMatchGenreQuery, artistMatchGenreText); 3952 3953 if (!result) { 3954 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mArtistMatchGenreQuery.lastQuery(); 3955 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mArtistMatchGenreQuery.lastError(); 3956 3957 Q_EMIT databaseError(); 3958 } 3959 } 3960 3961 { 3962 auto selectAllComposersWithFilterText = QStringLiteral("SELECT `ID`, " 3963 "`Name` " 3964 "FROM `Artists` " 3965 "ORDER BY `Name` COLLATE NOCASE"); 3966 3967 auto result = prepareQuery(d->mSelectAllComposersQuery, selectAllComposersWithFilterText); 3968 3969 if (!result) { 3970 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllComposersQuery.lastQuery(); 3971 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllComposersQuery.lastError(); 3972 3973 Q_EMIT databaseError(); 3974 } 3975 } 3976 3977 { 3978 auto selectAllLyricistsWithFilterText = QStringLiteral("SELECT `ID`, " 3979 "`Name` " 3980 "FROM `Lyricist` " 3981 "ORDER BY `Name` COLLATE NOCASE"); 3982 3983 auto result = prepareQuery(d->mSelectAllLyricistsQuery, selectAllLyricistsWithFilterText); 3984 3985 if (!result) { 3986 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllLyricistsQuery.lastQuery(); 3987 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllLyricistsQuery.lastError(); 3988 3989 Q_EMIT databaseError(); 3990 } 3991 } 3992 3993 { 3994 auto selectAllTracksText = QStringLiteral("SELECT " 3995 "tracks.`ID`, " 3996 "tracks.`Title`, " 3997 "album.`ID`, " 3998 "tracks.`ArtistName`, " 3999 "( " 4000 "SELECT " 4001 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 4002 "FROM " 4003 "`Tracks` tracksFromAlbum1 " 4004 "WHERE " 4005 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 4006 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 4007 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 4008 "album.`ArtistName` IS NULL " 4009 ") " 4010 ") AND " 4011 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 4012 ") AS ArtistsCount, " 4013 "( " 4014 "SELECT " 4015 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 4016 "FROM " 4017 "`Tracks` tracksFromAlbum2 " 4018 "WHERE " 4019 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 4020 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 4021 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 4022 "album.`ArtistName` IS NULL " 4023 ") " 4024 ") AND " 4025 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 4026 ") AS AllArtists, " 4027 "tracks.`AlbumArtistName`, " 4028 "tracksMapping.`FileName`, " 4029 "tracksMapping.`FileModifiedTime`, " 4030 "tracks.`TrackNumber`, " 4031 "tracks.`DiscNumber`, " 4032 "tracks.`Duration`, " 4033 "tracks.`AlbumTitle`, " 4034 "tracks.`Rating`, " 4035 "album.`CoverFileName`, " 4036 "(" 4037 "SELECT " 4038 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 4039 "FROM " 4040 "`Tracks` tracks2 " 4041 "WHERE " 4042 "tracks2.`AlbumTitle` = album.`Title` AND " 4043 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 4044 "(tracks2.`AlbumArtistName` IS NULL AND " 4045 "album.`ArtistName` IS NULL" 4046 ")" 4047 ") AND " 4048 "tracks2.`AlbumPath` = album.`AlbumPath` " 4049 ") as `IsSingleDiscAlbum`, " 4050 "trackGenre.`Name`, " 4051 "trackComposer.`Name`, " 4052 "trackLyricist.`Name`, " 4053 "tracks.`Comment`, " 4054 "tracks.`Year`, " 4055 "tracks.`Channels`, " 4056 "tracks.`BitRate`, " 4057 "tracks.`SampleRate`, " 4058 "tracks.`HasEmbeddedCover`, " 4059 "tracksMapping.`ImportDate`, " 4060 "tracksMapping.`FirstPlayDate`, " 4061 "tracksMapping.`LastPlayDate`, " 4062 "tracksMapping.`PlayCounter`, " 4063 "( " 4064 "SELECT tracksCover.`FileName` " 4065 "FROM " 4066 "`Tracks` tracksCover " 4067 "WHERE " 4068 "tracksCover.`HasEmbeddedCover` = 1 AND " 4069 "( " 4070 "(tracksCover.`AlbumTitle` IS NULL AND " 4071 "tracksCover.`FileName` = tracks.`FileName` ) OR " 4072 "( " 4073 "tracksCover.`AlbumTitle` = album.`Title` AND " 4074 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 4075 "(tracksCover.`AlbumArtistName` IS NULL AND " 4076 "album.`ArtistName` IS NULL " 4077 ") " 4078 ") AND " 4079 "tracksCover.`AlbumPath` = album.`AlbumPath` " 4080 ") " 4081 ") " 4082 ") as EmbeddedCover " 4083 "FROM " 4084 "`TracksData` tracksMapping " 4085 "LEFT JOIN " 4086 "`Tracks` tracks " 4087 "ON " 4088 "tracksMapping.`FileName` = tracks.`FileName` " 4089 "LEFT JOIN " 4090 "`Albums` album " 4091 "ON " 4092 "tracks.`AlbumTitle` = album.`Title` AND " 4093 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 4094 "tracks.`AlbumPath` = album.`AlbumPath` " 4095 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 4096 "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " 4097 "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " 4098 "WHERE " 4099 "tracks.`Title` IS NULL OR " 4100 "tracks.`Priority` = (" 4101 " SELECT " 4102 " MIN(`Priority`) " 4103 " FROM " 4104 " `Tracks` tracks2 " 4105 " WHERE " 4106 " tracks.`Title` = tracks2.`Title` AND " 4107 " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " 4108 " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " 4109 " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " 4110 " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" 4111 ")" 4112 ""); 4113 4114 auto result = prepareQuery(d->mSelectAllTracksQuery, selectAllTracksText); 4115 4116 if (!result) { 4117 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllTracksQuery.lastQuery(); 4118 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllTracksQuery.lastError(); 4119 4120 Q_EMIT databaseError(); 4121 } 4122 } 4123 4124 { 4125 auto selectAllRadiosText = QStringLiteral("SELECT " 4126 "radios.`ID`, " 4127 "radios.`Title`, " 4128 "radios.`HttpAddress`, " 4129 "radios.`ImageAddress`, " 4130 "radios.`Rating`, " 4131 "trackGenre.`Name`, " 4132 "radios.`Comment` " 4133 "FROM " 4134 "`Radios` radios " 4135 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = radios.`Genre` " 4136 ""); 4137 4138 auto result = prepareQuery(d->mSelectAllRadiosQuery, selectAllRadiosText); 4139 4140 if (!result) { 4141 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllRadiosQuery.lastQuery(); 4142 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllRadiosQuery.lastError(); 4143 4144 Q_EMIT databaseError(); 4145 } 4146 } 4147 4148 { 4149 auto selectAllTracksText = QStringLiteral("SELECT " 4150 "tracks.`ID`, " 4151 "tracks.`Title`, " 4152 "album.`ID`, " 4153 "tracks.`ArtistName`, " 4154 "( " 4155 "SELECT " 4156 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 4157 "FROM " 4158 "`Tracks` tracksFromAlbum1 " 4159 "WHERE " 4160 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 4161 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 4162 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 4163 "album.`ArtistName` IS NULL " 4164 ") " 4165 ") AND " 4166 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 4167 ") AS ArtistsCount, " 4168 "( " 4169 "SELECT " 4170 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 4171 "FROM " 4172 "`Tracks` tracksFromAlbum2 " 4173 "WHERE " 4174 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 4175 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 4176 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 4177 "album.`ArtistName` IS NULL " 4178 ") " 4179 ") AND " 4180 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 4181 ") AS AllArtists, " 4182 "tracks.`AlbumArtistName`, " 4183 "tracksMapping.`FileName`, " 4184 "tracksMapping.`FileModifiedTime`, " 4185 "tracks.`TrackNumber`, " 4186 "tracks.`DiscNumber`, " 4187 "tracks.`Duration`, " 4188 "tracks.`AlbumTitle`, " 4189 "tracks.`Rating`, " 4190 "album.`CoverFileName`, " 4191 "(" 4192 "SELECT " 4193 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 4194 "FROM " 4195 "`Tracks` tracks2 " 4196 "WHERE " 4197 "tracks2.`AlbumTitle` = album.`Title` AND " 4198 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 4199 "(tracks2.`AlbumArtistName` IS NULL AND " 4200 "album.`ArtistName` IS NULL" 4201 ")" 4202 ") AND " 4203 "tracks2.`AlbumPath` = album.`AlbumPath` " 4204 ") as `IsSingleDiscAlbum`, " 4205 "trackGenre.`Name`, " 4206 "trackComposer.`Name`, " 4207 "trackLyricist.`Name`, " 4208 "tracks.`Comment`, " 4209 "tracks.`Year`, " 4210 "tracks.`Channels`, " 4211 "tracks.`BitRate`, " 4212 "tracks.`SampleRate`, " 4213 "tracks.`HasEmbeddedCover`, " 4214 "tracksMapping.`ImportDate`, " 4215 "tracksMapping.`FirstPlayDate`, " 4216 "tracksMapping.`LastPlayDate`, " 4217 "tracksMapping.`PlayCounter`, " 4218 "( " 4219 "SELECT tracksCover.`FileName` " 4220 "FROM " 4221 "`Tracks` tracksCover " 4222 "WHERE " 4223 "tracksCover.`HasEmbeddedCover` = 1 AND " 4224 "( " 4225 "(tracksCover.`AlbumTitle` IS NULL AND " 4226 "tracksCover.`FileName` = tracks.`FileName` ) OR " 4227 "( " 4228 "tracksCover.`AlbumTitle` = album.`Title` AND " 4229 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 4230 "(tracksCover.`AlbumArtistName` IS NULL AND " 4231 "album.`ArtistName` IS NULL " 4232 ") " 4233 ") AND " 4234 "tracksCover.`AlbumPath` = album.`AlbumPath` " 4235 ") " 4236 ") " 4237 ") as EmbeddedCover " 4238 "FROM " 4239 "`Tracks` tracks, " 4240 "`TracksData` tracksMapping " 4241 "LEFT JOIN " 4242 "`Albums` album " 4243 "ON " 4244 "tracks.`AlbumTitle` = album.`Title` AND " 4245 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 4246 "tracks.`AlbumPath` = album.`AlbumPath` " 4247 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 4248 "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " 4249 "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " 4250 "WHERE " 4251 "tracksMapping.`FileName` = tracks.`FileName` AND " 4252 "tracksMapping.`PlayCounter` > 0 AND " 4253 "tracks.`Priority` = (" 4254 " SELECT " 4255 " MIN(`Priority`) " 4256 " FROM " 4257 " `Tracks` tracks2 " 4258 " WHERE " 4259 " tracks.`Title` = tracks2.`Title` AND " 4260 " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " 4261 " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " 4262 " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " 4263 " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" 4264 ")" 4265 "ORDER BY tracksMapping.`LastPlayDate` DESC " 4266 "LIMIT :maximumResults"); 4267 4268 auto result = prepareQuery(d->mSelectAllRecentlyPlayedTracksQuery, selectAllTracksText); 4269 4270 if (!result) { 4271 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllRecentlyPlayedTracksQuery.lastQuery(); 4272 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllRecentlyPlayedTracksQuery.lastError(); 4273 4274 Q_EMIT databaseError(); 4275 } 4276 } 4277 4278 { 4279 auto selectAllTracksText = QStringLiteral("SELECT " 4280 "tracks.`ID`, " 4281 "tracks.`Title`, " 4282 "album.`ID`, " 4283 "tracks.`ArtistName`, " 4284 "( " 4285 "SELECT " 4286 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 4287 "FROM " 4288 "`Tracks` tracksFromAlbum1 " 4289 "WHERE " 4290 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 4291 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 4292 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 4293 "album.`ArtistName` IS NULL " 4294 ") " 4295 ") AND " 4296 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 4297 ") AS ArtistsCount, " 4298 "( " 4299 "SELECT " 4300 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 4301 "FROM " 4302 "`Tracks` tracksFromAlbum2 " 4303 "WHERE " 4304 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 4305 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 4306 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 4307 "album.`ArtistName` IS NULL " 4308 ") " 4309 ") AND " 4310 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 4311 ") AS AllArtists, " 4312 "tracks.`AlbumArtistName`, " 4313 "tracksMapping.`FileName`, " 4314 "tracksMapping.`FileModifiedTime`, " 4315 "tracks.`TrackNumber`, " 4316 "tracks.`DiscNumber`, " 4317 "tracks.`Duration`, " 4318 "tracks.`AlbumTitle`, " 4319 "tracks.`Rating`, " 4320 "album.`CoverFileName`, " 4321 "(" 4322 "SELECT " 4323 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 4324 "FROM " 4325 "`Tracks` tracks2 " 4326 "WHERE " 4327 "tracks2.`AlbumTitle` = album.`Title` AND " 4328 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 4329 "(tracks2.`AlbumArtistName` IS NULL AND " 4330 "album.`ArtistName` IS NULL" 4331 ")" 4332 ") AND " 4333 "tracks2.`AlbumPath` = album.`AlbumPath` " 4334 ") as `IsSingleDiscAlbum`, " 4335 "trackGenre.`Name`, " 4336 "trackComposer.`Name`, " 4337 "trackLyricist.`Name`, " 4338 "tracks.`Comment`, " 4339 "tracks.`Year`, " 4340 "tracks.`Channels`, " 4341 "tracks.`BitRate`, " 4342 "tracks.`SampleRate`, " 4343 "tracks.`HasEmbeddedCover`, " 4344 "tracksMapping.`ImportDate`, " 4345 "tracksMapping.`FirstPlayDate`, " 4346 "tracksMapping.`LastPlayDate`, " 4347 "tracksMapping.`PlayCounter`, " 4348 "( " 4349 "SELECT tracksCover.`FileName` " 4350 "FROM " 4351 "`Tracks` tracksCover " 4352 "WHERE " 4353 "tracksCover.`HasEmbeddedCover` = 1 AND " 4354 "( " 4355 "(tracksCover.`AlbumTitle` IS NULL AND " 4356 "tracksCover.`FileName` = tracks.`FileName` ) OR " 4357 "( " 4358 "tracksCover.`AlbumTitle` = album.`Title` AND " 4359 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 4360 "(tracksCover.`AlbumArtistName` IS NULL AND " 4361 "album.`ArtistName` IS NULL " 4362 ") " 4363 ") AND " 4364 "tracksCover.`AlbumPath` = album.`AlbumPath` " 4365 ") " 4366 ") " 4367 ") as EmbeddedCover " 4368 "FROM " 4369 "`Tracks` tracks, " 4370 "`TracksData` tracksMapping " 4371 "LEFT JOIN " 4372 "`Albums` album " 4373 "ON " 4374 "tracks.`AlbumTitle` = album.`Title` AND " 4375 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 4376 "tracks.`AlbumPath` = album.`AlbumPath` " 4377 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 4378 "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " 4379 "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " 4380 "WHERE " 4381 "tracksMapping.`FileName` = tracks.`FileName` AND " 4382 "tracksMapping.`PlayCounter` > 0 AND " 4383 "tracks.`Priority` = (" 4384 " SELECT " 4385 " MIN(`Priority`) " 4386 " FROM " 4387 " `Tracks` tracks2 " 4388 " WHERE " 4389 " tracks.`Title` = tracks2.`Title` AND " 4390 " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " 4391 " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " 4392 " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " 4393 " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" 4394 ")" 4395 "ORDER BY tracksMapping.`PlayCounter` DESC " 4396 "LIMIT :maximumResults"); 4397 4398 auto result = prepareQuery(d->mSelectAllFrequentlyPlayedTracksQuery, selectAllTracksText); 4399 4400 if (!result) { 4401 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllFrequentlyPlayedTracksQuery.lastQuery(); 4402 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllFrequentlyPlayedTracksQuery.lastError(); 4403 4404 Q_EMIT databaseError(); 4405 } 4406 } 4407 4408 { 4409 auto clearAlbumsTableText = QStringLiteral("DELETE FROM `Albums`"); 4410 4411 auto result = prepareQuery(d->mClearAlbumsTable, clearAlbumsTableText); 4412 4413 if (!result) { 4414 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearAlbumsTable.lastQuery(); 4415 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearAlbumsTable.lastError(); 4416 4417 Q_EMIT databaseError(); 4418 } 4419 } 4420 4421 { 4422 auto clearArtistsTableText = QStringLiteral("DELETE FROM `Artists`"); 4423 4424 auto result = prepareQuery(d->mClearArtistsTable, clearArtistsTableText); 4425 4426 if (!result) { 4427 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearArtistsTable.lastQuery(); 4428 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearArtistsTable.lastError(); 4429 4430 Q_EMIT databaseError(); 4431 } 4432 } 4433 4434 { 4435 auto clearComposerTableText = QStringLiteral("DELETE FROM `Composer`"); 4436 4437 auto result = prepareQuery(d->mClearComposerTable, clearComposerTableText); 4438 4439 if (!result) { 4440 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearComposerTable.lastQuery(); 4441 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearComposerTable.lastError(); 4442 4443 Q_EMIT databaseError(); 4444 } 4445 } 4446 4447 { 4448 auto clearGenreTableText = QStringLiteral("DELETE FROM `Genre`"); 4449 4450 auto result = prepareQuery(d->mClearGenreTable, clearGenreTableText); 4451 4452 if (!result) { 4453 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearGenreTable.lastQuery(); 4454 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearGenreTable.lastError(); 4455 4456 Q_EMIT databaseError(); 4457 } 4458 } 4459 4460 { 4461 auto clearLyricistTableText = QStringLiteral("DELETE FROM `Lyricist`"); 4462 4463 auto result = prepareQuery(d->mClearLyricistTable, clearLyricistTableText); 4464 4465 if (!result) { 4466 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearLyricistTable.lastQuery(); 4467 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearLyricistTable.lastError(); 4468 4469 Q_EMIT databaseError(); 4470 } 4471 } 4472 4473 { 4474 auto clearTracksDataTableText = QStringLiteral("DELETE FROM `TracksData`"); 4475 4476 auto result = prepareQuery(d->mClearTracksDataTable, clearTracksDataTableText); 4477 4478 if (!result) { 4479 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearTracksDataTable.lastQuery(); 4480 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearTracksDataTable.lastError(); 4481 4482 Q_EMIT databaseError(); 4483 } 4484 } 4485 4486 { 4487 auto clearTracksTableText = QStringLiteral("DELETE FROM `Tracks`"); 4488 4489 auto result = prepareQuery(d->mClearTracksTable, clearTracksTableText); 4490 4491 if (!result) { 4492 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearTracksTable.lastQuery(); 4493 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mClearTracksTable.lastError(); 4494 4495 Q_EMIT databaseError(); 4496 } 4497 } 4498 4499 { 4500 auto selectAllTracksShortText = QStringLiteral("SELECT " 4501 "tracks.`ID`, " 4502 "tracks.`Title`, " 4503 "tracks.`ArtistName`, " 4504 "tracks.`AlbumTitle`, " 4505 "( " 4506 "SELECT " 4507 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 4508 "FROM " 4509 "`Tracks` tracksFromAlbum1 " 4510 "WHERE " 4511 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 4512 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 4513 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 4514 "album.`ArtistName` IS NULL " 4515 ") " 4516 ") AND " 4517 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 4518 ") AS ArtistsCount, " 4519 "( " 4520 "SELECT " 4521 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 4522 "FROM " 4523 "`Tracks` tracksFromAlbum2 " 4524 "WHERE " 4525 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 4526 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 4527 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 4528 "album.`ArtistName` IS NULL " 4529 ") " 4530 ") AND " 4531 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 4532 ") AS AllArtists, " 4533 "tracks.`AlbumArtistName`, " 4534 "tracks.`Duration`, " 4535 "album.`CoverFileName`, " 4536 "tracks.`TrackNumber`, " 4537 "tracks.`DiscNumber`, " 4538 "tracks.`Rating` " 4539 "FROM " 4540 "`Tracks` tracks " 4541 "LEFT JOIN " 4542 "`Albums` album " 4543 "ON " 4544 "tracks.`AlbumTitle` = album.`Title` AND " 4545 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 4546 "tracks.`AlbumPath` = album.`AlbumPath` " 4547 ""); 4548 4549 auto result = prepareQuery(d->mSelectAllTracksShortQuery, selectAllTracksShortText); 4550 4551 if (!result) { 4552 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllTracksShortQuery.lastQuery(); 4553 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllTracksShortQuery.lastError(); 4554 4555 Q_EMIT databaseError(); 4556 } 4557 } 4558 4559 { 4560 auto selectArtistByNameText = QStringLiteral("SELECT `ID`, " 4561 "`Name` " 4562 "FROM `Artists` " 4563 "WHERE " 4564 "`Name` = :name"); 4565 4566 auto result = prepareQuery(d->mSelectArtistByNameQuery, selectArtistByNameText); 4567 4568 if (!result) { 4569 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectArtistByNameQuery.lastQuery(); 4570 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectArtistByNameQuery.lastError(); 4571 4572 Q_EMIT databaseError(); 4573 } 4574 } 4575 4576 { 4577 auto selectComposerByNameText = QStringLiteral("SELECT `ID`, " 4578 "`Name` " 4579 "FROM `Composer` " 4580 "WHERE " 4581 "`Name` = :name"); 4582 4583 auto result = prepareQuery(d->mSelectComposerByNameQuery, selectComposerByNameText); 4584 4585 if (!result) { 4586 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectComposerByNameQuery.lastQuery(); 4587 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectComposerByNameQuery.lastError(); 4588 } 4589 } 4590 4591 { 4592 auto selectLyricistByNameText = QStringLiteral("SELECT `ID`, " 4593 "`Name` " 4594 "FROM `Lyricist` " 4595 "WHERE " 4596 "`Name` = :name"); 4597 4598 auto result = prepareQuery(d->mSelectLyricistByNameQuery, selectLyricistByNameText); 4599 4600 if (!result) { 4601 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectLyricistByNameQuery.lastQuery(); 4602 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectLyricistByNameQuery.lastError(); 4603 } 4604 } 4605 4606 { 4607 auto selectGenreByNameText = QStringLiteral("SELECT `ID`, " 4608 "`Name` " 4609 "FROM `Genre` " 4610 "WHERE " 4611 "`Name` = :name"); 4612 4613 auto result = prepareQuery(d->mSelectGenreByNameQuery, selectGenreByNameText); 4614 4615 if (!result) { 4616 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectGenreByNameQuery.lastQuery(); 4617 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectGenreByNameQuery.lastError(); 4618 4619 Q_EMIT databaseError(); 4620 } 4621 } 4622 4623 { 4624 auto insertArtistsText = QStringLiteral("INSERT INTO `Artists` (`ID`, `Name`) " 4625 "VALUES (:artistId, :name)"); 4626 4627 auto result = prepareQuery(d->mInsertArtistsQuery, insertArtistsText); 4628 4629 if (!result) { 4630 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertArtistsQuery.lastQuery(); 4631 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertArtistsQuery.lastError(); 4632 4633 Q_EMIT databaseError(); 4634 } 4635 } 4636 4637 { 4638 auto insertGenreText = QStringLiteral("INSERT INTO `Genre` (`ID`, `Name`) " 4639 "VALUES (:genreId, :name)"); 4640 4641 auto result = prepareQuery(d->mInsertGenreQuery, insertGenreText); 4642 4643 if (!result) { 4644 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertGenreQuery.lastQuery(); 4645 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertGenreQuery.lastError(); 4646 4647 Q_EMIT databaseError(); 4648 } 4649 } 4650 4651 { 4652 auto insertComposerText = QStringLiteral("INSERT INTO `Composer` (`ID`, `Name`) " 4653 "VALUES (:composerId, :name)"); 4654 4655 auto result = prepareQuery(d->mInsertComposerQuery, insertComposerText); 4656 4657 if (!result) { 4658 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertComposerQuery.lastQuery(); 4659 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertComposerQuery.lastError(); 4660 } 4661 } 4662 4663 { 4664 auto insertLyricistText = QStringLiteral("INSERT INTO `Lyricist` (`ID`, `Name`) " 4665 "VALUES (:lyricistId, :name)"); 4666 4667 auto result = prepareQuery(d->mInsertLyricistQuery, insertLyricistText); 4668 4669 if (!result) { 4670 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertLyricistQuery.lastQuery(); 4671 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertLyricistQuery.lastError(); 4672 } 4673 } 4674 4675 { 4676 auto selectTrackQueryText = QStringLiteral("SELECT " 4677 "tracks.`ID`, " 4678 "tracks.`Title`, " 4679 "album.`ID`, " 4680 "tracks.`ArtistName`, " 4681 "( " 4682 "SELECT " 4683 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 4684 "FROM " 4685 "`Tracks` tracksFromAlbum1 " 4686 "WHERE " 4687 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 4688 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 4689 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 4690 "album.`ArtistName` IS NULL " 4691 ") " 4692 ") AND " 4693 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 4694 ") AS ArtistsCount, " 4695 "( " 4696 "SELECT " 4697 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 4698 "FROM " 4699 "`Tracks` tracksFromAlbum2 " 4700 "WHERE " 4701 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 4702 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 4703 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 4704 "album.`ArtistName` IS NULL " 4705 ") " 4706 ") AND " 4707 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 4708 ") AS AllArtists, " 4709 "tracks.`AlbumArtistName`, " 4710 "tracksMapping.`FileName`, " 4711 "tracksMapping.`FileModifiedTime`, " 4712 "tracks.`TrackNumber`, " 4713 "tracks.`DiscNumber`, " 4714 "tracks.`Duration`, " 4715 "tracks.`AlbumTitle`, " 4716 "tracks.`Rating`, " 4717 "album.`CoverFileName`, " 4718 "(" 4719 "SELECT " 4720 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 4721 "FROM " 4722 "`Tracks` tracks2 " 4723 "WHERE " 4724 "tracks2.`AlbumTitle` = album.`Title` AND " 4725 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 4726 "(tracks2.`AlbumArtistName` IS NULL AND " 4727 "album.`ArtistName` IS NULL" 4728 ")" 4729 ") AND " 4730 "tracks2.`AlbumPath` = album.`AlbumPath` " 4731 ") as `IsSingleDiscAlbum`, " 4732 "trackGenre.`Name`, " 4733 "trackComposer.`Name`, " 4734 "trackLyricist.`Name`, " 4735 "tracks.`Comment`, " 4736 "tracks.`Year`, " 4737 "tracks.`Channels`, " 4738 "tracks.`BitRate`, " 4739 "tracks.`SampleRate`, " 4740 "tracks.`HasEmbeddedCover`, " 4741 "tracksMapping.`ImportDate`, " 4742 "tracksMapping.`FirstPlayDate`, " 4743 "tracksMapping.`LastPlayDate`, " 4744 "tracksMapping.`PlayCounter`, " 4745 "( " 4746 "SELECT tracksCover.`FileName` " 4747 "FROM " 4748 "`Tracks` tracksCover " 4749 "WHERE " 4750 "tracksCover.`HasEmbeddedCover` = 1 AND " 4751 "( " 4752 "(tracksCover.`AlbumTitle` IS NULL AND " 4753 "tracksCover.`FileName` = tracks.`FileName` ) OR " 4754 "( " 4755 "tracksCover.`AlbumTitle` = album.`Title` AND " 4756 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 4757 "(tracksCover.`AlbumArtistName` IS NULL AND " 4758 "album.`ArtistName` IS NULL " 4759 ") " 4760 ") AND " 4761 "tracksCover.`AlbumPath` = album.`AlbumPath` " 4762 ") " 4763 ") " 4764 ") as EmbeddedCover " 4765 "FROM " 4766 "`Tracks` tracks, " 4767 "`TracksData` tracksMapping " 4768 "LEFT JOIN " 4769 "`Albums` album " 4770 "ON " 4771 "album.`ID` = :albumId AND " 4772 "tracks.`AlbumTitle` = album.`Title` AND " 4773 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 4774 "tracks.`AlbumPath` = album.`AlbumPath` " 4775 "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " 4776 "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " 4777 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 4778 "WHERE " 4779 "tracksMapping.`FileName` = tracks.`FileName` AND " 4780 "album.`ID` = :albumId AND " 4781 "tracks.`Priority` = (" 4782 " SELECT " 4783 " MIN(`Priority`) " 4784 " FROM " 4785 " `Tracks` tracks2 " 4786 " WHERE " 4787 " tracks.`Title` = tracks2.`Title` AND " 4788 " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " 4789 " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " 4790 " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " 4791 " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" 4792 ")" 4793 "ORDER BY tracks.`DiscNumber` ASC, " 4794 "tracks.`TrackNumber` ASC"); 4795 4796 auto result = prepareQuery(d->mSelectTrackQuery, selectTrackQueryText); 4797 4798 if (!result) { 4799 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackQuery.lastQuery(); 4800 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackQuery.lastError(); 4801 4802 Q_EMIT databaseError(); 4803 } 4804 } 4805 4806 { 4807 auto selectTrackQueryText = QStringLiteral("SELECT " 4808 "tracks.`ID` " 4809 "FROM " 4810 "`Tracks` tracks, " 4811 "`TracksData` tracksMapping " 4812 "LEFT JOIN " 4813 "`Albums` album " 4814 "ON " 4815 "album.`ID` = :albumId AND " 4816 "tracks.`AlbumTitle` = album.`Title` AND " 4817 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 4818 "tracks.`AlbumPath` = album.`AlbumPath` " 4819 "WHERE " 4820 "tracksMapping.`FileName` = tracks.`FileName` AND " 4821 "album.`ID` = :albumId AND " 4822 "tracks.`Priority` = (" 4823 " SELECT " 4824 " MIN(`Priority`) " 4825 " FROM " 4826 " `Tracks` tracks2 " 4827 " WHERE " 4828 " tracks.`Title` = tracks2.`Title` AND " 4829 " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " 4830 " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " 4831 " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " 4832 " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" 4833 ")" 4834 "ORDER BY tracks.`DiscNumber` ASC, " 4835 "tracks.`TrackNumber` ASC"); 4836 4837 auto result = prepareQuery(d->mSelectTrackIdQuery, selectTrackQueryText); 4838 4839 if (!result) { 4840 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackIdQuery.lastQuery(); 4841 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackIdQuery.lastError(); 4842 4843 Q_EMIT databaseError(); 4844 } 4845 } 4846 4847 { 4848 auto selectTrackFromIdQueryText = QStringLiteral("SELECT " 4849 "tracks.`Id`, " 4850 "tracks.`Title`, " 4851 "album.`ID`, " 4852 "tracks.`ArtistName`, " 4853 "( " 4854 "SELECT " 4855 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 4856 "FROM " 4857 "`Tracks` tracksFromAlbum1 " 4858 "WHERE " 4859 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 4860 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 4861 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 4862 "album.`ArtistName` IS NULL " 4863 ") " 4864 ") AND " 4865 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 4866 ") AS ArtistsCount, " 4867 "( " 4868 "SELECT " 4869 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 4870 "FROM " 4871 "`Tracks` tracksFromAlbum2 " 4872 "WHERE " 4873 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 4874 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 4875 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 4876 "album.`ArtistName` IS NULL " 4877 ") " 4878 ") AND " 4879 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 4880 ") AS AllArtists, " 4881 "tracks.`AlbumArtistName`, " 4882 "tracksMapping.`FileName`, " 4883 "tracksMapping.`FileModifiedTime`, " 4884 "tracks.`TrackNumber`, " 4885 "tracks.`DiscNumber`, " 4886 "tracks.`Duration`, " 4887 "tracks.`AlbumTitle`, " 4888 "tracks.`Rating`, " 4889 "album.`CoverFileName`, " 4890 "(" 4891 "SELECT " 4892 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 4893 "FROM " 4894 "`Tracks` tracks2 " 4895 "WHERE " 4896 "tracks2.`AlbumTitle` = album.`Title` AND " 4897 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 4898 "(tracks2.`AlbumArtistName` IS NULL AND " 4899 "album.`ArtistName` IS NULL" 4900 ")" 4901 ") AND " 4902 "tracks2.`AlbumPath` = album.`AlbumPath` " 4903 ") as `IsSingleDiscAlbum`, " 4904 "trackGenre.`Name`, " 4905 "trackComposer.`Name`, " 4906 "trackLyricist.`Name`, " 4907 "tracks.`Comment`, " 4908 "tracks.`Year`, " 4909 "tracks.`Channels`, " 4910 "tracks.`BitRate`, " 4911 "tracks.`SampleRate`, " 4912 "tracks.`HasEmbeddedCover`, " 4913 "tracksMapping.`ImportDate`, " 4914 "tracksMapping.`FirstPlayDate`, " 4915 "tracksMapping.`LastPlayDate`, " 4916 "tracksMapping.`PlayCounter`, " 4917 "( " 4918 "SELECT tracksCover.`FileName` " 4919 "FROM " 4920 "`Tracks` tracksCover " 4921 "WHERE " 4922 "tracksCover.`HasEmbeddedCover` = 1 AND " 4923 "( " 4924 "(tracksCover.`AlbumTitle` IS NULL AND " 4925 "tracksCover.`FileName` = tracks.`FileName` ) OR " 4926 "( " 4927 "tracksCover.`AlbumTitle` = album.`Title` AND " 4928 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 4929 "(tracksCover.`AlbumArtistName` IS NULL AND " 4930 "album.`ArtistName` IS NULL " 4931 ") " 4932 ") AND " 4933 "tracksCover.`AlbumPath` = album.`AlbumPath` " 4934 ") " 4935 ") " 4936 ") as EmbeddedCover " 4937 "FROM " 4938 "`Tracks` tracks, " 4939 "`TracksData` tracksMapping " 4940 "LEFT JOIN " 4941 "`Albums` album " 4942 "ON " 4943 "tracks.`AlbumTitle` = album.`Title` AND " 4944 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 4945 "tracks.`AlbumPath` = album.`AlbumPath` " 4946 "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " 4947 "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " 4948 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 4949 "WHERE " 4950 "tracks.`ID` = :trackId AND " 4951 "tracksMapping.`FileName` = tracks.`FileName`" 4952 ""); 4953 4954 auto result = prepareQuery(d->mSelectTrackFromIdQuery, selectTrackFromIdQueryText); 4955 4956 if (!result) { 4957 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackFromIdQuery.lastQuery(); 4958 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackFromIdQuery.lastError(); 4959 4960 Q_EMIT databaseError(); 4961 } 4962 } 4963 4964 { 4965 auto selectTrackFromIdAndUrlQueryText = QStringLiteral("SELECT " 4966 "tracks.`Id`, " 4967 "tracks.`Title`, " 4968 "album.`ID`, " 4969 "tracks.`ArtistName`, " 4970 "( " 4971 "SELECT " 4972 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 4973 "FROM " 4974 "`Tracks` tracksFromAlbum1 " 4975 "WHERE " 4976 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 4977 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 4978 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 4979 "album.`ArtistName` IS NULL " 4980 ") " 4981 ") AND " 4982 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 4983 ") AS ArtistsCount, " 4984 "( " 4985 "SELECT " 4986 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 4987 "FROM " 4988 "`Tracks` tracksFromAlbum2 " 4989 "WHERE " 4990 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 4991 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 4992 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 4993 "album.`ArtistName` IS NULL " 4994 ") " 4995 ") AND " 4996 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 4997 ") AS AllArtists, " 4998 "tracks.`AlbumArtistName`, " 4999 "tracksMapping.`FileName`, " 5000 "tracksMapping.`FileModifiedTime`, " 5001 "tracks.`TrackNumber`, " 5002 "tracks.`DiscNumber`, " 5003 "tracks.`Duration`, " 5004 "tracks.`AlbumTitle`, " 5005 "tracks.`Rating`, " 5006 "album.`CoverFileName`, " 5007 "(" 5008 "SELECT " 5009 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 5010 "FROM " 5011 "`Tracks` tracks2 " 5012 "WHERE " 5013 "tracks2.`AlbumTitle` = album.`Title` AND " 5014 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 5015 "(tracks2.`AlbumArtistName` IS NULL AND " 5016 "album.`ArtistName` IS NULL" 5017 ")" 5018 ") AND " 5019 "tracks2.`AlbumPath` = album.`AlbumPath` " 5020 ") as `IsSingleDiscAlbum`, " 5021 "trackGenre.`Name`, " 5022 "trackComposer.`Name`, " 5023 "trackLyricist.`Name`, " 5024 "tracks.`Comment`, " 5025 "tracks.`Year`, " 5026 "tracks.`Channels`, " 5027 "tracks.`BitRate`, " 5028 "tracks.`SampleRate`, " 5029 "tracks.`HasEmbeddedCover`, " 5030 "tracksMapping.`ImportDate`, " 5031 "tracksMapping.`FirstPlayDate`, " 5032 "tracksMapping.`LastPlayDate`, " 5033 "tracksMapping.`PlayCounter`, " 5034 "( " 5035 "SELECT tracksCover.`FileName` " 5036 "FROM " 5037 "`Tracks` tracksCover " 5038 "WHERE " 5039 "tracksCover.`HasEmbeddedCover` = 1 AND " 5040 "( " 5041 "(tracksCover.`AlbumTitle` IS NULL AND " 5042 "tracksCover.`FileName` = tracks.`FileName` ) OR " 5043 "( " 5044 "tracksCover.`AlbumTitle` = album.`Title` AND " 5045 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 5046 "(tracksCover.`AlbumArtistName` IS NULL AND " 5047 "album.`ArtistName` IS NULL " 5048 ") " 5049 ") AND " 5050 "tracksCover.`AlbumPath` = album.`AlbumPath` " 5051 ") " 5052 ") " 5053 ") as EmbeddedCover " 5054 "FROM " 5055 "`Tracks` tracks, " 5056 "`TracksData` tracksMapping " 5057 "LEFT JOIN " 5058 "`Albums` album " 5059 "ON " 5060 "tracks.`AlbumTitle` = album.`Title` AND " 5061 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 5062 "tracks.`AlbumPath` = album.`AlbumPath` " 5063 "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " 5064 "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " 5065 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 5066 "WHERE " 5067 "tracks.`ID` = :trackId AND " 5068 "tracksMapping.`FileName` = tracks.`FileName` AND " 5069 "tracksMapping.`FileName` = :trackUrl " 5070 ""); 5071 5072 auto result = prepareQuery(d->mSelectTrackFromIdAndUrlQuery, selectTrackFromIdAndUrlQueryText); 5073 5074 if (!result) { 5075 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackFromIdAndUrlQuery.lastQuery(); 5076 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackFromIdAndUrlQuery.lastError(); 5077 5078 Q_EMIT databaseError(); 5079 } 5080 } 5081 5082 { 5083 auto selectRadioFromIdQueryText = QStringLiteral("SELECT " 5084 "radios.`ID`, " 5085 "radios.`Title`, " 5086 "radios.`HttpAddress`, " 5087 "radios.`ImageAddress`, " 5088 "radios.`Rating`, " 5089 "trackGenre.`Name`, " 5090 "radios.`Comment` " 5091 "FROM " 5092 "`Radios` radios " 5093 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = radios.`Genre` " 5094 "WHERE " 5095 "radios.`ID` = :radioId " 5096 ""); 5097 5098 auto result = prepareQuery(d->mSelectRadioFromIdQuery, selectRadioFromIdQueryText); 5099 5100 if (!result) { 5101 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectRadioFromIdQuery.lastQuery(); 5102 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectRadioFromIdQuery.lastError(); 5103 5104 Q_EMIT databaseError(); 5105 } 5106 } 5107 { 5108 auto selectCountAlbumsQueryText = QStringLiteral("SELECT count(*) " 5109 "FROM `Albums` album " 5110 "WHERE album.`ArtistName` = :artistName "); 5111 5112 const auto result = prepareQuery(d->mSelectCountAlbumsForArtistQuery, selectCountAlbumsQueryText); 5113 5114 if (!result) { 5115 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectCountAlbumsForArtistQuery.lastQuery(); 5116 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectCountAlbumsForArtistQuery.lastError(); 5117 5118 Q_EMIT databaseError(); 5119 } 5120 } 5121 5122 { 5123 auto selectGenreForArtistQueryText = QStringLiteral("SELECT DISTINCT trackGenre.`Name` " 5124 "FROM " 5125 "`Tracks` tracks " 5126 "LEFT JOIN " 5127 "`Albums` album " 5128 "ON " 5129 "tracks.`AlbumTitle` = album.`Title` AND " 5130 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 5131 "tracks.`AlbumPath` = album.`AlbumPath` " 5132 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 5133 "WHERE " 5134 "album.`ArtistName` = :artistName"); 5135 5136 const auto result = prepareQuery(d->mSelectGenreForArtistQuery, selectGenreForArtistQueryText); 5137 5138 if (!result) { 5139 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectGenreForArtistQuery.lastQuery(); 5140 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectGenreForArtistQuery.lastError(); 5141 5142 Q_EMIT databaseError(); 5143 } 5144 } 5145 5146 { 5147 auto selectGenreForAlbumQueryText = QStringLiteral("SELECT DISTINCT trackGenre.`Name` " 5148 "FROM " 5149 "`Tracks` tracks " 5150 "LEFT JOIN " 5151 "`Albums` album " 5152 "ON " 5153 "tracks.`AlbumTitle` = album.`Title` AND " 5154 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 5155 "tracks.`AlbumPath` = album.`AlbumPath` " 5156 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 5157 "WHERE " 5158 "album.`ID` = :albumId"); 5159 5160 const auto result = prepareQuery(d->mSelectGenreForAlbumQuery, selectGenreForAlbumQueryText); 5161 5162 if (!result) { 5163 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectGenreForAlbumQuery.lastQuery(); 5164 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectGenreForAlbumQuery.lastError(); 5165 5166 Q_EMIT databaseError(); 5167 } 5168 } 5169 5170 { 5171 auto selectCountAlbumsQueryText = QStringLiteral("SELECT distinct count(album.`ID`) " 5172 "FROM " 5173 "`Tracks` tracks, " 5174 "`Albums` album " 5175 "LEFT JOIN `Composer` albumComposer ON albumComposer.`Name` = tracks.`Composer` " 5176 "WHERE " 5177 "(tracks.`AlbumTitle` = album.`Title` OR tracks.`AlbumTitle` IS NULL ) AND " 5178 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 5179 "(tracks.`AlbumPath` = album.`AlbumPath` OR tracks.`AlbumPath` IS NULL ) AND " 5180 "albumComposer.`Name` = :artistName"); 5181 5182 const auto result = prepareQuery(d->mSelectCountAlbumsForComposerQuery, selectCountAlbumsQueryText); 5183 5184 if (!result) { 5185 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectCountAlbumsForComposerQuery.lastQuery(); 5186 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectCountAlbumsForComposerQuery.lastError(); 5187 5188 Q_EMIT databaseError(); 5189 } 5190 } 5191 5192 { 5193 auto selectCountAlbumsQueryText = QStringLiteral("SELECT distinct count(album.`ID`) " 5194 "FROM " 5195 "`Tracks` tracks, " 5196 "`Albums` album " 5197 "LEFT JOIN `Lyricist` albumLyricist ON albumLyricist.`Name` = tracks.`Lyricist` " 5198 "WHERE " 5199 "(tracks.`AlbumTitle` = album.`Title` OR tracks.`AlbumTitle` IS NULL ) AND " 5200 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 5201 "(tracks.`AlbumPath` = album.`AlbumPath` OR tracks.`AlbumPath` IS NULL ) AND " 5202 "albumLyricist.`Name` = :artistName"); 5203 5204 const auto result = prepareQuery(d->mSelectCountAlbumsForLyricistQuery, selectCountAlbumsQueryText); 5205 5206 if (!result) { 5207 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectCountAlbumsForLyricistQuery.lastQuery(); 5208 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectCountAlbumsForLyricistQuery.lastError(); 5209 5210 Q_EMIT databaseError(); 5211 } 5212 } 5213 5214 { 5215 auto selectAlbumIdFromTitleQueryText = QStringLiteral("SELECT " 5216 "album.`ID` " 5217 "FROM " 5218 "`Albums` album " 5219 "WHERE " 5220 "album.`ArtistName` = :artistName AND " 5221 "album.`Title` = :title"); 5222 5223 auto result = prepareQuery(d->mSelectAlbumIdFromTitleQuery, selectAlbumIdFromTitleQueryText); 5224 5225 if (!result) { 5226 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumIdFromTitleQuery.lastQuery(); 5227 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumIdFromTitleQuery.lastError(); 5228 5229 Q_EMIT databaseError(); 5230 } 5231 } 5232 5233 { 5234 auto selectAlbumIdFromTitleAndArtistQueryText = QStringLiteral("SELECT " 5235 "album.`ID` " 5236 "FROM " 5237 "`Albums` album " 5238 "WHERE " 5239 "(album.`ArtistName` = :artistName OR :artistName IS NULL OR album.`ArtistName` IS NULL) AND " 5240 "album.`Title` = :title AND " 5241 "album.`AlbumPath` = :albumPath"); 5242 5243 auto result = prepareQuery(d->mSelectAlbumIdFromTitleAndArtistQuery, selectAlbumIdFromTitleAndArtistQueryText); 5244 5245 if (!result) { 5246 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumIdFromTitleAndArtistQuery.lastQuery(); 5247 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumIdFromTitleAndArtistQuery.lastError(); 5248 5249 Q_EMIT databaseError(); 5250 } 5251 } 5252 5253 { 5254 auto selectAlbumIdFromTitleWithoutArtistQueryText = QStringLiteral("SELECT " 5255 "album.`ID` " 5256 "FROM " 5257 "`Albums` album " 5258 "WHERE " 5259 "album.`AlbumPath` = :albumPath AND " 5260 "album.`Title` = :title AND " 5261 "album.`ArtistName` IS NULL"); 5262 5263 auto result = prepareQuery(d->mSelectAlbumIdFromTitleWithoutArtistQuery, selectAlbumIdFromTitleWithoutArtistQueryText); 5264 5265 if (!result) { 5266 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.lastQuery(); 5267 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.lastError(); 5268 5269 Q_EMIT databaseError(); 5270 } 5271 } 5272 5273 { 5274 auto insertAlbumQueryText = QStringLiteral("INSERT INTO `Albums` " 5275 "(`ID`, " 5276 "`Title`, " 5277 "`ArtistName`, " 5278 "`AlbumPath`, " 5279 "`CoverFileName`) " 5280 "VALUES " 5281 "(:albumId, " 5282 ":title, " 5283 ":albumArtist, " 5284 ":albumPath, " 5285 ":coverFileName)"); 5286 5287 auto result = prepareQuery(d->mInsertAlbumQuery, insertAlbumQueryText); 5288 5289 if (!result) { 5290 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertAlbumQuery.lastQuery(); 5291 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertAlbumQuery.lastError(); 5292 5293 Q_EMIT databaseError(); 5294 } 5295 } 5296 5297 { 5298 auto insertTrackMappingQueryText = QStringLiteral("INSERT INTO " 5299 "`TracksData` " 5300 "(`FileName`, " 5301 "`FileModifiedTime`, " 5302 "`ImportDate`, " 5303 "`PlayCounter`) " 5304 "VALUES (:fileName, :mtime, :importDate, 0)"); 5305 5306 auto result = prepareQuery(d->mInsertTrackMapping, insertTrackMappingQueryText); 5307 5308 if (!result) { 5309 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertTrackMapping.lastQuery(); 5310 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertTrackMapping.lastError(); 5311 5312 Q_EMIT databaseError(); 5313 } 5314 } 5315 5316 { 5317 auto initialUpdateTracksValidityQueryText = QStringLiteral("UPDATE `TracksData` " 5318 "SET " 5319 "`FileModifiedTime` = :mtime " 5320 "WHERE `FileName` = :fileName"); 5321 5322 auto result = prepareQuery(d->mUpdateTrackFileModifiedTime, initialUpdateTracksValidityQueryText); 5323 5324 if (!result) { 5325 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackFileModifiedTime.lastQuery(); 5326 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackFileModifiedTime.lastError(); 5327 5328 Q_EMIT databaseError(); 5329 } 5330 } 5331 5332 { 5333 auto initialUpdateTracksValidityQueryText = QStringLiteral("UPDATE `Tracks` " 5334 "SET " 5335 "`Priority` = :priority " 5336 "WHERE `FileName` = :fileName"); 5337 5338 auto result = prepareQuery(d->mUpdateTrackPriority, initialUpdateTracksValidityQueryText); 5339 5340 if (!result) { 5341 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackPriority.lastQuery(); 5342 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackPriority.lastError(); 5343 5344 Q_EMIT databaseError(); 5345 } 5346 } 5347 5348 { 5349 auto removeTracksMappingFromSourceQueryText = QStringLiteral("DELETE FROM `TracksData` " 5350 "WHERE `FileName` = :fileName"); 5351 5352 auto result = prepareQuery(d->mRemoveTracksMappingFromSource, removeTracksMappingFromSourceQueryText); 5353 5354 if (!result) { 5355 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveTracksMappingFromSource.lastQuery(); 5356 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveTracksMappingFromSource.lastError(); 5357 5358 Q_EMIT databaseError(); 5359 } 5360 } 5361 5362 { 5363 auto removeTracksMappingQueryText = QStringLiteral("DELETE FROM `TracksData` " 5364 "WHERE `FileName` = :fileName"); 5365 5366 auto result = prepareQuery(d->mRemoveTracksMapping, removeTracksMappingQueryText); 5367 5368 if (!result) { 5369 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveTracksMapping.lastQuery(); 5370 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveTracksMapping.lastError(); 5371 5372 Q_EMIT databaseError(); 5373 } 5374 } 5375 5376 { 5377 auto selectTracksWithoutMappingQueryText = QStringLiteral("SELECT " 5378 "tracks.`Id`, " 5379 "tracks.`Title`, " 5380 "album.`ID`, " 5381 "tracks.`ArtistName`, " 5382 "( " 5383 "SELECT " 5384 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 5385 "FROM " 5386 "`Tracks` tracksFromAlbum1 " 5387 "WHERE " 5388 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 5389 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 5390 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 5391 "album.`ArtistName` IS NULL " 5392 ") " 5393 ") AND " 5394 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 5395 ") AS ArtistsCount, " 5396 "( " 5397 "SELECT " 5398 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 5399 "FROM " 5400 "`Tracks` tracksFromAlbum2 " 5401 "WHERE " 5402 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 5403 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 5404 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 5405 "album.`ArtistName` IS NULL " 5406 ") " 5407 ") AND " 5408 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 5409 ") AS AllArtists, " 5410 "tracks.`AlbumArtistName`, " 5411 "\"\" as FileName, " 5412 "NULL as FileModifiedTime, " 5413 "tracks.`TrackNumber`, " 5414 "tracks.`DiscNumber`, " 5415 "tracks.`Duration`, " 5416 "tracks.`AlbumTitle`, " 5417 "tracks.`Rating`, " 5418 "album.`CoverFileName`, " 5419 "(" 5420 "SELECT " 5421 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 5422 "FROM " 5423 "`Tracks` tracks2 " 5424 "WHERE " 5425 "tracks2.`AlbumTitle` = album.`Title` AND " 5426 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 5427 "(tracks2.`AlbumArtistName` IS NULL AND " 5428 "album.`ArtistName` IS NULL" 5429 ")" 5430 ") AND " 5431 "tracks2.`AlbumPath` = album.`AlbumPath` " 5432 ") as `IsSingleDiscAlbum`, " 5433 "trackGenre.`Name`, " 5434 "trackComposer.`Name`, " 5435 "trackLyricist.`Name`, " 5436 "tracks.`Comment`, " 5437 "tracks.`Year`, " 5438 "tracks.`Channels`, " 5439 "tracks.`BitRate`, " 5440 "tracks.`SampleRate`, " 5441 "tracks.`HasEmbeddedCover`, " 5442 "tracksMapping.`ImportDate`, " 5443 "tracksMapping.`FirstPlayDate`, " 5444 "tracksMapping.`LastPlayDate`, " 5445 "tracksMapping.`PlayCounter`, " 5446 "( " 5447 "SELECT tracksCover.`FileName` " 5448 "FROM " 5449 "`Tracks` tracksCover " 5450 "WHERE " 5451 "tracksCover.`HasEmbeddedCover` = 1 AND " 5452 "( " 5453 "(tracksCover.`AlbumTitle` IS NULL AND " 5454 "tracksCover.`FileName` = tracks.`FileName` ) OR " 5455 "( " 5456 "tracksCover.`AlbumTitle` = album.`Title` AND " 5457 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 5458 "(tracksCover.`AlbumArtistName` IS NULL AND " 5459 "album.`ArtistName` IS NULL " 5460 ") " 5461 ") AND " 5462 "tracksCover.`AlbumPath` = album.`AlbumPath` " 5463 ") " 5464 ") " 5465 ") as EmbeddedCover " 5466 "FROM " 5467 "`Tracks` tracks, " 5468 "`TracksData` tracksMapping " 5469 "LEFT JOIN " 5470 "`Albums` album " 5471 "ON " 5472 "tracks.`AlbumTitle` = album.`Title` AND " 5473 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 5474 "tracks.`AlbumPath` = album.`AlbumPath` " 5475 "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " 5476 "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " 5477 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 5478 "WHERE " 5479 "tracks.`FileName` = tracksMapping.`FileName` AND " 5480 "tracks.`FileName` NOT IN (SELECT tracksMapping2.`FileName` FROM `TracksData` tracksMapping2)"); 5481 5482 auto result = prepareQuery(d->mSelectTracksWithoutMappingQuery, selectTracksWithoutMappingQueryText); 5483 5484 if (!result) { 5485 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksWithoutMappingQuery.lastQuery(); 5486 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksWithoutMappingQuery.lastError(); 5487 5488 Q_EMIT databaseError(); 5489 } 5490 } 5491 5492 { 5493 auto selectTracksMappingQueryText = QStringLiteral("SELECT " 5494 "track.`ID`, " 5495 "trackData.`FileName`, " 5496 "track.`Priority`, " 5497 "trackData.`FileModifiedTime` " 5498 "FROM " 5499 "`TracksData` trackData " 5500 "LEFT JOIN " 5501 "`Tracks` track " 5502 "ON " 5503 "track.`FileName` = trackData.`FileName` " 5504 "WHERE " 5505 "trackData.`FileName` = :fileName"); 5506 5507 auto result = prepareQuery(d->mSelectTracksMapping, selectTracksMappingQueryText); 5508 5509 if (!result) { 5510 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksMapping.lastQuery(); 5511 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksMapping.lastError(); 5512 5513 Q_EMIT databaseError(); 5514 } 5515 } 5516 5517 { 5518 auto selectRadioIdFromHttpAddress = QStringLiteral("SELECT " 5519 "`ID` " 5520 "FROM " 5521 "`Radios` " 5522 "WHERE " 5523 "`HttpAddress` = :httpAddress"); 5524 5525 auto result = prepareQuery(d->mSelectRadioIdFromHttpAddress, selectRadioIdFromHttpAddress); 5526 5527 if (!result) { 5528 qCInfo(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectRadioIdFromHttpAddress.lastQuery(); 5529 qCInfo(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectRadioIdFromHttpAddress.lastError(); 5530 5531 Q_EMIT databaseError(); 5532 } 5533 } 5534 5535 { 5536 auto selectTracksMappingPriorityQueryText = QStringLiteral("SELECT " 5537 "max(tracks.`Priority`) AS Priority " 5538 "FROM " 5539 "`Tracks` tracks, " 5540 "`Albums` albums " 5541 "WHERE " 5542 "tracks.`Title` = :title AND " 5543 "(tracks.`ArtistName` = :trackArtist OR tracks.`ArtistName` IS NULL) AND " 5544 "(tracks.`AlbumTitle` = :album OR tracks.`AlbumTitle` IS NULL) AND " 5545 "(tracks.`AlbumArtistName` = :albumArtist OR tracks.`AlbumArtistName` IS NULL) AND " 5546 "(tracks.`AlbumPath` = :albumPath OR tracks.`AlbumPath` IS NULL)"); 5547 5548 auto result = prepareQuery(d->mSelectTracksMappingPriority, selectTracksMappingPriorityQueryText); 5549 5550 if (!result) { 5551 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksMappingPriority.lastQuery(); 5552 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksMappingPriority.lastError(); 5553 5554 Q_EMIT databaseError(); 5555 } 5556 } 5557 5558 { 5559 auto selectTracksMappingPriorityQueryByTrackIdText = QStringLiteral("SELECT " 5560 "MAX(track.`Priority`) " 5561 "FROM " 5562 "`TracksData` trackData, " 5563 "`Tracks` track " 5564 "WHERE " 5565 "track.`ID` = :trackId AND " 5566 "trackData.`FileName` = track.`FileName`"); 5567 5568 auto result = prepareQuery(d->mSelectTracksMappingPriorityByTrackId, selectTracksMappingPriorityQueryByTrackIdText); 5569 5570 if (!result) { 5571 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksMappingPriorityByTrackId.lastQuery(); 5572 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksMappingPriorityByTrackId.lastError(); 5573 5574 Q_EMIT databaseError(); 5575 } 5576 } 5577 5578 { 5579 auto selectAllTrackFilesFromSourceQueryText = QStringLiteral("SELECT " 5580 "tracksMapping.`FileName`, " 5581 "tracksMapping.`FileModifiedTime` " 5582 "FROM " 5583 "`TracksData` tracksMapping"); 5584 5585 auto result = prepareQuery(d->mSelectAllTrackFilesQuery, selectAllTrackFilesFromSourceQueryText); 5586 5587 if (!result) { 5588 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllTrackFilesQuery.lastQuery(); 5589 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAllTrackFilesQuery.lastError(); 5590 5591 Q_EMIT databaseError(); 5592 } 5593 } 5594 5595 { 5596 auto insertMusicSourceQueryText = QStringLiteral("INSERT OR IGNORE INTO `DiscoverSource` (`ID`, `Name`) " 5597 "VALUES (:discoverId, :name)"); 5598 5599 auto result = prepareQuery(d->mInsertMusicSource, insertMusicSourceQueryText); 5600 5601 if (!result) { 5602 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertMusicSource.lastQuery(); 5603 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertMusicSource.lastError(); 5604 5605 Q_EMIT databaseError(); 5606 } 5607 } 5608 5609 { 5610 auto selectMusicSourceQueryText = QStringLiteral("SELECT `ID` FROM `DiscoverSource` WHERE `Name` = :name"); 5611 5612 auto result = prepareQuery(d->mSelectMusicSource, selectMusicSourceQueryText); 5613 5614 if (!result) { 5615 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectMusicSource.lastQuery(); 5616 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectMusicSource.lastError(); 5617 5618 Q_EMIT databaseError(); 5619 } 5620 } 5621 5622 { 5623 auto selectTrackQueryText = QStringLiteral("SELECT " 5624 "tracks.`ID`, tracksMapping.`FileName` " 5625 "FROM " 5626 "`Tracks` tracks, " 5627 "`Albums` album, " 5628 "`TracksData` tracksMapping " 5629 "WHERE " 5630 "tracks.`Title` = :title AND " 5631 "album.`ID` = :album AND " 5632 "(tracks.`AlbumTitle` = album.`Title` OR tracks.`AlbumTitle` IS NULL ) AND " 5633 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 5634 "(tracks.`AlbumPath` = album.`AlbumPath` OR tracks.`AlbumPath` IS NULL ) AND " 5635 "tracks.`ArtistName` = :artist AND " 5636 "tracksMapping.`FileName` = tracks.`FileName` AND " 5637 "tracks.`Priority` = (" 5638 " SELECT " 5639 " MIN(`Priority`) " 5640 " FROM " 5641 " `Tracks` tracks2 " 5642 " WHERE " 5643 " tracks.`Title` = tracks2.`Title` AND " 5644 " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " 5645 " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " 5646 " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " 5647 " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" 5648 ")" 5649 ""); 5650 5651 auto result = prepareQuery(d->mSelectTrackIdFromTitleAlbumIdArtistQuery, selectTrackQueryText); 5652 5653 if (!result) { 5654 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackIdFromTitleAlbumIdArtistQuery.lastQuery(); 5655 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackIdFromTitleAlbumIdArtistQuery.lastError(); 5656 5657 Q_EMIT databaseError(); 5658 } 5659 } 5660 5661 { 5662 auto insertTrackQueryText = QStringLiteral("INSERT INTO `Tracks` " 5663 "(" 5664 "`ID`, " 5665 "`FileName`, " 5666 "`Priority`, " 5667 "`Title`, " 5668 "`ArtistName`, " 5669 "`AlbumTitle`, " 5670 "`AlbumArtistName`, " 5671 "`AlbumPath`, " 5672 "`Genre`, " 5673 "`Composer`, " 5674 "`Lyricist`, " 5675 "`Comment`, " 5676 "`TrackNumber`, " 5677 "`DiscNumber`, " 5678 "`Channels`, " 5679 "`BitRate`, " 5680 "`SampleRate`, " 5681 "`Year`, " 5682 "`Duration`, " 5683 "`Rating`, " 5684 "`HasEmbeddedCover`) " 5685 "VALUES " 5686 "(" 5687 ":trackId, " 5688 ":fileName, " 5689 ":priority, " 5690 ":title, " 5691 ":artistName, " 5692 ":albumTitle, " 5693 ":albumArtistName, " 5694 ":albumPath, " 5695 ":genre, " 5696 ":composer, " 5697 ":lyricist, " 5698 ":comment, " 5699 ":trackNumber, " 5700 ":discNumber, " 5701 ":channels, " 5702 ":bitRate, " 5703 ":sampleRate, " 5704 ":year, " 5705 ":trackDuration, " 5706 ":trackRating, " 5707 ":hasEmbeddedCover)"); 5708 5709 auto result = prepareQuery(d->mInsertTrackQuery, insertTrackQueryText); 5710 5711 if (!result) { 5712 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertTrackQuery.lastQuery(); 5713 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertTrackQuery.lastError(); 5714 5715 Q_EMIT databaseError(); 5716 } 5717 } 5718 5719 { 5720 auto updateTrackQueryText = QStringLiteral("UPDATE `Tracks` " 5721 "SET " 5722 "`FileName` = :fileName, " 5723 "`Title` = :title, " 5724 "`ArtistName` = :artistName, " 5725 "`AlbumTitle` = :albumTitle, " 5726 "`AlbumArtistName` = :albumArtistName, " 5727 "`AlbumPath` = :albumPath, " 5728 "`Genre` = :genre, " 5729 "`Composer` = :composer, " 5730 "`Lyricist` = :lyricist, " 5731 "`Comment` = :comment, " 5732 "`TrackNumber` = :trackNumber, " 5733 "`DiscNumber` = :discNumber, " 5734 "`Channels` = :channels, " 5735 "`BitRate` = :bitRate, " 5736 "`SampleRate` = :sampleRate, " 5737 "`Year` = :year, " 5738 " `Duration` = :trackDuration, " 5739 "`Rating` = :trackRating " 5740 "WHERE " 5741 "`ID` = :trackId"); 5742 5743 auto result = prepareQuery(d->mUpdateTrackQuery, updateTrackQueryText); 5744 5745 if (!result) { 5746 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackQuery.lastQuery(); 5747 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackQuery.lastError(); 5748 5749 Q_EMIT databaseError(); 5750 } 5751 } 5752 5753 { 5754 auto insertRadioQueryText = QStringLiteral("INSERT INTO `Radios` " 5755 "(" 5756 "`Title`, " 5757 "`httpAddress`, " 5758 "`Comment`, " 5759 "`Rating`, " 5760 "`ImageAddress`) " 5761 "VALUES " 5762 "(" 5763 ":title, " 5764 ":httpAddress, " 5765 ":comment, " 5766 ":trackRating," 5767 ":imageAddress)"); 5768 5769 auto result = prepareQuery(d->mInsertRadioQuery, insertRadioQueryText); 5770 5771 if (!result) { 5772 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertRadioQuery.lastQuery(); 5773 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mInsertRadioQuery.lastError(); 5774 5775 Q_EMIT databaseError(); 5776 } 5777 } 5778 5779 { 5780 auto deleteRadioQueryText = QStringLiteral("DELETE FROM `Radios` " 5781 "WHERE `ID` = :radioId"); 5782 5783 auto result = prepareQuery(d->mDeleteRadioQuery, deleteRadioQueryText); 5784 5785 if (!result) { 5786 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mDeleteRadioQuery.lastQuery(); 5787 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mDeleteRadioQuery.lastError(); 5788 5789 Q_EMIT databaseError(); 5790 } 5791 } 5792 5793 { 5794 auto updateRadioQueryText = QStringLiteral("UPDATE `Radios` " 5795 "SET " 5796 "`HttpAddress` = :httpAddress, " 5797 "`Title` = :title, " 5798 "`Comment` = :comment, " 5799 "`Rating` = :trackRating, " 5800 "`ImageAddress` = :imageAddress " 5801 "WHERE " 5802 "`ID` = :radioId"); 5803 5804 auto result = prepareQuery(d->mUpdateRadioQuery, updateRadioQueryText); 5805 5806 if (!result) { 5807 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateRadioQuery.lastQuery(); 5808 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateRadioQuery.lastError(); 5809 5810 Q_EMIT databaseError(); 5811 } 5812 } 5813 5814 { 5815 auto updateAlbumArtistQueryText = QStringLiteral("UPDATE `Albums` " 5816 "SET " 5817 "`ArtistName` = :artistName " 5818 "WHERE " 5819 "`ID` = :albumId"); 5820 5821 auto result = prepareQuery(d->mUpdateAlbumArtistQuery, updateAlbumArtistQueryText); 5822 5823 if (!result) { 5824 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateAlbumArtistQuery.lastQuery(); 5825 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateAlbumArtistQuery.lastError(); 5826 5827 Q_EMIT databaseError(); 5828 } 5829 } 5830 5831 { 5832 auto updateAlbumArtistInTracksQueryText = QStringLiteral("UPDATE `Tracks` " 5833 "SET " 5834 "`AlbumArtistName` = :artistName " 5835 "WHERE " 5836 "`AlbumTitle` = :albumTitle AND " 5837 "`AlbumPath` = :albumPath AND " 5838 "`AlbumArtistName` IS NULL"); 5839 5840 auto result = prepareQuery(d->mUpdateAlbumArtistInTracksQuery, updateAlbumArtistInTracksQueryText); 5841 5842 if (!result) { 5843 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateAlbumArtistInTracksQuery.lastQuery(); 5844 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateAlbumArtistInTracksQuery.lastError(); 5845 5846 Q_EMIT databaseError(); 5847 } 5848 } 5849 5850 { 5851 auto queryMaximumTrackIdQueryText = QStringLiteral("SELECT MAX(tracks.`ID`)" 5852 "FROM " 5853 "`Tracks` tracks"); 5854 5855 auto result = prepareQuery(d->mQueryMaximumTrackIdQuery, queryMaximumTrackIdQueryText); 5856 5857 if (!result) { 5858 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumTrackIdQuery.lastQuery(); 5859 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumTrackIdQuery.lastError(); 5860 5861 Q_EMIT databaseError(); 5862 } 5863 } 5864 5865 { 5866 auto queryMaximumAlbumIdQueryText = QStringLiteral("SELECT MAX(albums.`ID`)" 5867 "FROM " 5868 "`Albums` albums"); 5869 5870 auto result = prepareQuery(d->mQueryMaximumAlbumIdQuery, queryMaximumAlbumIdQueryText); 5871 5872 if (!result) { 5873 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumAlbumIdQuery.lastQuery(); 5874 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumAlbumIdQuery.lastError(); 5875 5876 Q_EMIT databaseError(); 5877 } 5878 } 5879 5880 { 5881 auto queryMaximumArtistIdQueryText = QStringLiteral("SELECT MAX(artists.`ID`)" 5882 "FROM " 5883 "`Artists` artists"); 5884 5885 auto result = prepareQuery(d->mQueryMaximumArtistIdQuery, queryMaximumArtistIdQueryText); 5886 5887 if (!result) { 5888 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumArtistIdQuery.lastQuery(); 5889 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumArtistIdQuery.lastError(); 5890 5891 Q_EMIT databaseError(); 5892 } 5893 } 5894 5895 { 5896 auto queryMaximumLyricistIdQueryText = QStringLiteral("SELECT MAX(lyricists.`ID`)" 5897 "FROM " 5898 "`Lyricist` lyricists"); 5899 5900 auto result = prepareQuery(d->mQueryMaximumLyricistIdQuery, queryMaximumLyricistIdQueryText); 5901 5902 if (!result) { 5903 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumLyricistIdQuery.lastQuery(); 5904 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumLyricistIdQuery.lastError(); 5905 5906 Q_EMIT databaseError(); 5907 } 5908 } 5909 5910 { 5911 auto queryMaximumComposerIdQueryText = QStringLiteral("SELECT MAX(composers.`ID`)" 5912 "FROM " 5913 "`Composer` composers"); 5914 5915 auto result = prepareQuery(d->mQueryMaximumComposerIdQuery, queryMaximumComposerIdQueryText); 5916 5917 if (!result) { 5918 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumComposerIdQuery.lastQuery(); 5919 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumComposerIdQuery.lastError(); 5920 5921 Q_EMIT databaseError(); 5922 } 5923 } 5924 5925 { 5926 auto queryMaximumGenreIdQueryText = QStringLiteral("SELECT MAX(genres.`ID`)" 5927 "FROM " 5928 "`Genre` genres"); 5929 5930 auto result = prepareQuery(d->mQueryMaximumGenreIdQuery, queryMaximumGenreIdQueryText); 5931 5932 if (!result) { 5933 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumGenreIdQuery.lastQuery(); 5934 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mQueryMaximumGenreIdQuery.lastError(); 5935 5936 Q_EMIT databaseError(); 5937 } 5938 } 5939 5940 { 5941 auto selectTrackQueryText = QStringLiteral("SELECT " 5942 "tracks.ID " 5943 "FROM " 5944 "`Tracks` tracks " 5945 "WHERE " 5946 "tracks.`Title` = :title AND " 5947 "(tracks.`AlbumTitle` = :album OR (:album IS NULL AND tracks.`AlbumTitle` IS NULL)) AND " 5948 "(tracks.`TrackNumber` = :trackNumber OR (:trackNumber IS NULL AND tracks.`TrackNumber` IS NULL)) AND " 5949 "(tracks.`DiscNumber` = :discNumber OR (:discNumber IS NULL AND tracks.`DiscNumber` IS NULL)) AND " 5950 "tracks.`ArtistName` = :artist"); 5951 5952 auto result = prepareQuery(d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery, selectTrackQueryText); 5953 5954 if (!result) { 5955 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.lastQuery(); 5956 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.lastError(); 5957 5958 Q_EMIT databaseError(); 5959 } 5960 } 5961 5962 { 5963 auto selectTrackQueryText = QStringLiteral("SELECT " 5964 "tracks.ID " 5965 "FROM " 5966 "`Tracks` tracks, " 5967 "`Albums` albums " 5968 "WHERE " 5969 "tracks.`Title` = :title AND " 5970 "tracks.`Priority` = :priority AND " 5971 "(tracks.`ArtistName` = :trackArtist OR tracks.`ArtistName` IS NULL) AND " 5972 "(tracks.`AlbumTitle` = :album OR tracks.`AlbumTitle` IS NULL) AND " 5973 "(tracks.`AlbumArtistName` = :albumArtist OR tracks.`AlbumArtistName` IS NULL) AND " 5974 "(tracks.`AlbumPath` = :albumPath OR tracks.`AlbumPath` IS NULL) AND " 5975 "(tracks.`TrackNumber` = :trackNumber OR tracks.`TrackNumber` IS NULL) AND " 5976 "(tracks.`DiscNumber` = :discNumber OR tracks.`DiscNumber` IS NULL) " 5977 ""); 5978 5979 auto result = prepareQuery(d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery, selectTrackQueryText); 5980 5981 if (!result) { 5982 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.lastQuery(); 5983 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.lastError(); 5984 5985 Q_EMIT databaseError(); 5986 } 5987 } 5988 5989 { 5990 auto selectAlbumArtUriFromAlbumIdQueryText = QStringLiteral("SELECT `CoverFileName`" 5991 "FROM " 5992 "`Albums` " 5993 "WHERE " 5994 "`ID` = :albumId"); 5995 5996 auto result = prepareQuery(d->mSelectAlbumArtUriFromAlbumIdQuery, selectAlbumArtUriFromAlbumIdQueryText); 5997 5998 if (!result) { 5999 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumArtUriFromAlbumIdQuery.lastQuery(); 6000 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumArtUriFromAlbumIdQuery.lastError(); 6001 6002 Q_EMIT databaseError(); 6003 } 6004 } 6005 6006 { 6007 auto updateAlbumArtUriFromAlbumIdQueryText = QStringLiteral("UPDATE `Albums` " 6008 "SET `CoverFileName` = :coverFileName " 6009 "WHERE " 6010 "`ID` = :albumId"); 6011 6012 auto result = prepareQuery(d->mUpdateAlbumArtUriFromAlbumIdQuery, updateAlbumArtUriFromAlbumIdQueryText); 6013 6014 if (!result) { 6015 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastQuery(); 6016 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastError(); 6017 6018 Q_EMIT databaseError(); 6019 } 6020 } 6021 6022 { 6023 auto selectUpToFourLatestCoversFromArtistNameQueryText = QStringLiteral("SELECT " 6024 "(CASE WHEN (album.`CoverFileName` IS NOT NULL AND " 6025 "album.`CoverFileName` IS NOT '') THEN album.`CoverFileName` " 6026 "ELSE track.`FileName` END) AS CoverFileName, " 6027 "(album.`CoverFileName` IS NULL OR " 6028 "album.`CoverFileName` IS '') AS IsTrackCover " 6029 "FROM " 6030 "`Tracks` track LEFT OUTER JOIN `Albums` album ON " 6031 "album.`Title` = track.`AlbumTitle` AND " 6032 "album.`ArtistName` = track.`AlbumArtistName` AND " 6033 "album.`AlbumPath` = track.`AlbumPath` " 6034 "WHERE " 6035 "(track.`HasEmbeddedCover` = 1 OR " 6036 "(album.`CoverFileName` IS NOT NULL AND " 6037 "album.`CoverFileName` IS NOT '')) AND " 6038 "(track.`ArtistName` = :artistName OR " 6039 "track.`AlbumArtistName` = :artistName) " 6040 "GROUP BY track.`AlbumTitle` " 6041 "ORDER BY track.`Year` DESC " 6042 "LIMIT 4 "); 6043 6044 auto result = prepareQuery(d->mSelectUpToFourLatestCoversFromArtistNameQuery, selectUpToFourLatestCoversFromArtistNameQueryText); 6045 6046 if (!result) { 6047 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectUpToFourLatestCoversFromArtistNameQuery.lastQuery(); 6048 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectUpToFourLatestCoversFromArtistNameQuery.lastError(); 6049 6050 Q_EMIT databaseError(); 6051 } 6052 } 6053 6054 { 6055 auto selectTracksFromArtistQueryText = QStringLiteral("SELECT " 6056 "tracks.`ID`, " 6057 "tracks.`Title`, " 6058 "album.`ID`, " 6059 "tracks.`ArtistName`, " 6060 "( " 6061 "SELECT " 6062 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 6063 "FROM " 6064 "`Tracks` tracksFromAlbum1 " 6065 "WHERE " 6066 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 6067 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 6068 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 6069 "album.`ArtistName` IS NULL " 6070 ") " 6071 ") AND " 6072 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 6073 ") AS ArtistsCount, " 6074 "( " 6075 "SELECT " 6076 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 6077 "FROM " 6078 "`Tracks` tracksFromAlbum2 " 6079 "WHERE " 6080 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 6081 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 6082 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 6083 "album.`ArtistName` IS NULL " 6084 ") " 6085 ") AND " 6086 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 6087 ") AS AllArtists, " 6088 "tracks.`AlbumArtistName`, " 6089 "tracksMapping.`FileName`, " 6090 "tracksMapping.`FileModifiedTime`, " 6091 "tracks.`TrackNumber`, " 6092 "tracks.`DiscNumber`, " 6093 "tracks.`Duration`, " 6094 "tracks.`AlbumTitle`, " 6095 "tracks.`Rating`, " 6096 "album.`CoverFileName`, " 6097 "(" 6098 "SELECT " 6099 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 6100 "FROM " 6101 "`Tracks` tracks2 " 6102 "WHERE " 6103 "tracks2.`AlbumTitle` = album.`Title` AND " 6104 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 6105 "(tracks2.`AlbumArtistName` IS NULL AND " 6106 "album.`ArtistName` IS NULL" 6107 ")" 6108 ") AND " 6109 "tracks2.`AlbumPath` = album.`AlbumPath` " 6110 ") as `IsSingleDiscAlbum`, " 6111 "trackGenre.`Name`, " 6112 "trackComposer.`Name`, " 6113 "trackLyricist.`Name`, " 6114 "tracks.`Comment`, " 6115 "tracks.`Year`, " 6116 "tracks.`Channels`, " 6117 "tracks.`BitRate`, " 6118 "tracks.`SampleRate`, " 6119 "tracks.`HasEmbeddedCover`, " 6120 "tracksMapping.`ImportDate`, " 6121 "tracksMapping.`FirstPlayDate`, " 6122 "tracksMapping.`LastPlayDate`, " 6123 "tracksMapping.`PlayCounter`, " 6124 "( " 6125 "SELECT tracksCover.`FileName` " 6126 "FROM " 6127 "`Tracks` tracksCover " 6128 "WHERE " 6129 "tracksCover.`HasEmbeddedCover` = 1 AND " 6130 "( " 6131 "(tracksCover.`AlbumTitle` IS NULL AND " 6132 "tracksCover.`FileName` = tracks.`FileName` ) OR " 6133 "( " 6134 "tracksCover.`AlbumTitle` = album.`Title` AND " 6135 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 6136 "(tracksCover.`AlbumArtistName` IS NULL AND " 6137 "album.`ArtistName` IS NULL " 6138 ") " 6139 ") AND " 6140 "tracksCover.`AlbumPath` = album.`AlbumPath` " 6141 ") " 6142 ") " 6143 ") as EmbeddedCover " 6144 "FROM " 6145 "`Tracks` tracks, " 6146 "`TracksData` tracksMapping " 6147 "LEFT JOIN " 6148 "`Albums` album " 6149 "ON " 6150 "tracks.`AlbumTitle` = album.`Title` AND " 6151 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 6152 "tracks.`AlbumPath` = album.`AlbumPath` " 6153 "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " 6154 "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " 6155 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 6156 "WHERE " 6157 "tracks.`ArtistName` = :artistName AND " 6158 "tracksMapping.`FileName` = tracks.`FileName` AND " 6159 "tracks.`Priority` = (" 6160 " SELECT " 6161 " MIN(`Priority`) " 6162 " FROM " 6163 " `Tracks` tracks2 " 6164 " WHERE " 6165 " tracks.`Title` = tracks2.`Title` AND " 6166 " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " 6167 " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " 6168 " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " 6169 " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" 6170 ")" 6171 "ORDER BY " 6172 "album.`Title` ASC, " 6173 "tracks.`DiscNumber` ASC, " 6174 "tracks.`TrackNumber` ASC, " 6175 "tracks.`Title` ASC" 6176 ""); 6177 6178 auto result = prepareQuery(d->mSelectTracksFromArtist, selectTracksFromArtistQueryText); 6179 6180 if (!result) { 6181 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksFromArtist.lastQuery(); 6182 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksFromArtist.lastError(); 6183 6184 Q_EMIT databaseError(); 6185 } 6186 } 6187 6188 { 6189 auto selectTracksFromGenreQueryText = QStringLiteral("SELECT " 6190 "tracks.`ID`, " 6191 "tracks.`Title`, " 6192 "album.`ID`, " 6193 "tracks.`ArtistName`, " 6194 "( " 6195 "SELECT " 6196 "COUNT(DISTINCT tracksFromAlbum1.`ArtistName`) " 6197 "FROM " 6198 "`Tracks` tracksFromAlbum1 " 6199 "WHERE " 6200 "tracksFromAlbum1.`AlbumTitle` = album.`Title` AND " 6201 "(tracksFromAlbum1.`AlbumArtistName` = album.`ArtistName` OR " 6202 "(tracksFromAlbum1.`AlbumArtistName` IS NULL AND " 6203 "album.`ArtistName` IS NULL " 6204 ") " 6205 ") AND " 6206 "tracksFromAlbum1.`AlbumPath` = album.`AlbumPath` " 6207 ") AS ArtistsCount, " 6208 "( " 6209 "SELECT " 6210 "GROUP_CONCAT(tracksFromAlbum2.`ArtistName`) " 6211 "FROM " 6212 "`Tracks` tracksFromAlbum2 " 6213 "WHERE " 6214 "tracksFromAlbum2.`AlbumTitle` = album.`Title` AND " 6215 "(tracksFromAlbum2.`AlbumArtistName` = album.`ArtistName` OR " 6216 "(tracksFromAlbum2.`AlbumArtistName` IS NULL AND " 6217 "album.`ArtistName` IS NULL " 6218 ") " 6219 ") AND " 6220 "tracksFromAlbum2.`AlbumPath` = album.`AlbumPath` " 6221 ") AS AllArtists, " 6222 "tracks.`AlbumArtistName`, " 6223 "tracksMapping.`FileName`, " 6224 "tracksMapping.`FileModifiedTime`, " 6225 "tracks.`TrackNumber`, " 6226 "tracks.`DiscNumber`, " 6227 "tracks.`Duration`, " 6228 "tracks.`AlbumTitle`, " 6229 "tracks.`Rating`, " 6230 "album.`CoverFileName`, " 6231 "(" 6232 "SELECT " 6233 "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " 6234 "FROM " 6235 "`Tracks` tracks2 " 6236 "WHERE " 6237 "tracks2.`AlbumTitle` = album.`Title` AND " 6238 "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " 6239 "(tracks2.`AlbumArtistName` IS NULL AND " 6240 "album.`ArtistName` IS NULL" 6241 ")" 6242 ") AND " 6243 "tracks2.`AlbumPath` = album.`AlbumPath` " 6244 ") as `IsSingleDiscAlbum`, " 6245 "trackGenre.`Name`, " 6246 "trackComposer.`Name`, " 6247 "trackLyricist.`Name`, " 6248 "tracks.`Comment`, " 6249 "tracks.`Year`, " 6250 "tracks.`Channels`, " 6251 "tracks.`BitRate`, " 6252 "tracks.`SampleRate`, " 6253 "tracks.`HasEmbeddedCover`, " 6254 "tracksMapping.`ImportDate`, " 6255 "tracksMapping.`FirstPlayDate`, " 6256 "tracksMapping.`LastPlayDate`, " 6257 "tracksMapping.`PlayCounter`, " 6258 "( " 6259 "SELECT tracksCover.`FileName` " 6260 "FROM " 6261 "`Tracks` tracksCover " 6262 "WHERE " 6263 "tracksCover.`HasEmbeddedCover` = 1 AND " 6264 "( " 6265 "(tracksCover.`AlbumTitle` IS NULL AND " 6266 "tracksCover.`FileName` = tracks.`FileName` ) OR " 6267 "( " 6268 "tracksCover.`AlbumTitle` = album.`Title` AND " 6269 "(tracksCover.`AlbumArtistName` = album.`ArtistName` OR " 6270 "(tracksCover.`AlbumArtistName` IS NULL AND " 6271 "album.`ArtistName` IS NULL " 6272 ") " 6273 ") AND " 6274 "tracksCover.`AlbumPath` = album.`AlbumPath` " 6275 ") " 6276 ") " 6277 ") as EmbeddedCover " 6278 "FROM " 6279 "`Tracks` tracks, " 6280 "`TracksData` tracksMapping " 6281 "LEFT JOIN " 6282 "`Albums` album " 6283 "ON " 6284 "tracks.`AlbumTitle` = album.`Title` AND " 6285 "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " 6286 "tracks.`AlbumPath` = album.`AlbumPath` " 6287 "LEFT JOIN `Composer` trackComposer ON trackComposer.`Name` = tracks.`Composer` " 6288 "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`Name` = tracks.`Lyricist` " 6289 "LEFT JOIN `Genre` trackGenre ON trackGenre.`Name` = tracks.`Genre` " 6290 "WHERE " 6291 "tracks.`Genre` = :genre AND " 6292 "tracksMapping.`FileName` = tracks.`FileName` AND " 6293 "tracks.`Priority` = (" 6294 " SELECT " 6295 " MIN(`Priority`) " 6296 " FROM " 6297 " `Tracks` tracks2 " 6298 " WHERE " 6299 " tracks.`Title` = tracks2.`Title` AND " 6300 " (tracks.`ArtistName` IS NULL OR tracks.`ArtistName` = tracks2.`ArtistName`) AND " 6301 " (tracks.`AlbumTitle` IS NULL OR tracks.`AlbumTitle` = tracks2.`AlbumTitle`) AND " 6302 " (tracks.`AlbumArtistName` IS NULL OR tracks.`AlbumArtistName` = tracks2.`AlbumArtistName`) AND " 6303 " (tracks.`AlbumPath` IS NULL OR tracks.`AlbumPath` = tracks2.`AlbumPath`)" 6304 ")" 6305 "ORDER BY " 6306 "album.`Title` ASC, " 6307 "tracks.`DiscNumber` ASC, " 6308 "tracks.`TrackNumber` ASC, " 6309 "tracks.`Title` ASC" 6310 ""); 6311 6312 auto result = prepareQuery(d->mSelectTracksFromGenre, selectTracksFromGenreQueryText); 6313 6314 if (!result) { 6315 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksFromGenre.lastQuery(); 6316 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectTracksFromGenre.lastError(); 6317 6318 Q_EMIT databaseError(); 6319 } 6320 } 6321 6322 { 6323 auto selectAlbumIdsFromArtistQueryText = QStringLiteral("SELECT " 6324 "album.`ID` " 6325 "FROM " 6326 "`Albums` album " 6327 "WHERE " 6328 "album.`ArtistName` = :artistName"); 6329 6330 auto result = prepareQuery(d->mSelectAlbumIdsFromArtist, selectAlbumIdsFromArtistQueryText); 6331 6332 if (!result) { 6333 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumIdsFromArtist.lastQuery(); 6334 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectAlbumIdsFromArtist.lastError(); 6335 6336 Q_EMIT databaseError(); 6337 } 6338 } 6339 6340 { 6341 auto selectArtistQueryText = QStringLiteral("SELECT `ID`, " 6342 "`Name` " 6343 "FROM `Artists` " 6344 "WHERE " 6345 "`ID` = :artistId"); 6346 6347 auto result = prepareQuery(d->mSelectArtistQuery, selectArtistQueryText); 6348 6349 if (!result) { 6350 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectArtistQuery.lastQuery(); 6351 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectArtistQuery.lastError(); 6352 6353 Q_EMIT databaseError(); 6354 } 6355 } 6356 6357 { 6358 auto updateTrackStartedStatisticsQueryText = QStringLiteral("UPDATE `TracksData` " 6359 "SET " 6360 "`LastPlayDate` = :playDate " 6361 "WHERE " 6362 "`FileName` = :fileName"); 6363 6364 auto result = prepareQuery(d->mUpdateTrackStartedStatistics, updateTrackStartedStatisticsQueryText); 6365 6366 if (!result) { 6367 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackStartedStatistics.lastQuery(); 6368 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackStartedStatistics.lastError(); 6369 6370 Q_EMIT databaseError(); 6371 } 6372 } 6373 6374 { 6375 auto updateTrackFinishedStatisticsQueryText = QStringLiteral("UPDATE `TracksData` " 6376 "SET " 6377 "`PlayCounter` = `PlayCounter` + 1 " 6378 "WHERE " 6379 "`FileName` = :fileName"); 6380 6381 auto result = prepareQuery(d->mUpdateTrackFinishedStatistics, updateTrackFinishedStatisticsQueryText); 6382 6383 if (!result) { 6384 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackFinishedStatistics.lastQuery(); 6385 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackFinishedStatistics.lastError(); 6386 6387 Q_EMIT databaseError(); 6388 } 6389 } 6390 6391 { 6392 auto updateTrackFirstPlayStatisticsQueryText = QStringLiteral("UPDATE `TracksData` " 6393 "SET " 6394 "`FirstPlayDate` = :playDate " 6395 "WHERE " 6396 "`FileName` = :fileName AND " 6397 "`FirstPlayDate` IS NULL"); 6398 6399 auto result = prepareQuery(d->mUpdateTrackFirstPlayStatistics, updateTrackFirstPlayStatisticsQueryText); 6400 6401 if (!result) { 6402 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackFirstPlayStatistics.lastQuery(); 6403 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mUpdateTrackFirstPlayStatistics.lastError(); 6404 6405 Q_EMIT databaseError(); 6406 } 6407 } 6408 6409 { 6410 auto selectGenreQueryText = QStringLiteral("SELECT `ID`, " 6411 "`Name` " 6412 "FROM `Genre` " 6413 "WHERE " 6414 "`ID` = :genreId"); 6415 6416 auto result = prepareQuery(d->mSelectGenreQuery, selectGenreQueryText); 6417 6418 if (!result) { 6419 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectGenreQuery.lastQuery(); 6420 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectGenreQuery.lastError(); 6421 6422 Q_EMIT databaseError(); 6423 } 6424 } 6425 6426 { 6427 auto selectComposerQueryText = QStringLiteral("SELECT `ID`, " 6428 "`Name` " 6429 "FROM `Composer` " 6430 "WHERE " 6431 "`ID` = :composerId"); 6432 6433 auto result = prepareQuery(d->mSelectComposerQuery, selectComposerQueryText); 6434 6435 if (!result) { 6436 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectComposerQuery.lastQuery(); 6437 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectComposerQuery.lastError(); 6438 } 6439 } 6440 6441 { 6442 auto selectLyricistQueryText = QStringLiteral("SELECT `ID`, " 6443 "`Name` " 6444 "FROM `Lyricist` " 6445 "WHERE " 6446 "`ID` = :lyricistId"); 6447 6448 auto result = prepareQuery(d->mSelectLyricistQuery, selectLyricistQueryText); 6449 6450 if (!result) { 6451 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectLyricistQuery.lastQuery(); 6452 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mSelectLyricistQuery.lastError(); 6453 } 6454 } 6455 6456 { 6457 auto removeTrackQueryText = QStringLiteral("DELETE FROM `Tracks` " 6458 "WHERE " 6459 "`ID` = :trackId"); 6460 6461 auto result = prepareQuery(d->mRemoveTrackQuery, removeTrackQueryText); 6462 6463 if (!result) { 6464 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveTrackQuery.lastQuery(); 6465 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveTrackQuery.lastError(); 6466 6467 Q_EMIT databaseError(); 6468 } 6469 } 6470 6471 { 6472 auto removeAlbumQueryText = QStringLiteral("DELETE FROM `Albums` " 6473 "WHERE " 6474 "`ID` = :albumId"); 6475 6476 auto result = prepareQuery(d->mRemoveAlbumQuery, removeAlbumQueryText); 6477 6478 if (!result) { 6479 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveAlbumQuery.lastQuery(); 6480 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveAlbumQuery.lastError(); 6481 6482 Q_EMIT databaseError(); 6483 } 6484 } 6485 6486 { 6487 auto removeAlbumQueryText = QStringLiteral("DELETE FROM `Artists` " 6488 "WHERE " 6489 "`ID` = :artistId"); 6490 6491 auto result = prepareQuery(d->mRemoveArtistQuery, removeAlbumQueryText); 6492 6493 if (!result) { 6494 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveArtistQuery.lastQuery(); 6495 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::initDataQueries" << d->mRemoveArtistQuery.lastError(); 6496 6497 Q_EMIT databaseError(); 6498 } 6499 } 6500 6501 finishTransaction(); 6502 6503 d->mInitFinished = true; 6504 Q_EMIT requestsInitDone(); 6505 } 6506 6507 void DatabaseInterface::initChangesTrackers() 6508 { 6509 d->mModifiedTrackIds.clear(); 6510 d->mModifiedAlbumIds.clear(); 6511 d->mModifiedArtistIds.clear(); 6512 d->mInsertedTracks.clear(); 6513 d->mInsertedAlbums.clear(); 6514 d->mInsertedArtists.clear(); 6515 } 6516 6517 void DatabaseInterface::recordModifiedTrack(qulonglong trackId) 6518 { 6519 d->mModifiedTrackIds.insert(trackId); 6520 } 6521 6522 void DatabaseInterface::recordModifiedAlbum(qulonglong albumId) 6523 { 6524 d->mModifiedAlbumIds.insert(albumId); 6525 } 6526 6527 void DatabaseInterface::internalInsertOneTrack(const DataTypes::TrackDataType &oneTrack, const QHash<QString, QUrl> &covers) 6528 { 6529 d->mSelectTracksMapping.bindValue(QStringLiteral(":fileName"), oneTrack.resourceURI()); 6530 6531 auto result = execQuery(d->mSelectTracksMapping); 6532 6533 if (!result || !d->mSelectTracksMapping.isSelect() || !d->mSelectTracksMapping.isActive()) { 6534 Q_EMIT databaseError(); 6535 6536 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertTracksList" << d->mSelectTracksMapping.lastQuery(); 6537 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertTracksList" << d->mSelectTracksMapping.boundValues(); 6538 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertTracksList" << d->mSelectTracksMapping.lastError(); 6539 6540 d->mSelectTracksMapping.finish(); 6541 6542 rollBackTransaction(); 6543 Q_EMIT finishInsertingTracksList(); 6544 return; 6545 } 6546 6547 bool isNewTrack = !d->mSelectTracksMapping.next(); 6548 6549 if (isNewTrack) { 6550 insertTrackOrigin(oneTrack.resourceURI(), oneTrack.fileModificationTime(), 6551 QDateTime::currentDateTime()); 6552 } else if (!d->mSelectTracksMapping.record().value(0).isNull() && d->mSelectTracksMapping.record().value(0).toULongLong() != 0) { 6553 updateTrackOrigin(oneTrack.resourceURI(), oneTrack.fileModificationTime()); 6554 } 6555 6556 d->mSelectTracksMapping.finish(); 6557 6558 bool isInserted = false; 6559 6560 const auto insertedTrackId = internalInsertTrack(oneTrack, covers, isInserted); 6561 6562 if (isInserted && insertedTrackId != 0) { 6563 d->mInsertedTracks.insert(insertedTrackId); 6564 } 6565 } 6566 6567 void DatabaseInterface::internalInsertOneRadio(const DataTypes::TrackDataType &oneTrack) 6568 { 6569 QSqlQuery query = d->mUpdateRadioQuery; 6570 6571 if (!oneTrack.hasDatabaseId()) { 6572 query = d->mInsertRadioQuery; 6573 } 6574 6575 query.bindValue(QStringLiteral(":httpAddress"), oneTrack.resourceURI()); 6576 query.bindValue(QStringLiteral(":radioId"), oneTrack.databaseId()); 6577 query.bindValue(QStringLiteral(":title"), oneTrack.title()); 6578 query.bindValue(QStringLiteral(":comment"), oneTrack.comment()); 6579 query.bindValue(QStringLiteral(":trackRating"), oneTrack.rating()); 6580 query.bindValue(QStringLiteral(":imageAddress"), oneTrack.albumCover()); 6581 6582 auto result = execQuery(query); 6583 6584 if (!result || !query.isActive()) { 6585 Q_EMIT databaseError(); 6586 6587 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertTracksList" << query.lastQuery(); 6588 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertTracksList" << query.boundValues(); 6589 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertTracksList" << query.lastError(); 6590 } else { 6591 if (!oneTrack.hasDatabaseId()) { 6592 auto radio = internalOneRadioPartialData(internalRadioIdFromHttpAddress(oneTrack.resourceURI().toString())); 6593 6594 Q_EMIT radioAdded(radio); 6595 } else { 6596 auto radio = internalOneRadioPartialData(oneTrack.databaseId()); 6597 6598 Q_EMIT radioModified(radio); 6599 } 6600 } 6601 6602 query.finish(); 6603 } 6604 6605 qulonglong DatabaseInterface::insertAlbum(const QString &title, const QString &albumArtist, 6606 const QString &trackPath, const QUrl &albumArtURI) 6607 { 6608 auto result = qulonglong(0); 6609 6610 if (title.isEmpty()) { 6611 return result; 6612 } 6613 6614 d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":title"), title); 6615 d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":albumPath"), trackPath); 6616 d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":artistName"), albumArtist); 6617 6618 auto queryResult = execQuery(d->mSelectAlbumIdFromTitleAndArtistQuery); 6619 6620 if (!queryResult || !d->mSelectAlbumIdFromTitleAndArtistQuery.isSelect() || !d->mSelectAlbumIdFromTitleAndArtistQuery.isActive()) { 6621 Q_EMIT databaseError(); 6622 6623 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mSelectAlbumIdFromTitleAndArtistQuery.lastQuery(); 6624 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mSelectAlbumIdFromTitleAndArtistQuery.boundValues(); 6625 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mSelectAlbumIdFromTitleAndArtistQuery.lastError(); 6626 6627 d->mSelectAlbumIdFromTitleAndArtistQuery.finish(); 6628 6629 return result; 6630 } 6631 6632 if (d->mSelectAlbumIdFromTitleAndArtistQuery.next()) { 6633 result = d->mSelectAlbumIdFromTitleAndArtistQuery.record().value(0).toULongLong(); 6634 6635 d->mSelectAlbumIdFromTitleAndArtistQuery.finish(); 6636 6637 if (!albumArtist.isEmpty()) { 6638 const auto similarAlbum = internalOneAlbumPartialData(result); 6639 updateAlbumArtist(result, title, trackPath, albumArtist); 6640 if (updateAlbumCover(result, albumArtURI)) { 6641 recordModifiedAlbum(result); 6642 } 6643 } 6644 6645 return result; 6646 } 6647 6648 d->mSelectAlbumIdFromTitleAndArtistQuery.finish(); 6649 6650 d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumId"), d->mAlbumId); 6651 d->mInsertAlbumQuery.bindValue(QStringLiteral(":title"), title); 6652 if (!albumArtist.isEmpty()) { 6653 insertArtist(albumArtist); 6654 d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumArtist"), albumArtist); 6655 } else { 6656 d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumArtist"), {}); 6657 } 6658 d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumPath"), trackPath); 6659 d->mInsertAlbumQuery.bindValue(QStringLiteral(":coverFileName"), albumArtURI); 6660 6661 queryResult = execQuery(d->mInsertAlbumQuery); 6662 6663 if (!queryResult || !d->mInsertAlbumQuery.isActive()) { 6664 Q_EMIT databaseError(); 6665 6666 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mInsertAlbumQuery.lastQuery(); 6667 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mInsertAlbumQuery.boundValues(); 6668 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertAlbum" << d->mInsertAlbumQuery.lastError(); 6669 6670 d->mInsertAlbumQuery.finish(); 6671 6672 return result; 6673 } 6674 6675 result = d->mAlbumId; 6676 6677 d->mInsertAlbumQuery.finish(); 6678 6679 ++d->mAlbumId; 6680 6681 d->mInsertedAlbums.insert(result); 6682 6683 return result; 6684 } 6685 6686 bool DatabaseInterface::updateAlbumFromId(qulonglong albumId, const QUrl &albumArtUri, 6687 const DataTypes::TrackDataType ¤tTrack, const QString &albumPath) 6688 { 6689 auto modifiedAlbum = false; 6690 6691 modifiedAlbum = updateAlbumCover(albumId, albumArtUri); 6692 6693 if (!isValidArtist(albumId) && currentTrack.hasAlbum() && (currentTrack.hasAlbumArtist() || currentTrack.hasArtist())) { 6694 updateAlbumArtist(albumId, currentTrack.album(), albumPath, currentTrack.albumArtist()); 6695 6696 modifiedAlbum = true; 6697 } 6698 6699 return modifiedAlbum; 6700 } 6701 6702 qulonglong DatabaseInterface::insertArtist(const QString &name) 6703 { 6704 auto result = qulonglong(0); 6705 6706 if (name.isEmpty()) { 6707 return result; 6708 } 6709 6710 d->mSelectArtistByNameQuery.bindValue(QStringLiteral(":name"), name); 6711 6712 auto queryResult = execQuery(d->mSelectArtistByNameQuery); 6713 6714 if (!queryResult || !d->mSelectArtistByNameQuery.isSelect() || !d->mSelectArtistByNameQuery.isActive()) { 6715 Q_EMIT databaseError(); 6716 6717 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.lastQuery(); 6718 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.boundValues(); 6719 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.lastError(); 6720 6721 d->mSelectArtistByNameQuery.finish(); 6722 6723 return result; 6724 } 6725 6726 if (d->mSelectArtistByNameQuery.next()) { 6727 result = d->mSelectArtistByNameQuery.record().value(0).toULongLong(); 6728 6729 d->mSelectArtistByNameQuery.finish(); 6730 6731 return result; 6732 } 6733 6734 d->mSelectArtistByNameQuery.finish(); 6735 6736 d->mInsertArtistsQuery.bindValue(QStringLiteral(":artistId"), d->mArtistId); 6737 d->mInsertArtistsQuery.bindValue(QStringLiteral(":name"), name); 6738 6739 queryResult = execQuery(d->mInsertArtistsQuery); 6740 6741 if (!queryResult || !d->mInsertArtistsQuery.isActive()) { 6742 Q_EMIT databaseError(); 6743 6744 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertArtistsQuery.lastQuery(); 6745 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertArtistsQuery.boundValues(); 6746 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertArtistsQuery.lastError(); 6747 6748 d->mInsertArtistsQuery.finish(); 6749 6750 return result; 6751 } 6752 6753 result = d->mArtistId; 6754 6755 ++d->mArtistId; 6756 6757 d->mInsertedArtists.insert(result); 6758 6759 d->mInsertArtistsQuery.finish(); 6760 6761 return result; 6762 } 6763 6764 qulonglong DatabaseInterface::insertComposer(const QString &name) 6765 { 6766 auto result = qulonglong(0); 6767 6768 if (name.isEmpty()) { 6769 return result; 6770 } 6771 6772 d->mSelectComposerByNameQuery.bindValue(QStringLiteral(":name"), name); 6773 6774 auto queryResult = execQuery(d->mSelectComposerByNameQuery); 6775 6776 if (!queryResult || !d->mSelectComposerByNameQuery.isSelect() || !d->mSelectComposerByNameQuery.isActive()) { 6777 Q_EMIT databaseError(); 6778 6779 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mSelectComposerByNameQuery.lastQuery(); 6780 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mSelectComposerByNameQuery.boundValues(); 6781 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mSelectComposerByNameQuery.lastError(); 6782 6783 d->mSelectComposerByNameQuery.finish(); 6784 6785 return result; 6786 } 6787 6788 6789 if (d->mSelectComposerByNameQuery.next()) { 6790 result = d->mSelectComposerByNameQuery.record().value(0).toULongLong(); 6791 6792 d->mSelectComposerByNameQuery.finish(); 6793 6794 return result; 6795 } 6796 6797 d->mSelectComposerByNameQuery.finish(); 6798 6799 d->mInsertComposerQuery.bindValue(QStringLiteral(":composerId"), d->mComposerId); 6800 d->mInsertComposerQuery.bindValue(QStringLiteral(":name"), name); 6801 6802 queryResult = execQuery(d->mInsertComposerQuery); 6803 6804 if (!queryResult || !d->mInsertComposerQuery.isActive()) { 6805 Q_EMIT databaseError(); 6806 6807 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mInsertComposerQuery.lastQuery(); 6808 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mInsertComposerQuery.boundValues(); 6809 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertComposer" << d->mInsertComposerQuery.lastError(); 6810 6811 d->mInsertComposerQuery.finish(); 6812 6813 return result; 6814 } 6815 6816 result = d->mComposerId; 6817 6818 ++d->mComposerId; 6819 6820 d->mInsertComposerQuery.finish(); 6821 6822 Q_EMIT composersAdded(internalAllComposersPartialData()); 6823 6824 return result; 6825 } 6826 6827 qulonglong DatabaseInterface::insertGenre(const QString &name) 6828 { 6829 auto result = qulonglong(0); 6830 6831 if (name.isEmpty()) { 6832 return result; 6833 } 6834 6835 d->mSelectGenreByNameQuery.bindValue(QStringLiteral(":name"), name); 6836 6837 auto queryResult = execQuery(d->mSelectGenreByNameQuery); 6838 6839 if (!queryResult || !d->mSelectGenreByNameQuery.isSelect() || !d->mSelectGenreByNameQuery.isActive()) { 6840 Q_EMIT databaseError(); 6841 6842 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mSelectGenreByNameQuery.lastQuery(); 6843 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mSelectGenreByNameQuery.boundValues(); 6844 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mSelectGenreByNameQuery.lastError(); 6845 6846 d->mSelectGenreByNameQuery.finish(); 6847 6848 return result; 6849 } 6850 6851 if (d->mSelectGenreByNameQuery.next()) { 6852 result = d->mSelectGenreByNameQuery.record().value(0).toULongLong(); 6853 6854 d->mSelectGenreByNameQuery.finish(); 6855 6856 return result; 6857 } 6858 6859 d->mSelectGenreByNameQuery.finish(); 6860 6861 d->mInsertGenreQuery.bindValue(QStringLiteral(":genreId"), d->mGenreId); 6862 d->mInsertGenreQuery.bindValue(QStringLiteral(":name"), name); 6863 6864 queryResult = execQuery(d->mInsertGenreQuery); 6865 6866 if (!queryResult || !d->mInsertGenreQuery.isActive()) { 6867 Q_EMIT databaseError(); 6868 6869 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mInsertGenreQuery.lastQuery(); 6870 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mInsertGenreQuery.boundValues(); 6871 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertGenre" << d->mInsertGenreQuery.lastError(); 6872 6873 d->mInsertGenreQuery.finish(); 6874 6875 return result; 6876 } 6877 6878 result = d->mGenreId; 6879 6880 ++d->mGenreId; 6881 6882 d->mInsertGenreQuery.finish(); 6883 6884 Q_EMIT genresAdded({{{DataTypes::DatabaseIdRole, result}, 6885 {DataTypes::TitleRole, name}, 6886 {DataTypes::ElementTypeRole, ElisaUtils::Genre}}}); 6887 6888 return result; 6889 } 6890 6891 void DatabaseInterface::insertTrackOrigin(const QUrl &fileNameURI, const QDateTime &fileModifiedTime, 6892 const QDateTime &importDate) 6893 { 6894 d->mInsertTrackMapping.bindValue(QStringLiteral(":fileName"), fileNameURI); 6895 d->mInsertTrackMapping.bindValue(QStringLiteral(":priority"), 1); 6896 d->mInsertTrackMapping.bindValue(QStringLiteral(":mtime"), fileModifiedTime); 6897 d->mInsertTrackMapping.bindValue(QStringLiteral(":importDate"), importDate.toMSecsSinceEpoch()); 6898 6899 auto queryResult = execQuery(d->mInsertTrackMapping); 6900 6901 if (!queryResult || !d->mInsertTrackMapping.isActive()) { 6902 Q_EMIT databaseError(); 6903 6904 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertTrackMapping.lastQuery(); 6905 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertTrackMapping.boundValues(); 6906 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mInsertTrackMapping.lastError(); 6907 6908 d->mInsertTrackMapping.finish(); 6909 6910 return; 6911 } 6912 6913 d->mInsertTrackMapping.finish(); 6914 } 6915 6916 void DatabaseInterface::updateTrackOrigin(const QUrl &fileName, const QDateTime &fileModifiedTime) 6917 { 6918 d->mUpdateTrackFileModifiedTime.bindValue(QStringLiteral(":fileName"), fileName); 6919 d->mUpdateTrackFileModifiedTime.bindValue(QStringLiteral(":mtime"), fileModifiedTime); 6920 6921 auto queryResult = execQuery(d->mUpdateTrackFileModifiedTime); 6922 6923 if (!queryResult || !d->mUpdateTrackFileModifiedTime.isActive()) { 6924 Q_EMIT databaseError(); 6925 6926 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackOrigin" << d->mUpdateTrackFileModifiedTime.lastQuery(); 6927 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackOrigin" << d->mUpdateTrackFileModifiedTime.boundValues(); 6928 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackOrigin" << d->mUpdateTrackFileModifiedTime.lastError(); 6929 6930 d->mUpdateTrackFileModifiedTime.finish(); 6931 6932 return; 6933 } 6934 6935 d->mUpdateTrackFileModifiedTime.finish(); 6936 } 6937 6938 qulonglong DatabaseInterface::internalInsertTrack(const DataTypes::TrackDataType &oneTrack, 6939 const QHash<QString, QUrl> &covers, bool &isInserted) 6940 { 6941 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack trying to insert" << oneTrack; 6942 6943 qulonglong resultId = 0; 6944 6945 const bool trackHasMetadata = !oneTrack.title().isEmpty(); 6946 6947 auto existingTrackId = internalTrackIdFromFileName(oneTrack.resourceURI()); 6948 bool isModifiedTrack = (existingTrackId != 0); 6949 6950 if (!trackHasMetadata) { 6951 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << oneTrack << "is not inserted"; 6952 6953 updateTrackOrigin(oneTrack.resourceURI(), oneTrack.fileModificationTime()); 6954 6955 isInserted = true; 6956 resultId = isModifiedTrack ? existingTrackId : d->mTrackId++; 6957 6958 return resultId; 6959 } 6960 6961 QUrl::FormattingOptions currentOptions = QUrl::PreferLocalFile | 6962 QUrl::RemoveAuthority | QUrl::RemoveFilename | QUrl::RemoveFragment | 6963 QUrl::RemovePassword | QUrl::RemovePort | QUrl::RemoveQuery | 6964 QUrl::RemoveScheme | QUrl::RemoveUserInfo; 6965 6966 const auto &trackPath = oneTrack.resourceURI().toString(currentOptions); 6967 6968 auto albumCover = covers[oneTrack.resourceURI().toString()]; 6969 if (albumCover.isEmpty() && !covers.contains(oneTrack.resourceURI().toString())) { 6970 albumCover = oneTrack.albumCover(); 6971 } 6972 6973 auto albumId = insertAlbum(oneTrack.album(), (oneTrack.hasAlbumArtist() ? oneTrack.albumArtist() : QString()), 6974 trackPath, oneTrack.hasEmbeddedCover() ? QUrl{} : albumCover); 6975 6976 if (isModifiedTrack) { 6977 resultId = existingTrackId; 6978 6979 6980 auto oldTrack = internalTrackFromDatabaseId(existingTrackId); 6981 qCDebug(orgKdeElisaDatabase()) << "DatabaseInterface::internalInsertTrack" << existingTrackId << oldTrack; 6982 const auto oldAlbumId = oldTrack.albumId(); 6983 6984 if (oldTrack.isSameTrack(oneTrack)) { 6985 return resultId; 6986 } 6987 6988 auto newTrack = oneTrack; 6989 newTrack[DataTypes::ColumnsRoles::DatabaseIdRole] = resultId; 6990 updateTrackInDatabase(newTrack, trackPath); 6991 updateTrackOrigin(oneTrack.resourceURI(), oneTrack.fileModificationTime()); 6992 auto albumIsModified = updateAlbumFromId(albumId, oneTrack.hasEmbeddedCover() ? QUrl{} : oneTrack.albumCover(), oneTrack, trackPath); 6993 6994 recordModifiedTrack(existingTrackId); 6995 if (albumIsModified && albumId != 0) { 6996 recordModifiedAlbum(albumId); 6997 } 6998 if (oldAlbumId != 0) { 6999 auto tracksCount = fetchTrackIds(oldAlbumId).count(); 7000 7001 if (tracksCount) { 7002 if (!oldTrack.albumInfoIsSame(oneTrack)) { 7003 recordModifiedAlbum(oldAlbumId); 7004 } 7005 } else { 7006 removeAlbumInDatabase(oldAlbumId); 7007 Q_EMIT albumRemoved(oldAlbumId); 7008 } 7009 } 7010 7011 isInserted = false; 7012 7013 return resultId; 7014 } 7015 7016 const auto needsHigherPriority = [this, &oneTrack, &trackPath](const int currentPriority) { 7017 return getDuplicateTrackIdFromTitleAlbumTrackDiscNumber( 7018 oneTrack.title(), oneTrack.artist(), oneTrack.album(), 7019 oneTrack.albumArtist(), trackPath, oneTrack.trackNumber(), 7020 oneTrack.discNumber(), currentPriority) != 0; 7021 }; 7022 7023 int priority = 1; 7024 while (needsHigherPriority(priority)) { 7025 ++priority; 7026 } 7027 7028 d->mInsertTrackQuery.bindValue(QStringLiteral(":trackId"), d->mTrackId); 7029 7030 d->mInsertTrackQuery.bindValue(QStringLiteral(":trackId"), d->mTrackId); 7031 7032 d->mInsertTrackQuery.bindValue(QStringLiteral(":fileName"), oneTrack.resourceURI()); 7033 7034 d->mInsertTrackQuery.bindValue(QStringLiteral(":priority"), priority); 7035 7036 d->mInsertTrackQuery.bindValue(QStringLiteral(":title"), oneTrack.title()); 7037 7038 d->mInsertTrackQuery.bindValue(QStringLiteral(":albumTitle"), oneTrack.hasAlbum() ? oneTrack.album() : QVariant{}); 7039 7040 d->mInsertTrackQuery.bindValue(QStringLiteral(":albumArtistName"), oneTrack.hasAlbumArtist() ? oneTrack.albumArtist() : QVariant{}); 7041 7042 d->mInsertTrackQuery.bindValue(QStringLiteral(":albumPath"), trackPath); 7043 7044 d->mInsertTrackQuery.bindValue(QStringLiteral(":trackNumber"), oneTrack.hasTrackNumber() ? oneTrack.trackNumber() : QVariant{}); 7045 7046 d->mInsertTrackQuery.bindValue(QStringLiteral(":discNumber"), oneTrack.hasDiscNumber() ? oneTrack.discNumber() : QVariant{}); 7047 7048 d->mInsertTrackQuery.bindValue(QStringLiteral(":trackDuration"), QVariant::fromValue<qlonglong>(oneTrack.duration().msecsSinceStartOfDay())); 7049 7050 d->mInsertTrackQuery.bindValue(QStringLiteral(":trackRating"), oneTrack.rating()); 7051 7052 d->mInsertTrackQuery.bindValue(QStringLiteral(":comment"), oneTrack.hasComment() ? oneTrack.comment() : QVariant{}); 7053 7054 d->mInsertTrackQuery.bindValue(QStringLiteral(":year"), oneTrack.hasYear() ? oneTrack.year() : QVariant{}); 7055 7056 d->mInsertTrackQuery.bindValue(QStringLiteral(":channels"), oneTrack.hasChannels() ? oneTrack.channels() : QVariant{}); 7057 7058 d->mInsertTrackQuery.bindValue(QStringLiteral(":bitRate"), oneTrack.hasBitRate() ? oneTrack.bitRate() : QVariant{}); 7059 7060 d->mInsertTrackQuery.bindValue(QStringLiteral(":sampleRate"), oneTrack.hasSampleRate() ? oneTrack.sampleRate() : QVariant{}); 7061 7062 d->mInsertTrackQuery.bindValue(QStringLiteral(":hasEmbeddedCover"), oneTrack.hasEmbeddedCover()); 7063 7064 // TODO: port Artist, Composer, Genre, Lyricist to use association tables 7065 const auto oneArtist = insertArtist(oneTrack.artist()) != 0 ? oneTrack.artist() : QVariant{}; 7066 d->mInsertTrackQuery.bindValue(QStringLiteral(":artistName"), oneArtist); 7067 7068 const auto oneGenre = insertGenre(oneTrack.genre()) != 0 ? oneTrack.genre() : QVariant{}; 7069 d->mInsertTrackQuery.bindValue(QStringLiteral(":genre"), oneGenre); 7070 7071 const auto oneComposer = insertComposer(oneTrack.composer()) != 0 ? oneTrack.composer() : QVariant{}; 7072 d->mInsertTrackQuery.bindValue(QStringLiteral(":composer"), oneComposer); 7073 7074 const auto oneLyricist = insertLyricist(oneTrack.lyricist()) != 0 ? oneTrack.lyricist() : QVariant{}; 7075 d->mInsertTrackQuery.bindValue(QStringLiteral(":lyricist"), oneLyricist); 7076 7077 auto result = execQuery(d->mInsertTrackQuery); 7078 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << oneTrack << "is inserted"; 7079 7080 if (!result || !d->mInsertTrackQuery.isActive()) { 7081 d->mInsertTrackQuery.finish(); 7082 7083 Q_EMIT databaseError(); 7084 7085 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << oneTrack << oneTrack.resourceURI(); 7086 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackQuery.lastQuery(); 7087 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackQuery.boundValues(); 7088 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackQuery.lastError(); 7089 7090 isInserted = false; 7091 return resultId; 7092 } 7093 7094 d->mInsertTrackQuery.finish(); 7095 7096 updateTrackOrigin(oneTrack.resourceURI(), oneTrack.fileModificationTime()); 7097 7098 if (albumId != 0) { 7099 if (updateAlbumFromId(albumId, covers[oneTrack.resourceURI().toString()], oneTrack, trackPath)) { 7100 auto modifiedTracks = fetchTrackIds(albumId); 7101 for (auto oneModifiedTrack : modifiedTracks) { 7102 if (oneModifiedTrack != resultId) { 7103 recordModifiedTrack(oneModifiedTrack); 7104 } 7105 } 7106 } 7107 recordModifiedAlbum(albumId); 7108 } 7109 7110 resultId = d->mTrackId++; 7111 isInserted = true; 7112 7113 return resultId; 7114 } 7115 7116 DataTypes::TrackDataType DatabaseInterface::buildTrackDataFromDatabaseRecord(const QSqlRecord &trackRecord) const 7117 { 7118 DataTypes::TrackDataType result; 7119 7120 result[DataTypes::TrackDataType::key_type::DatabaseIdRole] = trackRecord.value(DatabaseInterfacePrivate::TrackId); 7121 result[DataTypes::TrackDataType::key_type::TitleRole] = trackRecord.value(DatabaseInterfacePrivate::TrackTitle); 7122 if (!trackRecord.value(DatabaseInterfacePrivate::TrackAlbumTitle).isNull()) { 7123 result[DataTypes::TrackDataType::key_type::AlbumRole] = trackRecord.value(DatabaseInterfacePrivate::TrackAlbumTitle); 7124 result[DataTypes::TrackDataType::key_type::AlbumIdRole] = trackRecord.value(DatabaseInterfacePrivate::TrackAlbumId); 7125 } 7126 7127 if (!trackRecord.value(DatabaseInterfacePrivate::TrackAlbumArtistName).isNull()) { 7128 result[DataTypes::TrackDataType::key_type::IsValidAlbumArtistRole] = true; 7129 result[DataTypes::TrackDataType::key_type::AlbumArtistRole] = trackRecord.value(DatabaseInterfacePrivate::TrackAlbumArtistName); 7130 } else { 7131 result[DataTypes::TrackDataType::key_type::IsValidAlbumArtistRole] = false; 7132 if (trackRecord.value(DatabaseInterfacePrivate::TrackArtistsCount).toInt() == 1) { 7133 result[DataTypes::TrackDataType::key_type::AlbumArtistRole] = trackRecord.value(DatabaseInterfacePrivate::TrackArtistName); 7134 } else if (trackRecord.value(DatabaseInterfacePrivate::TrackArtistsCount).toInt() > 1) { 7135 result[DataTypes::TrackDataType::key_type::AlbumArtistRole] = i18nc("@item:intable", "Various Artists"); 7136 } 7137 } 7138 7139 result[DataTypes::TrackDataType::key_type::ResourceRole] = trackRecord.value(DatabaseInterfacePrivate::TrackFileName); 7140 if (!trackRecord.value(DatabaseInterfacePrivate::TrackNumber).isNull()) { 7141 result[DataTypes::TrackDataType::key_type::TrackNumberRole] = trackRecord.value(DatabaseInterfacePrivate::TrackNumber); 7142 } 7143 if (!trackRecord.value(DatabaseInterfacePrivate::TrackDiscNumber).isNull()) { 7144 result[DataTypes::TrackDataType::key_type::DiscNumberRole] = trackRecord.value(DatabaseInterfacePrivate::TrackDiscNumber); 7145 } 7146 result[DataTypes::TrackDataType::key_type::DurationRole] = QTime::fromMSecsSinceStartOfDay(trackRecord.value(DatabaseInterfacePrivate::TrackDuration).toInt()); 7147 result[DataTypes::TrackDataType::key_type::RatingRole] = trackRecord.value(DatabaseInterfacePrivate::TrackRating); 7148 if (!trackRecord.value(DatabaseInterfacePrivate::TrackCoverFileName).toString().isEmpty()) { 7149 result[DataTypes::TrackDataType::key_type::ImageUrlRole] = QUrl(trackRecord.value(DatabaseInterfacePrivate::TrackCoverFileName).toString()); 7150 } else if (!trackRecord.value(DatabaseInterfacePrivate::TrackEmbeddedCover).toString().isEmpty()) { 7151 result[DataTypes::TrackDataType::key_type::ImageUrlRole] = QVariant{QLatin1String("image://cover/") + trackRecord.value(DatabaseInterfacePrivate::TrackEmbeddedCover).toUrl().toLocalFile()}; 7152 } 7153 result[DataTypes::TrackDataType::key_type::IsSingleDiscAlbumRole] = trackRecord.value(DatabaseInterfacePrivate::TrackIsSingleDiscAlbum); 7154 if (!trackRecord.value(DatabaseInterfacePrivate::TrackComment).isNull()) { 7155 result[DataTypes::TrackDataType::key_type::CommentRole] = trackRecord.value(DatabaseInterfacePrivate::TrackComment); 7156 } 7157 if (!trackRecord.value(DatabaseInterfacePrivate::TrackYear).isNull()) { 7158 result[DataTypes::TrackDataType::key_type::YearRole] = trackRecord.value(DatabaseInterfacePrivate::TrackYear); 7159 } 7160 if (!trackRecord.value(DatabaseInterfacePrivate::TrackChannelsCount).isNull()) { 7161 result[DataTypes::TrackDataType::key_type::ChannelsRole] = trackRecord.value(DatabaseInterfacePrivate::TrackChannelsCount); 7162 } 7163 if (!trackRecord.value(DatabaseInterfacePrivate::TrackBitRate).isNull()) { 7164 result[DataTypes::TrackDataType::key_type::BitRateRole] = trackRecord.value(DatabaseInterfacePrivate::TrackBitRate); 7165 } 7166 if (!trackRecord.value(DatabaseInterfacePrivate::TrackSamplerate).isNull()) { 7167 result[DataTypes::TrackDataType::key_type::SampleRateRole] = trackRecord.value(DatabaseInterfacePrivate::TrackSamplerate); 7168 } 7169 result[DataTypes::TrackDataType::key_type::HasEmbeddedCover] = trackRecord.value(DatabaseInterfacePrivate::TrackHasEmbeddedCover); 7170 result[DataTypes::TrackDataType::key_type::FileModificationTime] = trackRecord.value(DatabaseInterfacePrivate::TrackFileModifiedTime); 7171 if (!trackRecord.value(DatabaseInterfacePrivate::TrackFirstPlayDate).isNull()) { 7172 result[DataTypes::TrackDataType::key_type::FirstPlayDate] = trackRecord.value(DatabaseInterfacePrivate::TrackFirstPlayDate); 7173 } 7174 if (!trackRecord.value(DatabaseInterfacePrivate::TrackLastPlayDate).isNull()) { 7175 result[DataTypes::TrackDataType::key_type::LastPlayDate] = trackRecord.value(DatabaseInterfacePrivate::TrackLastPlayDate); 7176 } 7177 result[DataTypes::TrackDataType::key_type::PlayCounter] = trackRecord.value(DatabaseInterfacePrivate::TrackPlayCounter); 7178 result[DataTypes::TrackDataType::key_type::ElementTypeRole] = QVariant::fromValue(ElisaUtils::Track); 7179 7180 // TODO: port Artist, Composer, Genre, Lyricist to use association tables 7181 if (!trackRecord.value(DatabaseInterfacePrivate::TrackArtistName).isNull()) { 7182 result[DataTypes::TrackDataType::key_type::ArtistRole] = trackRecord.value(DatabaseInterfacePrivate::TrackArtistName); 7183 } 7184 if (!trackRecord.value(DatabaseInterfacePrivate::TrackGenreName).isNull()) { 7185 result[DataTypes::TrackDataType::key_type::GenreRole] = trackRecord.value(DatabaseInterfacePrivate::TrackGenreName); 7186 } 7187 if (!trackRecord.value(DatabaseInterfacePrivate::TrackComposerName).isNull()) { 7188 result[DataTypes::TrackDataType::key_type::ComposerRole] = trackRecord.value(DatabaseInterfacePrivate::TrackComposerName); 7189 } 7190 if (!trackRecord.value(DatabaseInterfacePrivate::TrackLyricistName).isNull()) { 7191 result[DataTypes::TrackDataType::key_type::LyricistRole] = trackRecord.value(DatabaseInterfacePrivate::TrackLyricistName); 7192 } 7193 7194 return result; 7195 } 7196 7197 DataTypes::TrackDataType DatabaseInterface::buildRadioDataFromDatabaseRecord(const QSqlRecord &trackRecord) const 7198 { 7199 DataTypes::TrackDataType result; 7200 7201 result[DataTypes::TrackDataType::key_type::DatabaseIdRole] = trackRecord.value(DatabaseInterfacePrivate::RadioId); 7202 result[DataTypes::TrackDataType::key_type::TitleRole] = trackRecord.value(DatabaseInterfacePrivate::RadioTitle); 7203 result[DataTypes::TrackDataType::key_type::AlbumRole] = i18nc("@item:intable", "Radio Stations"); 7204 result[DataTypes::TrackDataType::key_type::ResourceRole] = trackRecord.value(DatabaseInterfacePrivate::RadioHttpAddress); 7205 result[DataTypes::TrackDataType::key_type::ImageUrlRole] = trackRecord.value(DatabaseInterfacePrivate::RadioImageAddress); 7206 result[DataTypes::TrackDataType::key_type::RatingRole] = trackRecord.value(DatabaseInterfacePrivate::RadioRating); 7207 if (!trackRecord.value(DatabaseInterfacePrivate::RadioGenreName).isNull()) { 7208 result[DataTypes::TrackDataType::key_type::GenreRole] = trackRecord.value(DatabaseInterfacePrivate::RadioGenreName); 7209 } 7210 result[DataTypes::TrackDataType::key_type::CommentRole] = trackRecord.value(DatabaseInterfacePrivate::RadioComment); 7211 result[DataTypes::TrackDataType::key_type::ElementTypeRole] = ElisaUtils::Radio; 7212 7213 return result; 7214 } 7215 7216 void DatabaseInterface::internalRemoveTracksList(const QList<QUrl> &removedTracks) 7217 { 7218 QSet<qulonglong> modifiedAlbums; 7219 7220 QUrl::FormattingOptions currentOptions = QUrl::PreferLocalFile | 7221 QUrl::RemoveAuthority | QUrl::RemoveFilename | QUrl::RemoveFragment | 7222 QUrl::RemovePassword | QUrl::RemovePort | QUrl::RemoveQuery | 7223 QUrl::RemoveScheme | QUrl::RemoveUserInfo; 7224 7225 for (const auto &removedTrackFileName : removedTracks) { 7226 auto removedTrackId = internalTrackIdFromFileName(removedTrackFileName); 7227 7228 Q_EMIT trackRemoved(removedTrackId); 7229 7230 auto oneRemovedTrack = internalTrackFromDatabaseId(removedTrackId); 7231 7232 removeTrackInDatabase(removedTrackId); 7233 7234 const auto &trackPath = oneRemovedTrack.resourceURI().toString(currentOptions); 7235 const auto &modifiedAlbumId = internalAlbumIdFromTitleAndArtist(oneRemovedTrack.album(), oneRemovedTrack.albumArtist(), trackPath); 7236 const auto &allTracksFromArtist = internalTracksFromAuthor(oneRemovedTrack.artist()); 7237 const auto &allAlbumsFromArtist = internalAlbumIdsFromAuthor(oneRemovedTrack.artist()); 7238 const auto &removedArtistId = internalArtistIdFromName(oneRemovedTrack.artist()); 7239 7240 if (modifiedAlbumId) { 7241 recordModifiedAlbum(modifiedAlbumId); 7242 modifiedAlbums.insert(modifiedAlbumId); 7243 } 7244 7245 if (removedArtistId != 0 && allTracksFromArtist.isEmpty() && allAlbumsFromArtist.isEmpty()) { 7246 removeArtistInDatabase(removedArtistId); 7247 Q_EMIT artistRemoved(removedArtistId); 7248 } 7249 7250 d->mRemoveTracksMapping.bindValue(QStringLiteral(":fileName"), removedTrackFileName.toString()); 7251 7252 auto result = execQuery(d->mRemoveTracksMapping); 7253 7254 if (!result || !d->mRemoveTracksMapping.isActive()) { 7255 Q_EMIT databaseError(); 7256 7257 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalRemoveTracksList" << d->mRemoveTracksMapping.lastQuery(); 7258 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalRemoveTracksList" << d->mRemoveTracksMapping.boundValues(); 7259 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalRemoveTracksList" << d->mRemoveTracksMapping.lastError(); 7260 7261 continue; 7262 } 7263 7264 d->mRemoveTracksMapping.finish(); 7265 } 7266 7267 for (auto modifiedAlbumId : modifiedAlbums) { 7268 const auto &modifiedAlbumData = internalOneAlbumPartialData(modifiedAlbumId); 7269 7270 auto tracksCount = fetchTrackIds(modifiedAlbumId).count(); 7271 7272 if (!modifiedAlbumData.isEmpty() && tracksCount) { 7273 auto modifiedAlbum = internalOneAlbumData(modifiedAlbumId); 7274 if (updateAlbumFromId(modifiedAlbumId, modifiedAlbum.at(0).albumCover(), modifiedAlbum.at(0), modifiedAlbum.at(0).resourceURI().toString(currentOptions))) { 7275 for (const auto &oneTrack : modifiedAlbum) { 7276 recordModifiedTrack(oneTrack.databaseId()); 7277 } 7278 } 7279 7280 Q_EMIT albumModified({{DataTypes::DatabaseIdRole, modifiedAlbumId}}, modifiedAlbumId); 7281 } else { 7282 removeAlbumInDatabase(modifiedAlbumId); 7283 Q_EMIT albumRemoved(modifiedAlbumId); 7284 7285 const auto &allTracksFromArtist = internalTracksFromAuthor(modifiedAlbumData[DataTypes::AlbumDataType::key_type::ArtistRole].toString()); 7286 const auto &allAlbumsFromArtist = internalAlbumIdsFromAuthor(modifiedAlbumData[DataTypes::AlbumDataType::key_type::ArtistRole].toString()); 7287 const auto &removedArtistId = internalArtistIdFromName(modifiedAlbumData[DataTypes::AlbumDataType::key_type::ArtistRole].toString()); 7288 7289 if (removedArtistId != 0 && allTracksFromArtist.isEmpty() && allAlbumsFromArtist.isEmpty()) { 7290 removeArtistInDatabase(removedArtistId); 7291 Q_EMIT artistRemoved(removedArtistId); 7292 } 7293 } 7294 } 7295 } 7296 7297 QUrl DatabaseInterface::internalAlbumArtUriFromAlbumId(qulonglong albumId) 7298 { 7299 auto result = QUrl(); 7300 7301 d->mSelectAlbumArtUriFromAlbumIdQuery.bindValue(QStringLiteral(":albumId"), albumId); 7302 7303 auto queryResult = execQuery(d->mSelectAlbumArtUriFromAlbumIdQuery); 7304 7305 if (!queryResult || !d->mSelectAlbumArtUriFromAlbumIdQuery.isSelect() || !d->mSelectAlbumArtUriFromAlbumIdQuery.isActive()) { 7306 Q_EMIT databaseError(); 7307 7308 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectAlbumArtUriFromAlbumIdQuery.lastQuery(); 7309 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectAlbumArtUriFromAlbumIdQuery.boundValues(); 7310 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectAlbumArtUriFromAlbumIdQuery.lastError(); 7311 7312 d->mSelectAlbumArtUriFromAlbumIdQuery.finish(); 7313 7314 return result; 7315 } 7316 7317 if (!d->mSelectAlbumArtUriFromAlbumIdQuery.next()) { 7318 d->mSelectAlbumArtUriFromAlbumIdQuery.finish(); 7319 7320 return result; 7321 } 7322 7323 result = d->mSelectAlbumArtUriFromAlbumIdQuery.record().value(0).toUrl(); 7324 7325 d->mSelectAlbumArtUriFromAlbumIdQuery.finish(); 7326 7327 return result; 7328 } 7329 7330 bool DatabaseInterface::isValidArtist(qulonglong albumId) 7331 { 7332 auto result = false; 7333 7334 d->mSelectAlbumQuery.bindValue(QStringLiteral(":albumId"), albumId); 7335 7336 auto queryResult = execQuery(d->mSelectAlbumQuery); 7337 7338 if (!queryResult || !d->mSelectAlbumQuery.isSelect() || !d->mSelectAlbumQuery.isActive()) { 7339 Q_EMIT databaseError(); 7340 7341 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumFromId" << d->mSelectAlbumQuery.lastQuery(); 7342 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumFromId" << d->mSelectAlbumQuery.boundValues(); 7343 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumFromId" << d->mSelectAlbumQuery.lastError(); 7344 7345 d->mSelectAlbumQuery.finish(); 7346 7347 return result; 7348 } 7349 7350 if (!d->mSelectAlbumQuery.next()) { 7351 d->mSelectAlbumQuery.finish(); 7352 7353 return result; 7354 } 7355 7356 const auto ¤tRecord = d->mSelectAlbumQuery.record(); 7357 7358 result = !currentRecord.value(2).toString().isEmpty(); 7359 7360 return result; 7361 } 7362 7363 bool DatabaseInterface::internalGenericPartialData(QSqlQuery &query) 7364 { 7365 auto result = false; 7366 7367 auto queryResult = execQuery(query); 7368 7369 if (!queryResult || !query.isSelect() || !query.isActive()) { 7370 Q_EMIT databaseError(); 7371 7372 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAllGenericPartialData" << query.lastQuery(); 7373 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAllGenericPartialData" << query.boundValues(); 7374 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAllGenericPartialData" << query.lastError(); 7375 7376 query.finish(); 7377 7378 auto transactionResult = finishTransaction(); 7379 if (!transactionResult) { 7380 return result; 7381 } 7382 7383 return result; 7384 } 7385 7386 result = true; 7387 7388 return result; 7389 } 7390 7391 qulonglong DatabaseInterface::insertLyricist(const QString &name) 7392 { 7393 auto result = qulonglong(0); 7394 7395 if (name.isEmpty()) { 7396 return result; 7397 } 7398 7399 d->mSelectLyricistByNameQuery.bindValue(QStringLiteral(":name"), name); 7400 7401 auto queryResult = execQuery(d->mSelectLyricistByNameQuery); 7402 7403 if (!queryResult || !d->mSelectLyricistByNameQuery.isSelect() || !d->mSelectLyricistByNameQuery.isActive()) { 7404 Q_EMIT databaseError(); 7405 7406 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mSelectLyricistByNameQuery.lastQuery(); 7407 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mSelectLyricistByNameQuery.boundValues(); 7408 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mSelectLyricistByNameQuery.lastError(); 7409 7410 d->mSelectLyricistByNameQuery.finish(); 7411 7412 return result; 7413 } 7414 7415 if (d->mSelectLyricistByNameQuery.next()) { 7416 result = d->mSelectLyricistByNameQuery.record().value(0).toULongLong(); 7417 7418 d->mSelectLyricistByNameQuery.finish(); 7419 7420 return result; 7421 } 7422 7423 d->mSelectLyricistByNameQuery.finish(); 7424 7425 d->mInsertLyricistQuery.bindValue(QStringLiteral(":lyricistId"), d->mLyricistId); 7426 d->mInsertLyricistQuery.bindValue(QStringLiteral(":name"), name); 7427 7428 queryResult = execQuery(d->mInsertLyricistQuery); 7429 7430 if (!queryResult || !d->mInsertLyricistQuery.isActive()) { 7431 Q_EMIT databaseError(); 7432 7433 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mInsertLyricistQuery.lastQuery(); 7434 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mInsertLyricistQuery.boundValues(); 7435 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertLyricist" << d->mInsertLyricistQuery.lastError(); 7436 7437 d->mInsertLyricistQuery.finish(); 7438 7439 return result; 7440 } 7441 7442 result = d->mLyricistId; 7443 7444 ++d->mLyricistId; 7445 7446 d->mInsertLyricistQuery.finish(); 7447 7448 Q_EMIT lyricistsAdded(internalAllLyricistsPartialData()); 7449 7450 return result; 7451 } 7452 7453 QHash<QUrl, QDateTime> DatabaseInterface::internalAllFileName() 7454 { 7455 auto allFileNames = QHash<QUrl, QDateTime>{}; 7456 7457 auto queryResult = execQuery(d->mSelectAllTrackFilesQuery); 7458 7459 if (!queryResult || !d->mSelectAllTrackFilesQuery.isSelect() || !d->mSelectAllTrackFilesQuery.isActive()) { 7460 Q_EMIT databaseError(); 7461 7462 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << d->mSelectAllTrackFilesQuery.lastQuery(); 7463 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << d->mSelectAllTrackFilesQuery.boundValues(); 7464 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << d->mSelectAllTrackFilesQuery.lastError(); 7465 7466 d->mSelectAllTrackFilesQuery.finish(); 7467 7468 return allFileNames; 7469 } 7470 7471 while(d->mSelectAllTrackFilesQuery.next()) { 7472 auto fileName = d->mSelectAllTrackFilesQuery.record().value(0).toUrl(); 7473 auto fileModificationTime = d->mSelectAllTrackFilesQuery.record().value(1).toDateTime(); 7474 7475 allFileNames[fileName] = fileModificationTime; 7476 } 7477 7478 d->mSelectAllTrackFilesQuery.finish(); 7479 7480 return allFileNames; 7481 } 7482 7483 qulonglong DatabaseInterface::internalArtistIdFromName(const QString &name) 7484 { 7485 auto result = qulonglong(0); 7486 7487 if (name.isEmpty()) { 7488 return result; 7489 } 7490 7491 d->mSelectArtistByNameQuery.bindValue(QStringLiteral(":name"), name); 7492 7493 auto queryResult = execQuery(d->mSelectArtistByNameQuery); 7494 7495 if (!queryResult || !d->mSelectArtistByNameQuery.isSelect() || !d->mSelectArtistByNameQuery.isActive()) { 7496 Q_EMIT databaseError(); 7497 7498 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.lastQuery(); 7499 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.boundValues(); 7500 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertArtist" << d->mSelectArtistByNameQuery.lastError(); 7501 7502 d->mSelectArtistByNameQuery.finish(); 7503 7504 return result; 7505 } 7506 7507 if (!d->mSelectArtistByNameQuery.next()) { 7508 d->mSelectArtistByNameQuery.finish(); 7509 7510 return result; 7511 } 7512 7513 result = d->mSelectArtistByNameQuery.record().value(0).toULongLong(); 7514 7515 d->mSelectArtistByNameQuery.finish(); 7516 7517 return result; 7518 } 7519 7520 void DatabaseInterface::removeTrackInDatabase(qulonglong trackId) 7521 { 7522 d->mRemoveTrackQuery.bindValue(QStringLiteral(":trackId"), trackId); 7523 7524 auto result = execQuery(d->mRemoveTrackQuery); 7525 7526 if (!result || !d->mRemoveTrackQuery.isActive()) { 7527 Q_EMIT databaseError(); 7528 7529 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeTrackInDatabase" << d->mRemoveTrackQuery.lastQuery(); 7530 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeTrackInDatabase" << d->mRemoveTrackQuery.boundValues(); 7531 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeTrackInDatabase" << d->mRemoveTrackQuery.lastError(); 7532 } 7533 7534 d->mRemoveTrackQuery.finish(); 7535 } 7536 7537 void DatabaseInterface::updateTrackInDatabase(const DataTypes::TrackDataType &oneTrack, const QString &albumPath) 7538 { 7539 d->mUpdateTrackQuery.bindValue(QStringLiteral(":fileName"), oneTrack.resourceURI()); 7540 d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackId"), oneTrack.databaseId()); 7541 d->mUpdateTrackQuery.bindValue(QStringLiteral(":title"), oneTrack.title()); 7542 7543 d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumTitle"), oneTrack.hasAlbum() ? oneTrack.album() : QVariant{}); 7544 7545 d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumArtistName"), oneTrack.hasAlbumArtist() ? oneTrack.albumArtist() : QVariant{}); 7546 7547 d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumPath"), albumPath); 7548 7549 d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackNumber"), oneTrack.hasTrackNumber() ? oneTrack.trackNumber() : QVariant{}); 7550 7551 d->mUpdateTrackQuery.bindValue(QStringLiteral(":discNumber"), oneTrack.hasDiscNumber() ? oneTrack.discNumber() : QVariant{}); 7552 7553 d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackDuration"), QVariant::fromValue<qlonglong>(oneTrack.duration().msecsSinceStartOfDay())); 7554 7555 d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackRating"), oneTrack.rating()); 7556 7557 d->mUpdateTrackQuery.bindValue(QStringLiteral(":comment"), oneTrack.hasComment() ? oneTrack.comment() : QVariant{}); 7558 7559 d->mUpdateTrackQuery.bindValue(QStringLiteral(":year"), oneTrack.hasYear() ? oneTrack.year() : QVariant{}); 7560 7561 d->mUpdateTrackQuery.bindValue(QStringLiteral(":channels"), oneTrack.hasChannels() ? oneTrack.channels() : QVariant{}); 7562 7563 d->mUpdateTrackQuery.bindValue(QStringLiteral(":bitRate"), oneTrack.hasBitRate() ? oneTrack.bitRate() : QVariant{}); 7564 7565 d->mUpdateTrackQuery.bindValue(QStringLiteral(":sampleRate"), oneTrack.hasSampleRate() ? oneTrack.sampleRate() : QVariant{}); 7566 7567 // TODO: port Artist, Composer, Genre, Lyricist to use association tables 7568 if (oneTrack.hasArtist()) { 7569 const auto oneArtist = insertArtist(oneTrack.artist()) != 0 ? oneTrack.artist() : QVariant{}; 7570 d->mUpdateTrackQuery.bindValue(QStringLiteral(":artistName"), oneArtist); 7571 } else { 7572 d->mUpdateTrackQuery.bindValue(QStringLiteral(":artistName"), {}); 7573 } 7574 7575 if (oneTrack.hasGenre()) { 7576 const auto oneGenre = insertGenre(oneTrack.genre()) != 0 ? oneTrack.genre() : QVariant{}; 7577 d->mUpdateTrackQuery.bindValue(QStringLiteral(":genre"), oneGenre); 7578 } else { 7579 d->mUpdateTrackQuery.bindValue(QStringLiteral(":genre"), {}); 7580 } 7581 7582 if (oneTrack.hasComposer()) { 7583 const auto oneComposer = insertComposer(oneTrack.composer()) != 0 ? oneTrack.composer() : QVariant{}; 7584 d->mUpdateTrackQuery.bindValue(QStringLiteral(":composer"), oneComposer); 7585 } else { 7586 d->mUpdateTrackQuery.bindValue(QStringLiteral(":composer"), {}); 7587 } 7588 7589 if (oneTrack.hasLyricist()) { 7590 const auto oneLyricist = insertComposer(oneTrack.lyricist()) != 0 ? oneTrack.lyricist() : QVariant{}; 7591 d->mUpdateTrackQuery.bindValue(QStringLiteral(":lyricist"), oneLyricist); 7592 } else { 7593 d->mUpdateTrackQuery.bindValue(QStringLiteral(":lyricist"), {}); 7594 } 7595 7596 auto result = execQuery(d->mUpdateTrackQuery); 7597 7598 if (!result || !d->mUpdateTrackQuery.isActive()) { 7599 Q_EMIT databaseError(); 7600 7601 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << d->mUpdateTrackQuery.lastQuery(); 7602 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << d->mUpdateTrackQuery.boundValues(); 7603 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << d->mUpdateTrackQuery.lastError(); 7604 } 7605 7606 d->mUpdateTrackQuery.finish(); 7607 } 7608 7609 void DatabaseInterface::removeRadio(qulonglong radioId) 7610 { 7611 QSqlQuery query = d->mDeleteRadioQuery; 7612 7613 query.bindValue(QStringLiteral(":radioId"), radioId); 7614 7615 auto result = execQuery(query); 7616 7617 if (!result || !query.isActive()) { 7618 Q_EMIT databaseError(); 7619 7620 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << query.lastQuery(); 7621 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << query.boundValues(); 7622 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackInDatabase" << query.lastError(); 7623 }else{ 7624 Q_EMIT radioRemoved(radioId); 7625 } 7626 7627 query.finish(); 7628 } 7629 7630 void DatabaseInterface::removeAlbumInDatabase(qulonglong albumId) 7631 { 7632 d->mRemoveAlbumQuery.bindValue(QStringLiteral(":albumId"), albumId); 7633 7634 auto result = execQuery(d->mRemoveAlbumQuery); 7635 7636 if (!result || !d->mRemoveAlbumQuery.isActive()) { 7637 Q_EMIT databaseError(); 7638 7639 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeAlbumInDatabase" << d->mRemoveAlbumQuery.lastQuery(); 7640 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeAlbumInDatabase" << d->mRemoveAlbumQuery.boundValues(); 7641 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeAlbumInDatabase" << d->mRemoveAlbumQuery.lastError(); 7642 } 7643 7644 d->mRemoveAlbumQuery.finish(); 7645 } 7646 7647 void DatabaseInterface::removeArtistInDatabase(qulonglong artistId) 7648 { 7649 d->mRemoveArtistQuery.bindValue(QStringLiteral(":artistId"), artistId); 7650 7651 auto result = execQuery(d->mRemoveArtistQuery); 7652 7653 if (!result || !d->mRemoveArtistQuery.isActive()) { 7654 Q_EMIT databaseError(); 7655 7656 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeArtistInDatabase" << d->mRemoveArtistQuery.lastQuery(); 7657 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeArtistInDatabase" << d->mRemoveArtistQuery.boundValues(); 7658 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::removeArtistInDatabase" << d->mRemoveArtistQuery.lastError(); 7659 } 7660 7661 d->mRemoveArtistQuery.finish(); 7662 } 7663 7664 void DatabaseInterface::reloadExistingDatabase() 7665 { 7666 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::reloadExistingDatabase"; 7667 7668 d->mArtistId = genericInitialId(d->mQueryMaximumArtistIdQuery); 7669 d->mComposerId = genericInitialId(d->mQueryMaximumComposerIdQuery); 7670 d->mLyricistId = genericInitialId(d->mQueryMaximumLyricistIdQuery); 7671 d->mAlbumId = genericInitialId(d->mQueryMaximumAlbumIdQuery); 7672 d->mTrackId = genericInitialId(d->mQueryMaximumTrackIdQuery); 7673 d->mGenreId = genericInitialId(d->mQueryMaximumGenreIdQuery); 7674 } 7675 7676 qulonglong DatabaseInterface::genericInitialId(QSqlQuery &request) 7677 { 7678 auto result = qulonglong(0); 7679 7680 auto transactionResult = startTransaction(); 7681 if (!transactionResult) { 7682 return result; 7683 } 7684 7685 auto queryResult = execQuery(request); 7686 7687 if (!queryResult || !request.isSelect() || !request.isActive()) { 7688 Q_EMIT databaseError(); 7689 7690 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << request.lastQuery(); 7691 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << request.boundValues(); 7692 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::insertMusicSource" << request.lastError(); 7693 7694 request.finish(); 7695 7696 transactionResult = finishTransaction(); 7697 if (!transactionResult) { 7698 return result; 7699 } 7700 7701 return result; 7702 } 7703 7704 if (request.next()) { 7705 result = request.record().value(0).toULongLong() + 1; 7706 7707 request.finish(); 7708 } 7709 7710 transactionResult = finishTransaction(); 7711 if (!transactionResult) { 7712 return result; 7713 } 7714 7715 return result; 7716 } 7717 7718 QList<qulonglong> DatabaseInterface::fetchTrackIds(qulonglong albumId) 7719 { 7720 auto allTracks = QList<qulonglong>(); 7721 7722 d->mSelectTrackIdQuery.bindValue(QStringLiteral(":albumId"), albumId); 7723 7724 auto result = execQuery(d->mSelectTrackIdQuery); 7725 7726 if (!result || !d->mSelectTrackIdQuery.isSelect() || !d->mSelectTrackIdQuery.isActive()) { 7727 Q_EMIT databaseError(); 7728 7729 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::fetchTrackIds" << d->mSelectTrackIdQuery.lastQuery(); 7730 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::fetchTrackIds" << d->mSelectTrackIdQuery.boundValues(); 7731 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::fetchTrackIds" << d->mSelectTrackIdQuery.lastError(); 7732 } 7733 7734 while (d->mSelectTrackIdQuery.next()) { 7735 const auto ¤tRecord = d->mSelectTrackIdQuery.record(); 7736 7737 allTracks.push_back(currentRecord.value(0).toULongLong()); 7738 } 7739 7740 d->mSelectTrackIdQuery.finish(); 7741 7742 return allTracks; 7743 } 7744 7745 qulonglong DatabaseInterface::internalAlbumIdFromTitleAndArtist(const QString &title, const QString &artist, const QString &albumPath) 7746 { 7747 auto result = qulonglong(0); 7748 7749 d->mSelectAlbumIdFromTitleQuery.bindValue(QStringLiteral(":title"), title); 7750 d->mSelectAlbumIdFromTitleQuery.bindValue(QStringLiteral(":artistName"), artist); 7751 7752 auto queryResult = execQuery(d->mSelectAlbumIdFromTitleQuery); 7753 7754 if (!queryResult || !d->mSelectAlbumIdFromTitleQuery.isSelect() || !d->mSelectAlbumIdFromTitleQuery.isActive()) { 7755 Q_EMIT databaseError(); 7756 7757 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleQuery.lastQuery(); 7758 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleQuery.boundValues(); 7759 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleQuery.lastError(); 7760 7761 d->mSelectAlbumIdFromTitleQuery.finish(); 7762 7763 return result; 7764 } 7765 7766 if (d->mSelectAlbumIdFromTitleQuery.next()) { 7767 result = d->mSelectAlbumIdFromTitleQuery.record().value(0).toULongLong(); 7768 } 7769 7770 d->mSelectAlbumIdFromTitleQuery.finish(); 7771 7772 if (result == 0) { 7773 d->mSelectAlbumIdFromTitleWithoutArtistQuery.bindValue(QStringLiteral(":title"), title); 7774 d->mSelectAlbumIdFromTitleWithoutArtistQuery.bindValue(QStringLiteral(":albumPath"), albumPath); 7775 7776 queryResult = execQuery(d->mSelectAlbumIdFromTitleWithoutArtistQuery); 7777 7778 if (!queryResult || !d->mSelectAlbumIdFromTitleWithoutArtistQuery.isSelect() || !d->mSelectAlbumIdFromTitleWithoutArtistQuery.isActive()) { 7779 Q_EMIT databaseError(); 7780 7781 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.lastQuery(); 7782 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.boundValues(); 7783 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalAlbumIdFromTitleAndArtist" << d->mSelectAlbumIdFromTitleWithoutArtistQuery.lastError(); 7784 7785 d->mSelectAlbumIdFromTitleWithoutArtistQuery.finish(); 7786 7787 return result; 7788 } 7789 7790 if (d->mSelectAlbumIdFromTitleWithoutArtistQuery.next()) { 7791 result = d->mSelectAlbumIdFromTitleWithoutArtistQuery.record().value(0).toULongLong(); 7792 } 7793 7794 d->mSelectAlbumIdFromTitleWithoutArtistQuery.finish(); 7795 } 7796 7797 return result; 7798 } 7799 7800 DataTypes::TrackDataType DatabaseInterface::internalTrackFromDatabaseId(qulonglong id) 7801 { 7802 auto result = DataTypes::TrackDataType(); 7803 7804 if (result.isValid()) { 7805 return result; 7806 } 7807 7808 if (!d || !d->mTracksDatabase.isValid() || !d->mInitFinished) { 7809 return result; 7810 } 7811 7812 d->mSelectTrackFromIdQuery.bindValue(QStringLiteral(":trackId"), id); 7813 7814 auto queryResult = execQuery(d->mSelectTrackFromIdQuery); 7815 7816 if (!queryResult || !d->mSelectTrackFromIdQuery.isSelect() || !d->mSelectTrackFromIdQuery.isActive()) { 7817 Q_EMIT databaseError(); 7818 7819 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackFromDatabaseId" << d->mSelectTrackFromIdQuery.lastQuery(); 7820 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackFromDatabaseId" << d->mSelectTrackFromIdQuery.boundValues(); 7821 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackFromDatabaseId" << d->mSelectTrackFromIdQuery.lastError(); 7822 7823 d->mSelectTrackFromIdQuery.finish(); 7824 7825 return result; 7826 } 7827 7828 if (!d->mSelectTrackFromIdQuery.next()) { 7829 d->mSelectTrackFromIdQuery.finish(); 7830 7831 return result; 7832 } 7833 7834 const auto ¤tRecord = d->mSelectTrackFromIdQuery.record(); 7835 7836 result = buildTrackDataFromDatabaseRecord(currentRecord); 7837 7838 d->mSelectTrackFromIdQuery.finish(); 7839 7840 return result; 7841 } 7842 7843 qulonglong DatabaseInterface::internalTrackIdFromTitleAlbumTracDiscNumber(const QString &title, const QString &artist, const std::optional<QString> &album, 7844 std::optional<int> trackNumber, std::optional<int> discNumber) 7845 { 7846 auto result = qulonglong(0); 7847 7848 if (!d) { 7849 return result; 7850 } 7851 7852 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":title"), title); 7853 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":artist"), artist); 7854 if (album.has_value()) { 7855 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":album"), album.value()); 7856 } else { 7857 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":album"), {}); 7858 } 7859 if (trackNumber.has_value()) { 7860 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":trackNumber"), trackNumber.value()); 7861 } else { 7862 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":trackNumber"), {}); 7863 } 7864 if (discNumber.has_value()) { 7865 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":discNumber"), discNumber.value()); 7866 } else { 7867 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":discNumber"), {}); 7868 } 7869 7870 auto queryResult = execQuery(d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery); 7871 7872 if (!queryResult || !d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.isSelect() || !d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.isActive()) { 7873 Q_EMIT databaseError(); 7874 7875 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.lastQuery(); 7876 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.boundValues(); 7877 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.lastError(); 7878 7879 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.finish(); 7880 7881 return result; 7882 } 7883 7884 if (d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.next()) { 7885 result = d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.record().value(0).toULongLong(); 7886 } 7887 7888 d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery.finish(); 7889 7890 return result; 7891 } 7892 7893 qulonglong DatabaseInterface::getDuplicateTrackIdFromTitleAlbumTrackDiscNumber(const QString &title, const QString &trackArtist, 7894 const QString &album, const QString &albumArtist, 7895 const QString &trackPath, int trackNumber, 7896 int discNumber, int priority) 7897 { 7898 auto result = qulonglong(0); 7899 7900 if (!d) { 7901 return result; 7902 } 7903 7904 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":title"), title); 7905 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":trackArtist"), trackArtist); 7906 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":album"), album); 7907 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":albumPath"), trackPath); 7908 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":albumArtist"), albumArtist); 7909 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":trackNumber"), trackNumber); 7910 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":discNumber"), discNumber); 7911 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":priority"), priority); 7912 7913 auto queryResult = execQuery(d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery); 7914 7915 if (!queryResult || !d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.isSelect() || !d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.isActive()) { 7916 Q_EMIT databaseError(); 7917 7918 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.lastQuery(); 7919 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.boundValues(); 7920 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::trackIdFromTitleAlbumArtist" << d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.lastError(); 7921 7922 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.finish(); 7923 7924 return result; 7925 } 7926 7927 if (d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.next()) { 7928 result = d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.record().value(0).toULongLong(); 7929 } 7930 7931 d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.finish(); 7932 7933 return result; 7934 } 7935 7936 qulonglong DatabaseInterface::internalTrackIdFromFileName(const QUrl &fileName) 7937 { 7938 auto result = qulonglong(0); 7939 7940 if (!d) { 7941 return result; 7942 } 7943 7944 d->mSelectTracksMapping.bindValue(QStringLiteral(":fileName"), fileName.toString()); 7945 7946 auto queryResult = execQuery(d->mSelectTracksMapping); 7947 7948 if (!queryResult || !d->mSelectTracksMapping.isSelect() || !d->mSelectTracksMapping.isActive()) { 7949 Q_EMIT databaseError(); 7950 7951 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectTracksMapping.lastQuery(); 7952 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectTracksMapping.boundValues(); 7953 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectTracksMapping.lastError(); 7954 7955 d->mSelectTracksMapping.finish(); 7956 7957 return result; 7958 } 7959 7960 if (d->mSelectTracksMapping.next()) { 7961 const auto ¤tRecordValue = d->mSelectTracksMapping.record().value(0); 7962 if (currentRecordValue.isValid()) { 7963 result = currentRecordValue.toULongLong(); 7964 } 7965 } 7966 7967 d->mSelectTracksMapping.finish(); 7968 7969 return result; 7970 } 7971 7972 qulonglong DatabaseInterface::internalRadioIdFromHttpAddress(const QString &httpAddress) 7973 { 7974 auto result = qulonglong(0); 7975 7976 if (!d) { 7977 return result; 7978 } 7979 7980 d->mSelectRadioIdFromHttpAddress.bindValue(QStringLiteral(":httpAddress"), httpAddress); 7981 7982 auto queryResult = execQuery(d->mSelectRadioIdFromHttpAddress); 7983 7984 if (!queryResult || !d->mSelectRadioIdFromHttpAddress.isSelect() || !d->mSelectRadioIdFromHttpAddress.isActive()) { 7985 Q_EMIT databaseError(); 7986 7987 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectRadioIdFromHttpAddress.lastQuery(); 7988 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectRadioIdFromHttpAddress.boundValues(); 7989 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalTrackIdFromFileName" << d->mSelectRadioIdFromHttpAddress.lastError(); 7990 7991 d->mSelectRadioIdFromHttpAddress.finish(); 7992 7993 return result; 7994 } 7995 7996 if (d->mSelectRadioIdFromHttpAddress.next()) { 7997 const auto ¤tRecordValue = d->mSelectRadioIdFromHttpAddress.record().value(0); 7998 if (currentRecordValue.isValid()) { 7999 result = currentRecordValue.toULongLong(); 8000 } 8001 } 8002 8003 d->mSelectRadioIdFromHttpAddress.finish(); 8004 8005 return result; 8006 } 8007 8008 DataTypes::ListTrackDataType DatabaseInterface::internalTracksFromAuthor(const QString &ArtistName) 8009 { 8010 auto allTracks = DataTypes::ListTrackDataType{}; 8011 8012 d->mSelectTracksFromArtist.bindValue(QStringLiteral(":artistName"), ArtistName); 8013 8014 auto result = execQuery(d->mSelectTracksFromArtist); 8015 8016 if (!result || !d->mSelectTracksFromArtist.isSelect() || !d->mSelectTracksFromArtist.isActive()) { 8017 Q_EMIT databaseError(); 8018 8019 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectTracksFromArtist.lastQuery(); 8020 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectTracksFromArtist.boundValues(); 8021 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectTracksFromArtist.lastError(); 8022 8023 return allTracks; 8024 } 8025 8026 while (d->mSelectTracksFromArtist.next()) { 8027 const auto ¤tRecord = d->mSelectTracksFromArtist.record(); 8028 8029 allTracks.push_back(buildTrackDataFromDatabaseRecord(currentRecord)); 8030 } 8031 8032 d->mSelectTracksFromArtist.finish(); 8033 8034 return allTracks; 8035 } 8036 8037 DataTypes::ListTrackDataType DatabaseInterface::internalTracksFromGenre(const QString &genre) 8038 { 8039 auto allTracks = DataTypes::ListTrackDataType{}; 8040 8041 d->mSelectTracksFromGenre.bindValue(QStringLiteral(":genre"), genre); 8042 8043 auto result = execQuery(d->mSelectTracksFromGenre); 8044 8045 if (!result || !d->mSelectTracksFromGenre.isSelect() || !d->mSelectTracksFromGenre.isActive()) { 8046 Q_EMIT databaseError(); 8047 8048 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromGenre" << d->mSelectTracksFromGenre.lastQuery(); 8049 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromGenre" << d->mSelectTracksFromGenre.boundValues(); 8050 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromGenre" << d->mSelectTracksFromGenre.lastError(); 8051 8052 return allTracks; 8053 } 8054 8055 while (d->mSelectTracksFromGenre.next()) { 8056 const auto ¤tRecord = d->mSelectTracksFromGenre.record(); 8057 8058 allTracks.push_back(buildTrackDataFromDatabaseRecord(currentRecord)); 8059 } 8060 8061 d->mSelectTracksFromGenre.finish(); 8062 8063 return allTracks; 8064 } 8065 8066 8067 QList<qulonglong> DatabaseInterface::internalAlbumIdsFromAuthor(const QString &ArtistName) 8068 { 8069 auto allAlbumIds = QList<qulonglong>(); 8070 8071 d->mSelectAlbumIdsFromArtist.bindValue(QStringLiteral(":artistName"), ArtistName); 8072 8073 auto result = execQuery(d->mSelectAlbumIdsFromArtist); 8074 8075 if (!result || !d->mSelectAlbumIdsFromArtist.isSelect() || !d->mSelectAlbumIdsFromArtist.isActive()) { 8076 Q_EMIT databaseError(); 8077 8078 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectAlbumIdsFromArtist.lastQuery(); 8079 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectAlbumIdsFromArtist.boundValues(); 8080 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::tracksFromAuthor" << d->mSelectAlbumIdsFromArtist.lastError(); 8081 8082 return allAlbumIds; 8083 } 8084 8085 while (d->mSelectAlbumIdsFromArtist.next()) { 8086 const auto ¤tRecord = d->mSelectAlbumIdsFromArtist.record(); 8087 8088 allAlbumIds.push_back(currentRecord.value(0).toULongLong()); 8089 } 8090 8091 d->mSelectAlbumIdsFromArtist.finish(); 8092 8093 return allAlbumIds; 8094 } 8095 8096 DataTypes::ListArtistDataType DatabaseInterface::internalAllArtistsPartialData(QSqlQuery &artistsQuery) 8097 { 8098 auto result = DataTypes::ListArtistDataType{}; 8099 8100 if (!internalGenericPartialData(artistsQuery)) { 8101 return result; 8102 } 8103 8104 while(artistsQuery.next()) { 8105 auto newData = DataTypes::ArtistDataType{}; 8106 8107 const auto ¤tRecord = artistsQuery.record(); 8108 8109 newData[DataTypes::DatabaseIdRole] = currentRecord.value(0); 8110 newData[DataTypes::TitleRole] = currentRecord.value(1); 8111 newData[DataTypes::GenreRole] = QVariant::fromValue(currentRecord.value(2).toString().split(QStringLiteral(", "))); 8112 8113 const auto covers = internalGetLatestFourCoversForArtist(currentRecord.value(1).toString()); 8114 newData[DataTypes::MultipleImageUrlsRole] = covers; 8115 newData[DataTypes::ImageUrlRole] = covers.value(0).toUrl(); 8116 8117 newData[DataTypes::ElementTypeRole] = ElisaUtils::Artist; 8118 8119 result.push_back(newData); 8120 } 8121 8122 artistsQuery.finish(); 8123 8124 return result; 8125 } 8126 8127 DataTypes::ListAlbumDataType DatabaseInterface::internalAllAlbumsPartialData(QSqlQuery &query) 8128 { 8129 auto result = DataTypes::ListAlbumDataType{}; 8130 8131 if (!internalGenericPartialData(query)) { 8132 return result; 8133 } 8134 8135 while(query.next()) { 8136 auto newData = DataTypes::AlbumDataType{}; 8137 8138 const auto ¤tRecord = query.record(); 8139 8140 newData[DataTypes::DatabaseIdRole] = currentRecord.value(DatabaseInterfacePrivate::AlbumsId); 8141 newData[DataTypes::TitleRole] = currentRecord.value(DatabaseInterfacePrivate::AlbumsTitle); 8142 if (!currentRecord.value(DatabaseInterfacePrivate::AlbumsCoverFileName).toString().isEmpty()) { 8143 newData[DataTypes::ImageUrlRole] = currentRecord.value(DatabaseInterfacePrivate::AlbumsCoverFileName); 8144 } else if (!currentRecord.value(DatabaseInterfacePrivate::AlbumsEmbeddedCover).toString().isEmpty()) { 8145 newData[DataTypes::ImageUrlRole] = QVariant{QLatin1String("image://cover/") + currentRecord.value(DatabaseInterfacePrivate::AlbumsEmbeddedCover).toUrl().toLocalFile()}; 8146 } 8147 auto allArtists = currentRecord.value(DatabaseInterfacePrivate::AlbumsAllArtists).toString().split(QStringLiteral(", ")); 8148 allArtists.removeDuplicates(); 8149 newData[DataTypes::AllArtistsRole] = QVariant::fromValue(allArtists); 8150 if (!currentRecord.value(DatabaseInterfacePrivate::AlbumsArtistName).isNull()) { 8151 newData[DataTypes::IsValidAlbumArtistRole] = true; 8152 newData[DataTypes::SecondaryTextRole] = currentRecord.value(DatabaseInterfacePrivate::AlbumsArtistName); 8153 } else { 8154 newData[DataTypes::IsValidAlbumArtistRole] = false; 8155 if (currentRecord.value(DatabaseInterfacePrivate::AlbumsArtistsCount).toInt() == 1) { 8156 newData[DataTypes::SecondaryTextRole] = allArtists.first(); 8157 } else if (currentRecord.value(DatabaseInterfacePrivate::AlbumsArtistsCount).toInt() > 1) { 8158 newData[DataTypes::SecondaryTextRole] = i18nc("@item:intable", "Various Artists"); 8159 } 8160 } 8161 newData[DataTypes::ArtistRole] = newData[DataTypes::SecondaryTextRole]; 8162 newData[DataTypes::HighestTrackRating] = currentRecord.value(DatabaseInterfacePrivate::AlbumsHighestRating); 8163 newData[DataTypes::IsSingleDiscAlbumRole] = currentRecord.value(DatabaseInterfacePrivate::AlbumsIsSingleDiscAlbum); 8164 newData[DataTypes::GenreRole] = QVariant::fromValue(currentRecord.value(DatabaseInterfacePrivate::AlbumsAllGenres).toString().split(QStringLiteral(", "))); 8165 auto allYears = currentRecord.value(DatabaseInterfacePrivate::AlbumsYear).toString().split(QStringLiteral(", ")); 8166 allYears.removeDuplicates(); 8167 if (allYears.size() == 1) { 8168 newData[DataTypes::YearRole] = allYears.at(0).toInt(); 8169 } else { 8170 newData[DataTypes::YearRole] = 0; 8171 } 8172 newData[DataTypes::ElementTypeRole] = ElisaUtils::Album; 8173 8174 result.push_back(newData); 8175 } 8176 8177 query.finish(); 8178 8179 return result; 8180 } 8181 8182 DataTypes::ListTrackDataType DatabaseInterface::internalOneAlbumData(qulonglong databaseId) 8183 { 8184 DataTypes::ListTrackDataType result; 8185 8186 d->mSelectTrackQuery.bindValue(QStringLiteral(":albumId"), databaseId); 8187 8188 auto queryResult = execQuery(d->mSelectTrackQuery); 8189 8190 if (!queryResult || !d->mSelectTrackQuery.isSelect() || !d->mSelectTrackQuery.isActive()) { 8191 Q_EMIT databaseError(); 8192 8193 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::albumData" << d->mSelectTrackQuery.lastQuery(); 8194 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::albumData" << d->mSelectTrackQuery.boundValues(); 8195 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::albumData" << d->mSelectTrackQuery.lastError(); 8196 } 8197 8198 while (d->mSelectTrackQuery.next()) { 8199 const auto ¤tRecord = d->mSelectTrackQuery.record(); 8200 8201 result.push_back(buildTrackDataFromDatabaseRecord(currentRecord)); 8202 } 8203 8204 d->mSelectTrackQuery.finish(); 8205 8206 return result; 8207 } 8208 8209 DataTypes::AlbumDataType DatabaseInterface::internalOneAlbumPartialData(qulonglong databaseId) 8210 { 8211 auto result = DataTypes::AlbumDataType{}; 8212 8213 d->mSelectAlbumQuery.bindValue(QStringLiteral(":albumId"), databaseId); 8214 8215 if (!internalGenericPartialData(d->mSelectAlbumQuery)) { 8216 return result; 8217 } 8218 8219 if (d->mSelectAlbumQuery.next()) { 8220 const auto ¤tRecord = d->mSelectAlbumQuery.record(); 8221 8222 result[DataTypes::DatabaseIdRole] = currentRecord.value(DatabaseInterfacePrivate::SingleAlbumId); 8223 result[DataTypes::TitleRole] = currentRecord.value(DatabaseInterfacePrivate::SingleAlbumTitle); 8224 if (!currentRecord.value(DatabaseInterfacePrivate::SingleAlbumCoverFileName).toString().isEmpty()) { 8225 result[DataTypes::ImageUrlRole] = currentRecord.value(DatabaseInterfacePrivate::SingleAlbumCoverFileName); 8226 } else if (!currentRecord.value(DatabaseInterfacePrivate::SingleAlbumEmbeddedCover).toString().isEmpty()) { 8227 result[DataTypes::ImageUrlRole] = QVariant{QLatin1String("image://cover/") + currentRecord.value(DatabaseInterfacePrivate::SingleAlbumEmbeddedCover).toUrl().toLocalFile()}; 8228 } 8229 8230 auto allArtists = currentRecord.value(DatabaseInterfacePrivate::SingleAlbumAllArtists).toString().split(QStringLiteral(", ")); 8231 allArtists.removeDuplicates(); 8232 result[DataTypes::AllArtistsRole] = QVariant::fromValue(allArtists); 8233 8234 if (!currentRecord.value(DatabaseInterfacePrivate::SingleAlbumArtistName).isNull()) { 8235 result[DataTypes::IsValidAlbumArtistRole] = true; 8236 result[DataTypes::SecondaryTextRole] = currentRecord.value(DatabaseInterfacePrivate::SingleAlbumArtistName); 8237 } else { 8238 result[DataTypes::IsValidAlbumArtistRole] = false; 8239 if (currentRecord.value(DatabaseInterfacePrivate::SingleAlbumArtistsCount).toInt() == 1) { 8240 result[DataTypes::SecondaryTextRole] = allArtists.first(); 8241 } else if (currentRecord.value(DatabaseInterfacePrivate::SingleAlbumArtistsCount).toInt() > 1) { 8242 result[DataTypes::SecondaryTextRole] = i18nc("@item:intable", "Various Artists"); 8243 } 8244 } 8245 result[DataTypes::ArtistRole] = result[DataTypes::SecondaryTextRole]; 8246 result[DataTypes::HighestTrackRating] = currentRecord.value(DatabaseInterfacePrivate::SingleAlbumHighestRating); 8247 result[DataTypes::IsSingleDiscAlbumRole] = currentRecord.value(DatabaseInterfacePrivate::SingleAlbumIsSingleDiscAlbum); 8248 result[DataTypes::GenreRole] = QVariant::fromValue(currentRecord.value(DatabaseInterfacePrivate::SingleAlbumAllGenres).toString().split(QStringLiteral(", "))); 8249 result[DataTypes::ElementTypeRole] = ElisaUtils::Album; 8250 8251 } 8252 8253 d->mSelectAlbumQuery.finish(); 8254 8255 return result; 8256 } 8257 8258 DataTypes::ArtistDataType DatabaseInterface::internalOneArtistPartialData(qulonglong databaseId) 8259 { 8260 auto result = DataTypes::ArtistDataType{}; 8261 8262 d->mSelectArtistQuery.bindValue(QStringLiteral(":artistId"), databaseId); 8263 8264 if (!internalGenericPartialData(d->mSelectArtistQuery)) { 8265 return result; 8266 } 8267 8268 if (d->mSelectArtistQuery.next()) { 8269 const auto ¤tRecord = d->mSelectArtistQuery.record(); 8270 8271 result[DataTypes::DatabaseIdRole] = currentRecord.value(0); 8272 result[DataTypes::TitleRole] = currentRecord.value(1); 8273 result[DataTypes::GenreRole] = QVariant::fromValue(currentRecord.value(2).toString().split(QStringLiteral(", "))); 8274 8275 const auto covers = internalGetLatestFourCoversForArtist(currentRecord.value(1).toString()); 8276 result[DataTypes::MultipleImageUrlsRole] = covers; 8277 result[DataTypes::ImageUrlRole] = covers.value(0).toUrl(); 8278 8279 result[DataTypes::ElementTypeRole] = ElisaUtils::Artist; 8280 } 8281 8282 d->mSelectArtistQuery.finish(); 8283 8284 return result; 8285 } 8286 8287 DataTypes::ListTrackDataType DatabaseInterface::internalAllTracksPartialData() 8288 { 8289 auto result = DataTypes::ListTrackDataType{}; 8290 8291 if (!internalGenericPartialData(d->mSelectAllTracksQuery)) { 8292 return result; 8293 } 8294 8295 while(d->mSelectAllTracksQuery.next()) { 8296 const auto ¤tRecord = d->mSelectAllTracksQuery.record(); 8297 8298 auto newData = buildTrackDataFromDatabaseRecord(currentRecord); 8299 8300 result.push_back(newData); 8301 } 8302 8303 d->mSelectAllTracksQuery.finish(); 8304 8305 return result; 8306 } 8307 8308 DataTypes::ListRadioDataType DatabaseInterface::internalAllRadiosPartialData() 8309 { 8310 auto result = DataTypes::ListRadioDataType{}; 8311 8312 if (!internalGenericPartialData(d->mSelectAllRadiosQuery)) { 8313 return result; 8314 } 8315 8316 while(d->mSelectAllRadiosQuery.next()) { 8317 const auto ¤tRecord = d->mSelectAllRadiosQuery.record(); 8318 8319 auto newData = buildRadioDataFromDatabaseRecord(currentRecord); 8320 8321 result.push_back(newData); 8322 } 8323 8324 d->mSelectAllRadiosQuery.finish(); 8325 8326 return result; 8327 } 8328 8329 DataTypes::ListTrackDataType DatabaseInterface::internalRecentlyPlayedTracksData(int count) 8330 { 8331 auto result = DataTypes::ListTrackDataType{}; 8332 8333 d->mSelectAllRecentlyPlayedTracksQuery.bindValue(QStringLiteral(":maximumResults"), count); 8334 8335 if (!internalGenericPartialData(d->mSelectAllRecentlyPlayedTracksQuery)) { 8336 return result; 8337 } 8338 8339 while(d->mSelectAllRecentlyPlayedTracksQuery.next()) { 8340 const auto ¤tRecord = d->mSelectAllRecentlyPlayedTracksQuery.record(); 8341 8342 auto newData = buildTrackDataFromDatabaseRecord(currentRecord); 8343 8344 result.push_back(newData); 8345 } 8346 8347 d->mSelectAllRecentlyPlayedTracksQuery.finish(); 8348 8349 return result; 8350 } 8351 8352 DataTypes::ListTrackDataType DatabaseInterface::internalFrequentlyPlayedTracksData(int count) 8353 { 8354 auto result = DataTypes::ListTrackDataType{}; 8355 8356 d->mSelectAllFrequentlyPlayedTracksQuery.bindValue(QStringLiteral(":maximumResults"), count); 8357 8358 if (!internalGenericPartialData(d->mSelectAllFrequentlyPlayedTracksQuery)) { 8359 return result; 8360 } 8361 8362 while(d->mSelectAllFrequentlyPlayedTracksQuery.next()) { 8363 const auto ¤tRecord = d->mSelectAllFrequentlyPlayedTracksQuery.record(); 8364 8365 auto newData = buildTrackDataFromDatabaseRecord(currentRecord); 8366 8367 result.push_back(newData); 8368 } 8369 8370 d->mSelectAllFrequentlyPlayedTracksQuery.finish(); 8371 8372 return result; 8373 } 8374 8375 DataTypes::TrackDataType DatabaseInterface::internalOneTrackPartialData(qulonglong databaseId) 8376 { 8377 auto result = DataTypes::TrackDataType{}; 8378 8379 d->mSelectTrackFromIdQuery.bindValue(QStringLiteral(":trackId"), databaseId); 8380 8381 if (!internalGenericPartialData(d->mSelectTrackFromIdQuery)) { 8382 return result; 8383 } 8384 8385 if (d->mSelectTrackFromIdQuery.next()) { 8386 const auto ¤tRecord = d->mSelectTrackFromIdQuery.record(); 8387 8388 result = buildTrackDataFromDatabaseRecord(currentRecord); 8389 } 8390 8391 d->mSelectTrackFromIdQuery.finish(); 8392 8393 return result; 8394 } 8395 8396 DataTypes::TrackDataType DatabaseInterface::internalOneTrackPartialDataByIdAndUrl(qulonglong databaseId, const QUrl &trackUrl) 8397 { 8398 auto result = DataTypes::TrackDataType{}; 8399 8400 d->mSelectTrackFromIdAndUrlQuery.bindValue(QStringLiteral(":trackId"), databaseId); 8401 d->mSelectTrackFromIdAndUrlQuery.bindValue(QStringLiteral(":trackUrl"), trackUrl); 8402 8403 if (!internalGenericPartialData(d->mSelectTrackFromIdAndUrlQuery)) { 8404 return result; 8405 } 8406 8407 if (d->mSelectTrackFromIdAndUrlQuery.next()) { 8408 const auto ¤tRecord = d->mSelectTrackFromIdAndUrlQuery.record(); 8409 8410 result = buildTrackDataFromDatabaseRecord(currentRecord); 8411 } 8412 8413 d->mSelectTrackFromIdAndUrlQuery.finish(); 8414 8415 return result; 8416 } 8417 8418 DataTypes::TrackDataType DatabaseInterface::internalOneRadioPartialData(qulonglong databaseId) 8419 { 8420 auto result = DataTypes::TrackDataType{}; 8421 8422 d->mSelectRadioFromIdQuery.bindValue(QStringLiteral(":radioId"), databaseId); 8423 8424 if (!internalGenericPartialData(d->mSelectRadioFromIdQuery)) { 8425 return result; 8426 } 8427 8428 if (d->mSelectRadioFromIdQuery.next()) { 8429 const auto ¤tRecord = d->mSelectRadioFromIdQuery.record(); 8430 8431 result = buildRadioDataFromDatabaseRecord(currentRecord); 8432 } 8433 8434 d->mSelectRadioFromIdQuery.finish(); 8435 8436 return result; 8437 } 8438 8439 DataTypes::ListGenreDataType DatabaseInterface::internalAllGenresPartialData() 8440 { 8441 DataTypes::ListGenreDataType result; 8442 8443 if (!internalGenericPartialData(d->mSelectAllGenresQuery)) { 8444 return result; 8445 } 8446 8447 while(d->mSelectAllGenresQuery.next()) { 8448 auto newData = DataTypes::GenreDataType{}; 8449 8450 const auto ¤tRecord = d->mSelectAllGenresQuery.record(); 8451 8452 newData[DataTypes::DatabaseIdRole] = currentRecord.value(0); 8453 newData[DataTypes::TitleRole] = currentRecord.value(1); 8454 newData[DataTypes::ElementTypeRole] = ElisaUtils::Genre; 8455 8456 result.push_back(newData); 8457 } 8458 8459 d->mSelectAllGenresQuery.finish(); 8460 8461 return result; 8462 } 8463 8464 DataTypes::ListArtistDataType DatabaseInterface::internalAllComposersPartialData() 8465 { 8466 DataTypes::ListArtistDataType result; 8467 8468 if (!internalGenericPartialData(d->mSelectAllComposersQuery)) { 8469 return result; 8470 } 8471 8472 while(d->mSelectAllComposersQuery.next()) { 8473 auto newData = DataTypes::ArtistDataType{}; 8474 8475 const auto ¤tRecord = d->mSelectAllComposersQuery.record(); 8476 8477 newData[DataTypes::DatabaseIdRole] = currentRecord.value(0); 8478 newData[DataTypes::TitleRole] = currentRecord.value(1); 8479 newData[DataTypes::ElementTypeRole] = ElisaUtils::Composer; 8480 8481 result.push_back(newData); 8482 } 8483 8484 d->mSelectAllComposersQuery.finish(); 8485 8486 return result; 8487 } 8488 8489 DataTypes::ListArtistDataType DatabaseInterface::internalAllLyricistsPartialData() 8490 { 8491 DataTypes::ListArtistDataType result; 8492 8493 if (!internalGenericPartialData(d->mSelectAllLyricistsQuery)) { 8494 return result; 8495 } 8496 8497 while(d->mSelectAllLyricistsQuery.next()) { 8498 auto newData = DataTypes::ArtistDataType{}; 8499 8500 const auto ¤tRecord = d->mSelectAllLyricistsQuery.record(); 8501 8502 newData[DataTypes::DatabaseIdRole] = currentRecord.value(0); 8503 newData[DataTypes::TitleRole] = currentRecord.value(1); 8504 newData[DataTypes::ElementTypeRole] = ElisaUtils::Lyricist; 8505 8506 result.push_back(newData); 8507 } 8508 8509 d->mSelectAllLyricistsQuery.finish(); 8510 8511 return result; 8512 } 8513 8514 void DatabaseInterface::updateAlbumArtist(qulonglong albumId, const QString &title, 8515 const QString &albumPath, 8516 const QString &artistName) 8517 { 8518 d->mUpdateAlbumArtistQuery.bindValue(QStringLiteral(":albumId"), albumId); 8519 insertArtist(artistName); 8520 d->mUpdateAlbumArtistQuery.bindValue(QStringLiteral(":artistName"), artistName); 8521 8522 auto queryResult = execQuery(d->mUpdateAlbumArtistQuery); 8523 8524 if (!queryResult || !d->mUpdateAlbumArtistQuery.isActive()) { 8525 Q_EMIT databaseError(); 8526 8527 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistQuery.lastQuery(); 8528 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistQuery.boundValues(); 8529 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistQuery.lastError(); 8530 8531 d->mUpdateAlbumArtistQuery.finish(); 8532 8533 return; 8534 } 8535 8536 d->mUpdateAlbumArtistQuery.finish(); 8537 8538 d->mUpdateAlbumArtistInTracksQuery.bindValue(QStringLiteral(":albumTitle"), title); 8539 d->mUpdateAlbumArtistInTracksQuery.bindValue(QStringLiteral(":albumPath"), albumPath); 8540 d->mUpdateAlbumArtistInTracksQuery.bindValue(QStringLiteral(":artistName"), artistName); 8541 8542 queryResult = execQuery(d->mUpdateAlbumArtistInTracksQuery); 8543 8544 if (!queryResult || !d->mUpdateAlbumArtistInTracksQuery.isActive()) { 8545 Q_EMIT databaseError(); 8546 8547 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistInTracksQuery.lastQuery(); 8548 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistInTracksQuery.boundValues(); 8549 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistInTracksQuery.lastError(); 8550 8551 d->mUpdateAlbumArtistInTracksQuery.finish(); 8552 8553 return; 8554 } 8555 8556 d->mUpdateAlbumArtistInTracksQuery.finish(); 8557 } 8558 8559 bool DatabaseInterface::updateAlbumCover(qulonglong albumId, const QUrl &albumArtUri) 8560 { 8561 bool modifiedAlbum = false; 8562 8563 auto storedAlbumArtUri = internalAlbumArtUriFromAlbumId(albumId); 8564 8565 if (albumArtUri.isValid() && (!storedAlbumArtUri.isValid() || storedAlbumArtUri != albumArtUri)) { 8566 d->mUpdateAlbumArtUriFromAlbumIdQuery.bindValue(QStringLiteral(":albumId"), albumId); 8567 d->mUpdateAlbumArtUriFromAlbumIdQuery.bindValue(QStringLiteral(":coverFileName"), albumArtUri); 8568 8569 auto result = execQuery(d->mUpdateAlbumArtUriFromAlbumIdQuery); 8570 8571 if (!result || !d->mUpdateAlbumArtUriFromAlbumIdQuery.isActive()) { 8572 Q_EMIT databaseError(); 8573 8574 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumCover" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastQuery(); 8575 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumCover" << d->mUpdateAlbumArtUriFromAlbumIdQuery.boundValues(); 8576 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateAlbumCover" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastError(); 8577 8578 d->mUpdateAlbumArtUriFromAlbumIdQuery.finish(); 8579 8580 return modifiedAlbum; 8581 } 8582 8583 d->mUpdateAlbumArtUriFromAlbumIdQuery.finish(); 8584 8585 modifiedAlbum = true; 8586 } 8587 8588 return modifiedAlbum; 8589 } 8590 8591 QVariantList DatabaseInterface::internalGetLatestFourCoversForArtist(const QString& artistName) { 8592 auto covers = QList<QVariant>{}; 8593 8594 d->mSelectUpToFourLatestCoversFromArtistNameQuery.bindValue(QStringLiteral(":artistName"), artistName); 8595 8596 auto queryResult = execQuery(d->mSelectUpToFourLatestCoversFromArtistNameQuery); 8597 8598 if (!queryResult || !d->mSelectUpToFourLatestCoversFromArtistNameQuery.isSelect() || !d->mSelectUpToFourLatestCoversFromArtistNameQuery.isActive()) { 8599 Q_EMIT databaseError(); 8600 8601 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalGetLatestFourCoversForArtist" << d->mSelectUpToFourLatestCoversFromArtistNameQuery.lastQuery(); 8602 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalGetLatestFourCoversForArtist" << d->mSelectUpToFourLatestCoversFromArtistNameQuery.boundValues(); 8603 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::internalGetLatestFourCoversForArtist" << d->mSelectUpToFourLatestCoversFromArtistNameQuery.lastError(); 8604 8605 d->mSelectUpToFourLatestCoversFromArtistNameQuery.finish(); 8606 8607 return covers; 8608 } 8609 8610 while (d->mSelectUpToFourLatestCoversFromArtistNameQuery.next()) { 8611 const auto& cover = d->mSelectUpToFourLatestCoversFromArtistNameQuery.record().value(0).toUrl(); 8612 const auto& isTrackCover = d->mSelectUpToFourLatestCoversFromArtistNameQuery.record().value(1).toBool(); 8613 if (isTrackCover) { 8614 covers.push_back(QVariant {QLatin1String {"image://cover/"} + cover.toLocalFile()}.toUrl()); 8615 } else { 8616 covers.push_back(cover); 8617 } 8618 } 8619 8620 d->mSelectUpToFourLatestCoversFromArtistNameQuery.finish(); 8621 8622 return covers; 8623 } 8624 8625 void DatabaseInterface::updateTrackStartedStatistics(const QUrl &fileName, const QDateTime &time) 8626 { 8627 d->mUpdateTrackStartedStatistics.bindValue(QStringLiteral(":fileName"), fileName); 8628 d->mUpdateTrackStartedStatistics.bindValue(QStringLiteral(":playDate"), time.toMSecsSinceEpoch()); 8629 8630 auto queryResult = execQuery(d->mUpdateTrackStartedStatistics); 8631 8632 if (!queryResult || !d->mUpdateTrackStartedStatistics.isActive()) { 8633 Q_EMIT databaseError(); 8634 8635 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackStartedStatistics" << d->mUpdateTrackStartedStatistics.lastQuery(); 8636 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackStartedStatistics" << d->mUpdateTrackStartedStatistics.boundValues(); 8637 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackStartedStatistics" << d->mUpdateTrackStartedStatistics.lastError(); 8638 8639 d->mUpdateTrackStartedStatistics.finish(); 8640 8641 return; 8642 } 8643 8644 d->mUpdateTrackStartedStatistics.finish(); 8645 } 8646 8647 void DatabaseInterface::updateTrackFinishedStatistics(const QUrl &fileName, const QDateTime &time) 8648 { 8649 d->mUpdateTrackFinishedStatistics.bindValue(QStringLiteral(":fileName"), fileName); 8650 d->mUpdateTrackFinishedStatistics.bindValue(QStringLiteral(":playDate"), time.toMSecsSinceEpoch()); 8651 8652 auto queryResult = execQuery(d->mUpdateTrackFinishedStatistics); 8653 8654 if (!queryResult || !d->mUpdateTrackFinishedStatistics.isActive()) { 8655 Q_EMIT databaseError(); 8656 8657 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackFinishedStatistics" << d->mUpdateTrackFinishedStatistics.lastQuery(); 8658 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackFinishedStatistics" << d->mUpdateTrackFinishedStatistics.boundValues(); 8659 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackFinishedStatistics" << d->mUpdateTrackFinishedStatistics.lastError(); 8660 8661 d->mUpdateTrackFinishedStatistics.finish(); 8662 8663 return; 8664 } 8665 8666 d->mUpdateTrackFinishedStatistics.finish(); 8667 8668 d->mUpdateTrackFirstPlayStatistics.bindValue(QStringLiteral(":fileName"), fileName); 8669 d->mUpdateTrackFirstPlayStatistics.bindValue(QStringLiteral(":playDate"), time.toMSecsSinceEpoch()); 8670 8671 queryResult = execQuery(d->mUpdateTrackFirstPlayStatistics); 8672 8673 if (!queryResult || !d->mUpdateTrackFirstPlayStatistics.isActive()) { 8674 Q_EMIT databaseError(); 8675 8676 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackFinishedStatistics" << d->mUpdateTrackFirstPlayStatistics.lastQuery(); 8677 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackFinishedStatistics" << d->mUpdateTrackFirstPlayStatistics.boundValues(); 8678 qCDebug(orgKdeElisaDatabase) << "DatabaseInterface::updateTrackFinishedStatistics" << d->mUpdateTrackFirstPlayStatistics.lastError(); 8679 8680 d->mUpdateTrackFirstPlayStatistics.finish(); 8681 8682 return; 8683 } 8684 8685 d->mUpdateTrackFirstPlayStatistics.finish(); 8686 } 8687 8688 #include "moc_databaseinterface.cpp"