DatabaseCommands: add "window" parameter to "search"/"find"

This commit is contained in:
Max Kellermann 2014-11-18 14:31:27 +01:00
parent c3f6502be2
commit f37481f843
5 changed files with 54 additions and 4 deletions

1
NEWS
View File

@ -1,6 +1,7 @@
ver 0.20 (not yet released)
* protocol
- "commands" returns playlist commands only if playlist_directory configured
- "search"/"find" have a "window" parameter
* output
- pulse: set channel map to WAVE-EX

View File

@ -1558,6 +1558,7 @@ OK
<arg choice="req"><replaceable>TYPE</replaceable></arg>
<arg choice="req"><replaceable>WHAT</replaceable></arg>
<arg choice="opt"><replaceable>...</replaceable></arg>
<arg choice="opt">window <replaceable>START</replaceable>:<replaceable>END</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
@ -1602,6 +1603,13 @@ OK
<para>
<varname>WHAT</varname> is what to find.
</para>
<para>
<varname>window</varname> can be used to query only a
portion of the real response. The parameter is two
zero-based record numbers; a start number and an end
number.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_findadd">
@ -1794,6 +1802,7 @@ OK
<arg choice="req"><replaceable>TYPE</replaceable></arg>
<arg choice="req"><replaceable>WHAT</replaceable></arg>
<arg choice="opt"><replaceable>...</replaceable></arg>
<arg choice="opt">window <replaceable>START</replaceable>:<replaceable>END</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>

View File

@ -32,6 +32,7 @@
#include "util/Error.hxx"
#include "SongFilter.hxx"
#include "protocol/Result.hxx"
#include "protocol/ArgParser.hxx"
#include "BulkEdit.hxx"
#include <string.h>
@ -70,6 +71,16 @@ handle_match(Client &client, unsigned argc, char *argv[], bool fold_case)
{
ConstBuffer<const char *> args(argv + 1, argc - 1);
unsigned window_start = 0, window_end = std::numeric_limits<int>::max();
if (args.size >= 2 && strcmp(args[args.size - 2], "window") == 0) {
if (!check_range(client, &window_start, &window_end,
args.back()))
return CommandResult::ERROR;
args.pop_back();
args.pop_back();
}
SongFilter filter;
if (!filter.Parse(args, fold_case)) {
command_error(client, ACK_ERROR_ARG, "incorrect arguments");
@ -79,7 +90,8 @@ handle_match(Client &client, unsigned argc, char *argv[], bool fold_case)
const DatabaseSelection selection("", true, &filter);
Error error;
return db_selection_print(client, selection, true, false, error)
return db_selection_print(client, selection, true, false,
window_start, window_end, error)
? CommandResult::OK
: print_error(client, error);
}

View File

@ -147,27 +147,49 @@ PrintPlaylistFull(Client &client, bool base,
bool
db_selection_print(Client &client, const DatabaseSelection &selection,
bool full, bool base, Error &error)
bool full, bool base,
unsigned window_start, unsigned window_end,
Error &error)
{
const Database *db = client.GetDatabase(error);
if (db == nullptr)
return false;
unsigned i = 0;
using namespace std::placeholders;
const auto d = selection.filter == nullptr
? std::bind(full ? PrintDirectoryFull : PrintDirectoryBrief,
std::ref(client), base, _1)
: VisitDirectory();
const auto s = std::bind(full ? PrintSongFull : PrintSongBrief,
std::ref(client), base, _1);
VisitSong s = std::bind(full ? PrintSongFull : PrintSongBrief,
std::ref(client), base, _1);
const auto p = selection.filter == nullptr
? std::bind(full ? PrintPlaylistFull : PrintPlaylistBrief,
std::ref(client), base, _1, _2)
: VisitPlaylist();
if (window_start > 0 || window_end < std::numeric_limits<int>::max())
s = [s, window_start, window_end, &i](const LightSong &song,
Error &error2){
const bool in_window = i >= window_start && i < window_end;
++i;
return !in_window || s(song, error2);
};
return db->Visit(selection, d, s, p, error);
}
bool
db_selection_print(Client &client, const DatabaseSelection &selection,
bool full, bool base,
Error &error)
{
return db_selection_print(client, selection, full, base,
0, std::numeric_limits<int>::max(),
error);
}
static bool
PrintSongURIVisitor(Client &client, const LightSong &song)
{

View File

@ -37,6 +37,12 @@ bool
db_selection_print(Client &client, const DatabaseSelection &selection,
bool full, bool base, Error &error);
bool
db_selection_print(Client &client, const DatabaseSelection &selection,
bool full, bool base,
unsigned window_start, unsigned window_end,
Error &error);
bool
PrintUniqueTags(Client &client, unsigned type, uint32_t group_mask,
const SongFilter *filter,