db/proxy: require MPD 0.21 or later
This commit is contained in:
parent
3be8375e4f
commit
e927655774
2
NEWS
2
NEWS
|
@ -9,6 +9,8 @@ ver 0.24 (not yet released)
|
||||||
- operator "starts_with"
|
- operator "starts_with"
|
||||||
- show PCRE support in "config" response
|
- show PCRE support in "config" response
|
||||||
- apply Unicode normalization to case-insensitive filter expressions
|
- apply Unicode normalization to case-insensitive filter expressions
|
||||||
|
* database
|
||||||
|
- proxy: require MPD 0.21 or later
|
||||||
* archive
|
* archive
|
||||||
- add option to disable archive plugins in mpd.conf
|
- add option to disable archive plugins in mpd.conf
|
||||||
* input
|
* input
|
||||||
|
|
|
@ -306,6 +306,8 @@ CheckError(struct mpd_connection *connection)
|
||||||
ThrowError(connection);
|
ThrowError(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !LIBMPDCLIENT_CHECK_VERSION(2, 15, 0)
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
SendConstraints(mpd_connection *connection, const ISongFilter &f)
|
SendConstraints(mpd_connection *connection, const ISongFilter &f)
|
||||||
{
|
{
|
||||||
|
@ -343,20 +345,19 @@ SendConstraints(mpd_connection *connection, const ISongFilter &f)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
SendConstraints(mpd_connection *connection, const SongFilter &filter)
|
SendConstraints(mpd_connection *connection, const SongFilter &filter)
|
||||||
{
|
{
|
||||||
#if LIBMPDCLIENT_CHECK_VERSION(2, 15, 0)
|
#if LIBMPDCLIENT_CHECK_VERSION(2, 15, 0)
|
||||||
if (mpd_connection_cmp_server_version(connection, 0, 21, 0) >= 0)
|
return mpd_search_add_expression(connection,
|
||||||
/* with MPD 0.21 (and libmpdclient 2.15), we can pass
|
filter.ToExpression().c_str());
|
||||||
arbitrary filters as expression */
|
#else
|
||||||
return mpd_search_add_expression(connection,
|
|
||||||
filter.ToExpression().c_str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return std::all_of(
|
return std::all_of(
|
||||||
filter.GetItems().begin(), filter.GetItems().end(),
|
filter.GetItems().begin(), filter.GetItems().end(),
|
||||||
[=](const auto &item) { return SendConstraints(connection, *item); });
|
[=](const auto &item) { return SendConstraints(connection, *item); });
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -373,8 +374,7 @@ SendConstraints(mpd_connection *connection, const DatabaseSelection &selection,
|
||||||
!SendConstraints(connection, *selection.filter))
|
!SendConstraints(connection, *selection.filter))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (selection.sort != TAG_NUM_OF_ITEM_TYPES &&
|
if (selection.sort != TAG_NUM_OF_ITEM_TYPES) {
|
||||||
mpd_connection_cmp_server_version(connection, 0, 21, 0) >= 0) {
|
|
||||||
#if LIBMPDCLIENT_CHECK_VERSION(2, 15, 0)
|
#if LIBMPDCLIENT_CHECK_VERSION(2, 15, 0)
|
||||||
if (selection.sort == SORT_TAG_LAST_MODIFIED) {
|
if (selection.sort == SORT_TAG_LAST_MODIFIED) {
|
||||||
if (!mpd_search_add_sort_name(connection, "Last-Modified",
|
if (!mpd_search_add_sort_name(connection, "Last-Modified",
|
||||||
|
@ -487,11 +487,11 @@ ProxyDatabase::Connect()
|
||||||
try {
|
try {
|
||||||
CheckError(connection);
|
CheckError(connection);
|
||||||
|
|
||||||
if (mpd_connection_cmp_server_version(connection, 0, 20, 0) < 0) {
|
if (mpd_connection_cmp_server_version(connection, 0, 21, 0) < 0) {
|
||||||
const unsigned *version =
|
const unsigned *version =
|
||||||
mpd_connection_get_server_version(connection);
|
mpd_connection_get_server_version(connection);
|
||||||
throw FmtRuntimeError("Connect to MPD {}.{}.{}, but this "
|
throw FmtRuntimeError("Connect to MPD {}.{}.{}, but this "
|
||||||
"plugin requires at least version 0.20",
|
"plugin requires at least version 0.21",
|
||||||
version[0], version[1], version[2]);
|
version[0], version[1], version[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -863,6 +863,8 @@ try {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !LIBMPDCLIENT_CHECK_VERSION(2, 15, 0)
|
||||||
|
|
||||||
[[gnu::pure]]
|
[[gnu::pure]]
|
||||||
static bool
|
static bool
|
||||||
IsFilterSupported(const ISongFilter &f) noexcept
|
IsFilterSupported(const ISongFilter &f) noexcept
|
||||||
|
@ -889,42 +891,33 @@ IsFilterSupported(const ISongFilter &f) noexcept
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::pure]]
|
|
||||||
static bool
|
|
||||||
IsFilterFullySupported(const SongFilter &filter,
|
|
||||||
const struct mpd_connection *connection) noexcept
|
|
||||||
{
|
|
||||||
#if LIBMPDCLIENT_CHECK_VERSION(2, 15, 0)
|
|
||||||
if (mpd_connection_cmp_server_version(connection, 0, 21, 0) >= 0)
|
|
||||||
/* with MPD 0.21 (and libmpdclient 2.15), we can pass
|
|
||||||
arbitrary filters as expression */
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
(void)connection;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
[[gnu::pure]]
|
||||||
|
static bool
|
||||||
|
IsFilterFullySupported(const SongFilter &filter) noexcept
|
||||||
|
{
|
||||||
|
#if LIBMPDCLIENT_CHECK_VERSION(2, 15, 0)
|
||||||
|
(void)filter;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
return std::all_of(filter.GetItems().begin(), filter.GetItems().end(),
|
return std::all_of(filter.GetItems().begin(), filter.GetItems().end(),
|
||||||
[](const auto &item) { return IsFilterSupported(*item); });
|
[](const auto &item) { return IsFilterSupported(*item); });
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::pure]]
|
[[gnu::pure]]
|
||||||
static bool
|
static bool
|
||||||
IsFilterFullySupported(const SongFilter *filter,
|
IsFilterFullySupported(const SongFilter *filter) noexcept
|
||||||
const struct mpd_connection *connection) noexcept
|
|
||||||
{
|
{
|
||||||
return filter == nullptr ||
|
return filter == nullptr ||
|
||||||
IsFilterFullySupported(*filter, connection);
|
IsFilterFullySupported(*filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[gnu::pure]]
|
[[gnu::pure]]
|
||||||
static bool
|
static bool
|
||||||
IsSortSupported(TagType tag_type,
|
IsSortSupported(TagType tag_type) noexcept
|
||||||
const struct mpd_connection *connection) noexcept
|
|
||||||
{
|
{
|
||||||
if (mpd_connection_cmp_server_version(connection, 0, 21, 0) < 0)
|
|
||||||
/* sorting requires MPD 0.21 */
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (tag_type == TagType(SORT_TAG_LAST_MODIFIED)) {
|
if (tag_type == TagType(SORT_TAG_LAST_MODIFIED)) {
|
||||||
/* sort "Last-Modified" requires libmpdclient 2.15 for
|
/* sort "Last-Modified" requires libmpdclient 2.15 for
|
||||||
mpd_search_add_sort_name() */
|
mpd_search_add_sort_name() */
|
||||||
|
@ -940,20 +933,19 @@ IsSortSupported(TagType tag_type,
|
||||||
|
|
||||||
[[gnu::pure]]
|
[[gnu::pure]]
|
||||||
static DatabaseSelection
|
static DatabaseSelection
|
||||||
CheckSelection(DatabaseSelection selection,
|
CheckSelection(DatabaseSelection selection) noexcept
|
||||||
struct mpd_connection *connection) noexcept
|
|
||||||
{
|
{
|
||||||
selection.uri.clear();
|
selection.uri.clear();
|
||||||
selection.filter = nullptr;
|
selection.filter = nullptr;
|
||||||
|
|
||||||
if (selection.sort != TAG_NUM_OF_ITEM_TYPES &&
|
if (selection.sort != TAG_NUM_OF_ITEM_TYPES &&
|
||||||
IsSortSupported(selection.sort, connection))
|
IsSortSupported(selection.sort))
|
||||||
/* we can forward the "sort" parameter to the other
|
/* we can forward the "sort" parameter to the other
|
||||||
MPD */
|
MPD */
|
||||||
selection.sort = TAG_NUM_OF_ITEM_TYPES;
|
selection.sort = TAG_NUM_OF_ITEM_TYPES;
|
||||||
|
|
||||||
if (selection.window != RangeArg::All() &&
|
if (selection.window != RangeArg::All() &&
|
||||||
IsFilterFullySupported(selection.filter, connection))
|
IsFilterFullySupported(selection.filter))
|
||||||
/* we can forward the "window" parameter to the other
|
/* we can forward the "window" parameter to the other
|
||||||
MPD */
|
MPD */
|
||||||
selection.window = RangeArg::All();
|
selection.window = RangeArg::All();
|
||||||
|
@ -970,7 +962,7 @@ ProxyDatabase::Visit(const DatabaseSelection &selection,
|
||||||
// TODO: eliminate the const_cast
|
// TODO: eliminate the const_cast
|
||||||
const_cast<ProxyDatabase *>(this)->EnsureConnected();
|
const_cast<ProxyDatabase *>(this)->EnsureConnected();
|
||||||
|
|
||||||
DatabaseVisitorHelper helper(CheckSelection(selection, connection),
|
DatabaseVisitorHelper helper(CheckSelection(selection),
|
||||||
visit_song);
|
visit_song);
|
||||||
|
|
||||||
if (!visit_directory && !visit_playlist && selection.recursive &&
|
if (!visit_directory && !visit_playlist && selection.recursive &&
|
||||||
|
|
Loading…
Reference in New Issue