Add sticker list command.
[mk: merged memory leak patch; fixed indentation (tabs); fixed documentation typo]
This commit is contained in:
parent
95b53281a4
commit
b8ebb748c9
@ -1222,6 +1222,21 @@ OK
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="command_sticker_list">
|
||||
<term>
|
||||
<cmdsynopsis>
|
||||
<command>sticker</command>
|
||||
<arg choice="plain">list</arg>
|
||||
<arg choice="req"><replaceable>TYPE</replaceable></arg>
|
||||
<arg choice="req"><replaceable>URI</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Lists the stickers for the specified object.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</section>
|
||||
|
||||
|
@ -1472,6 +1472,34 @@ handle_sticker_song(struct client *client, int argc, char *argv[])
|
||||
client_printf(client, "sticker: %s=%s\n", argv[4], value);
|
||||
g_free(value);
|
||||
|
||||
return COMMAND_RETURN_OK;
|
||||
} else if (argc == 4 && strcmp(argv[1], "list") == 0) {
|
||||
GList *list;
|
||||
GPtrArray *values;
|
||||
unsigned int x;
|
||||
|
||||
list = sticker_song_list_values(song);
|
||||
if (NULL == list) {
|
||||
command_error(client, ACK_ERROR_NO_EXIST,
|
||||
"no stickers found");
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
||||
for (x = 0; x < g_list_length(list); x++) {
|
||||
values = g_list_nth_data(list, x);
|
||||
if (NULL == values) {
|
||||
g_warning("NULL sticker found");
|
||||
continue;
|
||||
}
|
||||
client_printf(client, "sticker: %s=%s\n",
|
||||
(char *)g_ptr_array_index(values, 0),
|
||||
(char *)g_ptr_array_index(values, 1));
|
||||
g_free(g_ptr_array_index(values, 0));
|
||||
g_free(g_ptr_array_index(values, 1));
|
||||
g_ptr_array_free(values, TRUE);
|
||||
}
|
||||
g_list_free(list);
|
||||
|
||||
return COMMAND_RETURN_OK;
|
||||
} else if (argc == 6 && strcmp(argv[1], "set") == 0) {
|
||||
bool ret;
|
||||
@ -1479,7 +1507,7 @@ handle_sticker_song(struct client *client, int argc, char *argv[])
|
||||
ret = sticker_song_set_value(song, argv[4], argv[5]);
|
||||
if (!ret) {
|
||||
command_error(client, ACK_ERROR_SYSTEM,
|
||||
"failed to set sticker vqalue");
|
||||
"failed to set sticker value");
|
||||
return COMMAND_RETURN_ERROR;
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,22 @@ sticker_song_get_value(const struct song *song, const char *name)
|
||||
return value;
|
||||
}
|
||||
|
||||
GList *
|
||||
sticker_song_list_values(const struct song *song)
|
||||
{
|
||||
char *uri;
|
||||
GList *list;
|
||||
|
||||
assert(song != NULL);
|
||||
assert(song_in_database(song));
|
||||
|
||||
uri = song_get_uri(song);
|
||||
list = sticker_list_values("song", uri);
|
||||
g_free(uri);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
bool
|
||||
sticker_song_set_value(const struct song *song,
|
||||
const char *name, const char *value)
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define SONG_STICKER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <glib.h>
|
||||
|
||||
struct song;
|
||||
|
||||
@ -38,6 +39,15 @@ bool
|
||||
sticker_song_set_value(const struct song *song,
|
||||
const char *name, const char *value);
|
||||
|
||||
/**
|
||||
* Returns a list of key value pairs from a song's sticker record.
|
||||
* The caller must free each GPtrArray element of the returned list
|
||||
* with g_ptr_array_free(), as well as the returned GList with
|
||||
* g_list_free().
|
||||
*/
|
||||
GList *
|
||||
sticker_song_list_values(const struct song *song);
|
||||
|
||||
/**
|
||||
* Deletes a sticker from the database. All values are deleted.
|
||||
*/
|
||||
|
@ -40,6 +40,9 @@ static const char sticker_sql_create[] =
|
||||
static const char sticker_sql_get[] =
|
||||
"SELECT value FROM sticker WHERE type=? AND uri=? AND name=?";
|
||||
|
||||
static const char sticker_sql_list[] =
|
||||
"SELECT name,value FROM sticker WHERE type=? AND uri=?";
|
||||
|
||||
static const char sticker_sql_update[] =
|
||||
"UPDATE sticker SET value=? WHERE type=? AND uri=? AND name=?";
|
||||
|
||||
@ -50,8 +53,9 @@ static const char sticker_sql_delete[] =
|
||||
"DELETE FROM sticker WHERE type=? AND uri=?";
|
||||
|
||||
static sqlite3 *sticker_db;
|
||||
static sqlite3_stmt *sticker_stmt_get, *sticker_stmt_update,
|
||||
*sticker_stmt_insert, *sticker_stmt_delete;
|
||||
static sqlite3_stmt *sticker_stmt_get, *sticker_stmt_list,
|
||||
*sticker_stmt_update, *sticker_stmt_insert,
|
||||
*sticker_stmt_delete;
|
||||
|
||||
static sqlite3_stmt *
|
||||
sticker_prepare(const char *sql)
|
||||
@ -93,12 +97,14 @@ sticker_global_init(const char *path)
|
||||
/* prepare the statements we're going to use */
|
||||
|
||||
sticker_stmt_get = sticker_prepare(sticker_sql_get);
|
||||
sticker_stmt_list = sticker_prepare(sticker_sql_list);
|
||||
sticker_stmt_update = sticker_prepare(sticker_sql_update);
|
||||
sticker_stmt_insert = sticker_prepare(sticker_sql_insert);
|
||||
sticker_stmt_delete = sticker_prepare(sticker_sql_delete);
|
||||
|
||||
if (sticker_stmt_get == NULL || sticker_stmt_update == NULL ||
|
||||
sticker_stmt_insert == NULL || sticker_stmt_delete == NULL)
|
||||
sticker_stmt_insert == NULL || sticker_stmt_delete == NULL ||
|
||||
sticker_stmt_list == NULL)
|
||||
g_error("Failed to prepare sqlite statements");
|
||||
}
|
||||
|
||||
@ -112,6 +118,8 @@ sticker_global_finish(void)
|
||||
sqlite3_finalize(sticker_stmt_delete);
|
||||
sqlite3_finalize(sticker_stmt_update);
|
||||
sqlite3_finalize(sticker_stmt_insert);
|
||||
sqlite3_finalize(sticker_stmt_list);
|
||||
sqlite3_finalize(sticker_stmt_get);
|
||||
sqlite3_close(sticker_db);
|
||||
}
|
||||
|
||||
@ -181,6 +189,67 @@ sticker_load_value(const char *type, const char *uri, const char *name)
|
||||
return value;
|
||||
}
|
||||
|
||||
GList *
|
||||
sticker_list_values(const char *type, const char *uri)
|
||||
{
|
||||
int ret;
|
||||
char *name, *value;
|
||||
GPtrArray *arr;
|
||||
GList *list;
|
||||
|
||||
list = NULL;
|
||||
assert(type != NULL);
|
||||
assert(uri != NULL);
|
||||
|
||||
assert(sticker_enabled());
|
||||
|
||||
sqlite3_reset(sticker_stmt_list);
|
||||
|
||||
ret = sqlite3_bind_text(sticker_stmt_list, 1, type, -1, NULL);
|
||||
if (ret != SQLITE_OK) {
|
||||
g_warning("sqlite3_bind_text() failed: %s",
|
||||
sqlite3_errmsg(sticker_db));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = sqlite3_bind_text(sticker_stmt_list, 2, uri, -1, NULL);
|
||||
if (ret != SQLITE_OK) {
|
||||
g_warning("sqlite3_bind_text() failed: %s",
|
||||
sqlite3_errmsg(sticker_db));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = sqlite3_step(sticker_stmt_list);
|
||||
switch (ret) {
|
||||
case SQLITE_ROW:
|
||||
name = g_strdup((const char*)sqlite3_column_text(sticker_stmt_list, 0));
|
||||
value = g_strdup((const char*)sqlite3_column_text(sticker_stmt_list, 1));
|
||||
arr = g_ptr_array_new();
|
||||
g_ptr_array_add(arr, name);
|
||||
g_ptr_array_add(arr, value);
|
||||
list = g_list_prepend(list, arr);
|
||||
break;
|
||||
case SQLITE_DONE:
|
||||
break;
|
||||
case SQLITE_BUSY:
|
||||
/* no op */
|
||||
break;
|
||||
default:
|
||||
g_warning("sqlite3_step() failed: %s",
|
||||
sqlite3_errmsg(sticker_db));
|
||||
return NULL;
|
||||
}
|
||||
} while (ret != SQLITE_DONE);
|
||||
|
||||
list = g_list_reverse(list);
|
||||
|
||||
sqlite3_reset(sticker_stmt_list);
|
||||
sqlite3_clear_bindings(sticker_stmt_list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static bool
|
||||
sticker_update_value(const char *type, const char *uri,
|
||||
const char *name, const char *value)
|
||||
|
@ -41,6 +41,8 @@
|
||||
#ifndef STICKER_H
|
||||
#define STICKER_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
@ -61,6 +63,15 @@ sticker_global_finish(void);
|
||||
bool
|
||||
sticker_enabled(void);
|
||||
|
||||
/**
|
||||
* Populates a GList with GPtrArrays of sticker names and values from
|
||||
* an object's sticker record. The caller must free each GPtrArray
|
||||
* element of the returned list with g_ptr_array_free(), as well as
|
||||
* the returned GList with g_list_free().
|
||||
*/
|
||||
GList *
|
||||
sticker_list_values(const char *type, const char *uri);
|
||||
|
||||
/**
|
||||
* Returns one value from an object's sticker record. The caller must
|
||||
* free the return value with g_free().
|
||||
|
Loading…
Reference in New Issue
Block a user