diff --git a/autotests/allalbumsmodeltest.cpp b/autotests/allalbumsmodeltest.cpp --- a/autotests/allalbumsmodeltest.cpp +++ b/autotests/allalbumsmodeltest.cpp @@ -58,7 +58,7 @@ { DatabaseInterface musicDb; AllAlbumsModel albumsModel; - QAbstractItemModelTester testModel(&albumsModel, Qt::BlockingQueuedConnection); + QAbstractItemModelTester testModel(&albumsModel); connect(&musicDb, &DatabaseInterface::albumsAdded, &albumsModel, &AllAlbumsModel::albumsAdded); @@ -83,16 +83,9 @@ musicDb.insertTracksList(mNewTracks, mNewCovers, QStringLiteral("autoTest")); - while(beginInsertRowsSpy.count() < 5) { - QCOMPARE(beginInsertRowsSpy.wait(500), true); - } - while(endInsertRowsSpy.count() < 5) { - QCOMPARE(endInsertRowsSpy.wait(500), true); - } - QCOMPARE(albumsModel.rowCount(), 5); - QCOMPARE(beginInsertRowsSpy.count(), 5); - QCOMPARE(endInsertRowsSpy.count(), 5); + QCOMPARE(beginInsertRowsSpy.count(), 1); + QCOMPARE(endInsertRowsSpy.count(), 1); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); @@ -105,11 +98,9 @@ musicDb.removeTracksList({firstTrack.resourceURI()}); - QCOMPARE(dataChangedSpy.wait(500), true); - QCOMPARE(albumsModel.rowCount(), 5); - QCOMPARE(beginInsertRowsSpy.count(), 5); - QCOMPARE(endInsertRowsSpy.count(), 5); + QCOMPARE(beginInsertRowsSpy.count(), 1); + QCOMPARE(endInsertRowsSpy.count(), 1); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 1); @@ -119,7 +110,7 @@ { DatabaseInterface musicDb; AllAlbumsModel albumsModel; - QAbstractItemModelTester testModel(&albumsModel, Qt::BlockingQueuedConnection); + QAbstractItemModelTester testModel(&albumsModel); connect(&musicDb, &DatabaseInterface::albumsAdded, &albumsModel, &AllAlbumsModel::albumsAdded); @@ -145,16 +136,9 @@ musicDb.insertTracksList(mNewTracks, mNewCovers, QStringLiteral("autoTest")); - while(beginInsertRowsSpy.count() < 5) { - QCOMPARE(beginInsertRowsSpy.wait(500), true); - } - while(endInsertRowsSpy.count() < 5) { - QCOMPARE(endInsertRowsSpy.wait(500), true); - } - QCOMPARE(albumsModel.rowCount(), 5); - QCOMPARE(beginInsertRowsSpy.count(), 5); - QCOMPARE(endInsertRowsSpy.count(), 5); + QCOMPARE(beginInsertRowsSpy.count(), 1); + QCOMPARE(endInsertRowsSpy.count(), 1); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); @@ -171,16 +155,9 @@ musicDb.removeTracksList({firstTrack.resourceURI(), secondTrack.resourceURI(), thirdTrack.resourceURI()}); - while (beginRemoveRowsSpy.count() < 1) { - QCOMPARE(beginRemoveRowsSpy.wait(500), true); - } - while (endRemoveRowsSpy.count() < 1) { - QCOMPARE(endRemoveRowsSpy.wait(500), true); - } - QCOMPARE(albumsModel.rowCount(), 4); - QCOMPARE(beginInsertRowsSpy.count(), 5); - QCOMPARE(endInsertRowsSpy.count(), 5); + QCOMPARE(beginInsertRowsSpy.count(), 1); + QCOMPARE(endInsertRowsSpy.count(), 1); QCOMPARE(beginRemoveRowsSpy.count(), 1); QCOMPARE(endRemoveRowsSpy.count(), 1); QCOMPARE(dataChangedSpy.count(), 0); @@ -190,7 +167,7 @@ { DatabaseInterface musicDb; AllAlbumsModel albumsModel; - QAbstractItemModelTester testModel(&albumsModel, Qt::BlockingQueuedConnection); + QAbstractItemModelTester testModel(&albumsModel); connect(&musicDb, &DatabaseInterface::albumsAdded, &albumsModel, &AllAlbumsModel::albumsAdded); @@ -215,15 +192,8 @@ musicDb.insertTracksList(mNewTracks, mNewCovers, QStringLiteral("autoTest")); - while(beginInsertRowsSpy.count() < 5) { - QCOMPARE(beginInsertRowsSpy.wait(500), true); - } - while(endInsertRowsSpy.count() < 5) { - QCOMPARE(endInsertRowsSpy.wait(500), true); - } - - QCOMPARE(beginInsertRowsSpy.count(), 5); - QCOMPARE(endInsertRowsSpy.count(), 5); + QCOMPARE(beginInsertRowsSpy.count(), 1); + QCOMPARE(endInsertRowsSpy.count(), 1); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); @@ -239,12 +209,8 @@ musicDb.insertTracksList(newTracks, mNewCovers, QStringLiteral("autoTest")); - while(dataChangedSpy.count() < 1) { - QCOMPARE(dataChangedSpy.wait(500), true); - } - - QCOMPARE(beginInsertRowsSpy.count(), 5); - QCOMPARE(endInsertRowsSpy.count(), 5); + QCOMPARE(beginInsertRowsSpy.count(), 1); + QCOMPARE(endInsertRowsSpy.count(), 1); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 1); @@ -254,7 +220,7 @@ { DatabaseInterface musicDb; AllAlbumsModel albumsModel; - QAbstractItemModelTester testModel(&albumsModel, Qt::BlockingQueuedConnection); + QAbstractItemModelTester testModel(&albumsModel); connect(&musicDb, &DatabaseInterface::albumsAdded, &albumsModel, &AllAlbumsModel::albumsAdded); @@ -285,48 +251,29 @@ musicDb.insertTracksList(mNewTracks, mNewCovers, QStringLiteral("autoTest")); - while(beginInsertRowsSpy.count() < 5) { - QCOMPARE(beginInsertRowsSpy.wait(500), true); - } - while(endInsertRowsSpy.count() < 5) { - QCOMPARE(endInsertRowsSpy.wait(500), true); - } - - QCOMPARE(beginInsertRowsSpy.count(), 5); - QCOMPARE(endInsertRowsSpy.count(), 5); + QCOMPARE(beginInsertRowsSpy.count(), 1); + QCOMPARE(endInsertRowsSpy.count(), 1); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); - auto newTrack = MusicAudioTrack{true, QStringLiteral("$19"), QStringLiteral("0"), QStringLiteral("track1"), + auto newTrack = MusicAudioTrack{true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track1"), QStringLiteral("artist2"), QStringLiteral("album5"), QStringLiteral("artist2"), 1, 1, - QTime::fromMSecsSinceStartOfDay(19), {QUrl::fromLocalFile(QStringLiteral("/$19"))}, - QDateTime::fromMSecsSinceEpoch(19), - {QUrl::fromLocalFile(QStringLiteral("file://image$19"))}, 5, true, + QTime::fromMSecsSinceStartOfDay(23), {QUrl::fromLocalFile(QStringLiteral("/$23"))}, + QDateTime::fromMSecsSinceEpoch(23), + {QUrl::fromLocalFile(QStringLiteral("file://image$23"))}, 5, true, {}, QStringLiteral("composer1"), QStringLiteral("lyricist1")}; auto newTracks = QList(); newTracks.push_back(newTrack); auto newCover = QUrl::fromLocalFile(QStringLiteral("album5")); auto newCovers = QHash(); newCovers[QStringLiteral("album5")] = newCover; - auto newFiles2 = QList(); - for (const auto &oneTrack : newTracks) { - newFiles2.push_back(oneTrack.resourceURI()); - } - musicDb.insertTracksList(newTracks, newCovers, QStringLiteral("autoTest")); - while(beginInsertRowsSpy.count() < 6) { - QCOMPARE(beginInsertRowsSpy.wait(500), true); - } - while(endInsertRowsSpy.count() < 6) { - QCOMPARE(endInsertRowsSpy.wait(500), true); - } - - QCOMPARE(beginInsertRowsSpy.count(), 6); - QCOMPARE(endInsertRowsSpy.count(), 6); + QCOMPARE(beginInsertRowsSpy.count(), 2); + QCOMPARE(endInsertRowsSpy.count(), 2); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); QCOMPARE(dataChangedSpy.count(), 0); diff --git a/autotests/alltracksmodeltest.cpp b/autotests/alltracksmodeltest.cpp --- a/autotests/alltracksmodeltest.cpp +++ b/autotests/alltracksmodeltest.cpp @@ -217,7 +217,7 @@ QCOMPARE(endInsertRowsSpy.count(), 2); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); + QCOMPARE(dataChangedSpy.count(), 5); QCOMPARE(tracksModel.rowCount(), 23); } @@ -289,53 +289,11 @@ QCOMPARE(endInsertRowsSpy.count(), 2); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); + QCOMPARE(dataChangedSpy.count(), 5); QCOMPARE(tracksModel.rowCount(), 23); } - void addDuplicateTracks() - { - AllTracksModel tracksModel; - QAbstractItemModelTester testModel(&tracksModel); - - auto newTracks = QList(); - newTracks.push_back({true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track23"), - QStringLiteral("artist2"), QStringLiteral("album4"), QStringLiteral("artist2"), 23, 1, QTime::fromMSecsSinceStartOfDay(23), - {QUrl::fromLocalFile(QStringLiteral("/$23"))}, - QDateTime::fromMSecsSinceEpoch(23), - {QUrl::fromLocalFile(QStringLiteral("file://image$23"))}, 5, true, - {}, QStringLiteral("composer1"), QStringLiteral("lyricist1")}); - newTracks.push_back({true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track23"), - QStringLiteral("artist2"), QStringLiteral("album4"), QStringLiteral("artist2"), 23, 1, QTime::fromMSecsSinceStartOfDay(23), - {QUrl::fromLocalFile(QStringLiteral("/$23"))}, - QDateTime::fromMSecsSinceEpoch(23), - {QUrl::fromLocalFile(QStringLiteral("file://image$23"))}, 5, true, - {}, QStringLiteral("composer1"), QStringLiteral("lyricist1")}); - - QSignalSpy beginInsertRowsSpy(&tracksModel, &AllTracksModel::rowsAboutToBeInserted); - QSignalSpy endInsertRowsSpy(&tracksModel, &AllTracksModel::rowsInserted); - QSignalSpy beginRemoveRowsSpy(&tracksModel, &AllTracksModel::rowsAboutToBeRemoved); - QSignalSpy endRemoveRowsSpy(&tracksModel, &AllTracksModel::rowsRemoved); - QSignalSpy dataChangedSpy(&tracksModel, &AllTracksModel::dataChanged); - - QCOMPARE(beginInsertRowsSpy.count(), 0); - QCOMPARE(endInsertRowsSpy.count(), 0); - QCOMPARE(beginRemoveRowsSpy.count(), 0); - QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); - - tracksModel.tracksAdded(newTracks); - - QCOMPARE(beginInsertRowsSpy.count(), 1); - QCOMPARE(endInsertRowsSpy.count(), 1); - QCOMPARE(beginRemoveRowsSpy.count(), 0); - QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); - - QCOMPARE(tracksModel.rowCount(), 1); - } - void modifyOneTrack() { DatabaseInterface musicDb; @@ -485,7 +443,7 @@ QCOMPARE(endInsertRowsSpy.count(), 2); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); + QCOMPARE(dataChangedSpy.count(), 5); QCOMPARE(tracksModel.rowCount(), 23); } diff --git a/autotests/alltracksproxymodeltest.cpp b/autotests/alltracksproxymodeltest.cpp --- a/autotests/alltracksproxymodeltest.cpp +++ b/autotests/alltracksproxymodeltest.cpp @@ -227,7 +227,7 @@ QCOMPARE(endInsertRowsSpy.count(), 2); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); + QCOMPARE(dataChangedSpy.count(), 5); QCOMPARE(proxyTracksModel.rowCount(), 23); } @@ -302,56 +302,11 @@ QCOMPARE(endInsertRowsSpy.count(), 2); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); + QCOMPARE(dataChangedSpy.count(), 5); QCOMPARE(proxyTracksModel.rowCount(), 23); } - void addDuplicateTracks() - { - AllTracksModel tracksModel; - QAbstractItemModelTester testModel(&tracksModel); - AllTracksProxyModel proxyTracksModel; - QAbstractItemModelTester proxyTestModel(&proxyTracksModel); - proxyTracksModel.setSourceModel(&tracksModel); - - auto newTracks = QList(); - newTracks.push_back({true, QStringLiteral("$19"), QStringLiteral("0"), QStringLiteral("track6"), - QStringLiteral("artist2"), QStringLiteral("album4"), QStringLiteral("artist2"), 6, 1, - QTime::fromMSecsSinceStartOfDay(19), {QUrl::fromLocalFile(QStringLiteral("/$19"))}, - QDateTime::fromMSecsSinceEpoch(19), - {QUrl::fromLocalFile(QStringLiteral("file://image$19"))}, 5, true, - {}, QStringLiteral("composer1"), QStringLiteral("lyricist1")}); - newTracks.push_back({true, QStringLiteral("$19"), QStringLiteral("0"), QStringLiteral("track6"), - QStringLiteral("artist2"), QStringLiteral("album4"), QStringLiteral("artist2"), 6, 1, - QTime::fromMSecsSinceStartOfDay(19), {QUrl::fromLocalFile(QStringLiteral("/$19"))}, - QDateTime::fromMSecsSinceEpoch(19), - {QUrl::fromLocalFile(QStringLiteral("file://image$19"))}, 5, true, - {}, QStringLiteral("composer1"), QStringLiteral("lyricist1")}); - - QSignalSpy beginInsertRowsSpy(&proxyTracksModel, &AllTracksModel::rowsAboutToBeInserted); - QSignalSpy endInsertRowsSpy(&proxyTracksModel, &AllTracksModel::rowsInserted); - QSignalSpy beginRemoveRowsSpy(&proxyTracksModel, &AllTracksModel::rowsAboutToBeRemoved); - QSignalSpy endRemoveRowsSpy(&proxyTracksModel, &AllTracksModel::rowsRemoved); - QSignalSpy dataChangedSpy(&proxyTracksModel, &AllTracksModel::dataChanged); - - QCOMPARE(beginInsertRowsSpy.count(), 0); - QCOMPARE(endInsertRowsSpy.count(), 0); - QCOMPARE(beginRemoveRowsSpy.count(), 0); - QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); - - tracksModel.tracksAdded(newTracks); - - QCOMPARE(beginInsertRowsSpy.count(), 1); - QCOMPARE(endInsertRowsSpy.count(), 1); - QCOMPARE(beginRemoveRowsSpy.count(), 0); - QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); - - QCOMPARE(proxyTracksModel.rowCount(), 1); - } - void modifyOneTrack() { DatabaseInterface musicDb; @@ -508,7 +463,7 @@ QCOMPARE(endInsertRowsSpy.count(), 2); QCOMPARE(beginRemoveRowsSpy.count(), 0); QCOMPARE(endRemoveRowsSpy.count(), 0); - QCOMPARE(dataChangedSpy.count(), 0); + QCOMPARE(dataChangedSpy.count(), 5); QCOMPARE(proxyTracksModel.rowCount(), 23); } diff --git a/autotests/databaseinterfacetest.cpp b/autotests/databaseinterfacetest.cpp --- a/autotests/databaseinterfacetest.cpp +++ b/autotests/databaseinterfacetest.cpp @@ -55,6 +55,7 @@ qRegisterMetaType>("QVector"); qRegisterMetaType>("QHash"); qRegisterMetaType("MusicArtist"); + qRegisterMetaType>("QHash"); } void avoidCrashInTrackIdFromTitleAlbumArtist() @@ -77,9 +78,14 @@ void addOneTrackWithoutAlbumArtist() { + QTemporaryFile databaseFile; + databaseFile.open(); + + qDebug() << "addOneTrackWithoutAlbumArtist" << databaseFile.fileName(); + DatabaseInterface musicDb; - musicDb.init(QStringLiteral("testDb")); + musicDb.init(QStringLiteral("testDb"), databaseFile.fileName()); QSignalSpy musicDbArtistAddedSpy(&musicDb, &DatabaseInterface::artistsAdded); QSignalSpy musicDbAlbumAddedSpy(&musicDb, &DatabaseInterface::albumsAdded); @@ -254,7 +260,7 @@ QCOMPARE(musicDbAlbumAddedSpy.count(), 0); QCOMPARE(musicDbTrackAddedSpy.count(), 1); QCOMPARE(musicDbArtistRemovedSpy.count(), 1); - QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); + QCOMPARE(musicDbAlbumRemovedSpy.count(), 1); QCOMPARE(musicDbTrackRemovedSpy.count(), 1); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); @@ -403,11 +409,11 @@ musicDbTrackAddedSpy.wait(300); - QCOMPARE(musicDb.allAlbums().count(), 0); + QCOMPARE(musicDb.allAlbums().count(), 1); QCOMPARE(musicDb.allArtists().count(), 0); QCOMPARE(musicDb.allTracks().count(), 1); QCOMPARE(musicDbArtistAddedSpy.count(), 0); - QCOMPARE(musicDbAlbumAddedSpy.count(), 0); + QCOMPARE(musicDbAlbumAddedSpy.count(), 1); QCOMPARE(musicDbTrackAddedSpy.count(), 1); QCOMPARE(musicDbArtistRemovedSpy.count(), 0); QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); @@ -422,10 +428,10 @@ QCOMPARE(track.isValid(), true); QCOMPARE(track.title(), QStringLiteral("track11")); QCOMPARE(track.artist(), QString()); - QCOMPARE(track.albumName(), QString()); + QCOMPARE(track.albumName(), QStringLiteral("album4")); QCOMPARE(track.albumArtist(), QString()); QCOMPARE(track.isValidAlbumArtist(), false); - QCOMPARE(track.albumCover(), QUrl()); + QCOMPARE(track.albumCover(), QUrl::fromLocalFile(QStringLiteral("album4"))); QCOMPARE(track.trackNumber(), 9); QCOMPARE(track.discNumber(), 1); QCOMPARE(track.duration(), QTime::fromMSecsSinceStartOfDay(26)); @@ -437,15 +443,123 @@ musicDb.removeTracksList({track.resourceURI()}); + QCOMPARE(musicDb.allAlbums().count(), 0); + QCOMPARE(musicDb.allArtists().count(), 0); + QCOMPARE(musicDb.allTracks().count(), 0); + QCOMPARE(musicDbArtistAddedSpy.count(), 0); + QCOMPARE(musicDbAlbumAddedSpy.count(), 1); + QCOMPARE(musicDbTrackAddedSpy.count(), 1); + QCOMPARE(musicDbArtistRemovedSpy.count(), 0); + QCOMPARE(musicDbAlbumRemovedSpy.count(), 1); + QCOMPARE(musicDbTrackRemovedSpy.count(), 1); + QCOMPARE(musicDbArtistModifiedSpy.count(), 0); + QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); + } + + void addOneTrackWithoutAlbumArtistAndAnotherTrackWith() + { + DatabaseInterface musicDb; + + musicDb.init(QStringLiteral("testDb")); + + QSignalSpy musicDbArtistAddedSpy(&musicDb, &DatabaseInterface::artistsAdded); + QSignalSpy musicDbAlbumAddedSpy(&musicDb, &DatabaseInterface::albumsAdded); + QSignalSpy musicDbTrackAddedSpy(&musicDb, &DatabaseInterface::tracksAdded); + QSignalSpy musicDbArtistRemovedSpy(&musicDb, &DatabaseInterface::artistRemoved); + QSignalSpy musicDbAlbumRemovedSpy(&musicDb, &DatabaseInterface::albumRemoved); + QSignalSpy musicDbTrackRemovedSpy(&musicDb, &DatabaseInterface::trackRemoved); + QSignalSpy musicDbArtistModifiedSpy(&musicDb, &DatabaseInterface::artistModified); + QSignalSpy musicDbAlbumModifiedSpy(&musicDb, &DatabaseInterface::albumModified); + QSignalSpy musicDbTrackModifiedSpy(&musicDb, &DatabaseInterface::trackModified); + QSignalSpy musicDbDatabaseErrorSpy(&musicDb, &DatabaseInterface::databaseError); + QCOMPARE(musicDb.allAlbums().count(), 0); QCOMPARE(musicDb.allArtists().count(), 0); QCOMPARE(musicDb.allTracks().count(), 0); QCOMPARE(musicDbArtistAddedSpy.count(), 0); QCOMPARE(musicDbAlbumAddedSpy.count(), 0); + QCOMPARE(musicDbTrackAddedSpy.count(), 0); + QCOMPARE(musicDbArtistRemovedSpy.count(), 0); + QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); + QCOMPARE(musicDbTrackRemovedSpy.count(), 0); + QCOMPARE(musicDbArtistModifiedSpy.count(), 0); + QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); + + auto newTrack = MusicAudioTrack {true, QStringLiteral("$26"), QStringLiteral("0"), QStringLiteral("track11"), + {}, QStringLiteral("album4"), {}, + 9, 1, QTime::fromMSecsSinceStartOfDay(26), {QUrl::fromLocalFile(QStringLiteral("/$26"))}, QDateTime::fromMSecsSinceEpoch(26), + QUrl::fromLocalFile(QStringLiteral("file://image$26")), 9, true, + QStringLiteral("genre1"), QStringLiteral("composer1"), QStringLiteral("lyricist1")}; + auto newTracks = QList(); + newTracks.push_back(newTrack); + + auto newCovers = mNewCovers; + newCovers[QStringLiteral("file:///$26")] = QUrl::fromLocalFile(QStringLiteral("album4")); + + musicDb.insertTracksList(newTracks, newCovers, QStringLiteral("autoTest")); + + musicDbTrackAddedSpy.wait(300); + + QCOMPARE(musicDb.allAlbums().count(), 1); + QCOMPARE(musicDb.allArtists().count(), 0); + QCOMPARE(musicDb.allTracks().count(), 1); + QCOMPARE(musicDbArtistAddedSpy.count(), 0); + QCOMPARE(musicDbAlbumAddedSpy.count(), 1); QCOMPARE(musicDbTrackAddedSpy.count(), 1); QCOMPARE(musicDbArtistRemovedSpy.count(), 0); QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); - QCOMPARE(musicDbTrackRemovedSpy.count(), 1); + QCOMPARE(musicDbTrackRemovedSpy.count(), 0); + QCOMPARE(musicDbArtistModifiedSpy.count(), 0); + QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); + + auto track = musicDb.trackFromDatabaseId(musicDb.trackIdFromFileName(QUrl::fromLocalFile(QStringLiteral("/$26")))); + + QCOMPARE(track.isValid(), true); + QCOMPARE(track.title(), QStringLiteral("track11")); + QCOMPARE(track.artist(), QString()); + QCOMPARE(track.albumName(), QStringLiteral("album4")); + QCOMPARE(track.albumArtist(), QString()); + QCOMPARE(track.isValidAlbumArtist(), false); + QCOMPARE(track.albumCover(), QUrl::fromLocalFile(QStringLiteral("album4"))); + QCOMPARE(track.trackNumber(), 9); + QCOMPARE(track.discNumber(), 1); + QCOMPARE(track.duration(), QTime::fromMSecsSinceStartOfDay(26)); + QCOMPARE(track.resourceURI(), QUrl::fromLocalFile(QStringLiteral("/$26"))); + QCOMPARE(track.rating(), 9); + QCOMPARE(track.genre(), QStringLiteral("genre1")); + QCOMPARE(track.composer(), QStringLiteral("composer1")); + QCOMPARE(track.lyricist(), QStringLiteral("lyricist1")); + + newTrack = MusicAudioTrack {true, QStringLiteral("$27"), QStringLiteral("0"), QStringLiteral("track12"), + QStringLiteral("artist1"), QStringLiteral("album4"), QStringLiteral("artist2"), + 10, 1, QTime::fromMSecsSinceStartOfDay(27), {QUrl::fromLocalFile(QStringLiteral("/autre/$27"))}, QDateTime::fromMSecsSinceEpoch(27), + QUrl::fromLocalFile(QStringLiteral("file://image$27")), 10, true, + QStringLiteral("genre1"), QStringLiteral("composer1"), QStringLiteral("lyricist1")}; + newTracks = QList(); + newTracks.push_back(newTrack); + + newCovers = mNewCovers; + newCovers[QStringLiteral("file:///autre/$27")] = QUrl::fromLocalFile(QStringLiteral("album4")); + + musicDb.insertTracksList(newTracks, newCovers, QStringLiteral("autoTest")); + + musicDbTrackAddedSpy.wait(300); + + QCOMPARE(musicDb.allAlbums().count(), 2); + QCOMPARE(musicDb.allArtists().count(), 2); + QCOMPARE(musicDb.allTracks().count(), 2); + QCOMPARE(musicDbArtistAddedSpy.count(), 1); + QCOMPARE(musicDbAlbumAddedSpy.count(), 2); + QCOMPARE(musicDbTrackAddedSpy.count(), 2); + QCOMPARE(musicDbArtistRemovedSpy.count(), 0); + QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); + QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); QCOMPARE(musicDbTrackModifiedSpy.count(), 0); @@ -543,7 +657,7 @@ QCOMPARE(firstTrack.genre(), QStringLiteral("genre1")); QCOMPARE(firstTrack.composer(), QStringLiteral("composer1")); QCOMPARE(firstTrack.lyricist(), QStringLiteral("lyricist1")); - QCOMPARE(firstTrack.albumId(), qulonglong(2)); + QCOMPARE(firstTrack.albumId(), qulonglong(1)); auto secondTrack = musicDb.trackFromDatabaseId(musicDb.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track7"), QStringLiteral("artist3"), QStringLiteral("album3"), 7, 1)); @@ -563,7 +677,7 @@ QCOMPARE(secondTrack.genre(), QStringLiteral("genre1")); QCOMPARE(secondTrack.composer(), QStringLiteral("composer1")); QCOMPARE(secondTrack.lyricist(), QStringLiteral("lyricist1")); - QCOMPARE(secondTrack.albumId(), qulonglong(2)); + QCOMPARE(secondTrack.albumId(), qulonglong(1)); auto album = musicDb.albumFromTitleAndArtist(QStringLiteral("album3"), QStringLiteral("artist2")); @@ -795,7 +909,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 1); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto firstTrack = musicDb.trackFromDatabaseId(musicDb.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track6"), QStringLiteral("artist2"), @@ -817,7 +931,7 @@ QCOMPARE(firstTrack.composer(), QStringLiteral("composer1")); QCOMPARE(firstTrack.lyricist(), QStringLiteral("lyricist1")); QCOMPARE(firstTrack.isSingleDiscAlbum(), true); - QCOMPARE(firstTrack.albumId(), qulonglong(2)); + QCOMPARE(firstTrack.albumId(), qulonglong(1)); auto secondTrack = musicDb.trackFromDatabaseId(musicDb.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track7"), QStringLiteral("artist3"), QStringLiteral("album3"), 7, 1)); @@ -838,7 +952,7 @@ QCOMPARE(secondTrack.composer(), QStringLiteral("composer1")); QCOMPARE(secondTrack.lyricist(), QStringLiteral("lyricist1")); QCOMPARE(secondTrack.isSingleDiscAlbum(), true); - QCOMPARE(secondTrack.albumId(), qulonglong(2)); + QCOMPARE(secondTrack.albumId(), qulonglong(1)); auto album = musicDb.albumFromTitleAndArtist(QStringLiteral("album3"), QStringLiteral("artist4")); @@ -1012,7 +1126,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto firstAlbum = musicDb.albumFromTitleAndArtist(QStringLiteral("album1"), QStringLiteral("Various Artists")); @@ -1031,7 +1145,7 @@ QCOMPARE(fourthAlbum.tracksCount(), 4); - auto oneTrack = fourthAlbum.trackFromIndex(3); + const auto &oneTrack = fourthAlbum.trackFromIndex(3); QCOMPARE(oneTrack.isValid(), true); QCOMPARE(oneTrack.rating(), 5); @@ -1130,7 +1244,7 @@ QCOMPARE(fourthAlbum.tracksCount(), 4); - auto oneTrack = fourthAlbum.trackFromIndex(3); + const auto &oneTrack = fourthAlbum.trackFromIndex(3); QCOMPARE(oneTrack.isValid(), true); QCOMPARE(oneTrack.title(), QStringLiteral("track6")); @@ -1187,7 +1301,7 @@ auto firstTrackMilliSecondsDuration = firstTrack.duration().msecsSinceStartOfDay(); auto firstTrackTrackNumber = firstTrack.trackNumber(); auto firstTrackDiscNumber = firstTrack.discNumber(); - auto firstTrackResource = firstTrack.resourceURI(); + const auto &firstTrackResource = firstTrack.resourceURI(); auto firstTrackRating = firstTrack.rating(); auto firstIsSingleDiscAlbum = firstTrack.isSingleDiscAlbum(); @@ -1275,7 +1389,7 @@ auto firstTrackMilliSecondsDuration = firstTrack.duration().msecsSinceStartOfDay(); auto firstTrackTrackNumber = firstTrack.trackNumber(); auto firstTrackDiscNumber = firstTrack.discNumber(); - auto firstTrackResource = firstTrack.resourceURI(); + const auto &firstTrackResource = firstTrack.resourceURI(); auto firstTrackRating = firstTrack.rating(); auto firstIsSingleDiscAlbum = firstTrack.isSingleDiscAlbum(); @@ -1308,7 +1422,7 @@ auto secondTrackMilliSecondsDuration = secondTrack.duration().msecsSinceStartOfDay(); auto secondTrackTrackNumber = secondTrack.trackNumber(); auto secondTrackDiscNumber = secondTrack.discNumber(); - auto secondTrackResource = secondTrack.resourceURI(); + const auto &secondTrackResource = secondTrack.resourceURI(); auto secondTrackRating = secondTrack.rating(); auto secondIsSingleDiscAlbum = secondTrack.isSingleDiscAlbum(); @@ -1341,7 +1455,7 @@ auto thirdTrackMilliSecondsDuration = thirdTrack.duration().msecsSinceStartOfDay(); auto thirdTrackTrackNumber = thirdTrack.trackNumber(); auto thirdTrackDiscNumber = thirdTrack.discNumber(); - auto thirdTrackResource = thirdTrack.resourceURI(); + const auto &thirdTrackResource = thirdTrack.resourceURI(); auto thirdTrackRating = thirdTrack.rating(); auto thirdIsSingleDiscAlbum = thirdTrack.isSingleDiscAlbum(); @@ -1374,7 +1488,7 @@ auto fourthTrackMilliSecondsDuration = fourthTrack.duration().msecsSinceStartOfDay(); auto fourthTrackTrackNumber = fourthTrack.trackNumber(); auto fourthTrackDiscNumber = fourthTrack.discNumber(); - auto fourthTrackResource = fourthTrack.resourceURI(); + const auto &fourthTrackResource = fourthTrack.resourceURI(); auto fourthTrackRating = thirdTrack.rating(); auto fourthIsSingleDiscAlbum = fourthTrack.isSingleDiscAlbum(); @@ -1530,7 +1644,7 @@ auto firstTrackMilliSecondsDuration = firstTrack.duration().msecsSinceStartOfDay(); auto firstTrackTrackNumber = firstTrack.trackNumber(); auto firstTrackDiscNumber = firstTrack.discNumber(); - auto firstTrackResource = firstTrack.resourceURI(); + const auto &firstTrackResource = firstTrack.resourceURI(); auto firstTrackRating = firstTrack.rating(); auto firstIsSingleDiscAlbum = firstTrack.isSingleDiscAlbum(); @@ -1563,7 +1677,7 @@ auto secondTrackMilliSecondsDuration = secondTrack.duration().msecsSinceStartOfDay(); auto secondTrackTrackNumber = secondTrack.trackNumber(); auto secondTrackDiscNumber = secondTrack.discNumber(); - auto secondTrackResource = secondTrack.resourceURI(); + const auto &secondTrackResource = secondTrack.resourceURI(); auto secondTrackRating = secondTrack.rating(); auto secondIsSingleDiscAlbum = secondTrack.isSingleDiscAlbum(); @@ -1596,7 +1710,7 @@ auto thirdTrackMilliSecondsDuration = thirdTrack.duration().msecsSinceStartOfDay(); auto thirdTrackTrackNumber = thirdTrack.trackNumber(); auto thirdTrackDiscNumber = thirdTrack.discNumber(); - auto thirdTrackResource = thirdTrack.resourceURI(); + const auto &thirdTrackResource = thirdTrack.resourceURI(); auto thirdTrackRating = thirdTrack.rating(); auto thirdIsSingleDiscAlbum = thirdTrack.isSingleDiscAlbum(); @@ -1629,7 +1743,7 @@ auto fourthTrackMilliSecondsDuration = fourthTrack.duration().msecsSinceStartOfDay(); auto fourthTrackTrackNumber = fourthTrack.trackNumber(); auto fourthTrackDiscNumber = fourthTrack.discNumber(); - auto fourthTrackResource = fourthTrack.resourceURI(); + const auto &fourthTrackResource = fourthTrack.resourceURI(); auto fourthTrackRating = thirdTrack.rating(); auto fourthIsSingleDiscAlbum = fourthTrack.isSingleDiscAlbum(); @@ -1727,7 +1841,7 @@ auto firstTrackMilliSecondsDuration = firstTrack.duration().msecsSinceStartOfDay(); auto firstTrackTrackNumber = firstTrack.trackNumber(); auto firstTrackDiscNumber = firstTrack.discNumber(); - auto firstTrackResource = firstTrack.resourceURI(); + const auto &firstTrackResource = firstTrack.resourceURI(); auto firstTrackRating = firstTrack.rating(); auto firstIsSingleDiscAlbum = firstTrack.isSingleDiscAlbum(); @@ -1760,7 +1874,7 @@ auto secondTrackMilliSecondsDuration = secondTrack.duration().msecsSinceStartOfDay(); auto secondTrackTrackNumber = secondTrack.trackNumber(); auto secondTrackDiscNumber = secondTrack.discNumber(); - auto secondTrackResource = secondTrack.resourceURI(); + const auto &secondTrackResource = secondTrack.resourceURI(); auto secondTrackRating = secondTrack.rating(); auto secondIsSingleDiscAlbum = secondTrack.isSingleDiscAlbum(); @@ -1793,7 +1907,7 @@ auto thirdTrackMilliSecondsDuration = thirdTrack.duration().msecsSinceStartOfDay(); auto thirdTrackTrackNumber = thirdTrack.trackNumber(); auto thirdTrackDiscNumber = thirdTrack.discNumber(); - auto thirdTrackResource = thirdTrack.resourceURI(); + const auto &thirdTrackResource = thirdTrack.resourceURI(); auto thirdTrackRating = thirdTrack.rating(); auto thirdIsSingleDiscAlbum = thirdTrack.isSingleDiscAlbum(); @@ -1826,7 +1940,7 @@ auto fourthTrackMilliSecondsDuration = fourthTrack.duration().msecsSinceStartOfDay(); auto fourthTrackTrackNumber = fourthTrack.trackNumber(); auto fourthTrackDiscNumber = fourthTrack.discNumber(); - auto fourthTrackResource = fourthTrack.resourceURI(); + const auto &fourthTrackResource = fourthTrack.resourceURI(); auto fourthTrackRating = thirdTrack.rating(); auto fourthIsSingleDiscAlbum = fourthTrack.isSingleDiscAlbum(); @@ -1971,7 +2085,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto allAlbums = musicDb.allAlbums(); @@ -2011,7 +2125,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 1); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 1); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto allAlbumsV2 = musicDb.allAlbums(); @@ -2089,7 +2203,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto allAlbums = musicDb.allAlbums(); @@ -2129,7 +2243,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 1); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 1); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto allAlbumsV2 = musicDb.allAlbums(); @@ -2172,7 +2286,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 1); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 2); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 3); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto allAlbums3 = musicDb.allAlbums(); @@ -2247,7 +2361,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto allAlbums = musicDb.allAlbums(); @@ -2298,10 +2412,10 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 6); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); - auto removedAlbum = musicDb.albumFromTitleAndArtist(QStringLiteral("album2"), QStringLiteral("Invalid Artist")); + auto removedAlbum = musicDb.albumFromTitleAndArtist(QStringLiteral("album2"), QStringLiteral("artist1")); QCOMPARE(removedAlbum.isValid(), false); } @@ -2352,7 +2466,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto allAlbums = musicDb.allAlbums(); @@ -2387,7 +2501,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 1); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 1); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); } @@ -2437,7 +2551,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto newTrack = MusicAudioTrack{true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track6"), @@ -2467,7 +2581,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 1); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 3); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); } @@ -2550,7 +2664,7 @@ auto firstTrackMilliSecondsDuration = firstTrack.duration().msecsSinceStartOfDay(); auto firstTrackTrackNumber = firstTrack.trackNumber(); auto firstTrackDiscNumber = firstTrack.discNumber(); - auto firstTrackResource = firstTrack.resourceURI(); + const auto &firstTrackResource = firstTrack.resourceURI(); auto firstTrackRating = firstTrack.rating(); auto firstIsSingleDiscAlbum = firstTrack.isSingleDiscAlbum(); @@ -2628,7 +2742,7 @@ auto secondTrackMilliSecondsDuration = secondTrack.duration().msecsSinceStartOfDay(); auto secondTrackTrackNumber = secondTrack.trackNumber(); auto secondTrackDiscNumber = secondTrack.discNumber(); - auto secondTrackResource = secondTrack.resourceURI(); + const auto &secondTrackResource = secondTrack.resourceURI(); auto secondTrackRating = secondTrack.rating(); auto secondIsSingleDiscAlbum = secondTrack.isSingleDiscAlbum(); @@ -2743,7 +2857,7 @@ auto firstTrackMilliSecondsDuration = firstTrack.duration().msecsSinceStartOfDay(); auto firstTrackTrackNumber = firstTrack.trackNumber(); auto firstTrackDiscNumber = firstTrack.discNumber(); - auto firstTrackResource = firstTrack.resourceURI(); + const auto &firstTrackResource = firstTrack.resourceURI(); auto firstTrackRating = firstTrack.rating(); auto firstIsSingleDiscAlbum = firstTrack.isSingleDiscAlbum(); @@ -2823,7 +2937,7 @@ auto secondTrackMilliSecondsDuration = secondTrack.duration().msecsSinceStartOfDay(); auto secondTrackTrackNumber = secondTrack.trackNumber(); auto secondTrackDiscNumber = secondTrack.discNumber(); - auto secondTrackResource = secondTrack.resourceURI(); + const auto &secondTrackResource = secondTrack.resourceURI(); auto secondTrackRating = secondTrack.rating(); auto secondIsSingleDiscAlbum = secondTrack.isSingleDiscAlbum(); @@ -2874,7 +2988,7 @@ auto modifiedAlbumIds = QList{musicDbAlbumModifiedSpy.at(0).at(1).toULongLong(),}; std::sort(modifiedAlbumIds.begin(), modifiedAlbumIds.end()); - QCOMPARE(modifiedAlbumIds.at(0), qulonglong(2)); + QCOMPARE(modifiedAlbumIds.at(0), qulonglong(1)); } void addTwoTracksWithAlbumSameName() @@ -2956,7 +3070,7 @@ auto firstTrackMilliSecondsDuration = firstTrack.duration().msecsSinceStartOfDay(); auto firstTrackTrackNumber = firstTrack.trackNumber(); auto firstTrackDiscNumber = firstTrack.discNumber(); - auto firstTrackResource = firstTrack.resourceURI(); + const auto &firstTrackResource = firstTrack.resourceURI(); auto firstTrackRating = firstTrack.rating(); auto firstIsSingleDiscAlbum = firstTrack.isSingleDiscAlbum(); @@ -3036,7 +3150,7 @@ auto secondTrackMilliSecondsDuration = secondTrack.duration().msecsSinceStartOfDay(); auto secondTrackTrackNumber = secondTrack.trackNumber(); auto secondTrackDiscNumber = secondTrack.discNumber(); - auto secondTrackResource = secondTrack.resourceURI(); + const auto &secondTrackResource = secondTrack.resourceURI(); auto secondTrackRating = secondTrack.rating(); auto secondIsSingleDiscAlbum = secondTrack.isSingleDiscAlbum(); @@ -3131,7 +3245,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto newTrack = MusicAudioTrack{true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track6"), @@ -3161,7 +3275,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto trackId = musicDb.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track6"), QStringLiteral("artist2"), @@ -3198,7 +3312,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 1); - QCOMPARE(musicDbTrackModifiedSpy.count(), 3); + QCOMPARE(musicDbTrackModifiedSpy.count(), 1); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto secondTrackId = musicDb.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track7"), QStringLiteral("artist2"), @@ -3260,7 +3374,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto modifiedTrack = MusicAudioTrack{true, QStringLiteral("$3"), QStringLiteral("0"), QStringLiteral("track3"), @@ -3283,7 +3397,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 1); - QCOMPARE(musicDbTrackModifiedSpy.count(), 3); + QCOMPARE(musicDbTrackModifiedSpy.count(), 1); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto trackId = musicDb.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track3"), QStringLiteral("artist3"), @@ -3341,7 +3455,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto newTrack = MusicAudioTrack{true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track6"), @@ -3372,7 +3486,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); const auto &newAlbum = musicDb.albumFromTitleAndArtist(QStringLiteral("album7"), QStringLiteral("artist2")); @@ -3425,7 +3539,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto newTrack = MusicAudioTrack{true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track6"), @@ -3460,7 +3574,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 1); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 4); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); } @@ -3594,7 +3708,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); musicDb.removeAllTracksFromSource(QStringLiteral("autoTestNotValid")); @@ -3610,7 +3724,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); } @@ -3665,7 +3779,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); QList secondNewTracks = { @@ -3728,7 +3842,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 1); - QCOMPARE(musicDbTrackModifiedSpy.count(), 3); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); musicDb.removeAllTracksFromSource(QStringLiteral("autoTest")); @@ -3744,7 +3858,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 21); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 2); - QCOMPARE(musicDbTrackModifiedSpy.count(), 3); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); } @@ -3934,7 +4048,7 @@ QCOMPARE(firstTrack.genre(), QStringLiteral("genre1")); QCOMPARE(firstTrack.composer(), QStringLiteral("composer1")); QCOMPARE(firstTrack.lyricist(), QStringLiteral("lyricist1")); - QCOMPARE(firstTrack.albumId(), qulonglong(2)); + QCOMPARE(firstTrack.albumId(), qulonglong(1)); auto newTracks2 = QList(); @@ -4058,7 +4172,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 1); - QCOMPARE(musicDbTrackModifiedSpy.count(), 0); + QCOMPARE(musicDbTrackModifiedSpy.count(), 1); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto firstTrack = musicDb.trackFromDatabaseId(musicDb.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track6"), QStringLiteral("artist4"), @@ -4079,7 +4193,7 @@ QCOMPARE(firstTrack.genre(), QStringLiteral("genre1")); QCOMPARE(firstTrack.composer(), QStringLiteral("composer1")); QCOMPARE(firstTrack.lyricist(), QStringLiteral("lyricist1")); - QCOMPARE(firstTrack.albumId(), qulonglong(2)); + QCOMPARE(firstTrack.albumId(), qulonglong(1)); auto secondTrack = musicDb.trackFromDatabaseId(musicDb.trackIdFromTitleAlbumTrackDiscNumber(QStringLiteral("track7"), QStringLiteral("artist3"), QStringLiteral("album3"), 7, 1)); @@ -4099,7 +4213,7 @@ QCOMPARE(secondTrack.genre(), QStringLiteral("genre1")); QCOMPARE(secondTrack.composer(), QStringLiteral("composer1")); QCOMPARE(secondTrack.lyricist(), QStringLiteral("lyricist1")); - QCOMPARE(secondTrack.albumId(), qulonglong(2)); + QCOMPARE(secondTrack.albumId(), qulonglong(1)); auto album = musicDb.albumFromTitleAndArtist(QStringLiteral("album3"), QStringLiteral("artist4")); @@ -4397,7 +4511,7 @@ auto firstTrackMilliSecondsDuration = firstTrack.duration().msecsSinceStartOfDay(); auto firstTrackTrackNumber = firstTrack.trackNumber(); auto firstTrackDiscNumber = firstTrack.discNumber(); - auto firstTrackResource = firstTrack.resourceURI(); + const auto &firstTrackResource = firstTrack.resourceURI(); auto firstTrackRating = firstTrack.rating(); auto firstIsSingleDiscAlbum = firstTrack.isSingleDiscAlbum(); @@ -4477,7 +4591,7 @@ auto secondTrackMilliSecondsDuration = secondTrack.duration().msecsSinceStartOfDay(); auto secondTrackTrackNumber = secondTrack.trackNumber(); auto secondTrackDiscNumber = secondTrack.discNumber(); - auto secondTrackResource = secondTrack.resourceURI(); + const auto &secondTrackResource = secondTrack.resourceURI(); auto secondTrackRating = secondTrack.rating(); auto secondIsSingleDiscAlbum = secondTrack.isSingleDiscAlbum(); @@ -4510,7 +4624,7 @@ auto modifiedTrackMilliSecondsDuration = modifiedTrack.duration().msecsSinceStartOfDay(); auto modifiedTrackTrackNumber = modifiedTrack.trackNumber(); auto modifiedTrackDiscNumber = modifiedTrack.discNumber(); - auto modifiedTrackResource = modifiedTrack.resourceURI(); + const auto &modifiedTrackResource = modifiedTrack.resourceURI(); auto modifiedTrackRating = modifiedTrack.rating(); auto modifiedTrackIsSingleDiscAlbum = modifiedTrack.isSingleDiscAlbum(); @@ -4592,7 +4706,7 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto newTrack = MusicAudioTrack{true, QStringLiteral("$23"), QStringLiteral("0"), {}, @@ -4620,7 +4734,149 @@ QCOMPARE(musicDbTrackRemovedSpy.count(), 0); QCOMPARE(musicDbArtistModifiedSpy.count(), 0); QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); - QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); + } + + + void checkRestoredTracks() + { + DatabaseInterface musicDb; + + musicDb.init(QStringLiteral("testDb")); + + QSignalSpy musicDbArtistAddedSpy(&musicDb, &DatabaseInterface::artistsAdded); + QSignalSpy musicDbAlbumAddedSpy(&musicDb, &DatabaseInterface::albumsAdded); + QSignalSpy musicDbTrackAddedSpy(&musicDb, &DatabaseInterface::tracksAdded); + QSignalSpy musicDbArtistRemovedSpy(&musicDb, &DatabaseInterface::artistRemoved); + QSignalSpy musicDbAlbumRemovedSpy(&musicDb, &DatabaseInterface::albumRemoved); + QSignalSpy musicDbTrackRemovedSpy(&musicDb, &DatabaseInterface::trackRemoved); + QSignalSpy musicDbArtistModifiedSpy(&musicDb, &DatabaseInterface::artistModified); + QSignalSpy musicDbAlbumModifiedSpy(&musicDb, &DatabaseInterface::albumModified); + QSignalSpy musicDbTrackModifiedSpy(&musicDb, &DatabaseInterface::trackModified); + QSignalSpy musicDbDatabaseErrorSpy(&musicDb, &DatabaseInterface::databaseError); + QSignalSpy musicDbRestoredTracksSpy(&musicDb, &DatabaseInterface::restoredTracks); + + QCOMPARE(musicDb.allAlbums().count(), 0); + QCOMPARE(musicDb.allArtists().count(), 0); + QCOMPARE(musicDb.allTracks().count(), 0); + QCOMPARE(musicDbArtistAddedSpy.count(), 0); + QCOMPARE(musicDbAlbumAddedSpy.count(), 0); + QCOMPARE(musicDbTrackAddedSpy.count(), 0); + QCOMPARE(musicDbArtistRemovedSpy.count(), 0); + QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); + QCOMPARE(musicDbTrackRemovedSpy.count(), 0); + QCOMPARE(musicDbArtistModifiedSpy.count(), 0); + QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); + QCOMPARE(musicDbRestoredTracksSpy.count(), 0); + + musicDb.insertTracksList(mNewTracks, mNewCovers, QStringLiteral("autoTest")); + + musicDbTrackAddedSpy.wait(300); + + QCOMPARE(musicDb.allAlbums().count(), 5); + QCOMPARE(musicDb.allArtists().count(), 7); + QCOMPARE(musicDb.allTracks().count(), 22); + QCOMPARE(musicDbArtistAddedSpy.count(), 1); + QCOMPARE(musicDbAlbumAddedSpy.count(), 1); + QCOMPARE(musicDbTrackAddedSpy.count(), 1); + QCOMPARE(musicDbArtistRemovedSpy.count(), 0); + QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); + QCOMPARE(musicDbTrackRemovedSpy.count(), 0); + QCOMPARE(musicDbArtistModifiedSpy.count(), 0); + QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); + QCOMPARE(musicDbRestoredTracksSpy.count(), 0); + + musicDb.askRestoredTracks(QStringLiteral("autoTest")); + + QCOMPARE(musicDb.allAlbums().count(), 5); + QCOMPARE(musicDb.allArtists().count(), 7); + QCOMPARE(musicDb.allTracks().count(), 22); + QCOMPARE(musicDbArtistAddedSpy.count(), 1); + QCOMPARE(musicDbAlbumAddedSpy.count(), 1); + QCOMPARE(musicDbTrackAddedSpy.count(), 1); + QCOMPARE(musicDbArtistRemovedSpy.count(), 0); + QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); + QCOMPARE(musicDbTrackRemovedSpy.count(), 0); + QCOMPARE(musicDbArtistModifiedSpy.count(), 0); + QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); + QCOMPARE(musicDbRestoredTracksSpy.count(), 1); + + const auto &firstSignal = musicDbRestoredTracksSpy.at(0); + QCOMPARE(firstSignal.count(), 2); + + const auto &restoredSource = firstSignal.at(0).toString(); + QCOMPARE(restoredSource, QStringLiteral("autoTest")); + + const auto &restoredTracks = firstSignal.at(1).value>(); + QCOMPARE(restoredTracks.count(), 23); + } + + void addOneTrackWithParticularPath() + { + DatabaseInterface musicDb; + + musicDb.init(QStringLiteral("testDb")); + + QSignalSpy musicDbArtistAddedSpy(&musicDb, &DatabaseInterface::artistsAdded); + QSignalSpy musicDbAlbumAddedSpy(&musicDb, &DatabaseInterface::albumsAdded); + QSignalSpy musicDbTrackAddedSpy(&musicDb, &DatabaseInterface::tracksAdded); + QSignalSpy musicDbArtistRemovedSpy(&musicDb, &DatabaseInterface::artistRemoved); + QSignalSpy musicDbAlbumRemovedSpy(&musicDb, &DatabaseInterface::albumRemoved); + QSignalSpy musicDbTrackRemovedSpy(&musicDb, &DatabaseInterface::trackRemoved); + QSignalSpy musicDbArtistModifiedSpy(&musicDb, &DatabaseInterface::artistModified); + QSignalSpy musicDbAlbumModifiedSpy(&musicDb, &DatabaseInterface::albumModified); + QSignalSpy musicDbTrackModifiedSpy(&musicDb, &DatabaseInterface::trackModified); + QSignalSpy musicDbDatabaseErrorSpy(&musicDb, &DatabaseInterface::databaseError); + + QCOMPARE(musicDb.allAlbums().count(), 0); + QCOMPARE(musicDb.allArtists().count(), 0); + QCOMPARE(musicDb.allTracks().count(), 0); + QCOMPARE(musicDbArtistAddedSpy.count(), 0); + QCOMPARE(musicDbAlbumAddedSpy.count(), 0); + QCOMPARE(musicDbTrackAddedSpy.count(), 0); + QCOMPARE(musicDbArtistRemovedSpy.count(), 0); + QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); + QCOMPARE(musicDbTrackRemovedSpy.count(), 0); + QCOMPARE(musicDbArtistModifiedSpy.count(), 0); + QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); + + auto newTrack = MusicAudioTrack{true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track6"), + QStringLiteral("artist2"), QStringLiteral("album3"), QStringLiteral("artist2"), + 6, 1, QTime::fromMSecsSinceStartOfDay(23), {QUrl::fromLocalFile(QStringLiteral("/test{{test}}/$23"))}, + QDateTime::fromMSecsSinceEpoch(23), + QUrl::fromLocalFile(QStringLiteral("album3")), 5, true, + QStringLiteral("genre1"), QStringLiteral("composer1"), QStringLiteral("lyricist1")}; + auto newTracks = QList(); + newTracks.push_back(newTrack); + + auto newCovers = mNewCovers; + newCovers[QStringLiteral("/test{{test}}/$23")] = QUrl::fromLocalFile(QStringLiteral("album3")); + + musicDb.insertTracksList(newTracks, newCovers, QStringLiteral("autoTest")); + + musicDbTrackAddedSpy.wait(300); + + QCOMPARE(musicDb.allAlbums().count(), 1); + QCOMPARE(musicDb.allArtists().count(), 1); + QCOMPARE(musicDb.allTracks().count(), 1); + QCOMPARE(musicDbArtistAddedSpy.count(), 1); + QCOMPARE(musicDbAlbumAddedSpy.count(), 1); + QCOMPARE(musicDbTrackAddedSpy.count(), 1); + QCOMPARE(musicDbArtistRemovedSpy.count(), 0); + QCOMPARE(musicDbAlbumRemovedSpy.count(), 0); + QCOMPARE(musicDbTrackRemovedSpy.count(), 0); + QCOMPARE(musicDbArtistModifiedSpy.count(), 0); + QCOMPARE(musicDbAlbumModifiedSpy.count(), 0); + QCOMPARE(musicDbTrackModifiedSpy.count(), 0); QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); } }; diff --git a/autotests/qabstractitemmodeltester.h b/autotests/qabstractitemmodeltester.h --- a/autotests/qabstractitemmodeltester.h +++ b/autotests/qabstractitemmodeltester.h @@ -72,8 +72,8 @@ Fatal }; - QAbstractItemModelTester(QAbstractItemModel *model, Qt::ConnectionType type = Qt::AutoConnection, QObject *parent = nullptr); - QAbstractItemModelTester(QAbstractItemModel *model, FailureReportingMode mode, Qt::ConnectionType type = Qt::AutoConnection, QObject *parent = nullptr); + QAbstractItemModelTester(QAbstractItemModel *model, QObject *parent = nullptr); + QAbstractItemModelTester(QAbstractItemModel *model, FailureReportingMode mode, QObject *parent = nullptr); QAbstractItemModel *model() const; FailureReportingMode failureReportingMode() const; diff --git a/autotests/qabstractitemmodeltester.cpp b/autotests/qabstractitemmodeltester.cpp --- a/autotests/qabstractitemmodeltester.cpp +++ b/autotests/qabstractitemmodeltester.cpp @@ -71,8 +71,7 @@ { Q_DECLARE_PUBLIC(QAbstractItemModelTester) public: - QAbstractItemModelTesterPrivate(QAbstractItemModel *model, QAbstractItemModelTester::FailureReportingMode failureReportingMode, - Qt::ConnectionType type); + QAbstractItemModelTesterPrivate(QAbstractItemModel *model, QAbstractItemModelTester::FailureReportingMode failureReportingMode); void nonDestructiveBasicTest(); void rowAndColumnCount(); @@ -115,8 +114,6 @@ bool fetchingMore; - Qt::ConnectionType type; - QList changing; }; @@ -206,8 +203,8 @@ Creates a model tester instance, with the given \a parent, that will test the model \a model. */ -QAbstractItemModelTester::QAbstractItemModelTester(QAbstractItemModel *model, Qt::ConnectionType type, QObject *parent) - : QAbstractItemModelTester(model, FailureReportingMode::QtTest, type, parent) +QAbstractItemModelTester::QAbstractItemModelTester(QAbstractItemModel *model, QObject *parent) + : QAbstractItemModelTester(model, FailureReportingMode::QtTest, parent) { } @@ -217,8 +214,8 @@ \sa QAbstractItemModelTester::FailureReportingMode */ -QAbstractItemModelTester::QAbstractItemModelTester(QAbstractItemModel *model, FailureReportingMode mode, Qt::ConnectionType type, QObject *parent) - : QObject(*new QAbstractItemModelTesterPrivate(model, mode, type), parent) +QAbstractItemModelTester::QAbstractItemModelTester(QAbstractItemModel *model, FailureReportingMode mode, QObject *parent) + : QObject(*new QAbstractItemModelTesterPrivate(model, mode), parent) { if (!model) qFatal("%s: model must not be null", Q_FUNC_INFO); @@ -228,50 +225,50 @@ const auto &runAllTests = [d] { d->runAllTests(); }; connect(model, &QAbstractItemModel::columnsAboutToBeInserted, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::columnsAboutToBeRemoved, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::columnsInserted, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::columnsRemoved, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::dataChanged, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::headerDataChanged, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::layoutAboutToBeChanged, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::layoutChanged, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::modelReset, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::rowsAboutToBeInserted, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::rowsInserted, - this, runAllTests, d->type); + this, runAllTests); connect(model, &QAbstractItemModel::rowsRemoved, - this, runAllTests, d->type); + this, runAllTests); // Special checks for changes connect(model, &QAbstractItemModel::layoutAboutToBeChanged, this, [d]{ d->layoutAboutToBeChanged(); }); connect(model, &QAbstractItemModel::layoutChanged, this, [d]{ d->layoutChanged(); }); connect(model, &QAbstractItemModel::rowsAboutToBeInserted, - this, [d](const QModelIndex &parent, int start, int end) { d->rowsAboutToBeInserted(parent, start, end); }, d->type); + this, [d](const QModelIndex &parent, int start, int end) { d->rowsAboutToBeInserted(parent, start, end); }); connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, - this, [d](const QModelIndex &parent, int start, int end) { d->rowsAboutToBeRemoved(parent, start, end); }, d->type); + this, [d](const QModelIndex &parent, int start, int end) { d->rowsAboutToBeRemoved(parent, start, end); }); connect(model, &QAbstractItemModel::rowsInserted, - this, [d](const QModelIndex &parent, int start, int end) { d->rowsInserted(parent, start, end); }, d->type); + this, [d](const QModelIndex &parent, int start, int end) { d->rowsInserted(parent, start, end); }); connect(model, &QAbstractItemModel::rowsRemoved, - this, [d](const QModelIndex &parent, int start, int end) { d->rowsRemoved(parent, start, end); }, d->type); + this, [d](const QModelIndex &parent, int start, int end) { d->rowsRemoved(parent, start, end); }); connect(model, &QAbstractItemModel::dataChanged, - this, [d](const QModelIndex &topLeft, const QModelIndex &bottomRight) { d->dataChanged(topLeft, bottomRight); }, d->type); + this, [d](const QModelIndex &topLeft, const QModelIndex &bottomRight) { d->dataChanged(topLeft, bottomRight); }); connect(model, &QAbstractItemModel::headerDataChanged, - this, [d](Qt::Orientation orientation, int start, int end) { d->headerDataChanged(orientation, start, end); }, d->type); + this, [d](Qt::Orientation orientation, int start, int end) { d->headerDataChanged(orientation, start, end); }); runAllTests(); } @@ -302,12 +299,10 @@ return d->verify(statement, statementStr, description, file, line); } -QAbstractItemModelTesterPrivate::QAbstractItemModelTesterPrivate(QAbstractItemModel *model, QAbstractItemModelTester::FailureReportingMode failureReportingMode, - Qt::ConnectionType type) +QAbstractItemModelTesterPrivate::QAbstractItemModelTesterPrivate(QAbstractItemModel *model, QAbstractItemModelTester::FailureReportingMode failureReportingMode) : model(model), failureReportingMode(failureReportingMode), - fetchingMore(false), - type(type) + fetchingMore(false) { } diff --git a/src/abstractfile/abstractfilelisting.h b/src/abstractfile/abstractfilelisting.h --- a/src/abstractfile/abstractfilelisting.h +++ b/src/abstractfile/abstractfilelisting.h @@ -35,6 +35,7 @@ class MusicAudioTrack; class NotificationItem; class FileScanner; +class QFileInfo; class ELISALIB_EXPORT AbstractFileListing : public QObject { @@ -95,7 +96,7 @@ void scanDirectory(QList &newFiles, const QUrl &path); - virtual MusicAudioTrack scanOneFile(const QUrl &scanFile); + virtual MusicAudioTrack scanOneFile(const QUrl &scanFile, const QFileInfo &scanFileInfo); void watchPath(const QString &pathName); diff --git a/src/abstractfile/abstractfilelisting.cpp b/src/abstractfile/abstractfilelisting.cpp --- a/src/abstractfile/abstractfilelisting.cpp +++ b/src/abstractfile/abstractfilelisting.cpp @@ -90,7 +90,8 @@ void AbstractFileListing::newTrackFile(const MusicAudioTrack &partialTrack) { - const auto &newTrack = scanOneFile(partialTrack.resourceURI()); + auto scanFileInfo = QFileInfo(partialTrack.resourceURI().toLocalFile()); + const auto &newTrack = scanOneFile(partialTrack.resourceURI(), scanFileInfo); if (newTrack.isValid() && newTrack != partialTrack) { Q_EMIT modifyTracksList({newTrack}, d->mAllAlbumCover, d->mSourceName); @@ -193,7 +194,7 @@ continue; } - auto newTrack = scanOneFile(newFilePath); + auto newTrack = scanOneFile(newFilePath, oneEntry); if (newTrack.isValid() && d->mStopRequest == 0) { addCover(newTrack); @@ -240,9 +241,10 @@ void AbstractFileListing::fileChanged(const QString &modifiedFileName) { + QFileInfo modifiedFileInfo(modifiedFileName); auto modifiedFile = QUrl::fromLocalFile(modifiedFileName); - auto modifiedTrack = scanOneFile(modifiedFile); + auto modifiedTrack = scanOneFile(modifiedFile, modifiedFileInfo); if (modifiedTrack.isValid()) { Q_EMIT modifyTracksList({modifiedTrack}, d->mAllAlbumCover, d->mSourceName); @@ -264,7 +266,7 @@ triggerRefreshOfContent(); } -MusicAudioTrack AbstractFileListing::scanOneFile(const QUrl &scanFile) +MusicAudioTrack AbstractFileListing::scanOneFile(const QUrl &scanFile, const QFileInfo &scanFileInfo) { MusicAudioTrack newTrack; @@ -275,8 +277,6 @@ return newTrack; } - QFileInfo scanFileInfo(localFileName); - if (scanFileInfo.exists()) { auto itExistingFile = d->mAllFiles.find(scanFile); if (itExistingFile != d->mAllFiles.end()) { diff --git a/src/baloo/localbaloofilelisting.h b/src/baloo/localbaloofilelisting.h --- a/src/baloo/localbaloofilelisting.h +++ b/src/baloo/localbaloofilelisting.h @@ -77,7 +77,7 @@ void triggerRefreshOfContent() override; - MusicAudioTrack scanOneFile(const QUrl &scanFile) override; + MusicAudioTrack scanOneFile(const QUrl &scanFile, const QFileInfo &scanFileInfo) override; bool checkBalooConfiguration(); diff --git a/src/baloo/localbaloofilelisting.cpp b/src/baloo/localbaloofilelisting.cpp --- a/src/baloo/localbaloofilelisting.cpp +++ b/src/baloo/localbaloofilelisting.cpp @@ -126,9 +126,15 @@ void LocalBalooFileListing::newBalooFile(const QString &fileName) { + auto scanFileInfo = QFileInfo(fileName); + + if (!scanFileInfo.exists()) { + return; + } + auto newFile = QUrl::fromLocalFile(fileName); - auto newTrack = scanOneFile(newFile); + auto newTrack = scanOneFile(newFile, scanFileInfo); if (newTrack.isValid()) { QFileInfo newFileInfo(fileName); @@ -153,10 +159,6 @@ d->mIsRegisteredToBaloo = false; } else { d->mIsRegisteredToBaloo = true; - - if (d->mIsRegisteredToBaloo && d->mIsRegisteredToBalooWatcher) { - triggerRefreshOfContent(); - } } d->mIsRegisteringToBaloo = false; @@ -178,10 +180,6 @@ d->mIsRegisteredToBalooWatcher = false; } else { d->mIsRegisteredToBalooWatcher = true; - - if (d->mIsRegisteredToBaloo && d->mIsRegisteredToBalooWatcher) { - triggerRefreshOfContent(); - } } d->mIsRegisteringToBalooWatcher = false; @@ -311,13 +309,28 @@ auto newFiles = QList(); while(resultIterator.next() && d->mStopRequest == 0) { + const auto &fileName = resultIterator.filePath(); const auto &newFileUrl = QUrl::fromLocalFile(resultIterator.filePath()); - auto scanFileInfo = QFileInfo(resultIterator.filePath()); + + auto scanFileInfo = QFileInfo(fileName); + + if (!scanFileInfo.exists()) { + return; + } + + auto itExistingFile = allFiles().find(newFileUrl); + if (itExistingFile != allFiles().end()) { + if (*itExistingFile >= scanFileInfo.fileTime(QFile::FileModificationTime)) { + allFiles().erase(itExistingFile); + continue; + } + } + const auto currentDirectory = QUrl::fromLocalFile(scanFileInfo.absoluteDir().absolutePath()); addFileInDirectory(newFileUrl, currentDirectory); - const auto &newTrack = scanOneFile(newFileUrl); + const auto &newTrack = scanOneFile(newFileUrl, scanFileInfo); if (newTrack.isValid()) { newFiles.push_back(newTrack); @@ -337,24 +350,11 @@ Q_EMIT indexingFinished(); } -MusicAudioTrack LocalBalooFileListing::scanOneFile(const QUrl &scanFile) +MusicAudioTrack LocalBalooFileListing::scanOneFile(const QUrl &scanFile, const QFileInfo &scanFileInfo) { auto newTrack = MusicAudioTrack(); auto localFileName = scanFile.toLocalFile(); - auto scanFileInfo = QFileInfo(localFileName); - - if (!scanFileInfo.exists()) { - return newTrack; - } - - auto itExistingFile = allFiles().find(scanFile); - if (itExistingFile != allFiles().end()) { - if (*itExistingFile >= scanFileInfo.fileTime(QFile::FileModificationTime)) { - allFiles().erase(itExistingFile); - return newTrack; - } - } Baloo::File match(localFileName); @@ -366,7 +366,7 @@ fileScanner().scanProperties(match, newTrack); if (!newTrack.isValid()) { - newTrack = AbstractFileListing::scanOneFile(scanFile); + newTrack = AbstractFileListing::scanOneFile(scanFile, scanFileInfo); } if (newTrack.isValid()) { diff --git a/src/databaseinterface.h b/src/databaseinterface.h --- a/src/databaseinterface.h +++ b/src/databaseinterface.h @@ -168,6 +168,8 @@ void recordModifiedTrack(qulonglong trackId); + void recordModifiedAlbum(qulonglong albumId); + bool startTransaction() const; bool finishTransaction() const; @@ -178,8 +180,6 @@ QList fetchTrackIds(qulonglong albumId); - bool updateTracksCount(qulonglong albumId); - MusicArtist internalArtistFromId(qulonglong artistId); MusicAlbum internalAlbumFromId(qulonglong albumId); @@ -208,10 +208,10 @@ void initRequest(); qulonglong insertAlbum(const QString &title, const QString &albumArtist, const QString &trackArtist, - const QString &trackPath, const QUrl &albumArtURI, int tracksCount, - AlbumDiscsCount isSingleDiscAlbum); + const QString &trackPath, const QUrl &albumArtURI); - bool updateAlbumFromId(qulonglong albumId, const QUrl &albumArtUri, const MusicAudioTrack ¤tTrack); + bool updateAlbumFromId(qulonglong albumId, const QUrl &albumArtUri, + const MusicAudioTrack ¤tTrack, const QString &albumPath); qulonglong insertArtist(const QString &name); @@ -223,7 +223,7 @@ void removeTrackInDatabase(qulonglong trackId); - void updateTrackInDatabase(const MusicAudioTrack &oneTrack, qulonglong albumId); + void updateTrackInDatabase(const MusicAudioTrack &oneTrack, const QString &albumPath); void removeAlbumInDatabase(qulonglong albumId); @@ -281,10 +281,13 @@ QList> internalAllLyricistsPartialData(); QList internalAllPeople(QSqlQuery allPeopleQuery, - QSqlQuery selectCountAlbumsForPeopleQuery); + QSqlQuery selectCountAlbumsForPeopleQuery, bool withCache); bool prepareQuery(QSqlQuery &query, const QString &queryText) const; + void updateAlbumArtist(qulonglong albumId, const QString &title, const QString &albumPath, + const QString &artistName); + std::unique_ptr d; }; diff --git a/src/databaseinterface.cpp b/src/databaseinterface.cpp --- a/src/databaseinterface.cpp +++ b/src/databaseinterface.cpp @@ -40,8 +40,7 @@ : mTracksDatabase(tracksDatabase), mSelectAlbumQuery(mTracksDatabase), mSelectTrackQuery(mTracksDatabase), mSelectAlbumIdFromTitleQuery(mTracksDatabase), mInsertAlbumQuery(mTracksDatabase), mSelectTrackIdFromTitleAlbumIdArtistQuery(mTracksDatabase), - mInsertTrackQuery(mTracksDatabase), mSelectAlbumTrackCountQuery(mTracksDatabase), - mUpdateAlbumQuery(mTracksDatabase), mSelectTracksFromArtist(mTracksDatabase), + mInsertTrackQuery(mTracksDatabase), mSelectTracksFromArtist(mTracksDatabase), mSelectTrackFromIdQuery(mTracksDatabase), mSelectCountAlbumsForArtistQuery(mTracksDatabase), mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery(mTracksDatabase), mSelectAllAlbumsQuery(mTracksDatabase), mSelectAllAlbumsFromArtistQuery(mTracksDatabase), mSelectAllArtistsQuery(mTracksDatabase), @@ -51,14 +50,13 @@ mRemoveArtistQuery(mTracksDatabase), mSelectAllTracksQuery(mTracksDatabase), mInsertTrackMapping(mTracksDatabase), mSelectAllTracksFromSourceQuery(mTracksDatabase), mInsertMusicSource(mTracksDatabase), mSelectMusicSource(mTracksDatabase), - mUpdateIsSingleDiscAlbumFromIdQuery(mTracksDatabase), mUpdateTrackMapping(mTracksDatabase), + mUpdateTrackMapping(mTracksDatabase), mSelectTracksMapping(mTracksDatabase), mSelectTracksMappingPriority(mTracksDatabase), mUpdateAlbumArtUriFromAlbumIdQuery(mTracksDatabase), mSelectTracksMappingPriorityByTrackId(mTracksDatabase), mSelectAllTrackFilesFromSourceQuery(mTracksDatabase), mSelectAlbumIdsFromArtist(mTracksDatabase), mRemoveTracksMappingFromSource(mTracksDatabase), mRemoveTracksMapping(mTracksDatabase), mSelectTracksWithoutMappingQuery(mTracksDatabase), mSelectAlbumIdFromTitleAndArtistQuery(mTracksDatabase), - mSelectAlbumIdFromTitleWithoutArtistQuery(mTracksDatabase), mInsertAlbumArtistQuery(mTracksDatabase), - mInsertTrackArtistQuery(mTracksDatabase), mRemoveTrackArtistQuery(mTracksDatabase), mRemoveAlbumArtistQuery(mTracksDatabase), + mSelectAlbumIdFromTitleWithoutArtistQuery(mTracksDatabase), mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery(mTracksDatabase), mSelectAlbumArtUriFromAlbumIdQuery(mTracksDatabase), mInsertComposerQuery(mTracksDatabase), mSelectComposerByNameQuery(mTracksDatabase), mSelectComposerQuery(mTracksDatabase), mInsertLyricistQuery(mTracksDatabase), @@ -69,7 +67,8 @@ mSelectAllLyricistsQuery(mTracksDatabase), mSelectCountAlbumsForComposerQuery(mTracksDatabase), mSelectCountAlbumsForLyricistQuery(mTracksDatabase), mSelectAllGenresQuery(mTracksDatabase), mSelectGenreForArtistQuery(mTracksDatabase), mSelectGenreForAlbumQuery(mTracksDatabase), - mUpdateTrackQuery(mTracksDatabase) + mUpdateTrackQuery(mTracksDatabase), mUpdateAlbumArtistQuery(mTracksDatabase), + mUpdateAlbumArtistInTracksQuery(mTracksDatabase) { } @@ -87,10 +86,6 @@ QSqlQuery mInsertTrackQuery; - QSqlQuery mSelectAlbumTrackCountQuery; - - QSqlQuery mUpdateAlbumQuery; - QSqlQuery mSelectTracksFromArtist; QSqlQuery mSelectTrackFromIdQuery; @@ -129,8 +124,6 @@ QSqlQuery mSelectMusicSource; - QSqlQuery mUpdateIsSingleDiscAlbumFromIdQuery; - QSqlQuery mUpdateTrackMapping; QSqlQuery mSelectTracksMapping; @@ -155,14 +148,6 @@ QSqlQuery mSelectAlbumIdFromTitleWithoutArtistQuery; - QSqlQuery mInsertAlbumArtistQuery; - - QSqlQuery mInsertTrackArtistQuery; - - QSqlQuery mRemoveTrackArtistQuery; - - QSqlQuery mRemoveAlbumArtistQuery; - QSqlQuery mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery; QSqlQuery mSelectAlbumArtUriFromAlbumIdQuery; @@ -205,17 +190,27 @@ QSqlQuery mUpdateTrackQuery; + QSqlQuery mUpdateAlbumArtistQuery; + + QSqlQuery mUpdateAlbumArtistInTracksQuery; + QHash mTracksCache; - QSet mModifiedAlbumIds; + QHash mAlbumsCache; + + QHash mArtistsCache; QSet mModifiedTrackIds; - QList mInsertedTracks; + QSet mModifiedAlbumIds; + + QSet mModifiedArtistIds; + + QSet mInsertedTracks; - QList mInsertedAlbums; + QSet mInsertedAlbums; - QList mInsertedArtists; + QSet mInsertedArtists; qulonglong mAlbumId = 1; @@ -457,11 +452,18 @@ } while(d->mSelectAllAlbumsQuery.next()) { - auto newAlbum = MusicAlbum(); - const auto ¤tRecord = d->mSelectAllAlbumsQuery.record(); - newAlbum.setDatabaseId(currentRecord.value(0).toULongLong()); + auto albumId = currentRecord.value(0).toULongLong(); + + auto &newAlbum = d->mAlbumsCache[albumId]; + + if (newAlbum.isValid()) { + result.push_back(newAlbum); + continue; + } + + newAlbum.setDatabaseId(albumId); newAlbum.setTitle(currentRecord.value(1).toString()); newAlbum.setId(currentRecord.value(2).toString()); newAlbum.setArtist(currentRecord.value(3).toString()); @@ -518,7 +520,7 @@ return result; } - result = internalAllPeople(d->mSelectAllArtistsQuery, d->mSelectCountAlbumsForArtistQuery); + result = internalAllPeople(d->mSelectAllArtistsQuery, d->mSelectCountAlbumsForArtistQuery, true); return result; } @@ -571,24 +573,24 @@ QList DatabaseInterface::allComposers() { - return internalAllPeople(d->mSelectAllComposersQuery, d->mSelectCountAlbumsForComposerQuery); + return internalAllPeople(d->mSelectAllComposersQuery, d->mSelectCountAlbumsForComposerQuery, false); } QList DatabaseInterface::allLyricists() { - return internalAllPeople(d->mSelectAllLyricistsQuery, d->mSelectCountAlbumsForLyricistQuery); + return internalAllPeople(d->mSelectAllLyricistsQuery, d->mSelectCountAlbumsForLyricistQuery, false); } -QList DatabaseInterface::tracksFromAuthor(const QString &artistName) +QList DatabaseInterface::tracksFromAuthor(const QString &ArtistName) { auto allTracks = QList(); auto transactionResult = startTransaction(); if (!transactionResult) { return allTracks; } - allTracks = internalTracksFromAuthor(artistName); + allTracks = internalTracksFromAuthor(ArtistName); transactionResult = finishTransaction(); if (!transactionResult) { @@ -600,7 +602,11 @@ MusicArtist DatabaseInterface::internalArtistFromId(qulonglong artistId) { - auto result = MusicArtist(); + auto &result = d->mArtistsCache[artistId]; + + if (result.isValid()) { + return result; + } if (!d || !d->mTracksDatabase.isValid() || !d->mInitFinished) { return result; @@ -801,8 +807,9 @@ void DatabaseInterface::initChangesTrackers() { - d->mModifiedAlbumIds.clear(); d->mModifiedTrackIds.clear(); + d->mModifiedAlbumIds.clear(); + d->mModifiedArtistIds.clear(); d->mInsertedTracks.clear(); d->mInsertedAlbums.clear(); d->mInsertedArtists.clear(); @@ -814,6 +821,12 @@ d->mTracksCache.remove(trackId); } +void DatabaseInterface::recordModifiedAlbum(qulonglong albumId) +{ + d->mModifiedAlbumIds.insert(albumId); + d->mAlbumsCache.remove(albumId); +} + void DatabaseInterface::insertTracksList(const QList &tracks, const QHash &covers, const QString &musicSource) { if (d->mStopRequest == 1) { @@ -861,20 +874,7 @@ (isNewTrack ? TrackFileInsertType::NewTrackFileInsert : TrackFileInsertType::ModifiedTrackFileInsert)); if (isNewTrack && insertedTrackId != 0) { - d->mInsertedTracks.push_back(insertedTrackId); - } else if (insertedTrackId == 0) { - d->mRemoveTracksMappingFromSource.bindValue(QStringLiteral(":fileName"), oneTrack.resourceURI()); - d->mRemoveTracksMappingFromSource.bindValue(QStringLiteral(":sourceId"), internalSourceIdFromName(musicSource)); - - auto result = d->mRemoveTracksMappingFromSource.exec(); - - if (!result || !d->mRemoveTracksMappingFromSource.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::insertTracksList" << d->mRemoveTracksMappingFromSource.lastQuery(); - qDebug() << "DatabaseInterface::insertTracksList" << d->mRemoveTracksMappingFromSource.boundValues(); - qDebug() << "DatabaseInterface::insertTracksList" << d->mRemoveTracksMappingFromSource.lastError(); - } + d->mInsertedTracks.insert(insertedTrackId); } if (d->mStopRequest == 1) { @@ -904,11 +904,14 @@ Q_EMIT albumsAdded(newAlbums); } - const auto &constModifiedAlbumIds = d->mModifiedAlbumIds; - for (auto albumId : constModifiedAlbumIds) { + for (auto albumId : qAsConst(d->mModifiedAlbumIds)) { Q_EMIT albumModified(internalAlbumFromId(albumId), albumId); } + for (auto trackId : qAsConst(d->mInsertedTracks)) { + d->mModifiedTrackIds.remove(trackId); + } + for (auto trackId : qAsConst(d->mModifiedTrackIds)) { Q_EMIT trackModified(internalTrackFromDatabaseId(trackId)); } @@ -986,7 +989,7 @@ (modifyExistingTrack ? TrackFileInsertType::ModifiedTrackFileInsert : TrackFileInsertType::NewTrackFileInsert)); if (!modifyExistingTrack && insertedTrackId != 0) { - d->mInsertedTracks.push_back(insertedTrackId); + d->mInsertedTracks.insert(insertedTrackId); } } @@ -1082,10 +1085,11 @@ auto listTables = d->mTracksDatabase.tables(); - if (!listTables.contains(QStringLiteral("DatabaseVersionV5"))) { + if (!listTables.contains(QStringLiteral("DatabaseVersionV6"))) { auto oldTables = QStringList{QStringLiteral("DatabaseVersionV2"), QStringLiteral("DatabaseVersionV3"), QStringLiteral("DatabaseVersionV4"), + QStringLiteral("DatabaseVersionV5"), QStringLiteral("AlbumsArtists"), QStringLiteral("TracksArtists"), QStringLiteral("TracksMapping"), @@ -1116,10 +1120,10 @@ listTables = d->mTracksDatabase.tables(); } - if (!listTables.contains(QStringLiteral("DatabaseVersionV5"))) { + if (!listTables.contains(QStringLiteral("DatabaseVersionV6"))) { QSqlQuery createSchemaQuery(d->mTracksDatabase); - const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV5` (`Version` INTEGER PRIMARY KEY NOT NULL)")); + const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV6` (`Version` INTEGER PRIMARY KEY NOT NULL)")); if (!result) { qDebug() << "DatabaseInterface::initDatabase" << createSchemaQuery.lastQuery(); @@ -1210,35 +1214,17 @@ const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Albums` (" "`ID` INTEGER PRIMARY KEY NOT NULL, " "`Title` VARCHAR(55) NOT NULL, " + "`ArtistName` VARCHAR(55), " "`AlbumPath` VARCHAR(255) NOT NULL, " "`CoverFileName` VARCHAR(255) NOT NULL, " - "`TracksCount` INTEGER NOT NULL, " - "`IsSingleDiscAlbum` BOOLEAN NOT NULL, " - "`AlbumInternalID` VARCHAR(55))")); - - if (!result) { - qDebug() << "DatabaseInterface::initDatabase" << createSchemaQuery.lastQuery(); - qDebug() << "DatabaseInterface::initDatabase" << createSchemaQuery.lastError(); - } - } - - if (!listTables.contains(QStringLiteral("AlbumsArtists"))) { - QSqlQuery createSchemaQuery(d->mTracksDatabase); - - const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `AlbumsArtists` (" - "`AlbumID` INTEGER NOT NULL, " - "`ArtistID` INTEGER NOT NULL, " - "CONSTRAINT pk_albumsartists PRIMARY KEY (`AlbumID`, `ArtistID`), " - "CONSTRAINT fk_albums FOREIGN KEY (`AlbumID`) REFERENCES `Albums`(`ID`) " - "ON DELETE CASCADE, " - "CONSTRAINT fk_artists FOREIGN KEY (`ArtistID`) REFERENCES `Artists`(`ID`) " + "`AlbumInternalID` VARCHAR(55), " + "UNIQUE (`Title`, `ArtistName`, `AlbumPath`), " + "CONSTRAINT fk_artists FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`) " "ON DELETE CASCADE)")); if (!result) { qDebug() << "DatabaseInterface::initDatabase" << createSchemaQuery.lastQuery(); qDebug() << "DatabaseInterface::initDatabase" << createSchemaQuery.lastError(); - - Q_EMIT databaseError(); } } @@ -1248,7 +1234,10 @@ const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Tracks` (" "`ID` INTEGER PRIMARY KEY NOT NULL, " "`Title` VARCHAR(85) NOT NULL, " - "`AlbumID` INTEGER, " + "`ArtistName` VARCHAR(55), " + "`AlbumTitle` VARCHAR(55), " + "`AlbumArtistName` VARCHAR(55), " + "`AlbumPath` VARCHAR(255), " "`TrackNumber` INTEGER DEFAULT -1, " "`DiscNumber` INTEGER DEFAULT -1, " "`Duration` INTEGER NOT NULL, " @@ -1261,31 +1250,17 @@ "`Channels` INTEGER DEFAULT -1, " "`BitRate` INTEGER DEFAULT -1, " "`SampleRate` INTEGER DEFAULT -1, " - "UNIQUE (`Title`, `AlbumID`, `TrackNumber`, `DiscNumber`), " + "UNIQUE (" + "`Title`, `AlbumTitle`, `AlbumArtistName`, " + "`AlbumPath`, `TrackNumber`, `DiscNumber`" + "), " + "CONSTRAINT fk_artist FOREIGN KEY (`ArtistName`) REFERENCES `Artists`(`Name`), " "CONSTRAINT fk_tracks_composer FOREIGN KEY (`ComposerID`) REFERENCES `Composer`(`ID`), " "CONSTRAINT fk_tracks_lyricist FOREIGN KEY (`LyricistID`) REFERENCES `Lyricist`(`ID`), " "CONSTRAINT fk_tracks_genre FOREIGN KEY (`GenreID`) REFERENCES `Genre`(`ID`), " - "CONSTRAINT fk_tracks_album FOREIGN KEY (`AlbumID`) REFERENCES `Albums`(`ID`))")); - - if (!result) { - qDebug() << "DatabaseInterface::initDatabase" << createSchemaQuery.lastQuery(); - qDebug() << "DatabaseInterface::initDatabase" << createSchemaQuery.lastError(); - - Q_EMIT databaseError(); - } - } - - if (!listTables.contains(QStringLiteral("TracksArtists"))) { - QSqlQuery createSchemaQuery(d->mTracksDatabase); - - const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `TracksArtists` (" - "`TrackID` INTEGER NOT NULL, " - "`ArtistID` INTEGER NOT NULL, " - "CONSTRAINT pk_tracksartists PRIMARY KEY (`TrackID`, `ArtistID`), " - "CONSTRAINT fk_tracks FOREIGN KEY (`TrackID`) REFERENCES `Tracks`(`ID`) " - "ON DELETE CASCADE, " - "CONSTRAINT fk_artists FOREIGN KEY (`ArtistID`) REFERENCES `Artists`(`ID`) " - "ON DELETE CASCADE)")); + "CONSTRAINT fk_tracks_album FOREIGN KEY (" + "`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)" + "REFERENCES `Albums`(`Title`, `ArtistName`, `AlbumPath`))")); if (!result) { qDebug() << "DatabaseInterface::initDatabase" << createSchemaQuery.lastQuery(); @@ -1320,8 +1295,8 @@ const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " - "`TracksAlbumIndex` ON `Tracks` " - "(`AlbumID`)")); + "`TitleAlbumsIndex` ON `Albums` " + "(`Title`)")); if (!result) { qDebug() << "DatabaseInterface::initDatabase" << createTrackIndex.lastQuery(); @@ -1336,8 +1311,8 @@ const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " - "`AlbumsArtistsArtistIndex` ON `AlbumsArtists` " - "(`ArtistID`)")); + "`ArtistNameAlbumsIndex` ON `Albums` " + "(`ArtistName`)")); if (!result) { qDebug() << "DatabaseInterface::initDatabase" << createTrackIndex.lastQuery(); @@ -1352,40 +1327,8 @@ const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " "IF NOT EXISTS " - "`AlbumsArtistsAlbumIndex` ON `AlbumsArtists` " - "(`AlbumID`)")); - - if (!result) { - qDebug() << "DatabaseInterface::initDatabase" << createTrackIndex.lastQuery(); - qDebug() << "DatabaseInterface::initDatabase" << createTrackIndex.lastError(); - - Q_EMIT databaseError(); - } - } - - { - QSqlQuery createTrackIndex(d->mTracksDatabase); - - const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " - "IF NOT EXISTS " - "`TracksArtistsArtistIndex` ON `TracksArtists` " - "(`ArtistID`)")); - - if (!result) { - qDebug() << "DatabaseInterface::initDatabase" << createTrackIndex.lastQuery(); - qDebug() << "DatabaseInterface::initDatabase" << createTrackIndex.lastError(); - - Q_EMIT databaseError(); - } - } - - { - QSqlQuery createTrackIndex(d->mTracksDatabase); - - const auto &result = createTrackIndex.exec(QStringLiteral("CREATE INDEX " - "IF NOT EXISTS " - "`TracksArtistsTrackIndex` ON `TracksArtists` " - "(`TrackID`)")); + "`TracksAlbumIndex` ON `Tracks` " + "(`AlbumTitle`, `AlbumArtistName`, `AlbumPath`)")); if (!result) { qDebug() << "DatabaseInterface::initDatabase" << createTrackIndex.lastQuery(); @@ -1429,18 +1372,38 @@ "album.`ID`, " "album.`Title`, " "album.`AlbumInternalID`, " - "artist.`Name`, " + "album.`ArtistName`, " "album.`AlbumPath`, " "album.`CoverFileName`, " - "album.`TracksCount`, " - "album.`IsSingleDiscAlbum` " + "(" + "SELECT " + "COUNT(*) " + "FROM " + "`Tracks` tracks " + "WHERE " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks.`AlbumPath` = album.`AlbumPath` " + ") as `TracksCount`, " + "(" + "SELECT " + "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " + "FROM " + "`Tracks` tracks2 " + "WHERE " + "tracks2.`AlbumTitle` = album.`Title` AND " + "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks2.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks2.`AlbumPath` = album.`AlbumPath` " + ") as `IsSingleDiscAlbum` " "FROM `Albums` album " - "LEFT JOIN `AlbumsArtists` albumArtist " - "ON " - "albumArtist.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artist " - "ON " - "albumArtist.`ArtistID` = artist.`ID` " "WHERE " "album.`ID` = :albumId"); @@ -1459,18 +1422,38 @@ "album.`ID`, " "album.`Title`, " "album.`AlbumInternalID`, " - "artist.`Name`, " + "album.`ArtistName`, " "album.`AlbumPath`, " "album.`CoverFileName`, " - "album.`TracksCount`, " - "album.`IsSingleDiscAlbum` " + "(" + "SELECT " + "COUNT(*) " + "FROM " + "`Tracks` tracks " + "WHERE " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks.`AlbumPath` = album.`AlbumPath` " + ") as `TracksCount`, " + "(" + "SELECT " + "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " + "FROM " + "`Tracks` tracks2 " + "WHERE " + "tracks2.`AlbumTitle` = album.`Title` AND " + "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks2.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks2.`AlbumPath` = album.`AlbumPath` " + ") as `IsSingleDiscAlbum` " "FROM `Albums` album " - "LEFT JOIN `AlbumsArtists` albumArtist " - "ON " - "albumArtist.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artist " - "ON " - "albumArtist.`ArtistID` = artist.`ID` " "ORDER BY album.`Title` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllAlbumsQuery, selectAllAlbumsText); @@ -1504,14 +1487,8 @@ auto selectAllAlbumsText = QStringLiteral("SELECT " "album.`ID`, " "album.`Title`, " - "artist.`Name` " + "album.`ArtistName` " "FROM `Albums` album " - "LEFT JOIN `AlbumsArtists` albumArtist " - "ON " - "albumArtist.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artist " - "ON " - "albumArtist.`ArtistID` = artist.`ID` " "ORDER BY album.`Title` COLLATE NOCASE"); auto result = prepareQuery(d->mSelectAllAlbumsShortQuery, selectAllAlbumsText); @@ -1576,18 +1553,31 @@ auto selectAllTracksText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " - "tracks.`AlbumID`, " - "artist.`Name`, " - "artistAlbum.`Name`, " + "album.`ID`, " + "tracks.`ArtistName`, " + "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " - "album.`Title`, " + "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " - "album.`IsSingleDiscAlbum`, " + "(" + "SELECT " + "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " + "FROM " + "`Tracks` tracks2 " + "WHERE " + "tracks2.`AlbumTitle` = album.`Title` AND " + "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks2.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks2.`AlbumPath` = album.`AlbumPath` " + ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " @@ -1597,17 +1587,18 @@ "tracks.`BitRate`, " "tracks.`SampleRate` " "FROM " - "`Tracks` tracks, `Artists` artist, `TracksArtists` trackArtist, " + "`Tracks` tracks, " "`TracksMapping` tracksMapping " - "LEFT JOIN `Albums` album ON album.`ID` = tracks.`AlbumID` " - "LEFT JOIN `AlbumsArtists` artistAlbumMapping ON artistAlbumMapping.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artistAlbum ON artistAlbum.`ID` = artistAlbumMapping.`ArtistID` " + "LEFT JOIN " + "`Albums` album " + "ON " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = tracks.`GenreID` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`ID` = tracks.`ComposerID` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`ID` = tracks.`LyricistID` " "WHERE " - "tracks.`ID` = trackArtist.`TrackID` AND " - "artist.`ID` = trackArtist.`ArtistID` AND " "tracksMapping.`TrackID` = tracks.`ID` AND " "tracksMapping.`Priority` = (SELECT MIN(`Priority`) FROM `TracksMapping` WHERE `TrackID` = tracks.`ID`)"); @@ -1625,12 +1616,9 @@ auto selectAllTracksShortText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " - "artistAlbum.`Name` " + "tracks.`AlbumArtistName` " "FROM " - "`Tracks` tracks " - "LEFT JOIN `Albums` album ON album.`ID` = tracks.`AlbumID` " - "LEFT JOIN `AlbumsArtists` artistAlbumMapping ON artistAlbumMapping.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artistAlbum ON artistAlbum.`ID` = artistAlbumMapping.`ArtistID` "); + "`Tracks` tracks "); auto result = prepareQuery(d->mSelectAllTracksShortQuery, selectAllTracksShortText); @@ -1646,18 +1634,31 @@ auto selectAllTracksFromSourceQueryText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " - "tracks.`AlbumID`, " - "artist.`Name`, " - "artistAlbum.`Name`, " + "album.`ID`, " + "tracks.`ArtistName`, " + "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " - "album.`Title`, " + "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " - "album.`IsSingleDiscAlbum`, " + "(" + "SELECT " + "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " + "FROM " + "`Tracks` tracks2 " + "WHERE " + "tracks2.`AlbumTitle` = album.`Title` AND " + "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks2.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks2.`AlbumPath` = album.`AlbumPath` " + ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " @@ -1667,17 +1668,19 @@ "tracks.`BitRate`, " "tracks.`SampleRate` " "FROM " - "`Tracks` tracks, `Artists` artist, `TracksArtists` trackArtist, " - "`TracksMapping` tracksMapping, `DiscoverSource` source " - "LEFT JOIN `Albums` album ON album.`ID` = tracks.`AlbumID` " - "LEFT JOIN `AlbumsArtists` artistAlbumMapping ON artistAlbumMapping.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artistAlbum ON artistAlbum.`ID` = artistAlbumMapping.`ArtistID` " + "`Tracks` tracks, " + "`TracksMapping` tracksMapping, " + "`DiscoverSource` source " + "LEFT JOIN " + "`Albums` album " + "ON " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`ID` = tracks.`ComposerID` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`ID` = tracks.`LyricistID` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = tracks.`GenreID` " "WHERE " - "tracks.`ID` = trackArtist.`TrackID` AND " - "artist.`ID` = trackArtist.`ArtistID` AND " "source.`Name` = :source AND " "source.`ID` = tracksMapping.`DiscoverID` AND " "tracksMapping.`TrackID` = tracks.`ID` AND " @@ -1813,18 +1816,31 @@ auto selectTrackQueryText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " - "tracks.`AlbumID`, " - "artist.`Name`, " - "artistAlbum.`Name`, " + "album.`ID`, " + "tracks.`ArtistName`, " + "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " - "album.`Title`, " + "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " - "album.`IsSingleDiscAlbum`, " + "(" + "SELECT " + "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " + "FROM " + "`Tracks` tracks2 " + "WHERE " + "tracks2.`AlbumTitle` = album.`Title` AND " + "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks2.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks2.`AlbumPath` = album.`AlbumPath` " + ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " @@ -1834,17 +1850,18 @@ "tracks.`BitRate`, " "tracks.`SampleRate` " "FROM " - "`Tracks` tracks, `Artists` artist, `TracksArtists` trackArtist, " + "`Tracks` tracks, " "`TracksMapping` tracksMapping " - "LEFT JOIN `Albums` album ON album.`ID` = tracks.`AlbumID` " - "LEFT JOIN `AlbumsArtists` artistAlbumMapping ON artistAlbumMapping.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artistAlbum ON artistAlbum.`ID` = artistAlbumMapping.`ArtistID` " + "LEFT JOIN " + "`Albums` album " + "ON " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`ID` = tracks.`ComposerID` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`ID` = tracks.`LyricistID` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = tracks.`GenreID` " "WHERE " - "tracks.`ID` = trackArtist.`TrackID` AND " - "artist.`ID` = trackArtist.`ArtistID` AND " "tracksMapping.`TrackID` = tracks.`ID` AND " "album.`ID` = :albumId AND " "tracksMapping.`Priority` = (SELECT MIN(`Priority`) FROM `TracksMapping` WHERE `TrackID` = tracks.`ID`) " @@ -1864,18 +1881,31 @@ auto selectTrackFromIdQueryText = QStringLiteral("SELECT " "tracks.`Id`, " "tracks.`Title`, " - "tracks.`AlbumID`, " - "artist.`Name`, " - "artistAlbum.`Name`, " + "album.`ID`, " + "tracks.`ArtistName`, " + "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " - "album.`Title`, " + "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " - "album.`IsSingleDiscAlbum`, " + "(" + "SELECT " + "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " + "FROM " + "`Tracks` tracks2 " + "WHERE " + "tracks2.`AlbumTitle` = album.`Title` AND " + "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks2.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks2.`AlbumPath` = album.`AlbumPath` " + ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " @@ -1885,16 +1915,18 @@ "tracks.`BitRate`, " "tracks.`SampleRate` " "FROM " - "`Tracks` tracks, `Artists` artist, `TracksArtists` trackArtist, " + "`Tracks` tracks, " "`TracksMapping` tracksMapping " - "LEFT JOIN `Albums` album ON album.`ID` = tracks.`AlbumID` " "LEFT JOIN `AlbumsArtists` artistAlbumMapping ON artistAlbumMapping.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artistAlbum ON artistAlbum.`ID` = artistAlbumMapping.`ArtistID` " + "LEFT JOIN " + "`Albums` album " + "ON " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`ID` = tracks.`ComposerID` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`ID` = tracks.`LyricistID` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = tracks.`GenreID` " "WHERE " - "tracks.`ID` = trackArtist.`TrackID` AND " - "artist.`ID` = trackArtist.`ArtistID` AND " "tracks.`ID` = :trackId AND " "tracksMapping.`TrackID` = tracks.`ID` AND " "tracksMapping.`Priority` = (SELECT MIN(`Priority`) FROM `TracksMapping` WHERE `TrackID` = tracks.`ID`)"); @@ -1910,10 +1942,8 @@ } { auto selectCountAlbumsQueryText = QStringLiteral("SELECT count(*) " - "FROM `Albums` album, `Artists` artist, `AlbumsArtists` albumArtist " - "WHERE artist.`Name` = :artistName AND " - "album.`ID` = albumArtist.`AlbumID` AND " - "artist.`ID` = albumArtist.`ArtistID`"); + "FROM `Albums` album " + "WHERE album.`ArtistName` = :artistName "); const auto result = prepareQuery(d->mSelectCountAlbumsForArtistQuery, selectCountAlbumsQueryText); @@ -1928,15 +1958,16 @@ { auto selectGenreForArtistQueryText = QStringLiteral("SELECT DISTINCT trackGenre.`Name` " "FROM " - "`Albums` album, " - "`Artists` artist, " - "`AlbumsArtists` albumArtist, " - "`Tracks` track " - "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = track.`GenreID` " - "WHERE artist.`Name` = :artistName AND " - "album.`ID` = albumArtist.`AlbumID` AND " - "artist.`ID` = albumArtist.`ArtistID` AND " - "album.`ID` = track.`AlbumID`"); + "`Tracks` tracks " + "LEFT JOIN " + "`Albums` album " + "ON " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "tracks.`AlbumPath` = album.`AlbumPath` " + "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = tracks.`GenreID` " + "WHERE " + "album.`ArtistName` = :artistName"); const auto result = prepareQuery(d->mSelectGenreForArtistQuery, selectGenreForArtistQueryText); @@ -1951,10 +1982,16 @@ { auto selectGenreForAlbumQueryText = QStringLiteral("SELECT DISTINCT trackGenre.`Name` " "FROM " - "`Tracks` track " - "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = track.`GenreID` " + "`Tracks` tracks " + "LEFT JOIN " + "`Albums` album " + "ON " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "tracks.`AlbumPath` = album.`AlbumPath` " + "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = tracks.`GenreID` " "WHERE " - "track.`AlbumID` = :albumId"); + "album.`ID` = :albumId"); const auto result = prepareQuery(d->mSelectGenreForAlbumQuery, selectGenreForAlbumQueryText); @@ -1968,12 +2005,15 @@ { auto selectCountAlbumsQueryText = QStringLiteral("SELECT distinct count(album.`ID`) " - "FROM `Albums` album, " - "`Tracks` track, " - "`Composer` albumComposer " - "WHERE albumComposer.`Name` = :artistName AND " - "track.`ComposerID` = albumComposer.`ID` AND " - "track.`AlbumID` = album.`ID`"); + "FROM " + "`Tracks` tracks, " + "`Albums` album " + "LEFT JOIN `Composer` albumComposer ON albumComposer.`ID` = tracks.`ComposerID` " + "WHERE " + "(tracks.`AlbumTitle` = album.`Title` OR tracks.`AlbumTitle` IS NULL ) AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "(tracks.`AlbumPath` = album.`AlbumPath` OR tracks.`AlbumPath` IS NULL ) AND " + "albumComposer.`Name` = :artistName"); const auto result = prepareQuery(d->mSelectCountAlbumsForComposerQuery, selectCountAlbumsQueryText); @@ -1987,12 +2027,15 @@ { auto selectCountAlbumsQueryText = QStringLiteral("SELECT distinct count(album.`ID`) " - "FROM `Albums` album, " - "`Tracks` track, " - "`Lyricist` albumLyricist " - "WHERE albumLyricist.`Name` = :artistName AND " - "track.`LyricistID` = albumLyricist.`ID` AND " - "track.`AlbumID` = album.`ID`"); + "FROM " + "`Tracks` tracks, " + "`Albums` album " + "LEFT JOIN `Lyricist` albumLyricist ON albumLyricist.`ID` = tracks.`LyricistID` " + "WHERE " + "(tracks.`AlbumTitle` = album.`Title` OR tracks.`AlbumTitle` IS NULL ) AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "(tracks.`AlbumPath` = album.`AlbumPath` OR tracks.`AlbumPath` IS NULL ) AND " + "albumLyricist.`Name` = :artistName"); const auto result = prepareQuery(d->mSelectCountAlbumsForLyricistQuery, selectCountAlbumsQueryText); @@ -2008,11 +2051,9 @@ auto selectAlbumIdFromTitleQueryText = QStringLiteral("SELECT " "album.`ID` " "FROM " - "`Albums` album, `Artists` artist, `AlbumsArtists` albumArtist " + "`Albums` album " "WHERE " - "artist.`Name` = :artistName AND " - "album.`ID` = albumArtist.`AlbumID` AND " - "artist.`ID` = albumArtist.`ArtistID` AND " + "album.`ArtistName` = :artistName AND " "album.`Title` = :title"); auto result = prepareQuery(d->mSelectAlbumIdFromTitleQuery, selectAlbumIdFromTitleQueryText); @@ -2029,13 +2070,11 @@ auto selectAlbumIdFromTitleAndArtistQueryText = QStringLiteral("SELECT " "album.`ID` " "FROM " - "`Albums` album, " - "`AlbumsArtists` albumArtist " + "`Albums` album " "WHERE " - "album.`ID` = albumArtist.`AlbumID` AND " + "album.`ArtistName` = :artistName AND " "album.`Title` = :title AND " - "album.`AlbumPath` = :albumPath AND " - "albumArtist.`ArtistID` = :artistId"); + "album.`AlbumPath` = :albumPath"); auto result = prepareQuery(d->mSelectAlbumIdFromTitleAndArtistQuery, selectAlbumIdFromTitleAndArtistQueryText); @@ -2055,14 +2094,7 @@ "WHERE " "album.`AlbumPath` = :albumPath AND " "album.`Title` = :title AND " - "NOT EXISTS (" - "SELECT " - "albumArtist.`AlbumID` " - "FROM " - "`AlbumsArtists` albumArtist " - "WHERE " - "albumArtist.`AlbumID` = album.`ID`" - ")"); + "album.`ArtistName` IS NULL"); auto result = prepareQuery(d->mSelectAlbumIdFromTitleWithoutArtistQuery, selectAlbumIdFromTitleWithoutArtistQueryText); @@ -2078,17 +2110,15 @@ auto insertAlbumQueryText = QStringLiteral("INSERT INTO `Albums` " "(`ID`, " "`Title`, " + "`ArtistName`, " "`AlbumPath`, " - "`CoverFileName`, " - "`TracksCount`, " - "`IsSingleDiscAlbum`) " + "`CoverFileName`) " "VALUES " "(:albumId, " ":title, " + ":albumArtist, " ":albumPath, " - ":coverFileName, " - ":tracksCount, " - ":isSingleDiscAlbum)"); + ":coverFileName)"); auto result = prepareQuery(d->mInsertAlbumQuery, insertAlbumQueryText); @@ -2100,34 +2130,6 @@ } } - { - auto insertAlbumArtistQueryText = QStringLiteral("INSERT INTO `AlbumsArtists` (`AlbumID`, `ArtistID`) " - "VALUES (:albumId, :artistId)"); - - auto result = prepareQuery(d->mInsertAlbumArtistQuery, insertAlbumArtistQueryText); - - if (!result) { - qDebug() << "DatabaseInterface::initRequest" << d->mInsertAlbumArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::initRequest" << d->mInsertAlbumArtistQuery.lastError(); - - Q_EMIT databaseError(); - } - } - - { - auto insertTrackArtistQueryText = QStringLiteral("INSERT INTO `TracksArtists` (`TrackID`, `ArtistID`) " - "VALUES (:trackId, :artistId)"); - - auto result = prepareQuery(d->mInsertTrackArtistQuery, insertTrackArtistQueryText); - - if (!result) { - qDebug() << "DatabaseInterface::initRequest" << d->mInsertTrackArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::initRequest" << d->mInsertTrackArtistQuery.lastError(); - - Q_EMIT databaseError(); - } - } - { auto insertTrackMappingQueryText = QStringLiteral("INSERT INTO " "`TracksMapping` " @@ -2197,18 +2199,31 @@ auto selectTracksWithoutMappingQueryText = QStringLiteral("SELECT " "tracks.`Id`, " "tracks.`Title`, " - "tracks.`AlbumID`, " - "artist.`Name`, " - "artistAlbum.`Name`, " + "album.`ID`, " + "tracks.`ArtistName`, " + "tracks.`AlbumArtistName`, " "\"\" as FileName, " "NULL as FileModifiedTime, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " - "album.`Title`, " + "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " - "album.`IsSingleDiscAlbum`, " + "(" + "SELECT " + "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " + "FROM " + "`Tracks` tracks2 " + "WHERE " + "tracks2.`AlbumTitle` = album.`Title` AND " + "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks2.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks2.`AlbumPath` = album.`AlbumPath` " + ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " @@ -2218,18 +2233,17 @@ "tracks.`BitRate`, " "tracks.`SampleRate` " "FROM " - "`Tracks` tracks, " - "`Artists` artist, " - "`TracksArtists` trackArtist " - "LEFT JOIN `Albums` album ON album.`ID` = tracks.`AlbumID` " - "LEFT JOIN `AlbumsArtists` artistAlbumMapping ON artistAlbumMapping.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artistAlbum ON artistAlbum.`ID` = artistAlbumMapping.`ArtistID` " + "`Tracks` tracks " + "LEFT JOIN " + "`Albums` album " + "ON " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`ID` = tracks.`ComposerID` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`ID` = tracks.`LyricistID` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = tracks.`GenreID` " "WHERE " - "tracks.`ID` = trackArtist.`TrackID` AND " - "artist.`ID` = trackArtist.`ArtistID` AND " "tracks.`ID` NOT IN (SELECT tracksMapping2.`TrackID` FROM `TracksMapping` tracksMapping2)"); auto result = prepareQuery(d->mSelectTracksWithoutMappingQuery, selectTracksWithoutMappingQueryText); @@ -2351,14 +2365,16 @@ auto selectTrackQueryText = QStringLiteral("SELECT " "tracks.`ID`, tracksMapping.`FileName` " "FROM " - "`Tracks` tracks, `Artists` artist, `TracksArtists` trackArtist, " + "`Tracks` tracks, " + "`Albums` album, " "`TracksMapping` tracksMapping " "WHERE " "tracks.`Title` = :title AND " - "tracks.`AlbumID` = :album AND " - "artist.`Name` = :artist AND " - "tracks.`ID` = trackArtist.`TrackID` AND " - "artist.`ID` = trackArtist.`ArtistID` AND " + "album.`ID` = :album AND " + "(tracks.`AlbumTitle` = album.`Title` OR tracks.`AlbumTitle` IS NULL ) AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "(tracks.`AlbumPath` = album.`AlbumPath` OR tracks.`AlbumPath` IS NULL ) AND " + "tracks.`ArtistName` = :artist AND " "tracksMapping.`TrackID` = tracks.`ID` AND " "tracksMapping.`Priority` = (SELECT MIN(`Priority`) FROM `TracksMapping` WHERE `TrackID` = tracks.`ID`)"); @@ -2373,8 +2389,46 @@ } { - auto insertTrackQueryText = QStringLiteral("INSERT INTO `Tracks` (`ID`, `Title`, `AlbumID`, `GenreID`, `ComposerID`, `LyricistID`, `Comment`, `TrackNumber`, `DiscNumber`, `Channels`, `BitRate`, `SampleRate`, `Year`, `Duration`, `Rating` ) " - "VALUES (:trackId, :title, :album, :genreId, :composerId, :lyricistId, :comment, :trackNumber, :discNumber, :channels, :bitRate, :sampleRate, :year, :trackDuration, :trackRating)"); + auto insertTrackQueryText = QStringLiteral("INSERT INTO `Tracks` " + "(" + "`ID`, " + "`Title`, " + "`ArtistName`, " + "`AlbumTitle`, " + "`AlbumArtistName`, " + "`AlbumPath`, " + "`GenreID`, " + "`ComposerID`, " + "`LyricistID`, " + "`Comment`, " + "`TrackNumber`, " + "`DiscNumber`, " + "`Channels`, " + "`BitRate`, " + "`SampleRate`, " + "`Year`, " + "`Duration`, " + "`Rating` ) " + "VALUES " + "(" + ":trackId, " + ":title, " + ":artistName, " + ":albumTitle, " + ":albumArtistName, " + ":albumPath, " + ":genreId, " + ":composerId, " + ":lyricistId, " + ":comment, " + ":trackNumber, " + ":discNumber, " + ":channels, " + ":bitRate, " + ":sampleRate, " + ":year, " + ":trackDuration, " + ":trackRating)"); auto result = prepareQuery(d->mInsertTrackQuery, insertTrackQueryText); @@ -2390,7 +2444,10 @@ auto updateTrackQueryText = QStringLiteral("UPDATE `Tracks` " "SET " "`Title` = :title, " - "`AlbumID` = :album, " + "`ArtistName` = :artistName, " + "`AlbumTitle` = :albumTitle, " + "`AlbumArtistName` = :albumArtistName, " + "`AlbumPath` = :albumPath, " "`GenreID` = :genreId, " "`ComposerID` = :composerId, " "`LyricistID` = :lyricistId, " @@ -2416,23 +2473,53 @@ } } + { + auto updateAlbumArtistQueryText = QStringLiteral("UPDATE `Albums` " + "SET " + "`ArtistName` = :artistName " + "WHERE " + "`ID` = :albumId"); + + auto result = prepareQuery(d->mUpdateAlbumArtistQuery, updateAlbumArtistQueryText); + + if (!result) { + qDebug() << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtistQuery.lastQuery(); + qDebug() << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtistQuery.lastError(); + + Q_EMIT databaseError(); + } + } + + { + auto updateAlbumArtistInTracksQueryText = QStringLiteral("UPDATE `Tracks` " + "SET " + "`AlbumArtistName` = :artistName " + "WHERE " + "`AlbumTitle` = :albumTitle AND " + "`AlbumPath` = :albumPath AND " + "`AlbumArtistName` IS NULL"); + + auto result = prepareQuery(d->mUpdateAlbumArtistInTracksQuery, updateAlbumArtistInTracksQueryText); + + if (!result) { + qDebug() << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtistInTracksQuery.lastQuery(); + qDebug() << "DatabaseInterface::initRequest" << d->mUpdateAlbumArtistInTracksQuery.lastError(); + + Q_EMIT databaseError(); + } + } + { auto selectTrackQueryText = QStringLiteral("SELECT " "tracks.ID " "FROM " - "`Tracks` tracks, " - "`Albums` albums, " - "`TracksArtists` trackArtist, " - "`Artists` artist " + "`Tracks` tracks " "WHERE " "tracks.`Title` = :title AND " - "tracks.`AlbumID` = albums.`ID` AND " - "albums.`Title` = :album AND " + "tracks.`AlbumTitle` = :album AND " "tracks.`TrackNumber` = :trackNumber AND " "tracks.`DiscNumber` = :discNumber AND " - "trackArtist.`TrackID` = tracks.`ID` AND " - "trackArtist.`ArtistID` = artist.`ID` AND " - "artist.`Name` = :artist"); + "tracks.`ArtistName` = :artist"); auto result = prepareQuery(d->mSelectTrackIdFromTitleArtistAlbumTrackDiscNumberQuery, selectTrackQueryText); @@ -2452,27 +2539,16 @@ "`Albums` albums " "WHERE " "tracks.`Title` = :title AND " - "tracks.`AlbumID` = albums.`ID` AND " + "tracks.`AlbumTitle` = albums.`Title` AND " + "tracks.`AlbumArtistName` = albums.`ArtistName` AND " + "tracks.`AlbumPath` = albums.`AlbumPath` AND " "albums.`Title` = :album AND " "albums.`AlbumPath` = :albumPath AND " "tracks.`TrackNumber` = :trackNumber AND " "tracks.`DiscNumber` = :discNumber AND " "( " - "( NOT EXISTS (SELECT albumArtistMapping.`AlbumID` " - "FROM " - "`AlbumsArtists` albumArtistMapping " - "WHERE " - "albumArtistMapping.`AlbumID` = albums.`ID`) " - ") OR " - "( EXISTS (SELECT albumArtistMapping.`AlbumID` " - "FROM " - "`AlbumsArtists` albumArtistMapping, " - "`Artists` albumArtist " - "WHERE " - "albumArtist.`Name` = :albumArtist AND " - "albumArtist.`ID` = albumArtistMapping.`ArtistID` AND " - "albumArtistMapping.`AlbumID` = albums.`ID`) " - ") " + "( albums.`ArtistName` IS NULL) OR " + "( albums.`ArtistName` = :albumArtist) " ")"); auto result = prepareQuery(d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery, selectTrackQueryText); @@ -2502,54 +2578,6 @@ } } - { - auto selectAlbumTrackCountQueryText = QStringLiteral("SELECT `TracksCount` " - "FROM `Albums`" - "WHERE " - "`ID` = :albumId"); - - auto result = prepareQuery(d->mSelectAlbumTrackCountQuery, selectAlbumTrackCountQueryText); - - if (!result) { - qDebug() << "DatabaseInterface::initRequest" << d->mSelectAlbumTrackCountQuery.lastQuery(); - qDebug() << "DatabaseInterface::initRequest" << d->mSelectAlbumTrackCountQuery.lastError(); - - Q_EMIT databaseError(); - } - } - { - auto updateAlbumQueryText = QStringLiteral("UPDATE `Albums` " - "SET `TracksCount` = (SELECT COUNT(*) FROM `Tracks` WHERE `AlbumID` = `Albums`.`ID`) " - "WHERE " - "`ID` = :albumId"); - - auto result = prepareQuery(d->mUpdateAlbumQuery, updateAlbumQueryText); - - if (!result) { - qDebug() << "DatabaseInterface::initRequest" << d->mUpdateAlbumQuery.lastQuery(); - qDebug() << "DatabaseInterface::initRequest" << d->mUpdateAlbumQuery.lastError(); - - Q_EMIT databaseError(); - } - } - - { - auto updateIsSingleDiscAlbumFromIdQueryText = QStringLiteral("UPDATE `Albums` " - "SET `IsSingleDiscAlbum` = (SELECT COUNT(DISTINCT DiscNumber) = 1 FROM `Tracks` WHERE `AlbumID` = :albumId) " - "WHERE " - "`ID` = :albumId AND " - "`IsSingleDiscAlbum` != (SELECT COUNT(DISTINCT DiscNumber) = 1 FROM `Tracks` WHERE `AlbumID` = :albumId)"); - - auto result = prepareQuery(d->mUpdateIsSingleDiscAlbumFromIdQuery, updateIsSingleDiscAlbumFromIdQueryText); - - if (!result) { - qDebug() << "DatabaseInterface::initRequest" << d->mUpdateIsSingleDiscAlbumFromIdQuery.lastQuery(); - qDebug() << "DatabaseInterface::initRequest" << d->mUpdateIsSingleDiscAlbumFromIdQuery.lastError(); - - Q_EMIT databaseError(); - } - } - { auto updateAlbumArtUriFromAlbumIdQueryText = QStringLiteral("UPDATE `Albums` " "SET `CoverFileName` = :coverFileName " @@ -2570,38 +2598,53 @@ auto selectTracksFromArtistQueryText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " - "tracks.`AlbumID`, " - "artist.`Name`, " - "artistAlbum.`Name`, " + "album.`ID`, " + "tracks.`ArtistName`, " + "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " - "album.`Title`, " + "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " - "album.`IsSingleDiscAlbum`, " + "(" + "SELECT " + "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " + "FROM " + "`Tracks` tracks2 " + "WHERE " + "tracks2.`AlbumTitle` = album.`Title` AND " + "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks2.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks2.`AlbumPath` = album.`AlbumPath` " + ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " "tracks.`Comment`, " "tracks.`Year`, " "tracks.`Channels`, " "tracks.`BitRate`, " "tracks.`SampleRate` " - "FROM `Tracks` tracks, `Albums` album, `Artists` artist, `TracksArtists` trackArtist, " + "FROM " + "`Tracks` tracks, " "`TracksMapping` tracksMapping " - "LEFT JOIN `AlbumsArtists` artistAlbumMapping ON artistAlbumMapping.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artistAlbum ON artistAlbum.`ID` = artistAlbumMapping.`ArtistID` " + "LEFT JOIN " + "`Albums` album " + "ON " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`ID` = tracks.`ComposerID` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`ID` = tracks.`LyricistID` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = tracks.`GenreID` " "WHERE " - "artist.`Name` = :artistName AND " - "tracks.`AlbumID` = album.`ID` AND " - "artist.`ID` = trackArtist.`ArtistID` AND " - "tracks.`ID` = trackArtist.`TrackID` AND " + "tracks.`ArtistName` = :artistName AND " "tracksMapping.`TrackID` = tracks.`ID` AND " "tracksMapping.`Priority` = (SELECT MIN(`Priority`) FROM `TracksMapping` WHERE `TrackID` = tracks.`ID`) " "ORDER BY tracks.`Title` ASC, " @@ -2621,13 +2664,9 @@ auto selectAlbumIdsFromArtistQueryText = QStringLiteral("SELECT " "album.`ID` " "FROM " - "`Albums` album, " - "`Artists` artist," - "`AlbumsArtists` albumArtist " + "`Albums` album " "WHERE " - "album.`ID` = albumArtist.`AlbumID` AND " - "artist.`ID` = albumArtist.`ArtistID` AND " - "artist.`Name` = :artistName"); + "album.`ArtistName` = :artistName"); auto result = prepareQuery(d->mSelectAlbumIdsFromArtist, selectAlbumIdsFromArtistQueryText); @@ -2707,37 +2746,52 @@ auto selectTrackFromFilePathQueryText = QStringLiteral("SELECT " "tracks.`ID`, " "tracks.`Title`, " - "tracks.`AlbumID`, " - "artist.`Name`, " - "artistAlbum.`Name`, " + "album.`ID`, " + "tracks.`ArtistName`, " + "tracks.`AlbumArtistName`, " "tracksMapping.`FileName`, " "tracksMapping.`FileModifiedTime`, " "tracks.`TrackNumber`, " "tracks.`DiscNumber`, " "tracks.`Duration`, " - "album.`Title`, " + "tracks.`AlbumTitle`, " "tracks.`Rating`, " "album.`CoverFileName`, " - "album.`IsSingleDiscAlbum`, " + "(" + "SELECT " + "COUNT(DISTINCT tracks2.DiscNumber) <= 1 " + "FROM " + "`Tracks` tracks2 " + "WHERE " + "tracks2.`AlbumTitle` = album.`Title` AND " + "(tracks2.`AlbumArtistName` = album.`ArtistName` OR " + "(tracks2.`AlbumArtistName` IS NULL AND " + "album.`ArtistName` IS NULL" + ")" + ") AND " + "tracks2.`AlbumPath` = album.`AlbumPath` " + ") as `IsSingleDiscAlbum`, " "trackGenre.`Name`, " "trackComposer.`Name`, " "trackLyricist.`Name`, " "tracks.`Comment`, " "tracks.`Year`, " "tracks.`Channels`, " "tracks.`BitRate`, " "tracks.`SampleRate` " - "FROM `Tracks` tracks, `Artists` artist, `Albums` album, `TracksArtists` trackArtist, " + "FROM " + "`Tracks` tracks, " "`TracksMapping` tracksMapping " - "LEFT JOIN `AlbumsArtists` artistAlbumMapping ON artistAlbumMapping.`AlbumID` = album.`ID` " - "LEFT JOIN `Artists` artistAlbum ON artistAlbum.`ID` = artistAlbumMapping.`ArtistID` " + "LEFT JOIN " + "`Albums` album " + "ON " + "tracks.`AlbumTitle` = album.`Title` AND " + "(tracks.`AlbumArtistName` = album.`ArtistName` OR tracks.`AlbumArtistName` IS NULL ) AND " + "tracks.`AlbumPath` = album.`AlbumPath` " "LEFT JOIN `Composer` trackComposer ON trackComposer.`ID` = tracks.`ComposerID` " "LEFT JOIN `Lyricist` trackLyricist ON trackLyricist.`ID` = tracks.`LyricistID` " "LEFT JOIN `Genre` trackGenre ON trackGenre.`ID` = tracks.`GenreID` " "WHERE " - "tracks.`AlbumID` = album.`ID` AND " - "artist.`ID` = trackArtist.`ArtistID` AND " - "tracks.`ID` = trackArtist.`TrackID` AND " "tracksMapping.`TrackID` = tracks.`ID` AND " "tracksMapping.`FileName` = :filePath AND " "tracksMapping.`Priority` = (SELECT MIN(`Priority`) FROM `TracksMapping` WHERE `TrackID` = tracks.`ID`)"); @@ -2767,21 +2821,6 @@ } } - { - auto removeTrackArtistQueryText = QStringLiteral("DELETE FROM `TracksArtists` " - "WHERE " - "`TrackID` = :trackId"); - - auto result = prepareQuery(d->mRemoveTrackArtistQuery, removeTrackArtistQueryText); - - if (!result) { - qDebug() << "DatabaseInterface::initRequest" << d->mRemoveTrackArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::initRequest" << d->mRemoveTrackArtistQuery.lastError(); - - Q_EMIT databaseError(); - } - } - { auto removeAlbumQueryText = QStringLiteral("DELETE FROM `Albums` " "WHERE " @@ -2797,21 +2836,6 @@ } } - { - auto removeAlbumArtistQueryText = QStringLiteral("DELETE FROM `AlbumsArtists` " - "WHERE " - "`AlbumID` = :albumId"); - - auto result = prepareQuery(d->mRemoveAlbumArtistQuery, removeAlbumArtistQueryText); - - if (!result) { - qDebug() << "DatabaseInterface::initRequest" << d->mRemoveAlbumArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::initRequest" << d->mRemoveAlbumArtistQuery.lastError(); - - Q_EMIT databaseError(); - } - } - { auto removeAlbumQueryText = QStringLiteral("DELETE FROM `Artists` " "WHERE " @@ -2834,8 +2858,7 @@ } qulonglong DatabaseInterface::insertAlbum(const QString &title, const QString &albumArtist, const QString &trackArtist, - const QString &trackPath, const QUrl &albumArtURI, int tracksCount, - AlbumDiscsCount isSingleDiscAlbum) + const QString &trackPath, const QUrl &albumArtURI) { auto result = qulonglong(0); @@ -2847,9 +2870,9 @@ d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":title"), title); d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":albumPath"), trackPath); if (!albumArtist.isEmpty()) { - d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":artistId"), insertArtist(albumArtist)); + d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":artistName"), albumArtist); } else { - d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":artistId"), insertArtist(trackArtist)); + d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":artistName"), trackArtist); } auto queryResult = d->mSelectAlbumIdFromTitleAndArtistQuery.exec(); @@ -2908,10 +2931,14 @@ d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumId"), d->mAlbumId); d->mInsertAlbumQuery.bindValue(QStringLiteral(":title"), title); + if (!albumArtist.isEmpty()) { + insertArtist(albumArtist); + d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumArtist"), albumArtist); + } else { + d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumArtist"), {}); + } d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumPath"), trackPath); d->mInsertAlbumQuery.bindValue(QStringLiteral(":coverFileName"), albumArtURI); - d->mInsertAlbumQuery.bindValue(QStringLiteral(":tracksCount"), tracksCount); - d->mInsertAlbumQuery.bindValue(QStringLiteral(":isSingleDiscAlbum"), isSingleDiscAlbum == SingleDiscAlbum); auto queryResult = d->mInsertAlbumQuery.exec(); @@ -2931,56 +2958,18 @@ d->mInsertAlbumQuery.finish(); - if (!albumArtist.isEmpty()) { - d->mInsertAlbumArtistQuery.bindValue(QStringLiteral(":albumId"), d->mAlbumId); - d->mInsertAlbumArtistQuery.bindValue(QStringLiteral(":artistId"), insertArtist(albumArtist)); - - queryResult = d->mInsertAlbumArtistQuery.exec(); - - if (!queryResult || !d->mInsertAlbumArtistQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::insertAlbum" << d->mInsertAlbumArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::insertAlbum" << d->mInsertAlbumArtistQuery.boundValues(); - qDebug() << "DatabaseInterface::insertAlbum" << d->mInsertAlbumArtistQuery.lastError(); - - d->mInsertAlbumArtistQuery.finish(); - - return result; - } - - d->mInsertAlbumArtistQuery.finish(); - } - ++d->mAlbumId; - d->mInsertedAlbums.push_back(result); + d->mInsertedAlbums.insert(result); return result; } -bool DatabaseInterface::updateAlbumFromId(qulonglong albumId, const QUrl &albumArtUri, const MusicAudioTrack ¤tTrack) +bool DatabaseInterface::updateAlbumFromId(qulonglong albumId, const QUrl &albumArtUri, + const MusicAudioTrack ¤tTrack, const QString &albumPath) { auto modifiedAlbum = false; - - d->mUpdateIsSingleDiscAlbumFromIdQuery.bindValue(QStringLiteral(":albumId"), albumId); - - auto result = d->mUpdateIsSingleDiscAlbumFromIdQuery.exec(); - - if (!result || !d->mUpdateIsSingleDiscAlbumFromIdQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mUpdateIsSingleDiscAlbumFromIdQuery.lastQuery(); - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mUpdateIsSingleDiscAlbumFromIdQuery.boundValues(); - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mUpdateIsSingleDiscAlbumFromIdQuery.lastError(); - - d->mUpdateIsSingleDiscAlbumFromIdQuery.finish(); - - return modifiedAlbum; - } - - modifiedAlbum = (d->mUpdateIsSingleDiscAlbumFromIdQuery.numRowsAffected() != 0); - d->mUpdateIsSingleDiscAlbumFromIdQuery.finish(); + modifiedAlbum = true; if (!albumArtUri.isValid()) { return modifiedAlbum; @@ -2992,14 +2981,14 @@ d->mUpdateAlbumArtUriFromAlbumIdQuery.bindValue(QStringLiteral(":albumId"), albumId); d->mUpdateAlbumArtUriFromAlbumIdQuery.bindValue(QStringLiteral(":coverFileName"), albumArtUri); - result = d->mUpdateAlbumArtUriFromAlbumIdQuery.exec(); + auto result = d->mUpdateAlbumArtUriFromAlbumIdQuery.exec(); if (!result || !d->mUpdateAlbumArtUriFromAlbumIdQuery.isActive()) { Q_EMIT databaseError(); - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastQuery(); - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mUpdateAlbumArtUriFromAlbumIdQuery.boundValues(); - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastError(); + qDebug() << "DatabaseInterface::updateAlbumFromId" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastQuery(); + qDebug() << "DatabaseInterface::updateAlbumFromId" << d->mUpdateAlbumArtUriFromAlbumIdQuery.boundValues(); + qDebug() << "DatabaseInterface::updateAlbumFromId" << d->mUpdateAlbumArtUriFromAlbumIdQuery.lastError(); d->mUpdateAlbumArtUriFromAlbumIdQuery.finish(); @@ -3012,42 +3001,7 @@ } if (!isValidArtist(albumId) && currentTrack.isValidAlbumArtist()) { - d->mRemoveAlbumArtistQuery.bindValue(QStringLiteral(":albumId"), albumId); - - result = d->mRemoveAlbumArtistQuery.exec(); - - if (!result || !d->mRemoveAlbumArtistQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mRemoveAlbumArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mRemoveAlbumArtistQuery.boundValues(); - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mRemoveAlbumArtistQuery.lastError(); - - d->mRemoveAlbumArtistQuery.finish(); - - return modifiedAlbum; - } - - d->mRemoveAlbumArtistQuery.finish(); - - d->mInsertAlbumArtistQuery.bindValue(QStringLiteral(":albumId"), albumId); - d->mInsertAlbumArtistQuery.bindValue(QStringLiteral(":artistId"), insertArtist(currentTrack.albumArtist())); - - result = d->mInsertAlbumArtistQuery.exec(); - - if (!result || !d->mInsertAlbumArtistQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mInsertAlbumArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mInsertAlbumArtistQuery.boundValues(); - qDebug() << "DatabaseInterface::updateIsSingleDiscAlbumFromId" << d->mInsertAlbumArtistQuery.lastError(); - - d->mInsertAlbumArtistQuery.finish(); - - return modifiedAlbum; - } - - d->mInsertAlbumArtistQuery.finish(); + updateAlbumArtist(albumId, currentTrack.albumName(), albumPath, currentTrack.albumArtist()); modifiedAlbum = true; } @@ -3110,7 +3064,7 @@ ++d->mArtistId; - d->mInsertedArtists.push_back(result); + d->mInsertedArtists.insert(result); d->mInsertArtistsQuery.finish(); @@ -3396,7 +3350,7 @@ { qulonglong resultId = 0; - if (oneTrack.title().isEmpty() || oneTrack.artist().isEmpty()) { + if (oneTrack.title().isEmpty()) { return resultId; } @@ -3409,13 +3363,10 @@ const auto &trackPath = oneTrack.resourceURI().toString(currentOptions); - qulonglong albumId = 0; + auto albumId = insertAlbum(oneTrack.albumName(), (oneTrack.isValidAlbumArtist() ? oneTrack.albumArtist() : QString()), + oneTrack.artist(), trackPath, covers[oneTrack.resourceURI().toString()]); - /* album is only added if an album name and an album artist are given */ - if(!oneTrack.albumName().isEmpty() && !oneTrack.albumArtist().isEmpty()) { - albumId = insertAlbum(oneTrack.albumName(), (oneTrack.isValidAlbumArtist() ? oneTrack.albumArtist() : QString()), - oneTrack.artist(), trackPath, covers[oneTrack.resourceURI().toString()], 0, SingleDiscAlbum); - } + const auto ¤tAlbum = internalAlbumFromId(albumId); auto otherTrackId = getDuplicateTrackIdFromTitleAlbumTrackDiscNumber(oneTrack.title(), oneTrack.albumName(), oneTrack.albumArtist(), trackPath, oneTrack.trackNumber(), oneTrack.discNumber()); @@ -3456,14 +3407,16 @@ if (!isSameTrack) { auto newTrack = oneTrack; newTrack.setDatabaseId(oldTrack.databaseId()); - updateTrackInDatabase(newTrack, albumId); + updateTrackInDatabase(newTrack, trackPath); updateTrackOrigin(newTrack.databaseId(), oneTrack.resourceURI(), oneTrack.fileModificationTime()); - updateAlbumFromId(albumId, oneTrack.albumCover(), oneTrack); + updateAlbumFromId(albumId, oneTrack.albumCover(), oneTrack, trackPath); recordModifiedTrack(originTrackId); - d->mModifiedAlbumIds.insert(albumId); + if (albumId != 0) { + recordModifiedAlbum(albumId); + } if (oldAlbumId != 0) { - d->mModifiedAlbumIds.insert(oldAlbumId); + recordModifiedAlbum(oldAlbumId); } isSameTrack = true; @@ -3477,11 +3430,15 @@ if (!isSameTrack) { d->mInsertTrackQuery.bindValue(QStringLiteral(":trackId"), originTrackId); d->mInsertTrackQuery.bindValue(QStringLiteral(":title"), oneTrack.title()); - if (albumId != 0) { - d->mInsertTrackQuery.bindValue(QStringLiteral(":album"), albumId); + insertArtist(oneTrack.artist()); + d->mInsertTrackQuery.bindValue(QStringLiteral(":artistName"), oneTrack.artist()); + d->mInsertTrackQuery.bindValue(QStringLiteral(":albumTitle"), currentAlbum.title()); + if (currentAlbum.isValidArtist()) { + d->mInsertTrackQuery.bindValue(QStringLiteral(":albumArtistName"), currentAlbum.artist()); } else { - d->mInsertTrackQuery.bindValue(QStringLiteral(":album"), {}); + d->mInsertTrackQuery.bindValue(QStringLiteral(":albumArtistName"), {}); } + d->mInsertTrackQuery.bindValue(QStringLiteral(":albumPath"), trackPath); d->mInsertTrackQuery.bindValue(QStringLiteral(":trackNumber"), oneTrack.trackNumber()); d->mInsertTrackQuery.bindValue(QStringLiteral(":discNumber"), oneTrack.discNumber()); d->mInsertTrackQuery.bindValue(QStringLiteral(":trackDuration"), QVariant::fromValue(oneTrack.duration().msecsSinceStartOfDay())); @@ -3515,28 +3472,6 @@ if (result && d->mInsertTrackQuery.isActive()) { d->mInsertTrackQuery.finish(); - if (!isModifiedTrack || (!isSameTrack && oneTrack.artist() != oldTrack.artist())) { - d->mInsertTrackArtistQuery.bindValue(QStringLiteral(":trackId"), originTrackId); - d->mInsertTrackArtistQuery.bindValue(QStringLiteral(":artistId"), insertArtist(oneTrack.artist())); - - result = d->mInsertTrackArtistQuery.exec(); - - if (!result || !d->mInsertTrackArtistQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackArtistQuery.boundValues(); - qDebug() << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackArtistQuery.lastError(); - - d->mInsertTrackArtistQuery.finish(); - - return resultId; - } - - d->mInsertTrackArtistQuery.finish(); - } - - if (!isModifiedTrack) { ++d->mTrackId; } @@ -3546,26 +3481,23 @@ if (isModifiedTrack) { recordModifiedTrack(originTrackId); if (albumId != 0) { - d->mModifiedAlbumIds.insert(albumId); + recordModifiedAlbum(albumId); } if (oldAlbumId != 0) { - d->mModifiedAlbumIds.insert(oldAlbumId); + recordModifiedAlbum(oldAlbumId); } } if (albumId != 0) { - if (updateAlbumFromId(albumId, covers[oneTrack.resourceURI().toString()], oneTrack)) { + if (updateAlbumFromId(albumId, covers[oneTrack.resourceURI().toString()], oneTrack, trackPath)) { auto modifiedTracks = fetchTrackIds(albumId); for (auto oneModifiedTrack : modifiedTracks) { if (oneModifiedTrack != resultId) { recordModifiedTrack(oneModifiedTrack); } } - d->mModifiedAlbumIds.insert(albumId); - } - if (updateTracksCount(albumId)) { - d->mModifiedAlbumIds.insert(albumId); } + recordModifiedAlbum(albumId); } } else { d->mInsertTrackQuery.finish(); @@ -3586,7 +3518,7 @@ { auto id = trackRecord.value(0).toULongLong(); - auto result = d->mTracksCache.value(id); + auto &result = d->mTracksCache[id]; if (result.isValid()) { return result; @@ -3622,8 +3554,6 @@ result.setValid(true); - d->mTracksCache[id] = result; - return result; } @@ -3702,6 +3632,11 @@ QSet modifiedAlbums; + QUrl::FormattingOptions currentOptions = QUrl::PreferLocalFile | + QUrl::RemoveAuthority | QUrl::RemoveFilename | QUrl::RemoveFragment | + QUrl::RemovePassword | QUrl::RemovePort | QUrl::RemoveQuery | + QUrl::RemoveScheme | QUrl::RemoveUserInfo; + for (const auto &oneRemovedTrack : willRemoveTrack) { removeTrackInDatabase(oneRemovedTrack.databaseId()); @@ -3712,13 +3647,13 @@ const auto &allAlbumsFromArtist = internalAlbumIdsFromAuthor(oneRemovedTrack.artist()); const auto &removedArtistId = internalArtistIdFromName(oneRemovedTrack.artist()); const auto &removedArtist = internalArtistFromId(removedArtistId); + const auto &trackPath = oneRemovedTrack.resourceURI().toString(currentOptions); - if (updateTracksCount(modifiedAlbumId)) { - modifiedAlbums.insert(modifiedAlbumId); - } - updateAlbumFromId(modifiedAlbumId, oneRemovedTrack.albumCover(), oneRemovedTrack); + recordModifiedAlbum(modifiedAlbumId); + modifiedAlbums.insert(modifiedAlbumId); + updateAlbumFromId(modifiedAlbumId, oneRemovedTrack.albumCover(), oneRemovedTrack, trackPath); - if (allTracksFromArtist.isEmpty() && allAlbumsFromArtist.isEmpty()) { + if (removedArtistId != 0 && allTracksFromArtist.isEmpty() && allAlbumsFromArtist.isEmpty()) { removeArtistInDatabase(removedArtistId); Q_EMIT artistRemoved(removedArtist); } @@ -3738,7 +3673,7 @@ const auto &removedArtistId = internalArtistIdFromName(modifiedAlbum.artist()); const auto &removedArtist = internalArtistFromId(removedArtistId); - if (allTracksFromArtist.isEmpty() && allAlbumsFromArtist.isEmpty()) { + if (removedArtistId != 0 && allTracksFromArtist.isEmpty() && allAlbumsFromArtist.isEmpty()) { removeArtistInDatabase(removedArtistId); Q_EMIT artistRemoved(removedArtist); } @@ -3838,15 +3773,15 @@ sourceId = d->mSelectMusicSource.record().value(0).toULongLong(); + d->mSelectMusicSource.finish(); + return sourceId; } QHash DatabaseInterface::internalAllFileNameFromSource(qulonglong sourceId) { QHash allFileNames; - d->mSelectMusicSource.finish(); - d->mSelectAllTrackFilesFromSourceQuery.bindValue(QStringLiteral(":discoverId"), sourceId); auto queryResult = d->mSelectAllTrackFilesFromSourceQuery.exec(); @@ -3920,7 +3855,11 @@ MusicArtist DatabaseInterface::internalComposerFromId(qulonglong composerId) { - auto result = MusicArtist(); + auto result = MusicArtist{}; + + if (result.isValid()) { + return result; + } if (!d || !d->mTracksDatabase.isValid() || !d->mInitFinished) { return result; @@ -4023,7 +3962,11 @@ MusicArtist DatabaseInterface::internalLyricistFromId(qulonglong lyricistId) { - auto result = MusicArtist(); + auto result = MusicArtist{}; + + if (result.isValid()) { + return result; + } if (!d || !d->mTracksDatabase.isValid() || !d->mInitFinished) { return result; @@ -4101,23 +4044,11 @@ void DatabaseInterface::removeTrackInDatabase(qulonglong trackId) { - d->mRemoveTrackArtistQuery.bindValue(QStringLiteral(":trackId"), trackId); - - auto result = d->mRemoveTrackArtistQuery.exec(); - - if (!result || !d->mRemoveTrackArtistQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::removeTrackInDatabase" << d->mRemoveTrackArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::removeTrackInDatabase" << d->mRemoveTrackArtistQuery.boundValues(); - qDebug() << "DatabaseInterface::removeTrackInDatabase" << d->mRemoveTrackArtistQuery.lastError(); - } - - d->mRemoveTrackArtistQuery.finish(); - d->mRemoveTrackQuery.bindValue(QStringLiteral(":trackId"), trackId); - result = d->mRemoveTrackQuery.exec(); + d->mTracksCache.remove(trackId); + + auto result = d->mRemoveTrackQuery.exec(); if (!result || !d->mRemoveTrackQuery.isActive()) { Q_EMIT databaseError(); @@ -4130,11 +4061,19 @@ d->mRemoveTrackQuery.finish(); } -void DatabaseInterface::updateTrackInDatabase(const MusicAudioTrack &oneTrack, qulonglong albumId) +void DatabaseInterface::updateTrackInDatabase(const MusicAudioTrack &oneTrack, const QString &albumPath) { d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackId"), oneTrack.databaseId()); d->mUpdateTrackQuery.bindValue(QStringLiteral(":title"), oneTrack.title()); - d->mUpdateTrackQuery.bindValue(QStringLiteral(":album"), albumId); + insertArtist(oneTrack.artist()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":artistName"), oneTrack.artist()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumTitle"), oneTrack.albumName()); + if (oneTrack.isValidAlbumArtist()) { + d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumArtistName"), oneTrack.albumArtist()); + } else { + d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumArtistName"), {}); + } + d->mUpdateTrackQuery.bindValue(QStringLiteral(":albumPath"), albumPath); d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackNumber"), oneTrack.trackNumber()); d->mUpdateTrackQuery.bindValue(QStringLiteral(":discNumber"), oneTrack.discNumber()); d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackDuration"), QVariant::fromValue(oneTrack.duration().msecsSinceStartOfDay())); @@ -4165,73 +4104,24 @@ auto result = d->mUpdateTrackQuery.exec(); - if (result && d->mUpdateTrackQuery.isActive()) { - d->mUpdateTrackQuery.finish(); - - d->mRemoveTrackArtistQuery.bindValue(QStringLiteral(":trackId"), oneTrack.databaseId()); - - auto result = d->mRemoveTrackArtistQuery.exec(); - - if (!result || !d->mRemoveTrackArtistQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::updateTrackInDatabase" << d->mRemoveTrackArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::updateTrackInDatabase" << d->mRemoveTrackArtistQuery.boundValues(); - qDebug() << "DatabaseInterface::updateTrackInDatabase" << d->mRemoveTrackArtistQuery.lastError(); - } - - d->mRemoveTrackArtistQuery.finish(); - - d->mInsertTrackArtistQuery.bindValue(QStringLiteral(":trackId"), oneTrack.databaseId()); - d->mInsertTrackArtistQuery.bindValue(QStringLiteral(":artistId"), insertArtist(oneTrack.artist())); - - result = d->mInsertTrackArtistQuery.exec(); - - if (!result || !d->mInsertTrackArtistQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::updateTrackInDatabase" << d->mInsertTrackArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::updateTrackInDatabase" << d->mInsertTrackArtistQuery.boundValues(); - qDebug() << "DatabaseInterface::updateTrackInDatabase" << d->mInsertTrackArtistQuery.lastError(); - - d->mInsertTrackArtistQuery.finish(); - - return; - } - - d->mInsertTrackArtistQuery.finish(); - } else { + if (!result || !d->mUpdateTrackQuery.isActive()) { Q_EMIT databaseError(); qDebug() << "DatabaseInterface::updateTrackInDatabase" << d->mUpdateTrackQuery.lastQuery(); qDebug() << "DatabaseInterface::updateTrackInDatabase" << d->mUpdateTrackQuery.boundValues(); qDebug() << "DatabaseInterface::updateTrackInDatabase" << d->mUpdateTrackQuery.lastError(); - - d->mUpdateTrackQuery.finish(); - - return; } + + d->mUpdateTrackQuery.finish(); } void DatabaseInterface::removeAlbumInDatabase(qulonglong albumId) { - d->mRemoveAlbumArtistQuery.bindValue(QStringLiteral(":albumId"), albumId); - - auto result = d->mRemoveAlbumArtistQuery.exec(); - - if (!result || !d->mRemoveAlbumArtistQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::removeAlbumInDatabase" << d->mRemoveAlbumArtistQuery.lastQuery(); - qDebug() << "DatabaseInterface::removeAlbumInDatabase" << d->mRemoveAlbumArtistQuery.boundValues(); - qDebug() << "DatabaseInterface::removeAlbumInDatabase" << d->mRemoveAlbumArtistQuery.lastError(); - } - - d->mRemoveAlbumArtistQuery.finish(); - d->mRemoveAlbumQuery.bindValue(QStringLiteral(":albumId"), albumId); - result = d->mRemoveAlbumQuery.exec(); + d->mAlbumsCache.remove(albumId); + + auto result = d->mRemoveAlbumQuery.exec(); if (!result || !d->mRemoveAlbumQuery.isActive()) { Q_EMIT databaseError(); @@ -4248,6 +4138,8 @@ { d->mRemoveArtistQuery.bindValue(QStringLiteral(":artistId"), artistId); + d->mArtistsCache.remove(artistId); + auto result = d->mRemoveArtistQuery.exec(); if (!result || !d->mRemoveArtistQuery.isActive()) { @@ -4280,53 +4172,53 @@ for (const auto &oneArtist : restoredArtists) { d->mArtistId = std::max(d->mArtistId, oneArtist.databaseId()); } - ++d->mArtistId; if (!restoredArtists.isEmpty()) { + ++d->mArtistId; Q_EMIT artistsAdded(restoredArtists); } const auto restoredComposers = allComposers(); for (const auto &oneComposer : restoredComposers) { d->mComposerId = std::max(d->mComposerId, oneComposer.databaseId()); } - ++d->mComposerId; if (!restoredComposers.isEmpty()) { + ++d->mComposerId; Q_EMIT composersAdded(restoredComposers); } const auto restoredLyricists = allLyricists(); for (const auto &oneLyricist : restoredLyricists) { d->mLyricistId = std::max(d->mLyricistId, oneLyricist.databaseId()); } - ++d->mLyricistId; if (!restoredLyricists.isEmpty()) { + ++d->mLyricistId; Q_EMIT lyricistsAdded(restoredLyricists); } const auto restoredAlbums = allAlbums(); for (const auto &oneAlbum : restoredAlbums) { d->mAlbumId = std::max(d->mAlbumId, oneAlbum.databaseId()); } - ++d->mAlbumId; if (!restoredAlbums.isEmpty()) { + ++d->mAlbumId; Q_EMIT albumsAdded(restoredAlbums); } const auto restoredTracks = allTracks(); for (const auto &oneTrack : restoredTracks) { d->mTrackId = std::max(d->mTrackId, oneTrack.databaseId()); } - ++d->mTrackId; if (!restoredTracks.isEmpty()) { + ++d->mTrackId; Q_EMIT tracksAdded(restoredTracks); } const auto restoredGenres = allGenres(); for (const auto &oneGenre : restoredGenres) { d->mGenreId = std::max(d->mGenreId, oneGenre.databaseId()); } - ++d->mGenreId; if (!restoredGenres.isEmpty()) { + ++d->mGenreId; Q_EMIT genresAdded(restoredGenres); } } @@ -4436,90 +4328,17 @@ d->mSelectTrackQuery.finish(); - updateTracksCount(albumId); - return allTracks; } -bool DatabaseInterface::updateTracksCount(qulonglong albumId) +MusicAlbum DatabaseInterface::internalAlbumFromId(qulonglong albumId) { - bool isModified = false; - - d->mSelectAlbumTrackCountQuery.bindValue(QStringLiteral(":albumId"), albumId); - - auto result = d->mSelectAlbumTrackCountQuery.exec(); - - if (!result || !d->mSelectAlbumTrackCountQuery.isSelect() || !d->mSelectAlbumTrackCountQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::updateTracksCount" << d->mSelectAlbumTrackCountQuery.lastQuery(); - qDebug() << "DatabaseInterface::updateTracksCount" << d->mSelectAlbumTrackCountQuery.boundValues(); - qDebug() << "DatabaseInterface::updateTracksCount" << d->mSelectAlbumTrackCountQuery.lastError(); - - d->mSelectAlbumTrackCountQuery.finish(); - - return isModified; - } - - if (!d->mSelectAlbumTrackCountQuery.next()) { - d->mSelectAlbumTrackCountQuery.finish(); - - return isModified; - } - - auto oldTracksCount = d->mSelectAlbumTrackCountQuery.record().value(0).toInt(); - - d->mUpdateAlbumQuery.bindValue(QStringLiteral(":albumId"), albumId); - - result = d->mUpdateAlbumQuery.exec(); + auto &retrievedAlbum = d->mAlbumsCache[albumId]; - if (!result || !d->mUpdateAlbumQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::updateTracksCount" << d->mUpdateAlbumQuery.lastQuery(); - qDebug() << "DatabaseInterface::updateTracksCount" << d->mUpdateAlbumQuery.boundValues(); - qDebug() << "DatabaseInterface::updateTracksCount" << d->mUpdateAlbumQuery.lastError(); - - d->mUpdateAlbumQuery.finish(); - - return isModified; - } - - d->mUpdateAlbumQuery.finish(); - - d->mSelectAlbumTrackCountQuery.bindValue(QStringLiteral(":albumId"), albumId); - - result = d->mSelectAlbumTrackCountQuery.exec(); - - if (!result || !d->mSelectAlbumTrackCountQuery.isSelect() || !d->mSelectAlbumTrackCountQuery.isActive()) { - Q_EMIT databaseError(); - - qDebug() << "DatabaseInterface::updateTracksCount" << d->mSelectAlbumTrackCountQuery.lastQuery(); - qDebug() << "DatabaseInterface::updateTracksCount" << d->mSelectAlbumTrackCountQuery.boundValues(); - qDebug() << "DatabaseInterface::updateTracksCount" << d->mSelectAlbumTrackCountQuery.lastError(); - - d->mSelectAlbumTrackCountQuery.finish(); - - return isModified; - } - - if (!d->mSelectAlbumTrackCountQuery.next()) { - d->mSelectAlbumTrackCountQuery.finish(); - - return isModified; + if (retrievedAlbum.isValid()) { + return retrievedAlbum; } - auto newTracksCount = d->mSelectAlbumTrackCountQuery.record().value(0).toInt(); - - isModified = (newTracksCount != oldTracksCount); - - return isModified; -} - -MusicAlbum DatabaseInterface::internalAlbumFromId(qulonglong albumId) -{ - auto retrievedAlbum = MusicAlbum(); - d->mSelectAlbumQuery.bindValue(QStringLiteral(":albumId"), albumId); auto result = d->mSelectAlbumQuery.exec(); @@ -4811,11 +4630,11 @@ return result; } -QList DatabaseInterface::internalTracksFromAuthor(const QString &artistName) +QList DatabaseInterface::internalTracksFromAuthor(const QString &ArtistName) { auto allTracks = QList(); - d->mSelectTracksFromArtist.bindValue(QStringLiteral(":artistName"), artistName); + d->mSelectTracksFromArtist.bindValue(QStringLiteral(":artistName"), ArtistName); auto result = d->mSelectTracksFromArtist.exec(); @@ -4840,11 +4659,11 @@ return allTracks; } -QList DatabaseInterface::internalAlbumIdsFromAuthor(const QString &artistName) +QList DatabaseInterface::internalAlbumIdsFromAuthor(const QString &ArtistName) { auto allAlbumIds = QList(); - d->mSelectAlbumIdsFromArtist.bindValue(QStringLiteral(":artistName"), artistName); + d->mSelectAlbumIdsFromArtist.bindValue(QStringLiteral(":artistName"), ArtistName); auto result = d->mSelectAlbumIdsFromArtist.exec(); @@ -4900,7 +4719,8 @@ } QList DatabaseInterface::internalAllPeople(QSqlQuery allPeopleQuery, - QSqlQuery selectCountAlbumsForPeopleQuery) + QSqlQuery selectCountAlbumsForPeopleQuery, + bool withCache) { auto result = QList(); @@ -4933,11 +4753,19 @@ } while(allPeopleQuery.next()) { - auto newArtist = MusicArtist(); - const auto ¤tRecord = allPeopleQuery.record(); - newArtist.setDatabaseId(currentRecord.value(0).toULongLong()); + auto artistId = currentRecord.value(0).toULongLong(); + + auto fallBackArtist = MusicArtist{}; + auto &newArtist = (withCache ? d->mArtistsCache[artistId] : fallBackArtist); + + if (newArtist.isValid()) { + result.push_back(newArtist); + continue; + } + + newArtist.setDatabaseId(artistId); newArtist.setName(currentRecord.value(1).toString()); newArtist.setValid(true); @@ -5015,5 +4843,50 @@ return query.prepare(queryText); } +void DatabaseInterface::updateAlbumArtist(qulonglong albumId, const QString &title, + const QString &albumPath, + const QString &artistName) +{ + d->mUpdateAlbumArtistQuery.bindValue(QStringLiteral(":albumId"), albumId); + insertArtist(artistName); + d->mUpdateAlbumArtistQuery.bindValue(QStringLiteral(":artistName"), artistName); + + auto queryResult = d->mUpdateAlbumArtistQuery.exec(); + + if (!queryResult || !d->mUpdateAlbumArtistQuery.isActive()) { + Q_EMIT databaseError(); + + qDebug() << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistQuery.lastQuery(); + qDebug() << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistQuery.boundValues(); + qDebug() << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistQuery.lastError(); + + d->mUpdateAlbumArtistQuery.finish(); + + return; + } + + d->mUpdateAlbumArtistQuery.finish(); + + d->mUpdateAlbumArtistInTracksQuery.bindValue(QStringLiteral(":albumTitle"), title); + d->mUpdateAlbumArtistInTracksQuery.bindValue(QStringLiteral(":albumPath"), albumPath); + d->mUpdateAlbumArtistInTracksQuery.bindValue(QStringLiteral(":artistName"), artistName); + + queryResult = d->mUpdateAlbumArtistInTracksQuery.exec(); + + if (!queryResult || !d->mUpdateAlbumArtistInTracksQuery.isActive()) { + Q_EMIT databaseError(); + + qDebug() << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistInTracksQuery.lastQuery(); + qDebug() << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistInTracksQuery.boundValues(); + qDebug() << "DatabaseInterface::updateAlbumArtist" << d->mUpdateAlbumArtistInTracksQuery.lastError(); + + d->mUpdateAlbumArtistInTracksQuery.finish(); + + return; + } + + d->mUpdateAlbumArtistInTracksQuery.finish(); +} + #include "moc_databaseinterface.cpp" diff --git a/src/models/allalbumsmodel.h b/src/models/allalbumsmodel.h --- a/src/models/allalbumsmodel.h +++ b/src/models/allalbumsmodel.h @@ -72,7 +72,7 @@ public Q_SLOTS: - void albumsAdded(const QList &newAlbums); + void albumsAdded(QList newAlbums); void albumRemoved(const MusicAlbum &removedAlbum); diff --git a/src/models/allalbumsmodel.cpp b/src/models/allalbumsmodel.cpp --- a/src/models/allalbumsmodel.cpp +++ b/src/models/allalbumsmodel.cpp @@ -25,33 +25,18 @@ #include #include #include -#include -#include -#include -#include -#include +#include #include class AllAlbumsModelPrivate { public: - AllAlbumsModelPrivate() - { - mThreadPool.setMaxThreadCount(1); - } - - QVector mAllAlbums; - - QHash mAlbumsData; + QList mAllAlbums; AllArtistsModel *mAllArtistsModel = nullptr; - QReadWriteLock mDataLock; - - QThreadPool mThreadPool; - }; AllAlbumsModel::AllAlbumsModel(QObject *parent) : QAbstractItemModel(parent), d(std::make_unique()) @@ -63,7 +48,6 @@ int AllAlbumsModel::albumCount() const { - QReadLocker locker(&d->mDataLock); return d->mAllAlbums.size(); } @@ -75,8 +59,6 @@ return albumCount; } - QReadLocker locker(&d->mDataLock); - albumCount = d->mAllAlbums.size(); return albumCount; @@ -118,8 +100,6 @@ { auto result = QVariant(); - QReadLocker locker(&d->mDataLock); - const auto albumCount = d->mAllAlbums.size(); Q_ASSERT(index.isValid()); @@ -141,69 +121,69 @@ { case Qt::DisplayRole: case ElisaUtils::ColumnsRoles::TitleRole: - result = d->mAlbumsData[d->mAllAlbums[albumIndex]].title(); + result = d->mAllAlbums[albumIndex].title(); break; - /*case ElisaUtils::ColumnsRoles::AllTracksTitleRole: + /*case ElisaUtils::ColumnsRoles::AllTracksTitleRole: result = d->mAlbumsData[d->mAllAlbums[albumIndex]].allTracksTitle(); break;*/ case ElisaUtils::ColumnsRoles::ArtistRole: - result = d->mAlbumsData[d->mAllAlbums[albumIndex]].artist(); + result = d->mAllAlbums[albumIndex].artist(); break; case ElisaUtils::ColumnsRoles::AllArtistsRole: - result = d->mAlbumsData[d->mAllAlbums[albumIndex]].allArtists().join(QStringLiteral(", ")); + result = d->mAllAlbums[albumIndex].allArtists().join(QStringLiteral(", ")); break; case ElisaUtils::ColumnsRoles::ImageRole: { - auto albumArt = d->mAlbumsData[d->mAllAlbums[albumIndex]].albumArtURI(); + auto albumArt = d->mAllAlbums[albumIndex].albumArtURI(); if (albumArt.isValid()) { result = albumArt; } break; } - /*case ElisaUtils::ColumnsRoles::CountRole: + /*case ElisaUtils::ColumnsRoles::CountRole: result = d->mAlbumsData[d->mAllAlbums[albumIndex]].tracksCount(); break;*/ case ElisaUtils::ColumnsRoles::IdRole: - result = d->mAlbumsData[d->mAllAlbums[albumIndex]].id(); + result = d->mAllAlbums[albumIndex].id(); break; case ElisaUtils::ColumnsRoles::IsSingleDiscAlbumRole: - result = d->mAlbumsData[d->mAllAlbums[albumIndex]].isSingleDiscAlbum(); + result = d->mAllAlbums[albumIndex].isSingleDiscAlbum(); break; case ElisaUtils::ColumnsRoles::ContainerDataRole: - result = QVariant::fromValue(d->mAlbumsData[d->mAllAlbums[albumIndex]]); + result = QVariant::fromValue(d->mAllAlbums[albumIndex]); break; case ElisaUtils::ColumnsRoles::DatabaseIdRole: - result = QVariant::fromValue(d->mAlbumsData[d->mAllAlbums[albumIndex]].databaseId()); + result = QVariant::fromValue(d->mAllAlbums[albumIndex].databaseId()); break; case ElisaUtils::ColumnsRoles::HighestTrackRating: - result = d->mAlbumsData[d->mAllAlbums[albumIndex]].highestTrackRating(); + result = d->mAllAlbums[albumIndex].highestTrackRating(); break; case ElisaUtils::ColumnsRoles::SecondaryTextRole: - result = d->mAlbumsData[d->mAllAlbums[albumIndex]].artist(); + result = d->mAllAlbums[albumIndex].artist(); break; case ElisaUtils::ColumnsRoles::ImageUrlRole: { - auto albumArt = d->mAlbumsData[d->mAllAlbums[albumIndex]].albumArtURI(); + auto albumArt = d->mAllAlbums[albumIndex].albumArtURI(); if (albumArt.isValid()) { result = albumArt; } else { result = QUrl(QStringLiteral("image://icon/media-optical-audio")); } break; } case ElisaUtils::ColumnsRoles::ShadowForImageRole: - result = d->mAlbumsData[d->mAllAlbums[albumIndex]].albumArtURI().isValid(); + result = d->mAllAlbums[albumIndex].albumArtURI().isValid(); break; case ElisaUtils::ColumnsRoles::ChildModelRole: { - auto albumData = d->mAlbumsData[d->mAllAlbums[albumIndex]]; + auto albumData = d->mAllAlbums[albumIndex]; result = QVariant::fromValue(albumData); break; } case ElisaUtils::ColumnsRoles::GenreRole: - result = d->mAlbumsData[d->mAllAlbums[albumIndex]].genres(); + result = d->mAllAlbums[albumIndex].genres(); break; - /*case ElisaUtils::ColumnsRoles::IsTracksContainerRole: + /*case ElisaUtils::ColumnsRoles::IsTracksContainerRole: result = true; break;*/ } @@ -249,87 +229,57 @@ return d->mAllArtistsModel; } -void AllAlbumsModel::albumsAdded(const QList &newAlbums) +void AllAlbumsModel::albumsAdded(QList newAlbums) { - QtConcurrent::run(&d->mThreadPool, [=] () { - for (const auto &newAlbum : newAlbums) { - if (newAlbum.isValid()) { - beginInsertRows({}, d->mAllAlbums.size(), d->mAllAlbums.size()); - - { - QWriteLocker locker(&d->mDataLock); - - d->mAllAlbums.push_back(newAlbum.databaseId()); - d->mAlbumsData[newAlbum.databaseId()] = newAlbum; - } - - endInsertRows(); + if (d->mAllAlbums.isEmpty()) { + beginInsertRows({}, d->mAllAlbums.size(), d->mAllAlbums.size() + newAlbums.size() - 1); + d->mAllAlbums.swap(newAlbums); + endInsertRows(); + } else { + beginInsertRows({}, d->mAllAlbums.size(), d->mAllAlbums.size() + newAlbums.size() - 1); + d->mAllAlbums.append(newAlbums); + endInsertRows(); + } - Q_EMIT albumCountChanged(); - } - } - }); + Q_EMIT albumCountChanged(); } void AllAlbumsModel::albumRemoved(const MusicAlbum &removedAlbum) { - QtConcurrent::run(&d->mThreadPool, [=] () { - auto removedAlbumIterator = d->mAllAlbums.end(); - - { - QReadLocker locker(&d->mDataLock); + auto removedAlbumIterator = d->mAllAlbums.end(); - removedAlbumIterator = std::find(d->mAllAlbums.begin(), d->mAllAlbums.end(), removedAlbum.databaseId()); + removedAlbumIterator = std::find_if(d->mAllAlbums.begin(), d->mAllAlbums.end(), + [removedAlbum](auto album) {return album.databaseId() == removedAlbum.databaseId();}); - if (removedAlbumIterator == d->mAllAlbums.end()) { - return; - } + if (removedAlbumIterator == d->mAllAlbums.end()) { + return; + } - int albumIndex = removedAlbumIterator - d->mAllAlbums.begin(); + int albumIndex = removedAlbumIterator - d->mAllAlbums.begin(); - beginRemoveRows({}, albumIndex, albumIndex); + beginRemoveRows({}, albumIndex, albumIndex); - } + d->mAllAlbums.erase(removedAlbumIterator); - { - QWriteLocker writeLocker(&d->mDataLock); - d->mAlbumsData.remove(removedAlbum.databaseId()); - d->mAllAlbums.erase(removedAlbumIterator); - } + endRemoveRows(); - endRemoveRows(); - - Q_EMIT albumCountChanged(); - }); + Q_EMIT albumCountChanged(); } void AllAlbumsModel::albumModified(const MusicAlbum &modifiedAlbum) { - QtConcurrent::run(&d->mThreadPool, [=] () { - auto modifiedAlbumIterator = d->mAllAlbums.end(); - - { - QReadLocker locker(&d->mDataLock); + auto modifiedAlbumIterator = std::find_if(d->mAllAlbums.begin(), d->mAllAlbums.end(), + [modifiedAlbum](auto album) {return album.databaseId() == modifiedAlbum.databaseId();}); - modifiedAlbumIterator = std::find(d->mAllAlbums.begin(), d->mAllAlbums.end(), modifiedAlbum.databaseId()); - } - - int albumIndex = 0; - - { - QWriteLocker writeLocker(&d->mDataLock); - - if (modifiedAlbumIterator == d->mAllAlbums.end()) { - return; - } + if (modifiedAlbumIterator == d->mAllAlbums.end()) { + return; + } - albumIndex = modifiedAlbumIterator - d->mAllAlbums.begin(); + auto albumIndex = modifiedAlbumIterator - d->mAllAlbums.begin(); - d->mAlbumsData[modifiedAlbum.databaseId()] = modifiedAlbum; - } + d->mAllAlbums[albumIndex] = modifiedAlbum; - Q_EMIT dataChanged(index(albumIndex, 0), index(albumIndex, 0)); - }); + Q_EMIT dataChanged(index(albumIndex, 0), index(albumIndex, 0)); } void AllAlbumsModel::setAllArtists(AllArtistsModel *model) diff --git a/src/models/alltracksmodel.h b/src/models/alltracksmodel.h --- a/src/models/alltracksmodel.h +++ b/src/models/alltracksmodel.h @@ -54,7 +54,7 @@ public Q_SLOTS: - void tracksAdded(const QList &allTracks); + void tracksAdded(QList allTracks); void trackRemoved(qulonglong removedTrackId); diff --git a/src/models/alltracksmodel.cpp b/src/models/alltracksmodel.cpp --- a/src/models/alltracksmodel.cpp +++ b/src/models/alltracksmodel.cpp @@ -27,9 +27,7 @@ { public: - QHash mAllTracks; - - QList mIds; + QList mAllTracks; }; @@ -107,94 +105,94 @@ Q_ASSERT(index.model() == this); Q_ASSERT(index.internalId() == 0); - const auto &track = d->mAllTracks[d->mIds[index.row()]]; + const auto &track = d->mAllTracks[index.row()]; switch(role) { case ElisaUtils::ColumnsRoles::TitleRole: - if (d->mAllTracks[d->mIds[index.row()]].title().isEmpty()) { - result = d->mAllTracks[d->mIds[index.row()]].resourceURI().fileName(); + if (track.title().isEmpty()) { + result = track.resourceURI().fileName(); } else { - result = d->mAllTracks[d->mIds[index.row()]].title(); + result = track.title(); } break; case ElisaUtils::ColumnsRoles::MilliSecondsDurationRole: - result = d->mAllTracks[d->mIds[index.row()]].duration().msecsSinceStartOfDay(); + result = track.duration().msecsSinceStartOfDay(); break; case ElisaUtils::ColumnsRoles::DurationRole: { - QTime trackDuration = d->mAllTracks[d->mIds[index.row()]].duration(); + QTime trackDuration = track.duration(); if (trackDuration.hour() == 0) { result = trackDuration.toString(QStringLiteral("mm:ss")); } else { result = trackDuration.toString(); } break; } case ElisaUtils::ColumnsRoles::ArtistRole: - result = d->mAllTracks[d->mIds[index.row()]].artist(); + result = track.artist(); break; case ElisaUtils::ColumnsRoles::AlbumRole: - result = d->mAllTracks[d->mIds[index.row()]].albumName(); + result = track.albumName(); break; case ElisaUtils::ColumnsRoles::AlbumArtistRole: - result = d->mAllTracks[d->mIds[index.row()]].albumArtist(); + result = track.albumArtist(); break; case ElisaUtils::ColumnsRoles::TrackNumberRole: - result = d->mAllTracks[d->mIds[index.row()]].trackNumber(); + result = track.trackNumber(); break; case ElisaUtils::ColumnsRoles::DiscNumberRole: - result = d->mAllTracks[d->mIds[index.row()]].discNumber(); + result = track.discNumber(); break; case ElisaUtils::ColumnsRoles::IsSingleDiscAlbumRole: - result = d->mAllTracks[d->mIds[index.row()]].isSingleDiscAlbum(); + result = track.isSingleDiscAlbum(); break; case ElisaUtils::ColumnsRoles::RatingRole: - result = d->mAllTracks[d->mIds[index.row()]].rating(); + result = track.rating(); break; case ElisaUtils::ColumnsRoles::GenreRole: - result = d->mAllTracks[d->mIds[index.row()]].genre(); + result = track.genre(); break; case ElisaUtils::ColumnsRoles::LyricistRole: - result = d->mAllTracks[d->mIds[index.row()]].lyricist(); + result = track.lyricist(); break; case ElisaUtils::ColumnsRoles::ComposerRole: - result = d->mAllTracks[d->mIds[index.row()]].composer(); + result = track.composer(); break; case ElisaUtils::ColumnsRoles::CommentRole: - result = d->mAllTracks[d->mIds[index.row()]].comment(); + result = track.comment(); break; case ElisaUtils::ColumnsRoles::YearRole: - result = d->mAllTracks[d->mIds[index.row()]].year(); + result = track.year(); break; case ElisaUtils::ColumnsRoles::ChannelsRole: - result = d->mAllTracks[d->mIds[index.row()]].channels(); + result = track.channels(); break; case ElisaUtils::ColumnsRoles::BitRateRole: - result = d->mAllTracks[d->mIds[index.row()]].bitRate(); + result = track.bitRate(); break; case ElisaUtils::ColumnsRoles::SampleRateRole: - result = d->mAllTracks[d->mIds[index.row()]].sampleRate(); + result = track.sampleRate(); break; case ElisaUtils::ColumnsRoles::ImageRole: { - const auto &imageUrl = d->mAllTracks[d->mIds[index.row()]].albumCover(); + const auto &imageUrl = track.albumCover(); if (imageUrl.isValid()) { result = imageUrl; } break; } case ElisaUtils::ColumnsRoles::ResourceRole: - result = d->mAllTracks[d->mIds[index.row()]].resourceURI(); + result = track.resourceURI(); break; case ElisaUtils::ColumnsRoles::IdRole: - result = d->mAllTracks[d->mIds[index.row()]].title(); + result = track.title(); break; case ElisaUtils::ColumnsRoles::DatabaseIdRole: - result = d->mAllTracks[d->mIds[index.row()]].databaseId(); + result = track.databaseId(); break; case ElisaUtils::ColumnsRoles::ContainerDataRole: - result = QVariant::fromValue(d->mAllTracks[d->mIds[index.row()]]); + result = QVariant::fromValue(track); break; case Qt::DisplayRole: result = track.title(); @@ -221,16 +219,16 @@ } case ElisaUtils::ColumnsRoles::ImageUrlRole: { - const auto &imageUrl = d->mAllTracks[d->mIds[index.row()]].albumCover(); + const auto &imageUrl = track.albumCover(); if (imageUrl.isValid()) { result = imageUrl; } else { result = QUrl(QStringLiteral("image://icon/media-optical-audio")); } break; } case ElisaUtils::ColumnsRoles::ShadowForImageRole: - result = d->mAllTracks[d->mIds[index.row()]].albumCover().isValid(); + result = track.albumCover().isValid(); break; } @@ -274,61 +272,51 @@ return 1; } -void AllTracksModel::tracksAdded(const QList &allTracks) +void AllTracksModel::tracksAdded(QList allTracks) { - auto newAllTracks = d->mAllTracks; - auto newTracksIds = QList(); - - int countNewTracks = 0; - - for (const auto &oneTrack : allTracks) { - if (!newAllTracks.contains(oneTrack.databaseId())) { - newAllTracks[oneTrack.databaseId()] = oneTrack; - newTracksIds.push_back(oneTrack.databaseId()); - ++countNewTracks; - } + if (allTracks.isEmpty()) { + return; } - if (countNewTracks > 0) { - beginInsertRows({}, d->mAllTracks.size(), d->mAllTracks.size() + countNewTracks - 1); - - d->mAllTracks = newAllTracks; - d->mIds.append(newTracksIds); - + if (d->mAllTracks.isEmpty()) { + beginInsertRows({}, 0, allTracks.size() - 1); + d->mAllTracks.swap(allTracks); + endInsertRows(); + } else { + beginInsertRows({}, d->mAllTracks.size(), d->mAllTracks.size() + allTracks.size() - 1); + d->mAllTracks.append(allTracks); endInsertRows(); } } void AllTracksModel::trackRemoved(qulonglong removedTrackId) { - auto itTrack = std::find(d->mIds.begin(), d->mIds.end(), removedTrackId); - if (itTrack == d->mIds.end()) { + auto itTrack = std::find_if(d->mAllTracks.begin(), d->mAllTracks.end(), + [removedTrackId](auto track) {return track.databaseId() == removedTrackId;}); + + if (itTrack == d->mAllTracks.end()) { return; } - auto position = itTrack - d->mIds.begin(); + auto position = itTrack - d->mAllTracks.begin(); beginRemoveRows({}, position, position); - d->mIds.erase(itTrack); - d->mAllTracks.remove(removedTrackId); + d->mAllTracks.erase(itTrack); endRemoveRows(); } void AllTracksModel::trackModified(const MusicAudioTrack &modifiedTrack) { - auto trackExists = (d->mAllTracks.contains(modifiedTrack.databaseId())); - if (!trackExists) { - return; - } + auto itTrack = std::find_if(d->mAllTracks.begin(), d->mAllTracks.end(), + [modifiedTrack](auto track) {return track.databaseId() == modifiedTrack.databaseId();}); - auto itTrack = std::find(d->mIds.begin(), d->mIds.end(), modifiedTrack.databaseId()); - if (itTrack == d->mIds.end()) { + if (itTrack == d->mAllTracks.end()) { return; } - auto position = itTrack - d->mIds.begin(); + auto position = itTrack - d->mAllTracks.begin(); - d->mAllTracks[modifiedTrack.databaseId()] = modifiedTrack; + d->mAllTracks[position] = modifiedTrack; Q_EMIT dataChanged(index(position, 0), index(position, 0)); }