db/simple/Mount: drop mount point prefix from LOCATE_TAG_BASE_TYPE

Fixes search within mount points, resulting in error "No such
directory".

Closes #190
This commit is contained in:
Max Kellermann 2018-01-19 23:35:05 +01:00
parent ed2354cd9d
commit 8376578921
4 changed files with 53 additions and 0 deletions

2
NEWS
View File

@ -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)

View File

@ -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;
}

View File

@ -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;
};
/**

View File

@ -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);
}