diff options
| author | Paul Oliver <contact@pauloliver.dev> | 2026-05-25 19:30:41 +0200 |
|---|---|---|
| committer | Paul Oliver <contact@pauloliver.dev> | 2026-05-25 20:05:58 +0200 |
| commit | 5ce8953bcb98e037f50a37abadf664d95ee69cc2 (patch) | |
| tree | 5aac0bb58b637e3d7085cc0d7eafc113fa330a7e /core/sql.c | |
| parent | 65ce077940bc5916b7c67fde1856b112ba38de39 (diff) | |
data client (WIP)
Diffstat (limited to 'core/sql.c')
| -rw-r--r-- | core/sql.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/core/sql.c b/core/sql.c new file mode 100644 index 0000000..a03ce5d --- /dev/null +++ b/core/sql.c @@ -0,0 +1,49 @@ +void salis_exec_sql(int blob_cnt, const void **blobs, const int *blob_sizes, const char *sql_format, ...) { + assert(sql_format); + + va_list args; + va_start(args, sql_format); + int sql_len = vsnprintf(NULL, 0, sql_format, args) + 1; + char *sql_str = malloc(sql_len); + assert(sql_str); + va_end(args); + + va_start(args, sql_format); + vsprintf(sql_str, sql_format, args); + va_end(args); + + int sql_res; + sqlite3_stmt *sql_stmt; + + sql_res = sqlite3_prepare_v2(g_sim_db, sql_str, -1, &sql_stmt, NULL); + assert(sql_res == SQLITE_OK); + free(sql_str); + + for (int i = 0; i < blob_cnt; ++i) { + assert(blobs[i]); + sql_res = sqlite3_bind_blob(sql_stmt, i + 1, blobs[i], blob_sizes[i], SQLITE_STATIC); + assert(sql_res == SQLITE_OK); + } + + // Only handle SQLITE_BUSY error, in which case we retry the query. + // Setting 'journal_mode=wal;' should help prevent busy database errors. + while (true) { + sql_res = sqlite3_step(sql_stmt); + + if (sql_res == SQLITE_DONE || sql_res == SQLITE_ROW) { + break; + } + + g_warn("SQLite database returned error %d with message:", sql_res); + g_warn(sqlite3_errmsg(g_sim_db)); + + if (sql_res == SQLITE_BUSY) { + g_info("Will retry query..."); + continue; + } + + assert(false); + } + + sqlite3_finalize(sql_stmt); +} |
