SongFilter: make Item an interface
Prepare to allow more complex expressions.
This commit is contained in:
@@ -268,49 +268,53 @@ CheckError(struct mpd_connection *connection)
|
||||
}
|
||||
|
||||
static bool
|
||||
SendConstraints(mpd_connection *connection, const SongFilter::Item &item)
|
||||
SendConstraints(mpd_connection *connection, const ISongFilter &f)
|
||||
{
|
||||
switch (item.GetTag()) {
|
||||
mpd_tag_type tag;
|
||||
|
||||
#if LIBMPDCLIENT_CHECK_VERSION(2,9,0)
|
||||
case LOCATE_TAG_BASE_TYPE:
|
||||
if (mpd_connection_cmp_server_version(connection, 0, 18, 0) < 0)
|
||||
/* requires MPD 0.18 */
|
||||
if (auto t = dynamic_cast<const TagSongFilter *>(&f)) {
|
||||
if (t->IsNegated())
|
||||
// TODO implement
|
||||
return true;
|
||||
|
||||
return mpd_search_add_base_constraint(connection,
|
||||
MPD_OPERATOR_DEFAULT,
|
||||
item.GetValue());
|
||||
#endif
|
||||
if (t->GetTagType() == TAG_NUM_OF_ITEM_TYPES)
|
||||
return mpd_search_add_any_tag_constraint(connection,
|
||||
MPD_OPERATOR_DEFAULT,
|
||||
t->GetValue().c_str());
|
||||
|
||||
case LOCATE_TAG_FILE_TYPE:
|
||||
return mpd_search_add_uri_constraint(connection,
|
||||
MPD_OPERATOR_DEFAULT,
|
||||
item.GetValue());
|
||||
|
||||
case LOCATE_TAG_ANY_TYPE:
|
||||
return mpd_search_add_any_tag_constraint(connection,
|
||||
MPD_OPERATOR_DEFAULT,
|
||||
item.GetValue());
|
||||
|
||||
default:
|
||||
tag = Convert(TagType(item.GetTag()));
|
||||
const auto tag = Convert(t->GetTagType());
|
||||
if (tag == MPD_TAG_COUNT)
|
||||
return true;
|
||||
|
||||
return mpd_search_add_tag_constraint(connection,
|
||||
MPD_OPERATOR_DEFAULT,
|
||||
tag,
|
||||
item.GetValue());
|
||||
}
|
||||
t->GetValue().c_str());
|
||||
} else if (auto u = dynamic_cast<const UriSongFilter *>(&f)) {
|
||||
if (u->IsNegated())
|
||||
// TODO implement
|
||||
return true;
|
||||
|
||||
return mpd_search_add_uri_constraint(connection,
|
||||
MPD_OPERATOR_DEFAULT,
|
||||
u->GetValue().c_str());
|
||||
#if LIBMPDCLIENT_CHECK_VERSION(2,9,0)
|
||||
} else if (auto b = dynamic_cast<const BaseSongFilter *>(&f)) {
|
||||
if (mpd_connection_cmp_server_version(connection, 0, 18, 0) < 0)
|
||||
/* requires MPD 0.18 */
|
||||
return true;
|
||||
|
||||
return mpd_search_add_base_constraint(connection,
|
||||
MPD_OPERATOR_DEFAULT,
|
||||
b->GetValue());
|
||||
#endif
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
SendConstraints(mpd_connection *connection, const SongFilter &filter)
|
||||
{
|
||||
for (const auto &i : filter.GetItems())
|
||||
if (!SendConstraints(connection, i))
|
||||
if (!SendConstraints(connection, *i))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@@ -254,9 +254,9 @@ UpnpDatabase::SearchSongs(const ContentDirectoryService &server,
|
||||
|
||||
std::string cond;
|
||||
for (const auto &item : filter->GetItems()) {
|
||||
switch (auto tag = item.GetTag()) {
|
||||
case LOCATE_TAG_ANY_TYPE:
|
||||
{
|
||||
if (auto t = dynamic_cast<const TagSongFilter *>(item.get())) {
|
||||
auto tag = t->GetTagType();
|
||||
if (tag == TAG_NUM_OF_ITEM_TYPES) {
|
||||
if (!cond.empty()) {
|
||||
cond += " and ";
|
||||
}
|
||||
@@ -268,29 +268,21 @@ UpnpDatabase::SearchSongs(const ContentDirectoryService &server,
|
||||
else
|
||||
cond += " or ";
|
||||
cond += cap;
|
||||
if (item.GetFoldCase()) {
|
||||
if (t->GetFoldCase()) {
|
||||
cond += " contains ";
|
||||
} else {
|
||||
cond += " = ";
|
||||
}
|
||||
dquote(cond, item.GetValue());
|
||||
dquote(cond, t->GetValue().c_str());
|
||||
}
|
||||
cond += ')';
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Unhandled conditions like
|
||||
LOCATE_TAG_BASE_TYPE or
|
||||
LOCATE_TAG_FILE_TYPE won't have a
|
||||
corresponding upnp prop, so they will be
|
||||
skipped */
|
||||
if (tag == TAG_ALBUM_ARTIST)
|
||||
tag = TAG_ARTIST;
|
||||
|
||||
// TODO: support LOCATE_TAG_ANY_TYPE etc.
|
||||
const char *name = tag_table_lookup(upnp_tags,
|
||||
TagType(tag));
|
||||
const char *name = tag_table_lookup(upnp_tags, tag);
|
||||
if (name == nullptr)
|
||||
continue;
|
||||
|
||||
@@ -304,13 +296,15 @@ UpnpDatabase::SearchSongs(const ContentDirectoryService &server,
|
||||
case-insensitive, but at least some servers
|
||||
have the same convention as mpd (e.g.:
|
||||
minidlna) */
|
||||
if (item.GetFoldCase()) {
|
||||
if (t->GetFoldCase()) {
|
||||
cond += " contains ";
|
||||
} else {
|
||||
cond += " = ";
|
||||
}
|
||||
dquote(cond, item.GetValue());
|
||||
dquote(cond, t->GetValue().c_str());
|
||||
}
|
||||
|
||||
// TODO: support other ISongFilter implementations
|
||||
}
|
||||
|
||||
return server.search(handle, objid, cond.c_str());
|
||||
|
Reference in New Issue
Block a user