File indexing completed on 2024-04-28 08:41:06

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 &currentRecord = 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 &currentTrack, 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecordValue = 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 &currentRecordValue = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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 &currentRecord = 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"