From 0247c6063c5dc9e592e48fc85c807893d8b34033 Mon Sep 17 00:00:00 2001 From: "C. McEnroe" Date: Tue, 17 Dec 2019 19:02:53 -0500 Subject: Separate dbBindText wrappers to allow for transient --- database.h | 52 ++++++++++++++++++++++++++++++++++++++++++---------- unscoop.c | 16 ++++++++-------- 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 #include #include +#include #include #include #include @@ -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; -- cgit 1.4.1