diff --git a/src/libs/database/impl/Artist.cpp b/src/libs/database/impl/Artist.cpp index 5ade2f65..936d6779 100644 --- a/src/libs/database/impl/Artist.cpp +++ b/src/libs/database/impl/Artist.cpp @@ -45,7 +45,10 @@ Artist::getByName(Session& session, const std::string& name) { session.checkSharedLocked(); - Wt::Dbo::collection res = session.getDboSession().find().where("name = ?").bind( std::string{name, 0, _maxNameLength} ); + Wt::Dbo::collection res = session.getDboSession().find() + .where("name = ?").bind(std::string {name, 0, _maxNameLength}) + .orderBy("LENGTH(mbid) DESC"); // put mbid entries first + return std::vector(res.begin(), res.end()); } diff --git a/src/libs/database/impl/Session.cpp b/src/libs/database/impl/Session.cpp index 2cbf47ac..005bea2e 100644 --- a/src/libs/database/impl/Session.cpp +++ b/src/libs/database/impl/Session.cpp @@ -40,7 +40,7 @@ namespace Database { -#define LMS_DATABASE_VERSION 27 +#define LMS_DATABASE_VERSION 28 using Version = std::size_t; @@ -284,6 +284,12 @@ CREATE TABLE "user_backup" ( // Just increment the scan version of the settings to make the next scheduled scan rescan everything ScanSettings::get(*this).modify()->incScanVersion(); } + else if (version == 27) + { + // Composer, mixer, etc. support, now fallback on MBID tagged entries as there is no mean to provide MBID by tags for these kinf od artists + // Just increment the scan version of the settings to make the next scheduled scan rescan everything + ScanSettings::get(*this).modify()->incScanVersion(); + } else { LMS_LOG(DB, ERROR) << "Database version " << version << " cannot be handled using migration"; diff --git a/src/libs/database/include/database/ScanSettings.hpp b/src/libs/database/include/database/ScanSettings.hpp index 0a2ee450..c1d32718 100644 --- a/src/libs/database/include/database/ScanSettings.hpp +++ b/src/libs/database/include/database/ScanSettings.hpp @@ -56,13 +56,13 @@ class ScanSettings : public Wt::Dbo::Dbo static pointer get(Session& session); // Getters - std::size_t getScanVersion() const { return _scanVersion; } - std::filesystem::path getMediaDirectory() const { return _mediaDirectory; } - Wt::WTime getUpdateStartTime() const { return _startTime; } - UpdatePeriod getUpdatePeriod() const { return _updatePeriod; } + std::size_t getScanVersion() const { return _scanVersion; } + std::filesystem::path getMediaDirectory() const { return _mediaDirectory; } + Wt::WTime getUpdateStartTime() const { return _startTime; } + UpdatePeriod getUpdatePeriod() const { return _updatePeriod; } std::vector> getClusterTypes() const; std::unordered_set getAudioFileExtensions() const; - RecommendationEngineType getRecommendationEngineType() const { return _recommendationEngineType; } + RecommendationEngineType getRecommendationEngineType() const { return _recommendationEngineType; } // Setters void addAudioFileExtension(const std::filesystem::path& ext); diff --git a/src/libs/scanner/impl/MediaScanner.cpp b/src/libs/scanner/impl/MediaScanner.cpp index 3bc6984e..5f3660f2 100644 --- a/src/libs/scanner/impl/MediaScanner.cpp +++ b/src/libs/scanner/impl/MediaScanner.cpp @@ -121,7 +121,7 @@ updateArtistIfNeeded(const Artist::pointer& artist, const MetaData::Artist& arti } std::vector -getOrCreateArtists(Session& session, const std::vector& artistsInfo) +getOrCreateArtists(Session& session, const std::vector& artistsInfo, bool allowFallbackOnMBIDEntries) { std::vector artists; @@ -148,11 +148,11 @@ getOrCreateArtists(Session& session, const std::vector& artist for (const Artist::pointer& sameNamedArtist : Artist::getByName(session, artistInfo.name)) { // Do not fallback on artist that is correctly tagged - if (!sameNamedArtist->getMBID()) - { - artist = sameNamedArtist; - break; - } + if (!allowFallbackOnMBIDEntries && sameNamedArtist->getMBID()) + continue; + + artist = sameNamedArtist; + break; } // No Artist found with the same name and without MBID -> creating @@ -771,28 +771,31 @@ MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, S assert(track); track.modify()->clearArtistLinks(); - for (const Artist::pointer& artist : getOrCreateArtists(_dbSession, trackInfo->artists)) + // Do not fallback on artists with the same name but having a MBID for artist and releaseArtists, as it may be corrected by properly tagging files + for (const Artist::pointer& artist : getOrCreateArtists(_dbSession, trackInfo->artists, false)) track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, artist, Database::TrackArtistLinkType::Artist)); - for (const Artist::pointer& releaseArtist : getOrCreateArtists(_dbSession, trackInfo->albumArtists)) + for (const Artist::pointer& releaseArtist : getOrCreateArtists(_dbSession, trackInfo->albumArtists, false)) track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, releaseArtist, Database::TrackArtistLinkType::ReleaseArtist)); - for (const Artist::pointer& conductor : getOrCreateArtists(_dbSession, trackInfo->conductorArtists)) + // Allow fallbacks on artists with the same name even if they have MBID, since there is no tag to indicate the MBID of these artists + // We could ask MusicBrainz to get all the information, but that would heavily slow down the import process + for (const Artist::pointer& conductor : getOrCreateArtists(_dbSession, trackInfo->conductorArtists, true)) track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, conductor, Database::TrackArtistLinkType::Conductor)); - for (const Artist::pointer& composer : getOrCreateArtists(_dbSession, trackInfo->composerArtists)) + for (const Artist::pointer& composer : getOrCreateArtists(_dbSession, trackInfo->composerArtists, true)) track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, composer, Database::TrackArtistLinkType::Composer)); - for (const Artist::pointer& lyricist : getOrCreateArtists(_dbSession, trackInfo->lyricistArtists)) + for (const Artist::pointer& lyricist : getOrCreateArtists(_dbSession, trackInfo->lyricistArtists, true)) track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, lyricist, Database::TrackArtistLinkType::Lyricist)); - for (const Artist::pointer& mixer : getOrCreateArtists(_dbSession, trackInfo->mixerArtists)) + for (const Artist::pointer& mixer : getOrCreateArtists(_dbSession, trackInfo->mixerArtists, true)) track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, mixer, Database::TrackArtistLinkType::Mixer)); - for (const Artist::pointer& producer : getOrCreateArtists(_dbSession, trackInfo->producerArtists)) + for (const Artist::pointer& producer : getOrCreateArtists(_dbSession, trackInfo->producerArtists, true)) track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, producer, Database::TrackArtistLinkType::Producer)); - for (const Artist::pointer& remixer : getOrCreateArtists(_dbSession, trackInfo->remixerArtists)) + for (const Artist::pointer& remixer : getOrCreateArtists(_dbSession, trackInfo->remixerArtists, true)) track.modify()->addArtistLink(Database::TrackArtistLink::create(_dbSession, track, remixer, Database::TrackArtistLinkType::Remixer)); track.modify()->setScanVersion(_scanVersion);