aboutsummaryrefslogtreecommitdiffstats
path: root/src/sticker.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sticker.c')
-rw-r--r--src/sticker.c660
1 files changed, 0 insertions, 660 deletions
diff --git a/src/sticker.c b/src/sticker.c
deleted file mode 100644
index 346a827a5..000000000
--- a/src/sticker.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * Copyright (C) 2003-2011 The Music Player Daemon Project
- * http://www.musicpd.org
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include "config.h"
-#include "sticker.h"
-#include "idle.h"
-
-#include <glib.h>
-#include <sqlite3.h>
-#include <assert.h>
-
-#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "sticker"
-
-#if SQLITE_VERSION_NUMBER < 3003009
-#define sqlite3_prepare_v2 sqlite3_prepare
-#endif
-
-struct sticker {
- GHashTable *table;
-};
-
-enum sticker_sql {
- STICKER_SQL_GET,
- STICKER_SQL_LIST,
- STICKER_SQL_UPDATE,
- STICKER_SQL_INSERT,
- STICKER_SQL_DELETE,
- STICKER_SQL_DELETE_VALUE,
- STICKER_SQL_FIND,
-};
-
-static const char *const sticker_sql[] = {
- [STICKER_SQL_GET] =
- "SELECT value FROM sticker WHERE type=? AND uri=? AND name=?",
- [STICKER_SQL_LIST] =
- "SELECT name,value FROM sticker WHERE type=? AND uri=?",
- [STICKER_SQL_UPDATE] =
- "UPDATE sticker SET value=? WHERE type=? AND uri=? AND name=?",
- [STICKER_SQL_INSERT] =
- "INSERT INTO sticker(type,uri,name,value) VALUES(?, ?, ?, ?)",
- [STICKER_SQL_DELETE] =
- "DELETE FROM sticker WHERE type=? AND uri=?",
- [STICKER_SQL_DELETE_VALUE] =
- "DELETE FROM sticker WHERE type=? AND uri=? AND name=?",
- [STICKER_SQL_FIND] =
- "SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=?",
-};
-
-static const char sticker_sql_create[] =
- "CREATE TABLE IF NOT EXISTS sticker("
- " type VARCHAR NOT NULL, "
- " uri VARCHAR NOT NULL, "
- " name VARCHAR NOT NULL, "
- " value VARCHAR NOT NULL"
- ");"
- "CREATE UNIQUE INDEX IF NOT EXISTS"
- " sticker_value ON sticker(type, uri, name);"
- "";
-
-static sqlite3 *sticker_db;
-static sqlite3_stmt *sticker_stmt[G_N_ELEMENTS(sticker_sql)];
-
-static GQuark
-sticker_quark(void)
-{
- return g_quark_from_static_string("sticker");
-}
-
-static sqlite3_stmt *
-sticker_prepare(const char *sql, GError **error_r)
-{
- int ret;
- sqlite3_stmt *stmt;
-
- ret = sqlite3_prepare_v2(sticker_db, sql, -1, &stmt, NULL);
- if (ret != SQLITE_OK) {
- g_set_error(error_r, sticker_quark(), ret,
- "sqlite3_prepare_v2() failed: %s",
- sqlite3_errmsg(sticker_db));
- return NULL;
- }
-
- return stmt;
-}
-
-bool
-sticker_global_init(const char *path, GError **error_r)
-{
- int ret;
-
- if (path == NULL)
- /* not configured */
- return true;
-
- /* open/create the sqlite database */
-
- ret = sqlite3_open(path, &sticker_db);
- if (ret != SQLITE_OK) {
- g_set_error(error_r, sticker_quark(), ret,
- "Failed to open sqlite database '%s': %s",
- path, sqlite3_errmsg(sticker_db));
- return false;
- }
-
- /* create the table and index */
-
- ret = sqlite3_exec(sticker_db, sticker_sql_create, NULL, NULL, NULL);
- if (ret != SQLITE_OK) {
- g_set_error(error_r, sticker_quark(), ret,
- "Failed to create sticker table: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- /* prepare the statements we're going to use */
-
- for (unsigned i = 0; i < G_N_ELEMENTS(sticker_sql); ++i) {
- assert(sticker_sql[i] != NULL);
-
- sticker_stmt[i] = sticker_prepare(sticker_sql[i], error_r);
- if (sticker_stmt[i] == NULL)
- return false;
- }
-
- return true;
-}
-
-void
-sticker_global_finish(void)
-{
- if (sticker_db == NULL)
- /* not configured */
- return;
-
- for (unsigned i = 0; i < G_N_ELEMENTS(sticker_stmt); ++i) {
- assert(sticker_stmt[i] != NULL);
-
- sqlite3_finalize(sticker_stmt[i]);
- }
-
- sqlite3_close(sticker_db);
-}
-
-bool
-sticker_enabled(void)
-{
- return sticker_db != NULL;
-}
-
-char *
-sticker_load_value(const char *type, const char *uri, const char *name)
-{
- sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_GET];
- int ret;
- char *value;
-
- assert(sticker_enabled());
- assert(type != NULL);
- assert(uri != NULL);
- assert(name != NULL);
-
- if (*name == 0)
- return NULL;
-
- sqlite3_reset(stmt);
-
- ret = sqlite3_bind_text(stmt, 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(stmt, 2, uri, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return NULL;
- }
-
- ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return NULL;
- }
-
- do {
- ret = sqlite3_step(stmt);
- } while (ret == SQLITE_BUSY);
-
- if (ret == SQLITE_ROW) {
- /* record found */
- value = g_strdup((const char*)sqlite3_column_text(stmt, 0));
- } else if (ret == SQLITE_DONE) {
- /* no record found */
- value = NULL;
- } else {
- /* error */
- g_warning("sqlite3_step() failed: %s",
- sqlite3_errmsg(sticker_db));
- return NULL;
- }
-
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
-
- return value;
-}
-
-static bool
-sticker_list_values(GHashTable *hash, const char *type, const char *uri)
-{
- sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_LIST];
- int ret;
- char *name, *value;
-
- assert(hash != NULL);
- assert(type != NULL);
- assert(uri != NULL);
- assert(sticker_enabled());
-
- sqlite3_reset(stmt);
-
- ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 2, uri, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- do {
- ret = sqlite3_step(stmt);
- switch (ret) {
- case SQLITE_ROW:
- name = g_strdup((const char*)sqlite3_column_text(stmt, 0));
- value = g_strdup((const char*)sqlite3_column_text(stmt, 1));
- g_hash_table_insert(hash, name, value);
- break;
- case SQLITE_DONE:
- break;
- case SQLITE_BUSY:
- /* no op */
- break;
- default:
- g_warning("sqlite3_step() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
- } while (ret != SQLITE_DONE);
-
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
-
- return true;
-}
-
-static bool
-sticker_update_value(const char *type, const char *uri,
- const char *name, const char *value)
-{
- sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_UPDATE];
- int ret;
-
- assert(type != NULL);
- assert(uri != NULL);
- assert(name != NULL);
- assert(*name != 0);
- assert(value != NULL);
-
- assert(sticker_enabled());
-
- sqlite3_reset(stmt);
-
- ret = sqlite3_bind_text(stmt, 1, value, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 2, type, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 3, uri, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 4, name, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- do {
- ret = sqlite3_step(stmt);
- } while (ret == SQLITE_BUSY);
-
- if (ret != SQLITE_DONE) {
- g_warning("sqlite3_step() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_changes(sticker_db);
-
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
-
- idle_add(IDLE_STICKER);
- return ret > 0;
-}
-
-static bool
-sticker_insert_value(const char *type, const char *uri,
- const char *name, const char *value)
-{
- sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_INSERT];
- int ret;
-
- assert(type != NULL);
- assert(uri != NULL);
- assert(name != NULL);
- assert(*name != 0);
- assert(value != NULL);
-
- assert(sticker_enabled());
-
- sqlite3_reset(stmt);
-
- ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 2, uri, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 4, value, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- do {
- ret = sqlite3_step(stmt);
- } while (ret == SQLITE_BUSY);
-
- if (ret != SQLITE_DONE) {
- g_warning("sqlite3_step() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
-
-
- idle_add(IDLE_STICKER);
- return true;
-}
-
-bool
-sticker_store_value(const char *type, const char *uri,
- const char *name, const char *value)
-{
- assert(sticker_enabled());
- assert(type != NULL);
- assert(uri != NULL);
- assert(name != NULL);
- assert(value != NULL);
-
- if (*name == 0)
- return false;
-
- return sticker_update_value(type, uri, name, value) ||
- sticker_insert_value(type, uri, name, value);
-}
-
-bool
-sticker_delete(const char *type, const char *uri)
-{
- sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_DELETE];
- int ret;
-
- assert(sticker_enabled());
- assert(type != NULL);
- assert(uri != NULL);
-
- sqlite3_reset(stmt);
-
- ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 2, uri, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- do {
- ret = sqlite3_step(stmt);
- } while (ret == SQLITE_BUSY);
-
- if (ret != SQLITE_DONE) {
- g_warning("sqlite3_step() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
-
- idle_add(IDLE_STICKER);
- return true;
-}
-
-bool
-sticker_delete_value(const char *type, const char *uri, const char *name)
-{
- sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_DELETE_VALUE];
- int ret;
-
- assert(sticker_enabled());
- assert(type != NULL);
- assert(uri != NULL);
-
- sqlite3_reset(stmt);
-
- ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 2, uri, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- do {
- ret = sqlite3_step(stmt);
- } while (ret == SQLITE_BUSY);
-
- if (ret != SQLITE_DONE) {
- g_warning("sqlite3_step() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_changes(sticker_db);
-
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
-
- idle_add(IDLE_STICKER);
- return ret > 0;
-}
-
-static struct sticker *
-sticker_new(void)
-{
- struct sticker *sticker = g_new(struct sticker, 1);
-
- sticker->table = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, g_free);
- return sticker;
-}
-
-void
-sticker_free(struct sticker *sticker)
-{
- assert(sticker != NULL);
- assert(sticker->table != NULL);
-
- g_hash_table_destroy(sticker->table);
- g_free(sticker);
-}
-
-const char *
-sticker_get_value(const struct sticker *sticker, const char *name)
-{
- return g_hash_table_lookup(sticker->table, name);
-}
-
-struct sticker_foreach_data {
- void (*func)(const char *name, const char *value,
- gpointer user_data);
- gpointer user_data;
-};
-
-static void
-sticker_foreach_func(gpointer key, gpointer value, gpointer user_data)
-{
- struct sticker_foreach_data *data = user_data;
-
- data->func(key, value, data->user_data);
-}
-
-void
-sticker_foreach(const struct sticker *sticker,
- void (*func)(const char *name, const char *value,
- gpointer user_data),
- gpointer user_data)
-{
- struct sticker_foreach_data data = {
- .func = func,
- .user_data = user_data,
- };
-
- g_hash_table_foreach(sticker->table, sticker_foreach_func, &data);
-}
-
-struct sticker *
-sticker_load(const char *type, const char *uri)
-{
- struct sticker *sticker = sticker_new();
- bool success;
-
- success = sticker_list_values(sticker->table, type, uri);
- if (!success) {
- sticker_free(sticker);
- return NULL;
- }
-
- if (g_hash_table_size(sticker->table) == 0) {
- /* don't return empty sticker objects */
- sticker_free(sticker);
- return NULL;
- }
-
- return sticker;
-}
-
-bool
-sticker_find(const char *type, const char *base_uri, const char *name,
- void (*func)(const char *uri, const char *value,
- gpointer user_data),
- gpointer user_data)
-{
- sqlite3_stmt *const stmt = sticker_stmt[STICKER_SQL_FIND];
- int ret;
-
- assert(type != NULL);
- assert(name != NULL);
- assert(func != NULL);
- assert(sticker_enabled());
-
- sqlite3_reset(stmt);
-
- ret = sqlite3_bind_text(stmt, 1, type, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- if (base_uri == NULL)
- base_uri = "";
-
- ret = sqlite3_bind_text(stmt, 2, base_uri, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- ret = sqlite3_bind_text(stmt, 3, name, -1, NULL);
- if (ret != SQLITE_OK) {
- g_warning("sqlite3_bind_text() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
-
- do {
- ret = sqlite3_step(stmt);
- switch (ret) {
- case SQLITE_ROW:
- func((const char*)sqlite3_column_text(stmt, 0),
- (const char*)sqlite3_column_text(stmt, 1),
- user_data);
- break;
- case SQLITE_DONE:
- break;
- case SQLITE_BUSY:
- /* no op */
- break;
- default:
- g_warning("sqlite3_step() failed: %s",
- sqlite3_errmsg(sticker_db));
- return false;
- }
- } while (ret != SQLITE_DONE);
-
- sqlite3_reset(stmt);
- sqlite3_clear_bindings(stmt);
-
- return true;
-}