diff --git a/NEWS b/NEWS index 7700571c3..a654ef87a 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.22.2 (not yet released) * database - - simple: purge virtual directories for unavailable plugins on update + - simple: purge songs and virtual directories for unavailable plugins + on update ver 0.22.1 (2020/10/17) * decoder diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx index c5701d9aa..2562bffb3 100644 --- a/src/SongUpdate.cxx +++ b/src/SongUpdate.cxx @@ -23,6 +23,7 @@ #include "db/plugins/simple/Directory.hxx" #include "storage/StorageInterface.hxx" #include "storage/FileInfo.hxx" +#include "decoder/DecoderList.hxx" #include "fs/AllocatedPath.hxx" #include "fs/FileInfo.hxx" #include "tag/Builder.hxx" @@ -40,6 +41,14 @@ #ifdef ENABLE_DATABASE +bool +Song::IsPluginAvailable() const noexcept +{ + const char *suffix = GetFilenameSuffix(); + return suffix != nullptr && + decoder_plugins_supports_suffix(suffix); +} + SongPtr Song::LoadFile(Storage &storage, const char *path_utf8, Directory &parent) { diff --git a/src/db/plugins/simple/Song.cxx b/src/db/plugins/simple/Song.cxx index 3da13b9ea..eecf00277 100644 --- a/src/db/plugins/simple/Song.cxx +++ b/src/db/plugins/simple/Song.cxx @@ -34,6 +34,14 @@ Song::Song(DetachedSong &&other, Directory &_parent) noexcept { } +const char * +Song::GetFilenameSuffix() const noexcept +{ + return target.empty() + ? PathTraitsUTF8::GetFilenameSuffix(filename.c_str()) + : PathTraitsUTF8::GetPathSuffix(target.c_str()); +} + std::string Song::GetURI() const noexcept { diff --git a/src/db/plugins/simple/Song.hxx b/src/db/plugins/simple/Song.hxx index 04be80845..90334b031 100644 --- a/src/db/plugins/simple/Song.hxx +++ b/src/db/plugins/simple/Song.hxx @@ -108,6 +108,16 @@ struct Song { Song(DetachedSong &&other, Directory &_parent) noexcept; + gcc_pure + const char *GetFilenameSuffix() const noexcept; + + /** + * Checks whether the decoder plugin for this song is + * available. + */ + gcc_pure + bool IsPluginAvailable() const noexcept; + /** * allocate a new song structure with a local file name and attempt to * load its metadata. If all decoder plugin fail to read its meta diff --git a/src/db/update/Walk.cxx b/src/db/update/Walk.cxx index fc4af265a..3e0677e91 100644 --- a/src/db/update/Walk.cxx +++ b/src/db/update/Walk.cxx @@ -111,7 +111,11 @@ UpdateWalk::PurgeDeletedFromDirectory(Directory &directory) noexcept directory.ForEachSongSafe([&](Song &song){ if (!directory_child_is_regular(storage, directory, - song.filename)) { + song.filename) || + !song.IsPluginAvailable()) { + /* the song file was deleted (or the decoder + plugin is unavailable) */ + editor.LockDeleteSong(directory, &song); modified = true;