Files
tsqlite/include/tsqlite.h

85 lines
3.0 KiB
C

#pragma once
#include "tlibc/tlibc.h"
#include "tlibc/string/StringBuilder.h"
#include <sqlite3.h>
Result(void) tsqlite_init();
void tsqlite_deinit();
ErrorCodePage_declare(SQLITE);
/// @param code SQLITE_* result code
/// @return heap-allocated string
str tsqlite_error_toStr(i32 code, cstr msg);
#define RESULT_ERROR_SQLITE_CODE(CODE, MSG) RESULT_ERROR_CODE(SQLITE, CODE, tsqlite_error_toStr(CODE, MSG), true)
#define _try_sqlite3(CONN, CALL, N) do {\
i32 _rname(N) = CALL;\
if((_rname(N) & 0xff) != SQLITE_OK){\
return RESULT_ERROR_SQLITE_CODE(_rname(N), sqlite3_errmsg(CONN));\
}\
} while(0)
#define try_sqlite3(CONN, CALL) _try_sqlite3(CONN, CALL, __LINE__)
typedef sqlite3 tsqlite_connection;
/// @param file_path sqlite file
/// @return new sqlite connection
Result(tsqlite_connection*) tsqlite_connection_open(cstr file_path);
/// all statements and blobs must be destroyed before calling this
Result(void) tsqlite_connection_close(tsqlite_connection* db);
typedef struct tsqlite_statement {
tsqlite_connection* conn;
sqlite3_stmt* st;
i32 result_row;
i32 result_col;
} tsqlite_statement;
/// @brief Compile SQL statement to bytecode. Documentation: https://sqlite.org/c3ref/prepare.html
/// @param conn a database connection
/// @param sql_code SQL statement code. May contain placeholders.
/// **PLACEHOLDERS FORMAT**: `:name`, `@name`, `$name`, `$(some name)`
/// @return compiled statement
Result(tsqlite_statement*) tsqlite_statement_compile(tsqlite_connection* conn, str sql_code);
void tsqlite_statement_free(tsqlite_statement* st);
/// @brief execute statement or move to next result row.
/// Documentation: https://sqlite.org/c3ref/step.html
///
/// USAGE:
/// ```
/// while(true){
/// try(bool has_result, i, tsqlite_statement_execNext(st));
/// if(!has_result)
/// break;
/// /* get result columns */
/// }
/// ```
/// @return is result row avaliable
Result(bool) tsqlite_statement_execNext(tsqlite_statement* self);
/// call this after executing a compiled statement to use it again
Result(void) tsqlite_statement_reset(tsqlite_statement* st);
/// Bind value to a placeholder
Result(void) tsqlite_statement_bind_null(tsqlite_statement* self, cstr key);
Result(void) tsqlite_statement_bind_i64(tsqlite_statement* self, cstr key, i64 v);
Result(void) tsqlite_statement_bind_f64(tsqlite_statement* self, cstr key, f64 v);
Result(void) tsqlite_statement_bind_str(tsqlite_statement* self, cstr key, str v, NULLABLE(Destructor_t) d);
Result(void) tsqlite_statement_bind_blob(tsqlite_statement* self, cstr key, Array(u8) v, NULLABLE(Destructor_t) d);
Result(void) tsqlite_statement_bind_zeroblob(tsqlite_statement* self, cstr key, i32 size);
/// Get value at `self->result_col`. Increases `self->result_col` on success.
Result(i64) tsqlite_statement_getResult_i64(tsqlite_statement* self);
Result(i64) tsqlite_statement_getResult_f64(tsqlite_statement* self);
Result(void) tsqlite_statement_getResult_str(tsqlite_statement* self, str* out_v);
Result(void) tsqlite_statement_getResult_blob(tsqlite_statement* self, Array(u8)* out_v);