fixed tsqlite_statement bugs

This commit is contained in:
2025-12-15 13:34:29 +05:00
parent 3d18027489
commit 52a19d8db8
3 changed files with 86 additions and 33 deletions

View File

@@ -3,12 +3,20 @@
Result(tsqlite_statement*) tsqlite_statement_compile(tsqlite_connection* conn, str sql_code){
sqlite3_stmt* st = NULL;
i32 flags = SQLITE_PREPARE_PERSISTENT;
try_sqlite3(conn, sqlite3_prepare_v3(conn, sql_code.data, sql_code.len, flags, &st, NULL));
const char* tail;
try_sqlite3(conn, sqlite3_prepare_v3(conn, sql_code.data, sql_code.len, flags, &st, &tail));
for(u32 i = (u32)(tail - sql_code.data); i < sql_code.len; i++){
char c = sql_code.data[i];
if(c != ' ' && c != '\t' && c != '\r' && c != '\n'){
sqlite3_finalize(st);
return RESULT_ERROR_LITERAL("multiple statements cannot be compiled as one");
}
}
tsqlite_statement* self = malloc(sizeof(*self));
self->conn = conn;
self->st = st;
self->result_row = 0;
self->result_col = 0;
self->result_row = -1;
self->result_col = -1;
return RESULT_VALUE(p, self);
}
@@ -21,8 +29,8 @@ void tsqlite_statement_free(tsqlite_statement* self){
Result(void) tsqlite_statement_reset(tsqlite_statement* self){
try_sqlite3(self->conn, sqlite3_reset(self->st));
self->result_row = 0;
self->result_col = 0;
self->result_row = -1;
self->result_col = -1;
return RESULT_VOID;
}
@@ -30,7 +38,7 @@ Result(void) tsqlite_statement_reset(tsqlite_statement* self){
#define tryGetBindIndex(key) \
i32 bind_index = sqlite3_bind_parameter_index(self->st, key);\
if(bind_index == 0){\
return RESULT_ERROR_SQLITE_CODE(self->conn, sqlite3_errcode(self->conn));\
return RESULT_ERROR_CODE_FMT(SQLITE, SQLITE_ERROR, "bind placeholder '%s' not found", key);\
}\
Result(void) tsqlite_statement_bind_null(tsqlite_statement* self, cstr key){
@@ -74,45 +82,52 @@ Result(bool) tsqlite_statement_execNext(tsqlite_statement* self){
int r = sqlite3_step(self->st);
if(r == SQLITE_ROW){
self->result_row++;
self->result_col = -1;
return RESULT_VALUE(i, true);
}
if(r == SQLITE_DONE){
self->result_row++;
self->result_col = -1;
return RESULT_VALUE(i, false);
}
return RESULT_ERROR_SQLITE_CODE(self->conn, r);
}
#define validate_column()\
i32 errcode = sqlite3_errcode(self->conn);\
if(errcode != SQLITE_OK && errcode != SQLITE_ROW){\
return RESULT_ERROR_SQLITE_CODE(self->conn, errcode);\
}
Result(i64) tsqlite_statement_getResult_i64(tsqlite_statement* self){
i64 r = sqlite3_column_int64(self->st, self->result_col);
try_sqlite3(self->conn, sqlite3_errcode(self->conn));
self->result_col++;
i64 r = sqlite3_column_int64(self->st, self->result_col);
validate_column();
return RESULT_VALUE(i, r);
}
Result(i64) tsqlite_statement_getResult_f64(tsqlite_statement* self){
f64 r = sqlite3_column_double(self->st, self->result_col);
try_sqlite3(self->conn, sqlite3_errcode(self->conn));
self->result_col++;
f64 r = sqlite3_column_double(self->st, self->result_col);
validate_column();
return RESULT_VALUE(f, r);
}
Result(void) tsqlite_statement_getResult_str(tsqlite_statement* self, str* out_v){
self->result_col++;
void* data = (void*)sqlite3_column_text(self->st, self->result_col);
try_sqlite3(self->conn, sqlite3_errcode(self->conn));
validate_column();
u32 size = sqlite3_column_bytes(self->st, self->result_col);
*out_v = str_construct(data, size, true);
self->result_col++;
return RESULT_VOID;
}
Result(void) tsqlite_statement_getResult_blob(tsqlite_statement* self, Array(u8)* out_v){
self->result_col++;
void* data = (void*)sqlite3_column_blob(self->st, self->result_col);
try_sqlite3(self->conn, sqlite3_errcode(self->conn));
validate_column();
u32 size = sqlite3_column_bytes(self->st, self->result_col);
*out_v = Array_u8_construct(data, size);
self->result_col++;
return RESULT_VOID;
}