Tue, 09 Dec 2025 14:33:26 +0100
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);