diff --git a/autotests/databaseinterfacetest.cpp b/autotests/databaseinterfacetest.cpp --- a/autotests/databaseinterfacetest.cpp +++ b/autotests/databaseinterfacetest.cpp @@ -780,26 +780,77 @@ { DatabaseInterface musicDb; + 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 allNewTracks = mNewTracks; allNewTracks.push_back({true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track6"), QStringLiteral("artist2"), QStringLiteral("album3"), QStringLiteral("artist2"), 6, 1, QTime::fromMSecsSinceStartOfDay(23), {QUrl::fromLocalFile(QStringLiteral("/$23"))}, QDateTime::fromMSecsSinceEpoch(23), {QUrl::fromLocalFile(QStringLiteral("album3"))}, 5, true, QStringLiteral("genre1"), QStringLiteral("composer1"), QStringLiteral("lyricist1")}); - QSignalSpy musicDbTrackAddedSpy(&musicDb, &DatabaseInterface::tracksAdded); - musicDb.init(QStringLiteral("testDb1"), myTempDatabase.fileName()); + 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); + + qDebug() << "restoreModifiedTracksWidthDatabaseFile" << myTempDatabase.fileName(); + auto newCovers = mNewCovers; newCovers[QStringLiteral("file:///$23")] = QUrl::fromLocalFile(QStringLiteral("album3")); musicDb.insertTracksList(allNewTracks, newCovers, QStringLiteral("autoTest")); musicDbTrackAddedSpy.wait(300); QCOMPARE(musicDb.allAlbums().count(), 5); + QCOMPARE(musicDb.allArtists().count(), 7); + QCOMPARE(musicDb.allTracks().count(), 23); + 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(), 1); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); auto firstAlbum = musicDb.albumFromTitleAndArtist(QStringLiteral("album1"), QStringLiteral("Various Artists")); @@ -826,25 +877,78 @@ { DatabaseInterface musicDb; + 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 allNewTracks = mNewTracks; allNewTracks.push_back({true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track6"), QStringLiteral("artist2"), QStringLiteral("album3"), QStringLiteral("artist2"), 6, 1, QTime::fromMSecsSinceStartOfDay(23), {QUrl::fromLocalFile(QStringLiteral("/$23"))}, QDateTime::fromMSecsSinceEpoch(23), {QUrl::fromLocalFile(QStringLiteral("album3"))}, 3, true, QStringLiteral("genre1"), QStringLiteral("composer1"), QStringLiteral("lyricist1")}); - QSignalSpy musicDbTrackAddedSpy(&musicDb, &DatabaseInterface::tracksAdded); - musicDb.init(QStringLiteral("testDb2"), myTempDatabase.fileName()); + qDebug() << "restoreModifiedTracksWidthDatabaseFile" << myTempDatabase.fileName(); + + QCOMPARE(musicDb.allAlbums().count(), 5); + QCOMPARE(musicDb.allArtists().count(), 7); + QCOMPARE(musicDb.allTracks().count(), 23); + 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); + auto newCovers = mNewCovers; newCovers[QStringLiteral("file:///$23")] = QUrl::fromLocalFile(QStringLiteral("album3")); musicDb.insertTracksList(allNewTracks, newCovers, QStringLiteral("autoTest")); musicDbTrackAddedSpy.wait(300); + QCOMPARE(musicDb.allAlbums().count(), 5); + QCOMPARE(musicDb.allArtists().count(), 7); + QCOMPARE(musicDb.allTracks().count(), 23); + 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(), 2); + QCOMPARE(musicDbTrackModifiedSpy.count(), 2); + QCOMPARE(musicDbDatabaseErrorSpy.count(), 0); + QCOMPARE(musicDb.allAlbums().count(), 5); auto firstAlbum = musicDb.albumFromTitleAndArtist(QStringLiteral("album1"), QStringLiteral("Various Artists")); @@ -2202,9 +2306,14 @@ void addTwoTracksSameAlbumSameTitle() { + QTemporaryFile databaseFile; + databaseFile.open(); + + qDebug() << "addTwoTracksSameAlbumSameTitle" << databaseFile.fileName(); + DatabaseInterface musicDb; - musicDb.init(QStringLiteral("testDb")); + musicDb.init(QStringLiteral("testDb"), databaseFile.fileName()); QSignalSpy musicDbArtistAddedSpy(&musicDb, &DatabaseInterface::artistsAdded); QSignalSpy musicDbAlbumAddedSpy(&musicDb, &DatabaseInterface::albumsAdded); @@ -3832,6 +3941,212 @@ QCOMPARE(album.albumArtURI(), QUrl::fromLocalFile(QStringLiteral("album3"))); QCOMPARE(album.isSingleDiscAlbum(), true); } + + void addTowAlbumsWithDifferentPathsAndSameName() + { + QTemporaryFile databaseFile; + databaseFile.open(); + + qDebug() << "addTowAlbumsWithDifferentPathsAndSameName" << databaseFile.fileName(); + + DatabaseInterface musicDb; + + musicDb.init(QStringLiteral("testDb"), databaseFile.fileName()); + + 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 newTracks = QList(); + + newTracks = {{true, QStringLiteral("$20"), QStringLiteral("0"), QStringLiteral("track7"), + QStringLiteral("artist1"), QStringLiteral("album7"), {}, 7, 1, + QTime::fromMSecsSinceStartOfDay(20), {QUrl::fromLocalFile(QStringLiteral("/album7/$20"))}, + QDateTime::fromMSecsSinceEpoch(20), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre1"), QStringLiteral("composer1"), QStringLiteral("lyricist1")}, + {true, QStringLiteral("$21"), QStringLiteral("0"), QStringLiteral("track8"), + QStringLiteral("artist2"), QStringLiteral("album7"), {}, 8, 1, + QTime::fromMSecsSinceStartOfDay(21), {QUrl::fromLocalFile(QStringLiteral("/album7/$21"))}, + QDateTime::fromMSecsSinceEpoch(21), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre2"), QStringLiteral("composer2"), QStringLiteral("lyricist2")}, + {true, QStringLiteral("$22"), QStringLiteral("0"), QStringLiteral("track9"), + QStringLiteral("artist3"), QStringLiteral("album7"), {}, 9, 1, + QTime::fromMSecsSinceStartOfDay(22), {QUrl::fromLocalFile(QStringLiteral("/album8/$22"))}, + QDateTime::fromMSecsSinceEpoch(22), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre3"), QStringLiteral("composer3"), QStringLiteral("lyricist3")}, + {true, QStringLiteral("$23"), QStringLiteral("0"), QStringLiteral("track10"), + QStringLiteral("artist4"), QStringLiteral("album7"), {}, 10, 1, + QTime::fromMSecsSinceStartOfDay(23), {QUrl::fromLocalFile(QStringLiteral("/album8/$23"))}, + QDateTime::fromMSecsSinceEpoch(23), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre4"), QStringLiteral("composer4"), QStringLiteral("lyricist4")},}; + + auto newCovers = mNewCovers; + newCovers[QStringLiteral("file:///album7/$20")] = QUrl::fromLocalFile(QStringLiteral("album7")); + newCovers[QStringLiteral("file:///album7/$21")] = QUrl::fromLocalFile(QStringLiteral("album7")); + newCovers[QStringLiteral("file:///album8/$22")] = QUrl::fromLocalFile(QStringLiteral("album8")); + newCovers[QStringLiteral("file:///album8/$23")] = QUrl::fromLocalFile(QStringLiteral("album8")); + + musicDb.insertTracksList(newTracks, newCovers, QStringLiteral("autoTest")); + + musicDbTrackAddedSpy.wait(300); + + QCOMPARE(musicDb.allAlbums().count(), 2); + QCOMPARE(musicDb.allArtists().count(), 4); + QCOMPARE(musicDb.allTracks().count(), 4); + 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(musicDb.allAlbums().size(), 2); + QCOMPARE(musicDb.allArtists().size(), 4); + QCOMPARE(musicDb.allTracks().size(), 4); + + auto allAlbums = musicDb.allAlbums(); + auto firstAlbum = allAlbums[0]; + QCOMPARE(firstAlbum.tracksCount(), 2); + auto secondAlbum = allAlbums[1]; + QCOMPARE(secondAlbum.tracksCount(), 2); + } + + void addTowAlbumsWithDifferentPathsAndSameTracks() + { + QTemporaryFile databaseFile; + databaseFile.open(); + + qDebug() << "addTowAlbumsWithDifferentPathsAndSameName" << databaseFile.fileName(); + + DatabaseInterface musicDb; + + musicDb.init(QStringLiteral("testDb"), databaseFile.fileName()); + + 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 newTracks = QList(); + + newTracks = {{true, QStringLiteral("$20"), QStringLiteral("0"), QStringLiteral("track7"), + QStringLiteral("artist1"), QStringLiteral("album7"), {}, 7, 1, + QTime::fromMSecsSinceStartOfDay(20), {QUrl::fromLocalFile(QStringLiteral("/album7/$20"))}, + QDateTime::fromMSecsSinceEpoch(20), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre1"), QStringLiteral("composer1"), QStringLiteral("lyricist1")}, + {true, QStringLiteral("$21"), QStringLiteral("0"), QStringLiteral("track8"), + QStringLiteral("artist2"), QStringLiteral("album7"), {}, 8, 1, + QTime::fromMSecsSinceStartOfDay(21), {QUrl::fromLocalFile(QStringLiteral("/album7/$21"))}, + QDateTime::fromMSecsSinceEpoch(21), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre2"), QStringLiteral("composer2"), QStringLiteral("lyricist2")}, + {true, QStringLiteral("$22"), QStringLiteral("0"), QStringLiteral("track9"), + QStringLiteral("artist3"), QStringLiteral("album7"), {}, 9, 1, + QTime::fromMSecsSinceStartOfDay(22), {QUrl::fromLocalFile(QStringLiteral("/album7/$22"))}, + QDateTime::fromMSecsSinceEpoch(22), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre3"), QStringLiteral("composer3"), QStringLiteral("lyricist3")}, + {true, QStringLiteral("$20"), QStringLiteral("0"), QStringLiteral("track7"), + QStringLiteral("artist1"), QStringLiteral("album7"), {}, 7, 1, + QTime::fromMSecsSinceStartOfDay(20), {QUrl::fromLocalFile(QStringLiteral("/album8/$20"))}, + QDateTime::fromMSecsSinceEpoch(20), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre1"), QStringLiteral("composer1"), QStringLiteral("lyricist1")}, + {true, QStringLiteral("$21"), QStringLiteral("0"), QStringLiteral("track8"), + QStringLiteral("artist2"), QStringLiteral("album7"), {}, 8, 1, + QTime::fromMSecsSinceStartOfDay(21), {QUrl::fromLocalFile(QStringLiteral("/album8/$21"))}, + QDateTime::fromMSecsSinceEpoch(21), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre2"), QStringLiteral("composer2"), QStringLiteral("lyricist2")}, + {true, QStringLiteral("$22"), QStringLiteral("0"), QStringLiteral("track9"), + QStringLiteral("artist3"), QStringLiteral("album7"), {}, 9, 1, + QTime::fromMSecsSinceStartOfDay(22), {QUrl::fromLocalFile(QStringLiteral("/album8/$22"))}, + QDateTime::fromMSecsSinceEpoch(22), + {QUrl::fromLocalFile(QStringLiteral("album7"))}, 5, true, + QStringLiteral("genre3"), QStringLiteral("composer3"), QStringLiteral("lyricist3")},}; + + auto newCovers = mNewCovers; + newCovers[QStringLiteral("file:///album7/$20")] = QUrl::fromLocalFile(QStringLiteral("album7")); + newCovers[QStringLiteral("file:///album7/$21")] = QUrl::fromLocalFile(QStringLiteral("album7")); + newCovers[QStringLiteral("file:///album7/$22")] = QUrl::fromLocalFile(QStringLiteral("album7")); + newCovers[QStringLiteral("file:///album8/$20")] = QUrl::fromLocalFile(QStringLiteral("album8")); + newCovers[QStringLiteral("file:///album8/$21")] = QUrl::fromLocalFile(QStringLiteral("album8")); + newCovers[QStringLiteral("file:///album8/$22")] = QUrl::fromLocalFile(QStringLiteral("album8")); + + musicDb.insertTracksList(newTracks, newCovers, QStringLiteral("autoTest")); + + musicDbTrackAddedSpy.wait(300); + + QCOMPARE(musicDb.allAlbums().count(), 2); + QCOMPARE(musicDb.allArtists().count(), 3); + QCOMPARE(musicDb.allTracks().count(), 6); + 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); + + auto allAlbums = musicDb.allAlbums(); + auto firstAlbum = allAlbums[0]; + QCOMPARE(firstAlbum.tracksCount(), 3); + auto secondAlbum = allAlbums[1]; + QCOMPARE(secondAlbum.tracksCount(), 3); + } }; QTEST_GUILESS_MAIN(DatabaseInterfaceTests) diff --git a/autotests/mediaplaylisttest.cpp b/autotests/mediaplaylisttest.cpp --- a/autotests/mediaplaylisttest.cpp +++ b/autotests/mediaplaylisttest.cpp @@ -3863,7 +3863,7 @@ QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl()); + QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl(QStringLiteral("file:file://image$4"))); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$1"))); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayListSave.data(myPlayListSave.index(1, 0), MediaPlayList::ColumnsRoles::HasAlbumHeader).toBool(), true); @@ -3934,7 +3934,7 @@ QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 1); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 1); - QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl()); + QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl(QStringLiteral("file:file://image$4"))); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$1"))); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayListRead.data(myPlayListRead.index(1, 0), MediaPlayList::ColumnsRoles::HasAlbumHeader).toBool(), true); @@ -4070,7 +4070,7 @@ QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 3); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl()); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl(QStringLiteral("file:file://image$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$3"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::HasAlbumHeader).toBool(), true); @@ -4118,7 +4118,7 @@ QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 4); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl()); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl(QStringLiteral("file:file://image$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::HasAlbumHeader).toBool(), true); @@ -4246,7 +4246,7 @@ QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 3); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl()); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl(QStringLiteral("file:file://image$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$3"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::HasAlbumHeader).toBool(), true); @@ -4299,7 +4299,7 @@ QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 4); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl()); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl(QStringLiteral("file:file://image$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::HasAlbumHeader).toBool(), true); @@ -4415,7 +4415,7 @@ QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 3); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 3); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl()); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl(QStringLiteral("file:file://image$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("file:///$3"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::HasAlbumHeader).toBool(), true); @@ -4456,7 +4456,7 @@ QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::AlbumRole).toString(), QStringLiteral("album1")); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::TrackNumberRole).toInt(), 4); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::DiscNumberRole).toInt(), 4); - QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl()); + QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ImageRole).toUrl(), QUrl(QStringLiteral("file:file://image$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::ResourceRole).toUrl(), QUrl::fromUserInput(QStringLiteral("/$4"))); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::IsPlayingRole).toBool(), false); QCOMPARE(myPlayList.data(myPlayList.index(0, 0), MediaPlayList::ColumnsRoles::HasAlbumHeader).toBool(), true); diff --git a/src/databaseinterface.h b/src/databaseinterface.h --- a/src/databaseinterface.h +++ b/src/databaseinterface.h @@ -67,6 +67,13 @@ Q_ENUMS(PropertyType) + enum AlbumDiscsCount { + SingleDiscAlbum, + MultipleDiscsAlbum, + }; + + Q_ENUMS(AlbumDiscsCounts) + explicit DatabaseInterface(QObject *parent = nullptr); ~DatabaseInterface() override; @@ -180,8 +187,9 @@ qulonglong internalTrackIdFromTitleAlbumTracDiscNumber(const QString &title, const QString &artist, const QString &album, int trackNumber, int discNumber); - qulonglong getDuplicateTrackIdFromTitleAlbumTracDiscNumber(const QString &title, const QString &album, const QString &albumArtist, - int trackNumber, int discNumber); + qulonglong getDuplicateTrackIdFromTitleAlbumTrackDiscNumber(const QString &title, const QString &album, + const QString &albumArtist, const QString &trackPath, + int trackNumber, int discNumber); qulonglong internalTrackIdFromFileName(const QUrl &fileName); @@ -194,8 +202,9 @@ void initRequest(); qulonglong insertAlbum(const QString &title, const QString &albumArtist, const QString &trackArtist, - const QUrl &albumArtURI, int tracksCount, bool isSingleDiscAlbum, - QList &newAlbumIds, QList &newArtistsIds); + const QString &trackPath, const QUrl &albumArtURI, int tracksCount, + AlbumDiscsCount isSingleDiscAlbum, QList &newAlbumIds, + QList &newArtistsIds); bool updateAlbumFromId(qulonglong albumId, const QUrl &albumArtUri, const MusicAudioTrack ¤tTrack, QList &newArtistsIds); @@ -210,6 +219,9 @@ void removeTrackInDatabase(qulonglong trackId); + void updateTrackInDatabase(const MusicAudioTrack &oneTrack, qulonglong albumId, + QList &newArtistsIds); + void removeAlbumInDatabase(qulonglong albumId); void removeArtistInDatabase(qulonglong artistId); diff --git a/src/databaseinterface.cpp b/src/databaseinterface.cpp --- a/src/databaseinterface.cpp +++ b/src/databaseinterface.cpp @@ -70,7 +70,8 @@ mSelectAllAlbumsShortQuery(mTracksDatabase), mSelectAllComposersQuery(mTracksDatabase), mSelectAllLyricistsQuery(mTracksDatabase), mSelectCountAlbumsForComposerQuery(mTracksDatabase), mSelectCountAlbumsForLyricistQuery(mTracksDatabase), mSelectAllGenresQuery(mTracksDatabase), - mSelectGenreForArtistQuery(mTracksDatabase), mSelectGenreForAlbumQuery(mTracksDatabase) + mSelectGenreForArtistQuery(mTracksDatabase), mSelectGenreForAlbumQuery(mTracksDatabase), + mUpdateTrackQuery(mTracksDatabase) { } @@ -204,6 +205,8 @@ QSqlQuery mSelectGenreForAlbumQuery; + QSqlQuery mUpdateTrackQuery; + qulonglong mAlbumId = 1; qulonglong mArtistId = 1; @@ -254,6 +257,8 @@ } qDebug() << "DatabaseInterface::init" << (tracksDatabase.driver()->hasFeature(QSqlDriver::Transactions) ? "yes" : "no"); + tracksDatabase.exec(QStringLiteral("PRAGMA foreign_keys = ON;")); + d = std::make_unique(tracksDatabase); initDatabase(); @@ -450,9 +455,10 @@ newAlbum.setTitle(currentRecord.value(1).toString()); newAlbum.setId(currentRecord.value(2).toString()); newAlbum.setArtist(currentRecord.value(3).toString()); - newAlbum.setAlbumArtURI(currentRecord.value(4).toUrl()); - newAlbum.setTracksCount(currentRecord.value(5).toInt()); - newAlbum.setIsSingleDiscAlbum(currentRecord.value(6).toBool()); + newAlbum.setAlbumPath(currentRecord.value(4).toUrl()); + newAlbum.setAlbumArtURI(currentRecord.value(5).toUrl()); + newAlbum.setTracksCount(currentRecord.value(6).toInt()); + newAlbum.setIsSingleDiscAlbum(currentRecord.value(7).toBool()); newAlbum.setTracks(fetchTracks(newAlbum.databaseId())); newAlbum.setValid(true); @@ -1037,8 +1043,25 @@ auto listTables = d->mTracksDatabase.tables(); - if (!listTables.contains(QStringLiteral("DatabaseVersionV4"))) { - for (const auto &oneTable : listTables) { + if (!listTables.contains(QStringLiteral("DatabaseVersionV5"))) { + auto oldTables = QStringList{QStringLiteral("DatabaseVersionV2"), + QStringLiteral("DatabaseVersionV3"), + QStringLiteral("DatabaseVersionV4"), + QStringLiteral("AlbumsArtists"), + QStringLiteral("TracksArtists"), + QStringLiteral("TracksMapping"), + QStringLiteral("Tracks"), + QStringLiteral("Composer"), + QStringLiteral("Genre"), + QStringLiteral("Lyricist"), + QStringLiteral("Albums"), + QStringLiteral("DiscoverSource"), + QStringLiteral("Artists"),}; + for (const auto &oneTable : oldTables) { + if (listTables.indexOf(oneTable) == -1) { + continue; + } + QSqlQuery createSchemaQuery(d->mTracksDatabase); auto result = createSchemaQuery.exec(QStringLiteral("DROP TABLE ") + oneTable); @@ -1054,10 +1077,10 @@ listTables = d->mTracksDatabase.tables(); } - if (!listTables.contains(QStringLiteral("DatabaseVersionV4"))) { + if (!listTables.contains(QStringLiteral("DatabaseVersionV5"))) { QSqlQuery createSchemaQuery(d->mTracksDatabase); - const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV4` (`Version` INTEGER PRIMARY KEY NOT NULL)")); + const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `DatabaseVersionV5` (`Version` INTEGER PRIMARY KEY NOT NULL)")); if (!result) { qDebug() << "DatabaseInterface::initDatabase" << createSchemaQuery.lastQuery(); @@ -1148,6 +1171,7 @@ const auto &result = createSchemaQuery.exec(QStringLiteral("CREATE TABLE `Albums` (" "`ID` INTEGER PRIMARY KEY NOT NULL, " "`Title` VARCHAR(55) NOT NULL, " + "`AlbumPath` VARCHAR(255) NOT NULL, " "`CoverFileName` VARCHAR(255) NOT NULL, " "`TracksCount` INTEGER NOT NULL, " "`IsSingleDiscAlbum` BOOLEAN NOT NULL, " @@ -1243,7 +1267,7 @@ "`FileModifiedTime` DATETIME NOT NULL, " "PRIMARY KEY (`FileName`), " "CONSTRAINT TracksUnique UNIQUE (`TrackID`, `Priority`), " - "CONSTRAINT fk_tracksmapping_trackID FOREIGN KEY (`TrackID`) REFERENCES `Tracks`(`ID`), " + "CONSTRAINT fk_tracksmapping_trackID FOREIGN KEY (`TrackID`) REFERENCES `Tracks`(`ID`) ON DELETE CASCADE, " "CONSTRAINT fk_tracksmapping_discoverID FOREIGN KEY (`DiscoverID`) REFERENCES `DiscoverSource`(`ID`))")); if (!result) { @@ -1367,6 +1391,7 @@ "album.`Title`, " "album.`AlbumInternalID`, " "artist.`Name`, " + "album.`AlbumPath`, " "album.`CoverFileName`, " "album.`TracksCount`, " "album.`IsSingleDiscAlbum` " @@ -1396,6 +1421,7 @@ "album.`Title`, " "album.`AlbumInternalID`, " "artist.`Name`, " + "album.`AlbumPath`, " "album.`CoverFileName`, " "album.`TracksCount`, " "album.`IsSingleDiscAlbum` " @@ -1972,6 +1998,7 @@ "WHERE " "album.`ID` = albumArtist.`AlbumID` AND " "album.`Title` = :title AND " + "album.`AlbumPath` = :albumPath AND " "albumArtist.`ArtistID` = :artistId"); auto result = d->mSelectAlbumIdFromTitleAndArtistQuery.prepare(selectAlbumIdFromTitleAndArtistQueryText); @@ -1990,6 +2017,7 @@ "FROM " "`Albums` album " "WHERE " + "album.`AlbumPath` = :albumPath AND " "album.`Title` = :title AND " "NOT EXISTS (" "SELECT " @@ -2011,8 +2039,20 @@ } { - auto insertAlbumQueryText = QStringLiteral("INSERT INTO Albums (`ID`, `Title`, `CoverFileName`, `TracksCount`, `IsSingleDiscAlbum`) " - "VALUES (:albumId, :title, :coverFileName, :tracksCount, :isSingleDiscAlbum)"); + auto insertAlbumQueryText = QStringLiteral("INSERT INTO `Albums` " + "(`ID`, " + "`Title`, " + "`AlbumPath`, " + "`CoverFileName`, " + "`TracksCount`, " + "`IsSingleDiscAlbum`) " + "VALUES " + "(:albumId, " + ":title, " + ":albumPath, " + ":coverFileName, " + ":tracksCount, " + ":isSingleDiscAlbum)"); auto result = d->mInsertAlbumQuery.prepare(insertAlbumQueryText); @@ -2310,6 +2350,37 @@ Q_EMIT databaseError(); } } + + { + auto updateTrackQueryText = QStringLiteral("UPDATE `Tracks` " + "SET " + "`Title` = :title, " + "`AlbumID` = :album, " + "`GenreID` = :genreId, " + "`ComposerID` = :composerId, " + "`LyricistID` = :lyricistId, " + "`Comment` = :comment, " + "`TrackNumber` = :trackNumber, " + "`DiscNumber` = :discNumber, " + "`Channels` = :channels, " + "`BitRate` = :bitRate, " + "`SampleRate` = :sampleRate, " + "`Year` = :year, " + " `Duration` = :trackDuration, " + "`Rating` = :trackRating " + "WHERE " + "`ID` = :trackId"); + + auto result = d->mUpdateTrackQuery.prepare(updateTrackQueryText); + + if (!result) { + qDebug() << "DatabaseInterface::initRequest" << d->mUpdateTrackQuery.lastQuery(); + qDebug() << "DatabaseInterface::initRequest" << d->mUpdateTrackQuery.lastError(); + + Q_EMIT databaseError(); + } + } + { auto selectTrackQueryText = QStringLiteral("SELECT " "tracks.ID " @@ -2348,6 +2419,7 @@ "tracks.`Title` = :title AND " "tracks.`AlbumID` = albums.`ID` AND " "albums.`Title` = :album AND " + "albums.`AlbumPath` = :albumPath AND " "tracks.`TrackNumber` = :trackNumber AND " "tracks.`DiscNumber` = :discNumber AND " "( " @@ -2726,8 +2798,9 @@ } qulonglong DatabaseInterface::insertAlbum(const QString &title, const QString &albumArtist, const QString &trackArtist, - const QUrl &albumArtURI, int tracksCount, bool isSingleDiscAlbum, - QList &newAlbumIds, QList &newArtistsIds) + const QString &trackPath, const QUrl &albumArtURI, int tracksCount, + AlbumDiscsCount isSingleDiscAlbum, QList &newAlbumIds, + QList &newArtistsIds) { auto result = qulonglong(0); @@ -2737,6 +2810,7 @@ if (!albumArtist.isEmpty() || !trackArtist.isEmpty()) { d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":title"), title); + d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":albumPath"), trackPath); if (!albumArtist.isEmpty()) { d->mSelectAlbumIdFromTitleAndArtistQuery.bindValue(QStringLiteral(":artistId"), insertArtist(albumArtist, newArtistsIds)); } else { @@ -2770,6 +2844,7 @@ if (result == 0) { d->mSelectAlbumIdFromTitleWithoutArtistQuery.bindValue(QStringLiteral(":title"), title); + d->mSelectAlbumIdFromTitleWithoutArtistQuery.bindValue(QStringLiteral(":albumPath"), trackPath); auto queryResult = d->mSelectAlbumIdFromTitleWithoutArtistQuery.exec(); @@ -2798,6 +2873,7 @@ d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumId"), d->mAlbumId); d->mInsertAlbumQuery.bindValue(QStringLiteral(":title"), title); + d->mInsertAlbumQuery.bindValue(QStringLiteral(":albumPath"), trackPath); d->mInsertAlbumQuery.bindValue(QStringLiteral(":coverFileName"), albumArtURI); d->mInsertAlbumQuery.bindValue(QStringLiteral(":tracksCount"), tracksCount); d->mInsertAlbumQuery.bindValue(QStringLiteral(":isSingleDiscAlbum"), isSingleDiscAlbum); @@ -3287,19 +3363,29 @@ { qulonglong resultId = 0; + auto oldTrack = oneTrack; + if (oneTrack.albumArtist().isEmpty()) { return resultId; } + QUrl::FormattingOptions currentOptions = QUrl::PreferLocalFile | + QUrl::RemoveAuthority | QUrl::RemoveFilename | QUrl::RemoveFragment | + QUrl::RemovePassword | QUrl::RemovePort | QUrl::RemoveQuery | + QUrl::RemoveScheme | QUrl::RemoveUserInfo; + + const auto &trackPath = oneTrack.resourceURI().toString(currentOptions); + auto albumId = insertAlbum(oneTrack.albumName(), (oneTrack.isValidAlbumArtist() ? oneTrack.albumArtist() : QString()), - oneTrack.artist(), covers[oneTrack.resourceURI().toString()], 0, true, newAlbumIds, newArtistsIds); + oneTrack.artist(), trackPath, covers[oneTrack.resourceURI().toString()], 0, SingleDiscAlbum, + newAlbumIds, newArtistsIds); if (albumId == 0) { return resultId; } - auto otherTrackId = getDuplicateTrackIdFromTitleAlbumTracDiscNumber(oneTrack.title(), oneTrack.albumName(), oneTrack.albumArtist(), - oneTrack.trackNumber(), oneTrack.discNumber()); + auto otherTrackId = getDuplicateTrackIdFromTitleAlbumTrackDiscNumber(oneTrack.title(), oneTrack.albumName(), oneTrack.albumArtist(), + trackPath, oneTrack.trackNumber(), oneTrack.discNumber()); bool isModifiedTrack = (otherTrackId != 0) || (insertType == TrackFileInsertType::ModifiedTrackFileInsert); bool isSameTrack = false; @@ -3312,7 +3398,7 @@ originTrackId = otherTrackId; - const auto &oldTrack = internalTrackFromDatabaseId(originTrackId); + oldTrack = internalTrackFromDatabaseId(originTrackId); isSameTrack = (oldTrack.title() == oneTrack.title()); isSameTrack = isSameTrack && (oldTrack.albumName() == oneTrack.albumName()); @@ -3335,7 +3421,21 @@ oldAlbumId = internalAlbumIdFromTitleAndArtist(oldTrack.albumName(), oldTrack.albumArtist()); if (!isSameTrack) { - removeTrackInDatabase(originTrackId); + auto newTrack = oneTrack; + newTrack.setDatabaseId(oldTrack.databaseId()); + updateTrackInDatabase(newTrack, albumId, newArtistsIds); + updateTrackOrigin(newTrack.databaseId(), oneTrack.resourceURI(), oneTrack.fileModificationTime()); + if (oldTrack.albumCover() != oneTrack.albumCover()) { + updateAlbumFromId(albumId, oneTrack.albumCover(), oneTrack, newArtistsIds); + } + + Q_EMIT trackModified(internalTrackFromDatabaseId(originTrackId)); + modifiedAlbumIds.insert(albumId); + if (oldAlbumId != 0) { + modifiedAlbumIds.insert(oldAlbumId); + } + + isSameTrack = true; } } else { originTrackId = d->mTrackId; @@ -3380,24 +3480,26 @@ if (result && d->mInsertTrackQuery.isActive()) { d->mInsertTrackQuery.finish(); - d->mInsertTrackArtistQuery.bindValue(QStringLiteral(":trackId"), originTrackId); - d->mInsertTrackArtistQuery.bindValue(QStringLiteral(":artistId"), insertArtist(oneTrack.artist(), newArtistsIds)); + if (!isModifiedTrack || (!isSameTrack && oneTrack.artist() != oldTrack.artist())) { + d->mInsertTrackArtistQuery.bindValue(QStringLiteral(":trackId"), originTrackId); + d->mInsertTrackArtistQuery.bindValue(QStringLiteral(":artistId"), insertArtist(oneTrack.artist(), newArtistsIds)); - result = d->mInsertTrackArtistQuery.exec(); + result = d->mInsertTrackArtistQuery.exec(); - if (!result || !d->mInsertTrackArtistQuery.isActive()) { - Q_EMIT databaseError(); + 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(); + qDebug() << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackArtistQuery.lastQuery(); + qDebug() << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackArtistQuery.boundValues(); + qDebug() << "DatabaseInterface::internalInsertTrack" << d->mInsertTrackArtistQuery.lastError(); - d->mInsertTrackArtistQuery.finish(); + d->mInsertTrackArtistQuery.finish(); - return resultId; - } + return resultId; + } - d->mInsertTrackArtistQuery.finish(); + d->mInsertTrackArtistQuery.finish(); + } if (!isModifiedTrack) { @@ -3976,6 +4078,90 @@ d->mRemoveTrackQuery.finish(); } +void DatabaseInterface::updateTrackInDatabase(const MusicAudioTrack &oneTrack, qulonglong albumId, + QList &newArtistsIds) +{ + d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackId"), oneTrack.databaseId()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":title"), oneTrack.title()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":album"), albumId); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackNumber"), oneTrack.trackNumber()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":discNumber"), oneTrack.discNumber()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackDuration"), QVariant::fromValue(oneTrack.duration().msecsSinceStartOfDay())); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":trackRating"), oneTrack.rating()); + auto genreId = insertGenre(oneTrack.genre()); + if (genreId != 0) { + d->mUpdateTrackQuery.bindValue(QStringLiteral(":genreId"), genreId); + } else { + d->mUpdateTrackQuery.bindValue(QStringLiteral(":genreId"), {}); + } + auto composerId = insertComposer(oneTrack.composer()); + if (composerId != 0) { + d->mUpdateTrackQuery.bindValue(QStringLiteral(":composerId"), composerId); + } else { + d->mUpdateTrackQuery.bindValue(QStringLiteral(":composerId"), {}); + } + auto lyricistId = insertLyricist(oneTrack.lyricist()); + if (lyricistId != 0) { + d->mUpdateTrackQuery.bindValue(QStringLiteral(":lyricistId"), lyricistId); + } else { + d->mUpdateTrackQuery.bindValue(QStringLiteral(":lyricistId"), {}); + } + d->mUpdateTrackQuery.bindValue(QStringLiteral(":comment"), oneTrack.comment()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":year"), oneTrack.year()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":channels"), oneTrack.channels()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":bitRate"), oneTrack.bitRate()); + d->mUpdateTrackQuery.bindValue(QStringLiteral(":sampleRate"), oneTrack.sampleRate()); + + 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(), newArtistsIds)); + + 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 { + 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; + } +} + void DatabaseInterface::removeAlbumInDatabase(qulonglong albumId) { d->mRemoveAlbumArtistQuery.bindValue(QStringLiteral(":albumId"), albumId); @@ -4284,9 +4470,10 @@ retrievedAlbum.setTitle(currentRecord.value(1).toString()); retrievedAlbum.setId(currentRecord.value(2).toString()); retrievedAlbum.setArtist(currentRecord.value(3).toString()); - retrievedAlbum.setAlbumArtURI(currentRecord.value(4).toUrl()); - retrievedAlbum.setTracksCount(currentRecord.value(5).toInt()); - retrievedAlbum.setIsSingleDiscAlbum(currentRecord.value(6).toBool()); + retrievedAlbum.setAlbumPath(currentRecord.value(4).toUrl()); + retrievedAlbum.setAlbumArtURI(currentRecord.value(5).toUrl()); + retrievedAlbum.setTracksCount(currentRecord.value(6).toInt()); + retrievedAlbum.setIsSingleDiscAlbum(currentRecord.value(7).toBool()); retrievedAlbum.setTracks(fetchTracks(albumId)); retrievedAlbum.setValid(true); @@ -4466,8 +4653,9 @@ return result; } -qulonglong DatabaseInterface::getDuplicateTrackIdFromTitleAlbumTracDiscNumber(const QString &title, const QString &album, - const QString &albumArtist, int trackNumber, int discNumber) +qulonglong DatabaseInterface::getDuplicateTrackIdFromTitleAlbumTrackDiscNumber(const QString &title, const QString &album, + const QString &albumArtist, const QString &trackPath, + int trackNumber, int discNumber) { auto result = qulonglong(0); @@ -4477,6 +4665,7 @@ d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":title"), title); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":album"), album); + d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":albumPath"), trackPath); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":albumArtist"), albumArtist); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":trackNumber"), trackNumber); d->mSelectTrackIdFromTitleAlbumTrackDiscNumberQuery.bindValue(QStringLiteral(":discNumber"), discNumber); diff --git a/src/musicalbum.h b/src/musicalbum.h --- a/src/musicalbum.h +++ b/src/musicalbum.h @@ -84,6 +84,10 @@ bool canUpdateArtist(const MusicAudioTrack ¤tTrack) const; + void setAlbumPath(const QUrl &value); + + QUrl albumPath() const; + void setAlbumArtURI(const QUrl &value); QUrl albumArtURI() const; diff --git a/src/musicalbum.cpp b/src/musicalbum.cpp --- a/src/musicalbum.cpp +++ b/src/musicalbum.cpp @@ -42,6 +42,8 @@ QString mArtist; + QUrl mAlbumPath; + QUrl mAlbumArtURI; QUrl mResourceURI; @@ -368,3 +370,13 @@ return result; } + +void MusicAlbum::setAlbumPath(const QUrl &value) +{ + d->mAlbumPath = value; +} + +QUrl MusicAlbum::albumPath() const +{ + return d->mAlbumPath; +}