sticker/Match: add operator "EQUALS"

Mapped to "=" in the MPD protocol.  This is the first operator,
initially supporting value matches in the MPD protocol.
This commit is contained in:
Max Kellermann 2014-12-12 22:12:19 +01:00
parent fed44e95b3
commit cc143105b8
5 changed files with 52 additions and 3 deletions

1
NEWS
View File

@ -3,6 +3,7 @@ ver 0.20 (not yet released)
- "commands" returns playlist commands only if playlist_directory configured
- "search"/"find" have a "window" parameter
- report song duration with milliseconds precision
- "sticker find" can match sticker values
* tags
- ape, ogg: drop support for non-standard tag "album artist"
affected filetypes: vorbis, flac, opus & all files with ape2 tags

View File

@ -2138,6 +2138,25 @@ OK
</para>
</listitem>
</varlistentry>
<varlistentry id="command_sticker_find_equals">
<term>
<cmdsynopsis>
<command>sticker</command>
<arg choice="plain">find</arg>
<arg choice="req"><replaceable>TYPE</replaceable></arg>
<arg choice="req"><replaceable>URI</replaceable></arg>
<arg choice="req"><replaceable>NAME</replaceable></arg>
<arg choice="plain">=</arg>
<arg choice="req"><replaceable>VALUE</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Searches for stickers with the given value.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>

View File

@ -138,7 +138,8 @@ handle_sticker_song(Client &client, ConstBuffer<const char *> args)
return CommandResult::OK;
/* find song dir key */
} else if (args.size == 4 && strcmp(cmd, "find") == 0) {
} else if ((args.size == 4 || args.size == 6) &&
strcmp(cmd, "find") == 0) {
/* "sticker find song a/directory name" */
const char *const base_uri = args[2];
@ -146,6 +147,21 @@ handle_sticker_song(Client &client, ConstBuffer<const char *> args)
StickerOperator op = StickerOperator::EXISTS;
const char *value = nullptr;
if (args.size == 6) {
/* match the value */
const char *op_s = args[4];
value = args[5];
if (strcmp(op_s, "=") == 0)
op = StickerOperator::EQUALS;
else {
command_error(client, ACK_ERROR_ARG,
"bad operator");
return CommandResult::ERROR;
}
}
bool success;
struct sticker_song_find_data data = {
client,

View File

@ -26,6 +26,12 @@ enum class StickerOperator {
* "value" parameter is ignored (must be nullptr).
*/
EXISTS,
/**
* Matches if a sticker with the specified name and value
* exists.
*/
EQUALS,
};
#endif

View File

@ -43,6 +43,7 @@ enum sticker_sql {
STICKER_SQL_DELETE,
STICKER_SQL_DELETE_VALUE,
STICKER_SQL_FIND,
STICKER_SQL_FIND_VALUE,
};
static const char *const sticker_sql[] = {
@ -60,6 +61,9 @@ static const char *const sticker_sql[] = {
"DELETE FROM sticker WHERE type=? AND uri=? AND name=?",
//[STICKER_SQL_FIND] =
"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=?",
//[STICKER_SQL_FIND_VALUE] =
"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=? AND value=?",
};
static const char sticker_sql_create[] =
@ -383,9 +387,12 @@ BindFind(const char *type, const char *base_uri, const char *name,
case StickerOperator::EXISTS:
return BindAllOrNull(error, sticker_stmt[STICKER_SQL_FIND],
type, base_uri, name);
}
(void)value;
case StickerOperator::EQUALS:
return BindAllOrNull(error,
sticker_stmt[STICKER_SQL_FIND_VALUE],
type, base_uri, name, value);
}
assert(false);
gcc_unreachable();