From 3a4d20faa2ee6e5e514b82a92c7973978679d47d Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Wed, 1 Apr 2009 18:42:06 +0200
Subject: sticker: added sticker_find()

sticker_find() finds stickers with the specified name.
---
 src/sticker.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/sticker.h | 16 ++++++++++++++
 2 files changed, 85 insertions(+)

diff --git a/src/sticker.c b/src/sticker.c
index 255bfe177..e2d774f3d 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_FIND,
 };
 
 static const char *const sticker_sql[] = {
@@ -50,6 +51,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_FIND] =
+	"SELECT uri,value FROM sticker WHERE type=? AND uri LIKE (? || '%') AND name=?",
 };
 
 static const char sticker_sql_create[] =
@@ -508,3 +511,69 @@ sticker_load(const char *type, const char *uri)
 
 	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;
+}
diff --git a/src/sticker.h b/src/sticker.h
index 77363d61e..5daba3def 100644
--- a/src/sticker.h
+++ b/src/sticker.h
@@ -129,4 +129,20 @@ sticker_foreach(const struct sticker *sticker,
 struct sticker *
 sticker_load(const char *type, const char *uri);
 
+/**
+ * Finds stickers with the specified name below the specified URI.
+ *
+ * @param type the resource type, e.g. "song"
+ * @param base_uri the URI prefix of the resources, or NULL if all
+ * resources should be searched
+ * @param name the name of the sticker
+ * @return true on success (even if no sticker was found), false on
+ * failure
+ */
+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);
+
 #endif
-- 
cgit v1.2.3