From 610940a06dc09fc14581cffc2829358e926ec9c3 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Tue, 28 Apr 2009 20:23:27 +0200
Subject: sticker: added sticker_delete_value()

sticker_delete_value() deletes only one value in a sticker, while
the old function sticker_delete() deletes all values.
---
 src/song_sticker.c | 16 ++++++++++++++++
 src/song_sticker.h |  7 +++++++
 src/sticker.c      | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/sticker.h      |  7 +++++++
 4 files changed, 85 insertions(+)

(limited to 'src')

diff --git a/src/song_sticker.c b/src/song_sticker.c
index 131519bcd..2758ff534 100644
--- a/src/song_sticker.c
+++ b/src/song_sticker.c
@@ -75,6 +75,22 @@ sticker_song_delete(const struct song *song)
 	return ret;
 }
 
+bool
+sticker_song_delete_value(const struct song *song, const char *name)
+{
+	char *uri;
+	bool success;
+
+	assert(song != NULL);
+	assert(song_in_database(song));
+
+	uri = song_get_uri(song);
+	success = sticker_delete_value("song", uri, name);
+	g_free(uri);
+
+	return success;
+}
+
 struct sticker *
 sticker_song_get(const struct song *song)
 {
diff --git a/src/song_sticker.h b/src/song_sticker.h
index 435e4c935..9652052e0 100644
--- a/src/song_sticker.h
+++ b/src/song_sticker.h
@@ -48,6 +48,13 @@ sticker_song_set_value(const struct song *song,
 bool
 sticker_song_delete(const struct song *song);
 
+/**
+ * Deletes a sticker value.  Does nothing if the sticker did not
+ * exist.
+ */
+bool
+sticker_song_delete_value(const struct song *song, const char *name);
+
 /**
  * Loads the sticker for the specified song.
  *
diff --git a/src/sticker.c b/src/sticker.c
index e2d774f3d..0d30fbb70 100644
--- a/src/sticker.c
+++ b/src/sticker.c
@@ -37,6 +37,7 @@ enum sticker_sql {
 	STICKER_SQL_UPDATE,
 	STICKER_SQL_INSERT,
 	STICKER_SQL_DELETE,
+	STICKER_SQL_DELETE_VALUE,
 	STICKER_SQL_FIND,
 };
 
@@ -51,6 +52,8 @@ static const char *const sticker_sql[] = {
 	"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=?",
 };
@@ -439,6 +442,58 @@ sticker_delete(const char *type, const char *uri)
 	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)
 {
diff --git a/src/sticker.h b/src/sticker.h
index 5daba3def..8e6410914 100644
--- a/src/sticker.h
+++ b/src/sticker.h
@@ -88,6 +88,13 @@ sticker_store_value(const char *type, const char *uri,
 bool
 sticker_delete(const char *type, const char *uri);
 
+/**
+ * Deletes a sticker value.  Fails if no sticker with this name
+ * exists.
+ */
+bool
+sticker_delete_value(const char *type, const char *uri, const char *name);
+
 /**
  * Frees resources held by the sticker object.
  *
-- 
cgit v1.2.3