diff --git a/NEWS b/NEWS index f5182a945..2836e984e 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.20.16 (not yet released) +* database + - simple: fix search within mount points * fix crash in debug build on Haiku and other operating systems ver 0.20.15 (2018/01/05) diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx index a42f15ff4..c0e0a2edd 100644 --- a/src/SongFilter.cxx +++ b/src/SongFilter.cxx @@ -24,6 +24,8 @@ #include "tag/Tag.hxx" #include "util/ConstBuffer.hxx" #include "util/StringAPI.hxx" +#include "util/StringCompare.hxx" +#include "util/StringView.hxx" #include "util/ASCII.hxx" #include "util/TimeParser.hxx" #include "util/UriUtil.hxx" @@ -274,3 +276,33 @@ SongFilter::GetBase() const noexcept return nullptr; } + +SongFilter +SongFilter::WithoutBasePrefix(const char *_prefix) const noexcept +{ + const StringView prefix(_prefix); + SongFilter result; + + for (const auto &i : items) { + if (i.GetTag() == LOCATE_TAG_BASE_TYPE) { + const char *s = StringAfterPrefix(i.GetValue(), prefix); + if (s != nullptr) { + if (*s == 0) + continue; + + if (*s == '/') { + ++s; + + if (*s != 0) + result.items.emplace_back(LOCATE_TAG_BASE_TYPE, s); + + continue; + } + } + } + + result.items.emplace_back(i); + } + + return result; +} diff --git a/src/SongFilter.hxx b/src/SongFilter.hxx index d102db94f..f0fa73635 100644 --- a/src/SongFilter.hxx +++ b/src/SongFilter.hxx @@ -152,6 +152,13 @@ public: */ gcc_pure const char *GetBase() const noexcept; + + /** + * Create a copy of the filter with the given prefix stripped + * from all #LOCATE_TAG_BASE_TYPE items. This is used to + * filter songs in mounted databases. + */ + SongFilter WithoutBasePrefix(const char *prefix) const noexcept; }; /** diff --git a/src/db/plugins/simple/Mount.cxx b/src/db/plugins/simple/Mount.cxx index 1945b74c6..22db95f46 100644 --- a/src/db/plugins/simple/Mount.cxx +++ b/src/db/plugins/simple/Mount.cxx @@ -20,6 +20,7 @@ #include "config.h" #include "Mount.hxx" #include "PrefixedLightSong.hxx" +#include "SongFilter.hxx" #include "db/Selection.hxx" #include "db/LightDirectory.hxx" #include "db/Interface.hxx" @@ -86,5 +87,16 @@ WalkMount(const char *base, const Database &db, vp = std::bind(PrefixVisitPlaylist, base, std::ref(visit_playlist), _1, _2); + SongFilter prefix_filter; + + if (base != nullptr && filter != nullptr) { + /* if the SongFilter contains a LOCATE_TAG_BASE_TYPE + item, copy the SongFilter and drop the mount point + from the filter, because the mounted database + doesn't know its own location within MPD's VFS */ + prefix_filter = filter->WithoutBasePrefix(base); + filter = &prefix_filter; + } + db.Visit(DatabaseSelection(uri, recursive, filter), vd, vs, vp); }