diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/SongFilter.cxx | 10 | ||||
-rw-r--r-- | src/SongFilter.hxx | 11 | ||||
-rw-r--r-- | src/db/Selection.cxx | 12 | ||||
-rw-r--r-- | src/db/Selection.hxx | 9 | ||||
-rw-r--r-- | src/db/plugins/ProxyDatabasePlugin.cxx | 22 |
5 files changed, 63 insertions, 1 deletions
diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx index 432280e4e..0640ae19e 100644 --- a/src/SongFilter.cxx +++ b/src/SongFilter.cxx @@ -214,6 +214,16 @@ SongFilter::Match(const LightSong &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 852220f29..ca7d7bd90 100644 --- a/src/SongFilter.hxx +++ b/src/SongFilter.hxx @@ -117,6 +117,11 @@ public: return items; } + gcc_pure + bool IsEmpty() const { + return items.empty(); + } + /** * Is there at least one item with "fold case" enabled? */ @@ -130,6 +135,12 @@ public: } /** + * 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/Selection.cxx b/src/db/Selection.cxx index 96382eed7..a886916cb 100644 --- a/src/db/Selection.cxx +++ b/src/db/Selection.cxx @@ -31,6 +31,18 @@ DatabaseSelection::DatabaseSelection(const char *_uri, bool _recursive, } bool +DatabaseSelection::IsEmpty() const +{ + return uri.empty() && (filter == nullptr || filter->IsEmpty()); +} + +bool +DatabaseSelection::HasOtherThanBase() const +{ + return filter != nullptr && filter->HasOtherThanBase(); +} + +bool DatabaseSelection::Match(const LightSong &song) const { return filter == nullptr || filter->Match(song); diff --git a/src/db/Selection.hxx b/src/db/Selection.hxx index a39ce7afe..9802603fc 100644 --- a/src/db/Selection.hxx +++ b/src/db/Selection.hxx @@ -45,6 +45,15 @@ struct DatabaseSelection { 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 LightSong &song) const; }; diff --git a/src/db/plugins/ProxyDatabasePlugin.cxx b/src/db/plugins/ProxyDatabasePlugin.cxx index 1ef281e23..918e6be49 100644 --- a/src/db/plugins/ProxyDatabasePlugin.cxx +++ b/src/db/plugins/ProxyDatabasePlugin.cxx @@ -695,6 +695,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, @@ -706,7 +723,10 @@ ProxyDatabase::Visit(const DatabaseSelection &selection, if (!const_cast<ProxyDatabase *>(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); |