summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-12-17 19:02:53 -0500
committerJune McEnroe <june@causal.agency>2019-12-17 19:02:53 -0500
commit0247c6063c5dc9e592e48fc85c807893d8b34033 (patch)
tree73d304794ee71454de7d63079ce2c1e3cfce9318
parentUse parameter names for all binds (diff)
downloadlitterbox-0247c6063c5dc9e592e48fc85c807893d8b34033.tar.gz
litterbox-0247c6063c5dc9e592e48fc85c807893d8b34033.zip
Separate dbBindText wrappers to allow for transient
-rw-r--r--database.h52
-rw-r--r--unscoop.c16
2 files changed, 50 insertions, 18 deletions
diff --git a/database.h b/database.h
index 4ca9c81..ad0d0ba 100644
--- a/database.h
+++ b/database.h
@@ -18,6 +18,7 @@
 #include <errno.h>
 #include <limits.h>
 #include <sqlite3.h>
+#include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -107,30 +108,61 @@ dbPrepare(sqlite3 *db, unsigned flags, const char *sql) {
 	return stmt;
 }
 
-static inline void
-dbBindText(sqlite3_stmt *stmt, const char *param, const char *text, int len) {
+static inline int dbParam(sqlite3_stmt *stmt, const char *param) {
 	int index = sqlite3_bind_parameter_index(stmt, param);
-	if (!index) errx(EX_SOFTWARE, "no such parameter %s", param);
-	int error = sqlite3_bind_text(stmt, index, text, len, NULL);
-	if (!error) return;
+	if (index) return index;
 	errx(
-		EX_SOFTWARE, "sqlite3_bind_text: %s",
+		EX_SOFTWARE, "no such parameter %s: %s",
+		param, sqlite3_sql(stmt)
+	);
+}
+
+static inline void dbBindNull(sqlite3_stmt *stmt, const char *param) {
+	if (!sqlite3_bind_null(stmt, dbParam(stmt, param))) return;
+	errx(
+		EX_SOFTWARE, "sqlite3_bind_null: %s",
 		sqlite3_errmsg(sqlite3_db_handle(stmt))
 	);
 }
 
 static inline void
 dbBindInt(sqlite3_stmt *stmt, const char *param, int64_t value) {
-	int index = sqlite3_bind_parameter_index(stmt, param);
-	if (!index) errx(EX_SOFTWARE, "no such parameter %s", param);
-	int error = sqlite3_bind_int64(stmt, index, value);
-	if (!error) return;
+	if (!sqlite3_bind_int64(stmt, dbParam(stmt, param), value)) return;
 	errx(
 		EX_SOFTWARE, "sqlite3_bind_int64: %s",
 		sqlite3_errmsg(sqlite3_db_handle(stmt))
 	);
 }
 
+static inline void dbBindText5(
+	sqlite3_stmt *stmt, const char *param,
+	const char *text, int len, bool copy
+) {
+	int error = sqlite3_bind_text(
+		stmt, dbParam(stmt, param), text, len, (copy ? SQLITE_TRANSIENT : NULL)
+	);
+	if (!error) return;
+	errx(
+		EX_SOFTWARE, "sqlite3_bind_text: %s",
+		sqlite3_errmsg(sqlite3_db_handle(stmt))
+	);
+}
+
+static inline void
+dbBindText(sqlite3_stmt *stmt, const char *param, const char *text) {
+	dbBindText5(stmt, param, text, -1, false);
+}
+
+static inline void
+dbBindTextLen(sqlite3_stmt *stmt, const char *param, const char *text, int len) {
+	dbBindText5(stmt, param, text, len, false);
+}
+
+static inline void
+dbBindTextCopy(sqlite3_stmt *stmt, const char *param, const char *text) {
+	dbBindText5(stmt, param, text, -1, true);
+}
+
 static inline int dbStep(sqlite3_stmt *stmt) {
 	int error = sqlite3_step(stmt);
 	if (error == SQLITE_ROW || error == SQLITE_DONE) return error;
diff --git a/unscoop.c b/unscoop.c
index c4e9d33..6fd8c28 100644
--- a/unscoop.c
+++ b/unscoop.c
@@ -210,9 +210,9 @@ static void bindMatch(
 	sqlite3_stmt *stmt, const char *param, const char *str, regmatch_t match
 ) {
 	if (match.rm_so < 0) {
-		dbBindText(stmt, param, NULL, -1);
+		dbBindNull(stmt, param);
 	} else {
-		dbBindText(stmt, param, &str[match.rm_so], match.rm_eo - match.rm_so);
+		dbBindTextLen(stmt, param, &str[match.rm_so], match.rm_eo - match.rm_so);
 	}
 }
 
@@ -245,8 +245,8 @@ static void prepareInsert(sqlite3 *db) {
 			AND names.host = coalesce(:host, '*');
 	);
 	insertEvent = dbPrepare(db, SQLITE_PREPARE_PERSISTENT, InsertEvent);
-	paramNetwork = sqlite3_bind_parameter_index(insertEvent, ":network");
-	paramContext = sqlite3_bind_parameter_index(insertEvent, ":context");
+	paramNetwork = dbParam(insertEvent, ":network");
+	paramContext = dbParam(insertEvent, ":context");
 }
 
 static void
@@ -348,12 +348,12 @@ int main(int argc, char *argv[]) {
 	sqlite3_stmt *insertContext = dbPrepare(
 		db, SQLITE_PREPARE_PERSISTENT, InsertContext
 	);
-	dbBindText(insertContext, ":network", network, -1);
-	dbBindText(insertContext, ":context", context, -1);
+	dbBindText(insertContext, ":network", network);
+	dbBindText(insertContext, ":context", context);
 
 	prepareInsert(db);
-	dbBindText(insertEvent, ":network", network, -1);
-	dbBindText(insertEvent, ":context", context, -1);
+	dbBindText(insertEvent, ":network", network);
+	dbBindText(insertEvent, ":context", context);
 
 	size_t sizeTotal = 0;
 	size_t sizeRead = 0;