This commit adds the sort and window parameter to "sticker find"
The three new compare operators "eq", "gt" and "lt" are casting the values to int. Sort supports: - uri: sort by uri - value: sort by value as string - value_int: casts value to int Closes #1894
This commit is contained in:
parent
1efb9d41db
commit
45553c5f61
1
NEWS
1
NEWS
|
@ -13,6 +13,7 @@ ver 0.24 (not yet released)
|
||||||
- new commands "stickernames" and "playlistlength"
|
- new commands "stickernames" and "playlistlength"
|
||||||
- new "search"/"find" filter "added-since"
|
- new "search"/"find" filter "added-since"
|
||||||
- allow range in listplaylist and listplaylistinfo
|
- allow range in listplaylist and listplaylistinfo
|
||||||
|
- "sticker find" supports sort and window parameter and new sticker compare operators "eq", "lt" and "gt"
|
||||||
* database
|
* database
|
||||||
- attribute "added" shows when each song was added to the database
|
- attribute "added" shows when each song was added to the database
|
||||||
- proxy: require MPD 0.21 or later
|
- proxy: require MPD 0.21 or later
|
||||||
|
|
|
@ -1486,19 +1486,21 @@ the database for songs).
|
||||||
|
|
||||||
.. _command_sticker_find:
|
.. _command_sticker_find:
|
||||||
|
|
||||||
:command:`sticker find {TYPE} {URI} {NAME}`
|
:command:`sticker find {TYPE} {URI} {NAME} [sort {SORTTYPE}] [window {START:END}]`
|
||||||
Searches the sticker database for stickers with the
|
Searches the sticker database for stickers with the
|
||||||
specified name, below the specified directory (URI).
|
specified name, below the specified directory (URI).
|
||||||
For each matching song, it prints the URI and that one
|
For each matching song, it prints the URI and that one
|
||||||
sticker's value.
|
sticker's value.
|
||||||
|
|
||||||
|
``sort`` sorts the result by "``uri``","``value`` or "``value_int``" (casts the sticker value to an integer). [#since_0_24]_
|
||||||
|
|
||||||
.. _command_sticker_find_value:
|
.. _command_sticker_find_value:
|
||||||
|
|
||||||
:command:`sticker find {TYPE} {URI} {NAME} = {VALUE}`
|
:command:`sticker find {TYPE} {URI} {NAME} = {VALUE} [sort {SORTTYPE}] [window {START:END}]`
|
||||||
Searches for stickers with the given value.
|
Searches for stickers with the given value.
|
||||||
|
|
||||||
Other supported operators are:
|
Other supported operators are:
|
||||||
"``<``", "``>``"
|
"``<``", "``>``" for strings and "``eq``", "``lt``", "``gt``" to cast the value to an integer.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,8 @@ public:
|
||||||
return CommandResult::OK;
|
return CommandResult::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual CommandResult Find(const char *uri, const char *name, StickerOperator op, const char *value) {
|
virtual CommandResult Find(const char *uri, const char *name, StickerOperator op, const char *value,
|
||||||
|
const char *sort, bool descending, RangeArg window) {
|
||||||
auto data = CallbackContext{
|
auto data = CallbackContext{
|
||||||
.name = name,
|
.name = name,
|
||||||
.sticker_type = sticker_type,
|
.sticker_type = sticker_type,
|
||||||
|
@ -97,6 +98,7 @@ public:
|
||||||
uri,
|
uri,
|
||||||
name,
|
name,
|
||||||
op, value,
|
op, value,
|
||||||
|
sort, descending, window,
|
||||||
callback, &data);
|
callback, &data);
|
||||||
|
|
||||||
return CommandResult::OK;
|
return CommandResult::OK;
|
||||||
|
@ -172,7 +174,8 @@ public:
|
||||||
database.ReturnSong(song);
|
database.ReturnSong(song);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandResult Find(const char *uri, const char *name, StickerOperator op, const char *value) override {
|
CommandResult Find(const char *uri, const char *name, StickerOperator op, const char *value,
|
||||||
|
const char *sort, bool descending, RangeArg window) override {
|
||||||
struct sticker_song_find_data data = {
|
struct sticker_song_find_data data = {
|
||||||
response,
|
response,
|
||||||
name,
|
name,
|
||||||
|
@ -180,6 +183,7 @@ public:
|
||||||
|
|
||||||
sticker_song_find(sticker_database, database, uri, data.name,
|
sticker_song_find(sticker_database, database, uri, data.name,
|
||||||
op, value,
|
op, value,
|
||||||
|
sort, descending, window,
|
||||||
sticker_song_find_print_cb, &data);
|
sticker_song_find_print_cb, &data);
|
||||||
|
|
||||||
return CommandResult::OK;
|
return CommandResult::OK;
|
||||||
|
@ -386,7 +390,37 @@ handle_sticker(Client &client, Request args, Response &r)
|
||||||
return handler->Delete(uri, sticker_name);
|
return handler->Delete(uri, sticker_name);
|
||||||
|
|
||||||
/* find */
|
/* find */
|
||||||
if ((args.size() == 4 || args.size() == 6) && StringIsEqual(cmd, "find")) {
|
if (args.size() >= 4 && StringIsEqual(cmd, "find")) {
|
||||||
|
RangeArg window = RangeArg::All();
|
||||||
|
if (args.size() >= 6 && StringIsEqual(args[args.size() - 2], "window")) {
|
||||||
|
window = args.ParseRange(args.size() - 1);
|
||||||
|
args.pop_back();
|
||||||
|
args.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto sort = "";
|
||||||
|
bool descending = false;
|
||||||
|
if (args.size() >= 6 && StringIsEqual(args[args.size() - 2], "sort")) {
|
||||||
|
const char *s = args.back();
|
||||||
|
if (*s == '-') {
|
||||||
|
descending = true;
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
if (StringIsEqual(s, "uri") ||
|
||||||
|
StringIsEqual(s, "value") ||
|
||||||
|
StringIsEqual(s, "value_int")
|
||||||
|
) {
|
||||||
|
sort = s;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r.FmtError(ACK_ERROR_ARG, "Unknown sort tag \"{}\"", s);
|
||||||
|
return CommandResult::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.pop_back();
|
||||||
|
args.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
bool has_op = args.size() > 4;
|
bool has_op = args.size() > 4;
|
||||||
auto value = has_op ? args[5] : nullptr;
|
auto value = has_op ? args[5] : nullptr;
|
||||||
StickerOperator op = StickerOperator::EXISTS;
|
StickerOperator op = StickerOperator::EXISTS;
|
||||||
|
@ -399,12 +433,18 @@ handle_sticker(Client &client, Request args, Response &r)
|
||||||
op = StickerOperator::LESS_THAN;
|
op = StickerOperator::LESS_THAN;
|
||||||
else if (StringIsEqual(op_s, ">"))
|
else if (StringIsEqual(op_s, ">"))
|
||||||
op = StickerOperator::GREATER_THAN;
|
op = StickerOperator::GREATER_THAN;
|
||||||
|
else if (StringIsEqual(op_s, "eq"))
|
||||||
|
op = StickerOperator::EQUALS_INT;
|
||||||
|
else if (StringIsEqual(op_s, "lt"))
|
||||||
|
op = StickerOperator::LESS_THAN_INT;
|
||||||
|
else if (StringIsEqual(op_s, "gt"))
|
||||||
|
op = StickerOperator::GREATER_THAN_INT;
|
||||||
else {
|
else {
|
||||||
r.FmtError(ACK_ERROR_ARG, "bad operator \"{}\"", op_s);
|
r.FmtError(ACK_ERROR_ARG, "bad operator \"{}\"", op_s);
|
||||||
return CommandResult::ERROR;
|
return CommandResult::ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return handler->Find(uri, sticker_name, op, value);
|
return handler->Find(uri, sticker_name, op, value, sort, descending, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Error(ACK_ERROR_ARG, "bad request");
|
r.Error(ACK_ERROR_ARG, "bad request");
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "util/StringCompare.hxx"
|
#include "util/StringCompare.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
@ -17,6 +18,19 @@
|
||||||
|
|
||||||
using namespace Sqlite;
|
using namespace Sqlite;
|
||||||
|
|
||||||
|
enum sticker_sql_find {
|
||||||
|
STICKER_SQL_FIND,
|
||||||
|
STICKER_SQL_FIND_VALUE,
|
||||||
|
STICKER_SQL_FIND_LT,
|
||||||
|
STICKER_SQL_FIND_GT,
|
||||||
|
|
||||||
|
STICKER_SQL_FIND_EQ_INT,
|
||||||
|
STICKER_SQL_FIND_LT_INT,
|
||||||
|
STICKER_SQL_FIND_GT_INT,
|
||||||
|
|
||||||
|
STICKER_SQL_FIND_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
enum sticker_sql {
|
enum sticker_sql {
|
||||||
STICKER_SQL_GET,
|
STICKER_SQL_GET,
|
||||||
STICKER_SQL_LIST,
|
STICKER_SQL_LIST,
|
||||||
|
@ -24,10 +38,6 @@ enum sticker_sql {
|
||||||
STICKER_SQL_INSERT,
|
STICKER_SQL_INSERT,
|
||||||
STICKER_SQL_DELETE,
|
STICKER_SQL_DELETE,
|
||||||
STICKER_SQL_DELETE_VALUE,
|
STICKER_SQL_DELETE_VALUE,
|
||||||
STICKER_SQL_FIND,
|
|
||||||
STICKER_SQL_FIND_VALUE,
|
|
||||||
STICKER_SQL_FIND_LT,
|
|
||||||
STICKER_SQL_FIND_GT,
|
|
||||||
STICKER_SQL_DISTINCT_TYPE_URI,
|
STICKER_SQL_DISTINCT_TYPE_URI,
|
||||||
STICKER_SQL_TRANSACTION_BEGIN,
|
STICKER_SQL_TRANSACTION_BEGIN,
|
||||||
STICKER_SQL_TRANSACTION_COMMIT,
|
STICKER_SQL_TRANSACTION_COMMIT,
|
||||||
|
@ -37,6 +47,29 @@ enum sticker_sql {
|
||||||
STICKER_SQL_COUNT
|
STICKER_SQL_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr auto sticker_sql_find = std::array {
|
||||||
|
//[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=?",
|
||||||
|
|
||||||
|
//[STICKER_SQL_FIND_LT] =
|
||||||
|
"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=? AND value<?",
|
||||||
|
|
||||||
|
//[STICKER_SQL_FIND_GT] =
|
||||||
|
"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=? AND value>?",
|
||||||
|
|
||||||
|
//[STICKER_SQL_FIND_EQ_INT] =
|
||||||
|
"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=? AND CAST(value AS INT)=?",
|
||||||
|
|
||||||
|
//[STICKER_SQL_FIND_LT_INT] =
|
||||||
|
"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=? AND CAST(value AS INT)<?",
|
||||||
|
|
||||||
|
//[STICKER_SQL_FIND_GT_INT] =
|
||||||
|
"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=? AND CAST(value AS INT)>?",
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr auto sticker_sql = std::array {
|
static constexpr auto sticker_sql = std::array {
|
||||||
//[STICKER_SQL_GET] =
|
//[STICKER_SQL_GET] =
|
||||||
"SELECT value FROM sticker WHERE type=? AND uri=? AND name=?",
|
"SELECT value FROM sticker WHERE type=? AND uri=? AND name=?",
|
||||||
|
@ -50,17 +83,6 @@ static constexpr auto sticker_sql = std::array {
|
||||||
"DELETE FROM sticker WHERE type=? AND uri=?",
|
"DELETE FROM sticker WHERE type=? AND uri=?",
|
||||||
//[STICKER_SQL_DELETE_VALUE] =
|
//[STICKER_SQL_DELETE_VALUE] =
|
||||||
"DELETE FROM sticker WHERE type=? AND uri=? AND name=?",
|
"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=?",
|
|
||||||
|
|
||||||
//[STICKER_SQL_FIND_LT] =
|
|
||||||
"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=? AND value<?",
|
|
||||||
|
|
||||||
//[STICKER_SQL_FIND_GT] =
|
|
||||||
"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=? AND value>?",
|
|
||||||
|
|
||||||
//[STICKER_SQL_DISTINCT_TYPE_URI] =
|
//[STICKER_SQL_DISTINCT_TYPE_URI] =
|
||||||
"SELECT DISTINCT type,uri FROM sticker",
|
"SELECT DISTINCT type,uri FROM sticker",
|
||||||
|
@ -297,7 +319,8 @@ StickerDatabase::Load(const char *type, const char *uri)
|
||||||
sqlite3_stmt *
|
sqlite3_stmt *
|
||||||
StickerDatabase::BindFind(const char *type, const char *base_uri,
|
StickerDatabase::BindFind(const char *type, const char *base_uri,
|
||||||
const char *name,
|
const char *name,
|
||||||
StickerOperator op, const char *value)
|
StickerOperator op, const char *value,
|
||||||
|
const char *sort, bool descending, RangeArg window)
|
||||||
{
|
{
|
||||||
assert(type != nullptr);
|
assert(type != nullptr);
|
||||||
assert(name != nullptr);
|
assert(name != nullptr);
|
||||||
|
@ -305,25 +328,70 @@ StickerDatabase::BindFind(const char *type, const char *base_uri,
|
||||||
if (base_uri == nullptr)
|
if (base_uri == nullptr)
|
||||||
base_uri = "";
|
base_uri = "";
|
||||||
|
|
||||||
|
auto order_by = StringIsEmpty(sort)
|
||||||
|
? std::string()
|
||||||
|
: StringIsEqual(sort, "value_int")
|
||||||
|
? fmt::format("ORDER BY CAST(value AS INT) {}", descending ? "desc" : "asc")
|
||||||
|
: fmt::format("ORDER BY {} {}", sort, descending ? "desc" : "asc");
|
||||||
|
|
||||||
|
auto offset = window.IsAll()
|
||||||
|
? std::string()
|
||||||
|
: window.IsOpenEnded()
|
||||||
|
? fmt::format("LIMIT -1 OFFSET {}", window.start)
|
||||||
|
: fmt::format("LIMIT {} OFFSET {}", window.Count(), window.start);
|
||||||
|
|
||||||
|
std::string sql_str;
|
||||||
|
sqlite3_stmt *sql;
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case StickerOperator::EXISTS:
|
case StickerOperator::EXISTS:
|
||||||
BindAll(stmt[STICKER_SQL_FIND], type, base_uri, name);
|
sql_str = fmt::format("{} {} {}",
|
||||||
return stmt[STICKER_SQL_FIND];
|
sticker_sql_find[STICKER_SQL_FIND], order_by, offset);
|
||||||
|
sql = Prepare(db, sql_str.c_str());
|
||||||
|
BindAll(sql, type, base_uri, name);
|
||||||
|
return sql;
|
||||||
|
|
||||||
case StickerOperator::EQUALS:
|
case StickerOperator::EQUALS:
|
||||||
BindAll(stmt[STICKER_SQL_FIND_VALUE],
|
sql_str = fmt::format("{} {} {}",
|
||||||
type, base_uri, name, value);
|
sticker_sql_find[STICKER_SQL_FIND_VALUE], order_by, offset);
|
||||||
return stmt[STICKER_SQL_FIND_VALUE];
|
sql = Prepare(db, sql_str.c_str());
|
||||||
|
BindAll(sql, type, base_uri, name, value);
|
||||||
|
return sql;
|
||||||
|
|
||||||
case StickerOperator::LESS_THAN:
|
case StickerOperator::LESS_THAN:
|
||||||
BindAll(stmt[STICKER_SQL_FIND_LT],
|
sql_str = fmt::format("{} {} {}",
|
||||||
type, base_uri, name, value);
|
sticker_sql_find[STICKER_SQL_FIND_LT], order_by, offset);
|
||||||
return stmt[STICKER_SQL_FIND_LT];
|
sql = Prepare(db, sql_str.c_str());
|
||||||
|
BindAll(sql, type, base_uri, name, value);
|
||||||
|
return sql;
|
||||||
|
|
||||||
case StickerOperator::GREATER_THAN:
|
case StickerOperator::GREATER_THAN:
|
||||||
BindAll(stmt[STICKER_SQL_FIND_GT],
|
sql_str = fmt::format("{} {} {}",
|
||||||
type, base_uri, name, value);
|
sticker_sql_find[STICKER_SQL_FIND_GT], order_by, offset);
|
||||||
return stmt[STICKER_SQL_FIND_GT];
|
sql = Prepare(db, sql_str.c_str());
|
||||||
|
BindAll(sql, type, base_uri, name, value);
|
||||||
|
return sql;
|
||||||
|
|
||||||
|
case StickerOperator::EQUALS_INT:
|
||||||
|
sql_str = fmt::format("{} {} {}",
|
||||||
|
sticker_sql_find[STICKER_SQL_FIND_EQ_INT], order_by, offset);
|
||||||
|
sql = Prepare(db, sql_str.c_str());
|
||||||
|
BindAll(sql, type, base_uri, name, value);
|
||||||
|
return sql;
|
||||||
|
|
||||||
|
case StickerOperator::LESS_THAN_INT:
|
||||||
|
sql_str = fmt::format("{} {} {}",
|
||||||
|
sticker_sql_find[STICKER_SQL_FIND_LT_INT], order_by, offset);
|
||||||
|
sql = Prepare(db, sql_str.c_str());
|
||||||
|
BindAll(sql, type, base_uri, name, value);
|
||||||
|
return sql;
|
||||||
|
|
||||||
|
case StickerOperator::GREATER_THAN_INT:
|
||||||
|
sql_str = fmt::format("{} {} {}",
|
||||||
|
sticker_sql_find[STICKER_SQL_FIND_GT_INT], order_by, offset);
|
||||||
|
sql = Prepare(db, sql_str.c_str());
|
||||||
|
BindAll(sql, type, base_uri, name, value);
|
||||||
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
|
@ -333,18 +401,18 @@ StickerDatabase::BindFind(const char *type, const char *base_uri,
|
||||||
void
|
void
|
||||||
StickerDatabase::Find(const char *type, const char *base_uri, const char *name,
|
StickerDatabase::Find(const char *type, const char *base_uri, const char *name,
|
||||||
StickerOperator op, const char *value,
|
StickerOperator op, const char *value,
|
||||||
|
const char *sort, bool descending, RangeArg window,
|
||||||
void (*func)(const char *uri, const char *value,
|
void (*func)(const char *uri, const char *value,
|
||||||
void *user_data),
|
void *user_data),
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
assert(func != nullptr);
|
assert(func != nullptr);
|
||||||
|
|
||||||
sqlite3_stmt *const s = BindFind(type, base_uri, name, op, value);
|
sqlite3_stmt *const s = BindFind(type, base_uri, name, op, value, sort, descending, window);
|
||||||
assert(s != nullptr);
|
assert(s != nullptr);
|
||||||
|
|
||||||
AtScopeExit(s) {
|
AtScopeExit(s) {
|
||||||
sqlite3_reset(s);
|
sqlite3_finalize(s);
|
||||||
sqlite3_clear_bindings(s);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ExecuteForEach(s, [s, func, user_data](){
|
ExecuteForEach(s, [s, func, user_data](){
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "Match.hxx"
|
#include "Match.hxx"
|
||||||
#include "lib/sqlite/Database.hxx"
|
#include "lib/sqlite/Database.hxx"
|
||||||
|
#include "protocol/RangeArg.hxx"
|
||||||
|
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
@ -46,10 +47,6 @@ class StickerDatabase {
|
||||||
SQL_INSERT,
|
SQL_INSERT,
|
||||||
SQL_DELETE,
|
SQL_DELETE,
|
||||||
SQL_DELETE_VALUE,
|
SQL_DELETE_VALUE,
|
||||||
SQL_FIND,
|
|
||||||
SQL_FIND_VALUE,
|
|
||||||
SQL_FIND_LT,
|
|
||||||
SQL_FIND_GT,
|
|
||||||
SQL_DISTINCT_TYPE_URI,
|
SQL_DISTINCT_TYPE_URI,
|
||||||
SQL_TRANSACTION_BEGIN,
|
SQL_TRANSACTION_BEGIN,
|
||||||
SQL_TRANSACTION_COMMIT,
|
SQL_TRANSACTION_COMMIT,
|
||||||
|
@ -59,6 +56,19 @@ class StickerDatabase {
|
||||||
SQL_COUNT
|
SQL_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SQL_FIND {
|
||||||
|
SQL_FIND,
|
||||||
|
SQL_FIND_VALUE,
|
||||||
|
SQL_FIND_LT,
|
||||||
|
SQL_FIND_GT,
|
||||||
|
|
||||||
|
SQL_FIND_EQ_INT,
|
||||||
|
SQL_FIND_LT_INT,
|
||||||
|
SQL_FIND_GT_INT,
|
||||||
|
|
||||||
|
SQL_FIND_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
std::string path;
|
std::string path;
|
||||||
|
|
||||||
Sqlite::Database db;
|
Sqlite::Database db;
|
||||||
|
@ -143,6 +153,7 @@ public:
|
||||||
*/
|
*/
|
||||||
void Find(const char *type, const char *base_uri, const char *name,
|
void Find(const char *type, const char *base_uri, const char *name,
|
||||||
StickerOperator op, const char *value,
|
StickerOperator op, const char *value,
|
||||||
|
const char *sort, bool descending, RangeArg window,
|
||||||
void (*func)(const char *uri, const char *value,
|
void (*func)(const char *uri, const char *value,
|
||||||
void *user_data),
|
void *user_data),
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
@ -178,7 +189,8 @@ private:
|
||||||
|
|
||||||
sqlite3_stmt *BindFind(const char *type, const char *base_uri,
|
sqlite3_stmt *BindFind(const char *type, const char *base_uri,
|
||||||
const char *name,
|
const char *name,
|
||||||
StickerOperator op, const char *value);
|
StickerOperator op, const char *value,
|
||||||
|
const char *sort, bool descending, RangeArg window);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,24 @@ enum class StickerOperator {
|
||||||
* value bigger than the specified one.
|
* value bigger than the specified one.
|
||||||
*/
|
*/
|
||||||
GREATER_THAN,
|
GREATER_THAN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches if a sticker with the specified name exists with a
|
||||||
|
* integer value equal the specified one.
|
||||||
|
*/
|
||||||
|
EQUALS_INT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches if a sticker with the specified name exists with a
|
||||||
|
* integer value smaller than the specified one.
|
||||||
|
*/
|
||||||
|
LESS_THAN_INT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches if a sticker with the specified name exists with a
|
||||||
|
* integer value bigger than the specified one.
|
||||||
|
*/
|
||||||
|
GREATER_THAN_INT,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -92,6 +92,7 @@ void
|
||||||
sticker_song_find(StickerDatabase &sticker_database, const Database &db,
|
sticker_song_find(StickerDatabase &sticker_database, const Database &db,
|
||||||
const char *base_uri, const char *name,
|
const char *base_uri, const char *name,
|
||||||
StickerOperator op, const char *value,
|
StickerOperator op, const char *value,
|
||||||
|
const char *sort, bool descending, RangeArg window,
|
||||||
void (*func)(const LightSong &song, const char *value,
|
void (*func)(const LightSong &song, const char *value,
|
||||||
void *user_data),
|
void *user_data),
|
||||||
void *user_data)
|
void *user_data)
|
||||||
|
@ -114,5 +115,6 @@ sticker_song_find(StickerDatabase &sticker_database, const Database &db,
|
||||||
data.base_uri_length = strlen(data.base_uri);
|
data.base_uri_length = strlen(data.base_uri);
|
||||||
|
|
||||||
sticker_database.Find("song", data.base_uri, name, op, value,
|
sticker_database.Find("song", data.base_uri, name, op, value,
|
||||||
|
sort, descending, window,
|
||||||
sticker_song_find_cb, &data);
|
sticker_song_find_cb, &data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#define MPD_SONG_STICKER_HXX
|
#define MPD_SONG_STICKER_HXX
|
||||||
|
|
||||||
#include "Match.hxx"
|
#include "Match.hxx"
|
||||||
|
#include "protocol/RangeArg.hxx"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ void
|
||||||
sticker_song_find(StickerDatabase &sticker_database, const Database &db,
|
sticker_song_find(StickerDatabase &sticker_database, const Database &db,
|
||||||
const char *base_uri, const char *name,
|
const char *base_uri, const char *name,
|
||||||
StickerOperator op, const char *value,
|
StickerOperator op, const char *value,
|
||||||
|
const char *sort, bool descending, RangeArg window,
|
||||||
void (*func)(const LightSong &song, const char *value,
|
void (*func)(const LightSong &song, const char *value,
|
||||||
void *user_data),
|
void *user_data),
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
|
Loading…
Reference in New Issue