aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DatabaseSelection.cxx12
-rw-r--r--src/DatabaseSelection.hxx9
-rw-r--r--src/SongFilter.cxx10
-rw-r--r--src/SongFilter.hxx11
-rw-r--r--src/db/ProxyDatabasePlugin.cxx22
5 files changed, 63 insertions, 1 deletions
diff --git a/src/DatabaseSelection.cxx b/src/DatabaseSelection.cxx
index 96018cbae..ffe5f7d39 100644
--- a/src/DatabaseSelection.cxx
+++ b/src/DatabaseSelection.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 Song &song) const
{
return filter == nullptr || filter->Match(song);
diff --git a/src/DatabaseSelection.hxx b/src/DatabaseSelection.hxx
index 6c1a1dc8d..4825c738c 100644
--- a/src/DatabaseSelection.hxx
+++ b/src/DatabaseSelection.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 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?
*/
@@ -122,6 +127,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/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<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);