add dbuSqlExec API

Tue, 09 Dec 2025 14:33:26 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 09 Dec 2025 14:33:26 +0100
changeset 24
df671b62538e
parent 23
b26390e77237
child 25
0bb91d1f9bba

add dbuSqlExec API

dbutils/db.c file | annotate | diff | comparison | revisions
dbutils/dbutils/db.h file | annotate | diff | comparison | revisions
dbutils/sqlite.c file | annotate | diff | comparison | revisions
test/database.c file | annotate | diff | comparison | revisions
test/database.h file | annotate | diff | comparison | revisions
test/main.c file | annotate | diff | comparison | revisions
--- a/dbutils/db.c	Tue Dec 09 12:13:43 2025 +0100
+++ b/dbutils/db.c	Tue Dec 09 14:33:26 2025 +0100
@@ -51,6 +51,16 @@
     return conn->createQuery(conn, a);
 }
 
+DBUQuery* dbuQueryCreate(DBUConnection *conn, const CxAllocator *a, const char *sql) {
+    DBUQuery *query = dbuConnectionQuery(conn, a);
+    if(query) {
+        if(dbuQuerySetSQL(query, sql)) {
+            dbuQueryFree(query);
+            return NULL;
+        }
+    }
+    return query;
+}
 
 int dbuQuerySetSQL(DBUQuery *q, const char *sql) {
     return q->setSQL(q, sql);
@@ -208,22 +218,108 @@
     return -1;
 }
 
-static DBUQuery* createIntParamQuery(DBUConnection *conn, const char *sql, int64_t param) {
+static DBUQuery* execInt64ParamQuery(DBUConnection *conn, const char *sql, int64_t param) {
     DBUQuery *q = conn->createQuery(conn, cxDefaultAllocator);
-    dbuQuerySetSQL(q, sql);
+    if(dbuQuerySetSQL(q, sql)) {
+        dbuQueryFree(q);
+        return NULL;
+    }
     dbuQuerySetParamInt64(q, 1, param);
+    if(dbuQueryExec(q)) {
+        dbuQueryFree(q);
+        return NULL;
+    }
+    return q;
+}
+
+static DBUQuery* execStringParamQuery(DBUConnection *conn, const char *sql, cxstring param) {
+    DBUQuery *q = conn->createQuery(conn, cxDefaultAllocator);
+    if(dbuQuerySetSQL(q, sql)) {
+        dbuQueryFree(q);
+        return NULL;
+    }
+    dbuQuerySetParamString(q, 1, param);
+    if(dbuQueryExec(q)) {
+        dbuQueryFree(q);
+        return NULL;
+    }
     return q;
 }
 
-static DBUQuery* createStringParamQuery(DBUConnection *conn, const char *sql, cxstring param) {
-    DBUQuery *q = conn->createQuery(conn, cxDefaultAllocator);
-    dbuQuerySetSQL(q, sql);
-    dbuQuerySetParamString(q, 1, param);
-    return q;
+DBUResult* dbuSqlExec(DBUConnection *conn, const CxAllocator *a, const char *sql) {
+    DBUQuery *q = dbuQueryCreate(conn, a, sql);
+    if(!q) {
+        return NULL;
+    }
+    if(dbuQueryExec(q)) {
+        dbuQueryFree(q);
+        return NULL;
+    }
+    DBUResult *result = dbuQueryGetResult(q);
+    dbuQueryFree(q);
+    return result;
+}
+
+DBUResult* dbuSqlExecParamInt32(DBUConnection *conn, const CxAllocator *a, const char *sql, int32_t param) {
+    DBUQuery *q = execInt64ParamQuery(conn, sql, param);
+    if(!q) return NULL;
+    DBUResult *r = dbuQueryGetResult(q);
+    dbuQueryFree(q);
+    return r;
+}
+
+DBUResult* dbuSqlExecParamInt64(DBUConnection *conn, const CxAllocator *a, const char *sql, int64_t param) {
+    DBUQuery *q = execInt64ParamQuery(conn, sql, param);
+    if(!q) return NULL;
+    DBUResult *r = dbuQueryGetResult(q);
+    dbuQueryFree(q);
+    return r;
 }
 
+DBUResult* dbuSqlExecParamUInt32(DBUConnection *conn, const CxAllocator *a, const char *sql, uint32_t param) {
+    DBUQuery *q = execInt64ParamQuery(conn, sql, param);
+    if(!q) return NULL;
+    DBUResult *r = dbuQueryGetResult(q);
+    dbuQueryFree(q);
+    return r;
+}
+
+DBUResult* dbuSqlExecParamUInt64(DBUConnection *conn, const CxAllocator *a, const char *sql, uint32_t param) {
+    DBUQuery *q = execInt64ParamQuery(conn, sql, param);
+    if(!q) return NULL;
+    DBUResult *r = dbuQueryGetResult(q);
+    dbuQueryFree(q);
+    return r;
+}
+
+DBUResult* dbuSqlExecParamString(DBUConnection *conn, const CxAllocator *a, const char *sql, const char *param) {
+    DBUQuery *q = execStringParamQuery(conn, sql, cx_str(param));
+    if(!q) return NULL;
+    DBUResult *r = dbuQueryGetResult(q);
+    dbuQueryFree(q);
+    return r;
+}
+
+DBUResult* dbuSqlExecParamCxString(DBUConnection *conn, const CxAllocator *a, const char *sql, cxstring param) {
+    DBUQuery *q = execStringParamQuery(conn, sql, param);
+    if(!q) return NULL;
+    DBUResult *r = dbuQueryGetResult(q);
+    dbuQueryFree(q);
+    return r;
+}
+
+DBUResult* dbuSqlExecParamCxMutStr(DBUConnection *conn, const CxAllocator *a, const char *sql, cxmutstr param) {
+    DBUQuery *q = execStringParamQuery(conn, sql, cx_strcast(param));
+    if(!q) return NULL;
+    DBUResult *r = dbuQueryGetResult(q);
+    dbuQueryFree(q);
+    return r;
+}
+
+
 int dbuSimpleGetInt64WithIntParam(DBUConnection *conn, const char *sql, int64_t param, int64_t *result) {
-    DBUQuery *q = createIntParamQuery(conn, sql, param);
+    DBUQuery *q = execInt64ParamQuery(conn, sql, param);
+    if(!q) return 1;
     int err = dbuQueryExec(q);
     dbuQueryFree(q);
     if(!err) {
@@ -234,40 +330,36 @@
 }
 
 int dbuSimpleGetInt64WithStringParam(DBUConnection *conn, const char *sql, cxstring param, int64_t *result) {
-    DBUQuery *q = createStringParamQuery(conn, sql, param);
-    int err = dbuQueryExec(q);
+    DBUQuery *q = execStringParamQuery(conn, sql, param);
+    if(!q) return 1;
+    DBUResult *r = dbuQueryGetResult(q);
     dbuQueryFree(q);
-    if(!err) {
-        DBUResult *r = dbuQueryGetResult(q);
-        err = dbuResultAsInt64(r, result);
-    }
-    return err;
+    return dbuResultAsInt64(r, result);;
 }
 
 int dbuSimpleGetStringWithIntParam(DBUConnection *conn, const char *sql, int64_t param, const CxAllocator *a, cxmutstr *result) {
-    DBUQuery *q = createIntParamQuery(conn, sql, param);
-    int err = dbuQueryExec(q);
+    DBUQuery *q = execInt64ParamQuery(conn, sql, param);
+    if(!q) return 1;
+    DBUResult *r = dbuQueryGetResult(q);
     dbuQueryFree(q);
-    if(!err) {
-        DBUResult *r = dbuQueryGetResult(q);
-        err = dbuResultAsCxStringA(r, a, result);
-    }
-    return err;
+    return dbuResultAsCxStringA(r, a, result);
 }
 
 int dbuSimpleGetStringWithStringParam(DBUConnection *conn, const char *sql, cxstring param, const CxAllocator *a, cxmutstr *result) {
-    DBUQuery *q = createStringParamQuery(conn, sql, param);
-    int err = dbuQueryExec(q);
+    DBUQuery *q = execStringParamQuery(conn, sql, param);
+    if(!q) return 1;
+    DBUResult *r = dbuQueryGetResult(q);
     dbuQueryFree(q);
-    if(!err) {
-        DBUResult *r = dbuQueryGetResult(q);
-        err = dbuResultAsCxStringA(r, a, result);
-    }
-    return err;
+    return dbuResultAsCxStringA(r, a, result);
 }
 
 CxList* dbuSimpleGetListWithIntParam(DBUConnection *conn, const char *sql, int64_t param, const CxAllocator *a, DBUClass *type) {
-    DBUQuery *q = createIntParamQuery(conn, sql, param);
+    DBUQuery *q = conn->createQuery(conn, cxDefaultAllocator);
+    if(dbuQuerySetSQL(q, sql)) {
+        dbuQueryFree(q);
+        return NULL;
+    }
+    dbuQuerySetParamInt64(q, 1, param);
     DBUObjectBuilder *builder = dbuObjectBuilder(type, q, a);
     CxList *list = dbuObjectBuilderGetList(builder);
     dbuObjectBuilderDestroy(builder);
@@ -275,7 +367,12 @@
 }
 
 CxList* dbuSimpleGetListWithStringParam(DBUConnection *conn, const char *sql, cxstring param, const CxAllocator *a, DBUClass *type) {
-    DBUQuery *q = createStringParamQuery(conn, sql, param);
+    DBUQuery *q = conn->createQuery(conn, cxDefaultAllocator);
+    if(dbuQuerySetSQL(q, sql)) {
+        dbuQueryFree(q);
+        return NULL;
+    }
+    dbuQuerySetParamString(q, 1, param);
     DBUObjectBuilder *builder = dbuObjectBuilder(type, q, a);
     CxList *list = dbuObjectBuilderGetList(builder);
     dbuObjectBuilderDestroy(builder);
--- a/dbutils/dbutils/db.h	Tue Dec 09 12:13:43 2025 +0100
+++ b/dbutils/dbutils/db.h	Tue Dec 09 14:33:26 2025 +0100
@@ -100,6 +100,7 @@
 int dbuConnectionIsActive(DBUConnection *conn);
 void dbuConnectionFree(DBUConnection *conn);
 DBUQuery* dbuConnectionQuery(DBUConnection *conn, const CxAllocator *a);
+DBUQuery* dbuQueryCreate(DBUConnection *conn, const CxAllocator *a, const char *sql);
 
 int dbuQuerySetSQL(DBUQuery *q, const char *sql);
 int dbuQuerySetParamString(DBUQuery *q, int index, cxstring str);
@@ -121,7 +122,6 @@
 void dbuResultFree(DBUResult *result);
 
 
-
 #define dbuResultAsValue(r, result) \
     _Generic(result, \
     int32_t* : dbuResultAsInt32, \
@@ -152,6 +152,28 @@
 // TODO: implement
 int dbuObjectBuilderAddSubquery(DBUObjectBuilder *builder, DBUClass *type, DBUQuery *subquery);
 
+#define dbuSqlExecParam(conn, a, sql, param) \
+    _Generic(param, \
+    int32_t    : dbuSqlExecParamInt32, \
+    int64_t    : dbuSqlExecParamInt64, \
+    uint32_t   : dbuSqlExecParamUInt32, \
+    uint64_t   : dbuSqlExecParamUInt64, \
+    char*      : dbuSqlExecParamString, \
+    const char*: dbuSqlExecParamString, \
+    cxstring   : dbuSqlExecParamCxString, \
+    cxmutstr   : dbuSqlExecParamCxMutStr)(conn, a, sql, param)
+
+DBUResult* dbuSqlExec(DBUConnection *conn, const CxAllocator *a, const char *sql);
+DBUResult* dbuSqlExecParamInt32(DBUConnection *conn, const CxAllocator *a, const char *sql, int32_t param);
+DBUResult* dbuSqlExecParamInt64(DBUConnection *conn, const CxAllocator *a, const char *sql, int64_t param);
+DBUResult* dbuSqlExecParamUInt32(DBUConnection *conn, const CxAllocator *a, const char *sql, uint32_t param);
+DBUResult* dbuSqlExecParamUInt64(DBUConnection *conn, const CxAllocator *a, const char *sql, uint32_t param);
+DBUResult* dbuSqlExecParamString(DBUConnection *conn, const CxAllocator *a, const char *sql, const char *param);
+DBUResult* dbuSqlExecParamCxString(DBUConnection *conn, const CxAllocator *a, const char *sql, cxstring param);
+DBUResult* dbuSqlExecParamCxMutStr(DBUConnection *conn, const CxAllocator *a, const char *sql, cxmutstr param);
+
+
+
 int dbuSimpleGetInt64WithIntParam(DBUConnection *conn, const char *sql, int64_t param, int64_t *result);
 int dbuSimpleGetInt64WithStringParam(DBUConnection *conn, const char *sql, cxstring param, int64_t *result);
 int dbuSimpleGetStringWithIntParam(DBUConnection *conn, const char *sql, int64_t param, const CxAllocator *a, cxmutstr *result);
--- a/dbutils/sqlite.c	Tue Dec 09 12:13:43 2025 +0100
+++ b/dbutils/sqlite.c	Tue Dec 09 14:33:26 2025 +0100
@@ -118,32 +118,32 @@
 
 int dbuSQLiteQuerySetParamString(DBUQuery *q, int index, cxstring str) {
     DBUSQLiteQuery *query = (DBUSQLiteQuery*)q;
-    return sqlite3_bind_text(query->stmt, index+1, str.ptr, str.length, NULL);
+    return sqlite3_bind_text(query->stmt, index, str.ptr, str.length, NULL);
 }
 
 int dbuSQLiteQuerySetParamInt(DBUQuery *q, int index, int i) {
     DBUSQLiteQuery *query = (DBUSQLiteQuery*)q;
-    return sqlite3_bind_int(query->stmt, index+1, i);
+    return sqlite3_bind_int(query->stmt, index, i);
 }
 
 int dbuSQLiteQuerySetParamInt64(DBUQuery *q, int index, int64_t i) {
     DBUSQLiteQuery *query = (DBUSQLiteQuery*)q;
-    return sqlite3_bind_int64(query->stmt, index+1, i);
+    return sqlite3_bind_int64(query->stmt, index, i);
 }
 
 int dbuSQLiteQuerySetParamDouble(DBUQuery *q, int index, double d) {
     DBUSQLiteQuery *query = (DBUSQLiteQuery*)q;
-    return sqlite3_bind_double(query->stmt, index+1, d);
+    return sqlite3_bind_double(query->stmt, index, d);
 }
 
 int dbuSQLiteQuerySetParamNull(DBUQuery *q, int index) {
     DBUSQLiteQuery *query = (DBUSQLiteQuery*)q;
-    return sqlite3_bind_null(query->stmt, index+1);
+    return sqlite3_bind_null(query->stmt, index);
 }
 
 int dbuSQLiteQuerySetParamBytes(DBUQuery *q, int index, void *bytes, int len) {
     DBUSQLiteQuery *query = (DBUSQLiteQuery*)q;
-    return sqlite3_bind_blob(query->stmt, index+1, bytes, len, NULL);
+    return sqlite3_bind_blob(query->stmt, index, bytes, len, NULL);
 }
 
 int dbuSQLiteQueryExec(DBUQuery *q) {
--- a/test/database.c	Tue Dec 09 12:13:43 2025 +0100
+++ b/test/database.c	Tue Dec 09 14:33:26 2025 +0100
@@ -194,3 +194,35 @@
         
     }
 }
+
+CX_TEST(testSqlExec) {
+    CX_TEST_DO {
+        CX_TEST_ASSERT(conn);
+        
+        DBUResult *r = dbuSqlExec(conn, NULL, "select email from person where name = 'alice';");
+        CX_TEST_ASSERT(r);
+        cxmutstr value;
+        CX_TEST_ASSERT(dbuResultAsValue(r, &value) == 0);
+        CX_TEST_ASSERT(!cx_strcmp(value, "alice@example.com"));
+        free(value.ptr);
+    }
+}
+
+CX_TEST(testSqlExecParam) {
+    CX_TEST_DO {
+        CX_TEST_ASSERT(conn);
+        
+        DBUResult *r = dbuSqlExecParam(conn, NULL, "select email from person where name = ?;", "alice");
+        CX_TEST_ASSERT(r);
+        cxmutstr value;
+        CX_TEST_ASSERT(dbuResultAsValue(r, &value) == 0);
+        CX_TEST_ASSERT(!cx_strcmp(value, "alice@example.com"));
+        free(value.ptr);
+        
+        r = dbuSqlExecParam(conn, NULL, "select name from person where hash = ?;", 987654321);
+        CX_TEST_ASSERT(r);
+        CX_TEST_ASSERT(dbuResultAsValue(r, &value) == 0);
+        CX_TEST_ASSERT(!cx_strcmp(value, "bob"));
+        free(value.ptr);
+    }
+}
--- a/test/database.h	Tue Dec 09 12:13:43 2025 +0100
+++ b/test/database.h	Tue Dec 09 14:33:26 2025 +0100
@@ -49,6 +49,8 @@
 CX_TEST(testSqliteConnection);
 CX_TEST(testConnectionExec);
 CX_TEST(testSingleValueQuery);
+CX_TEST(testSqlExec);
+CX_TEST(testSqlExecParam);
 
 
 #ifdef __cplusplus
--- a/test/main.c	Tue Dec 09 12:13:43 2025 +0100
+++ b/test/main.c	Tue Dec 09 14:33:26 2025 +0100
@@ -128,6 +128,8 @@
     cx_test_register(suite, testSqliteConnection);
     cx_test_register(suite, testConnectionExec);
     cx_test_register(suite, testSingleValueQuery);
+    cx_test_register(suite, testSqlExec);
+    cx_test_register(suite, testSqlExecParam);
 #endif
     
     cx_test_run_stdout(suite);

mercurial