From b1b630a4cc435e35029b7895b2ff6d6b1ad07552 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Mon, 25 Mar 2019 18:30:56 +0100
Subject: [PATCH] command/database: support "sort" and "window" in more
 commands

Closes https://github.com/MusicPlayerDaemon/MPD/issues/516
---
 NEWS                             |  3 +++
 doc/protocol.rst                 |  6 +++---
 src/command/DatabaseCommands.cxx | 34 ++++++++------------------------
 3 files changed, 14 insertions(+), 29 deletions(-)

diff --git a/NEWS b/NEWS
index 224a5521a..f67b3da47 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,7 @@
 ver 0.22 (not yet released)
+* protocol
+  - "findadd"/"searchadd"/"searchaddpl" support the "sort" and
+    "window" parameters
 * input
   - ffmpeg: allow partial reads
 * filter
diff --git a/doc/protocol.rst b/doc/protocol.rst
index c103efe64..02a7ecfc4 100644
--- a/doc/protocol.rst
+++ b/doc/protocol.rst
@@ -849,7 +849,7 @@ The music database
 
 .. _command_findadd:
 
-:command:`findadd {FILTER}`
+:command:`findadd {FILTER} [sort {TYPE}] [window {START:END}]`
     Search the database for songs matching
     ``FILTER`` (see :ref:`Filters <filter_syntax>`) and add them to
     the queue.  Parameters have the same meaning as for
@@ -961,14 +961,14 @@ The music database
 
 .. _command_searchadd:
 
-:command:`searchadd {FILTER}`
+:command:`searchadd {FILTER} [sort {TYPE}] [window {START:END}]`
     Search the database for songs matching
     ``FILTER`` (see :ref:`Filters <filter_syntax>`) and add them to
     the queue.
 
     Parameters have the same meaning as for :ref:`search <command_search>`.
 
-:command:`searchaddpl {NAME} {FILTER}`
+:command:`searchaddpl {NAME} {FILTER} [sort {TYPE}] [window {START:END}]`
     Search the database for songs matching
     ``FILTER`` (see :ref:`Filters <filter_syntax>`) and add them to
     the playlist named ``NAME``.
diff --git a/src/command/DatabaseCommands.cxx b/src/command/DatabaseCommands.cxx
index 262254b55..e3f14d408 100644
--- a/src/command/DatabaseCommands.cxx
+++ b/src/command/DatabaseCommands.cxx
@@ -140,55 +140,37 @@ handle_search(Client &client, Request args, Response &r)
 }
 
 static CommandResult
-handle_match_add(Client &client, Request args, Response &r, bool fold_case)
+handle_match_add(Client &client, Request args, bool fold_case)
 {
 	SongFilter filter;
-	try {
-		filter.Parse(args, fold_case);
-	} catch (...) {
-		r.Error(ACK_ERROR_ARG,
-			GetFullMessage(std::current_exception()).c_str());
-		return CommandResult::ERROR;
-	}
-	filter.Optimize();
+	const auto selection = ParseDatabaseSelection(args, fold_case, filter);
 
 	auto &partition = client.GetPartition();
-	const ScopeBulkEdit bulk_edit(partition);
-
-	const DatabaseSelection selection("", true, &filter);
 	AddFromDatabase(partition, selection);
 	return CommandResult::OK;
 }
 
 CommandResult
-handle_findadd(Client &client, Request args, Response &r)
+handle_findadd(Client &client, Request args, Response &)
 {
-	return handle_match_add(client, args, r, false);
+	return handle_match_add(client, args, false);
 }
 
 CommandResult
-handle_searchadd(Client &client, Request args, Response &r)
+handle_searchadd(Client &client, Request args, Response &)
 {
-	return handle_match_add(client, args, r, true);
+	return handle_match_add(client, args, true);
 }
 
 CommandResult
-handle_searchaddpl(Client &client, Request args, Response &r)
+handle_searchaddpl(Client &client, Request args, Response &)
 {
 	const char *playlist = args.shift();
 
 	SongFilter filter;
-	try {
-		filter.Parse(args, true);
-	} catch (...) {
-		r.Error(ACK_ERROR_ARG,
-			GetFullMessage(std::current_exception()).c_str());
-		return CommandResult::ERROR;
-	}
-	filter.Optimize();
+	const auto selection = ParseDatabaseSelection(args, true, filter);
 
 	const Database &db = client.GetDatabaseOrThrow();
-	const DatabaseSelection selection("", true, &filter);
 
 	search_add_to_playlist(db, client.GetStorage(),
 			       playlist, selection);