[mpd] add support for count command

This commit is contained in:
chme 2015-04-06 09:19:48 +02:00
parent e101812478
commit b7d5b1650e
3 changed files with 129 additions and 2 deletions

View File

@ -1493,6 +1493,29 @@ db_build_query_browse(struct query_params *qp, char *field, char *sort_field, ch
return 0;
}
static int
db_build_query_count_items(struct query_params *qp, char **q)
{
char *query;
qp->results = 1;
if (qp->filter)
query = sqlite3_mprintf("SELECT COUNT(*), SUM(song_length) FROM files f WHERE f.disabled = 0 AND %s;", qp->filter);
else
return -1;
if (!query)
{
DPRINTF(E_LOG, L_DB, "Out of memory for query string\n");
return -1;
}
*q = query;
return 0;
}
int
db_query_start(struct query_params *qp)
{
@ -1551,6 +1574,10 @@ db_query_start(struct query_params *qp)
ret = db_build_query_browse(qp, "year", "year", &query);
break;
case Q_COUNT_ITEMS:
ret = db_build_query_count_items(qp, &query);
break;
default:
DPRINTF(E_LOG, L_DB, "Unknown query type\n");
return -1;
@ -1805,6 +1832,43 @@ db_query_fetch_group(struct query_params *qp, struct db_group_info *dbgri)
return 0;
}
int
db_query_fetch_count(struct query_params *qp, struct count_info *ci)
{
int ret;
memset(ci, 0, sizeof(struct count_info));
if (!qp->stmt)
{
DPRINTF(E_LOG, L_DB, "Query not started!\n");
return -1;
}
if (qp->type != Q_COUNT_ITEMS)
{
DPRINTF(E_LOG, L_DB, "Not a count query!\n");
return -1;
}
ret = db_blocking_step(qp->stmt);
if (ret == SQLITE_DONE)
{
DPRINTF(E_DBG, L_DB, "End of query results for count query\n");
return 0;
}
else if (ret != SQLITE_ROW)
{
DPRINTF(E_LOG, L_DB, "Could not step: %s\n", sqlite3_errmsg(hdl));
return -1;
}
ci->count = sqlite3_column_int(qp->stmt, 0);
ci->length = sqlite3_column_int(qp->stmt, 1);
return 0;
}
int
db_query_fetch_string(struct query_params *qp, char **string)
{

View File

@ -40,6 +40,7 @@ enum query_type {
Q_GROUP_ITEMS = (1 << 9),
Q_GROUP_DIRS = Q_F_BROWSE | (1 << 10),
Q_BROWSE_YEARS = Q_F_BROWSE | (1 << 11),
Q_COUNT_ITEMS = (1 << 12),
};
#define ARTWORK_UNKNOWN 0
@ -312,6 +313,10 @@ struct watch_enum {
sqlite3_stmt *stmt;
};
struct count_info {
uint32_t count;
uint32_t length;
};
char *
db_escape_string(const char *str);
@ -364,6 +369,9 @@ db_query_fetch_pl(struct query_params *qp, struct db_playlist_info *dbpli);
int
db_query_fetch_group(struct query_params *qp, struct db_group_info *dbgri);
int
db_query_fetch_count(struct query_params *qp, struct count_info *ci);
int
db_query_fetch_string(struct query_params *qp, char **string);

View File

@ -2065,6 +2065,63 @@ mpd_get_query_params_find(int argc, char **argv, struct query_params *qp)
return 0;
}
static int
mpd_command_count(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
{
struct query_params qp;
struct count_info ci;
int ret;
if (argc < 3 || ((argc - 1) % 2) != 0)
{
DPRINTF(E_LOG, L_MPD, "Missing argument(s) for command 'find'\n");
ret = asprintf(errmsg, "Missing argument(s) for command 'find'");
if (ret < 0)
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
return ACK_ERROR_ARG;
}
memset(&qp, 0, sizeof(struct query_params));
qp.type = Q_COUNT_ITEMS;
mpd_get_query_params_find(argc - 1, argv + 1, &qp);
ret = db_query_start(&qp);
if (ret < 0)
{
db_query_end(&qp);
DPRINTF(E_LOG, L_MPD, "Could not start query\n");
ret = asprintf(errmsg, "Could not start query");
if (ret < 0)
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
return ACK_ERROR_UNKNOWN;
}
ret = db_query_fetch_count(&qp, &ci);
if (ret < 0)
{
db_query_end(&qp);
DPRINTF(E_LOG, L_MPD, "Could not fetch query count\n");
ret = asprintf(errmsg, "Could not fetch query count");
if (ret < 0)
DPRINTF(E_LOG, L_MPD, "Out of memory\n");
return ACK_ERROR_UNKNOWN;
}
evbuffer_add_printf(evbuf,
"songs: %d\n"
"playtime: %d\n",
ci.count,
(ci.length / 1000));
db_query_end(&qp);
return 0;
}
static int
mpd_command_find(struct evbuffer *evbuf, int argc, char **argv, char **errmsg)
{
@ -3175,12 +3232,10 @@ static struct command mpd_handlers[] =
/*
* The music database
*/
/*
{
.mpdcommand = "count",
.handler = mpd_command_count
},
*/
{
.mpdcommand = "find",
.handler = mpd_command_find