From 4f61ba766d5e3e94df3584d7e33e9a9f4452ca67 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 23 Jun 2014 09:14:35 +0200 Subject: [PATCH 1/3] configure.ac: prepare for 0.18.12 --- NEWS | 2 ++ configure.ac | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d8e901654..0bd6899df 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +ver 0.18.12 (not yet released) + ver 0.18.11 (2014/05/12) * decoder - opus: fix missing song length on high-latency files diff --git a/configure.ac b/configure.ac index 48933c4cf..36f785f4d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ(2.60) -AC_INIT(mpd, 0.18.11, mpd-devel@musicpd.org) +AC_INIT(mpd, 0.18.12, mpd-devel@musicpd.org) VERSION_MAJOR=0 VERSION_MINOR=18 From 4c8a5dfb0522b0ff7d6acb96fd2fbc33c22c14e6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 23 Jun 2014 08:57:51 +0200 Subject: [PATCH 2/3] db/proxy: use mpd_song_get_{start,end}() only with libmpdclient >= 2.3 --- NEWS | 2 ++ src/db/ProxyDatabasePlugin.cxx | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 0bd6899df..5375d1395 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.18.12 (not yet released) +* database + - proxy: fix build failure with libmpdclient 2.2 ver 0.18.11 (2014/05/12) * decoder diff --git a/src/db/ProxyDatabasePlugin.cxx b/src/db/ProxyDatabasePlugin.cxx index 00b5d445f..e41ecdec0 100644 --- a/src/db/ProxyDatabasePlugin.cxx +++ b/src/db/ProxyDatabasePlugin.cxx @@ -398,8 +398,13 @@ Convert(const struct mpd_song *song) Song *s = Song::NewDetached(mpd_song_get_uri(song)); s->mtime = mpd_song_get_last_modified(song); + +#if LIBMPDCLIENT_CHECK_VERSION(2,3,0) s->start_ms = mpd_song_get_start(song) * 1000; s->end_ms = mpd_song_get_end(song) * 1000; +#else + s->start_ms = s->end_ms = 0; +#endif TagBuilder tag; tag.SetTime(mpd_song_get_duration(song)); From 848ed1478866e4d99c10aa962a6d976a6b989536 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 23 Jun 2014 09:12:51 +0200 Subject: [PATCH 3/3] db/proxy: fall back to recursive walk on old libmpdclient/MPD Error message was 'too few arguments for "find"' because the "base" constraint was not supported, and no other constraints remained. --- NEWS | 1 + src/DatabaseSelection.cxx | 12 ++++++++++++ src/DatabaseSelection.hxx | 9 +++++++++ src/SongFilter.cxx | 10 ++++++++++ src/SongFilter.hxx | 11 +++++++++++ src/db/ProxyDatabasePlugin.cxx | 22 +++++++++++++++++++++- 6 files changed, 64 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 5375d1395..add093393 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.18.12 (not yet released) * database - proxy: fix build failure with libmpdclient 2.2 + - proxy: fix add/search and other commands with libmpdclient < 2.9 ver 0.18.11 (2014/05/12) * decoder diff --git a/src/DatabaseSelection.cxx b/src/DatabaseSelection.cxx index 96018cbae..ffe5f7d39 100644 --- a/src/DatabaseSelection.cxx +++ b/src/DatabaseSelection.cxx @@ -30,6 +30,18 @@ DatabaseSelection::DatabaseSelection(const char *_uri, bool _recursive, uri = filter->GetBase(); } +bool +DatabaseSelection::IsEmpty() const +{ + return uri.empty() && (filter == nullptr || filter->IsEmpty()); +} + +bool +DatabaseSelection::HasOtherThanBase() const +{ + return filter != nullptr && filter->HasOtherThanBase(); +} + bool DatabaseSelection::Match(const Song &song) const { diff --git a/src/DatabaseSelection.hxx b/src/DatabaseSelection.hxx index 6c1a1dc8d..4825c738c 100644 --- a/src/DatabaseSelection.hxx +++ b/src/DatabaseSelection.hxx @@ -44,6 +44,15 @@ struct DatabaseSelection { DatabaseSelection(const char *_uri, bool _recursive, const SongFilter *_filter=nullptr); + gcc_pure + bool IsEmpty() const; + + /** + * Does this selection contain constraints other than "base"? + */ + gcc_pure + bool HasOtherThanBase() const; + gcc_pure bool Match(const Song &song) const; }; diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx index 49c966b6f..235dfe7a0 100644 --- a/src/SongFilter.cxx +++ b/src/SongFilter.cxx @@ -203,6 +203,16 @@ SongFilter::Match(const Song &song) const return true; } +bool +SongFilter::HasOtherThanBase() const +{ + for (const auto &i : items) + if (i.GetTag() != LOCATE_TAG_BASE_TYPE) + return true; + + return false; +} + std::string SongFilter::GetBase() const { diff --git a/src/SongFilter.hxx b/src/SongFilter.hxx index b15127c07..8c46ed5f3 100644 --- a/src/SongFilter.hxx +++ b/src/SongFilter.hxx @@ -109,6 +109,11 @@ public: return items; } + gcc_pure + bool IsEmpty() const { + return items.empty(); + } + /** * Is there at least one item with "fold case" enabled? */ @@ -121,6 +126,12 @@ public: return false; } + /** + * Does this filter contain constraints other than "base"? + */ + gcc_pure + bool HasOtherThanBase() const; + /** * Returns the "base" specification (if there is one) or an * empty string. diff --git a/src/db/ProxyDatabasePlugin.cxx b/src/db/ProxyDatabasePlugin.cxx index e41ecdec0..cb1bcdc6b 100644 --- a/src/db/ProxyDatabasePlugin.cxx +++ b/src/db/ProxyDatabasePlugin.cxx @@ -566,6 +566,23 @@ SearchSongs(struct mpd_connection *connection, return result && CheckError(connection, error); } +/** + * Check whether we can use the "base" constraint. Requires + * libmpdclient 2.9 and MPD 0.18. + */ +gcc_pure +static bool +ServerSupportsSearchBase(const struct mpd_connection *connection) +{ +#if LIBMPDCLIENT_CHECK_VERSION(2,9,0) + return mpd_connection_cmp_server_version(connection, 0, 18, 0) >= 0; +#else + (void)connection; + + return false; +#endif +} + bool ProxyDatabase::Visit(const DatabaseSelection &selection, VisitDirectory visit_directory, @@ -577,7 +594,10 @@ ProxyDatabase::Visit(const DatabaseSelection &selection, if (!const_cast(this)->EnsureConnected(error)) return nullptr; - if (!visit_directory && !visit_playlist && selection.recursive) + if (!visit_directory && !visit_playlist && selection.recursive && + (ServerSupportsSearchBase(connection) + ? !selection.IsEmpty() + : selection.HasOtherThanBase())) /* this optimized code path can only be used under certain conditions */ return ::SearchSongs(connection, selection, visit_song, error);