initial commit

This commit is contained in:
2025-12-13 03:35:34 +05:00
commit 16d44cf730
15 changed files with 766 additions and 0 deletions

16
src/connection.c Normal file
View File

@@ -0,0 +1,16 @@
#include "tsqlite.h"
Result(tsqlite_connection*) tsqlite_connection_open(cstr file_path,
NULLABLE(void*) logger, NULLABLE(sqlite3_error_log_func_t) log_func)
{
tsqlite_connection* conn = NULL;
try_sqlite3(sqlite3_open(file_path, &conn));
try_sqlite3(sqlite3_db_config(conn, SQLITE_CONFIG_LOG, log_func, logger));
try_sqlite3(sqlite3_extended_result_codes(conn, true));
return RESULT_VALUE(p, conn);
}
Result(void) tsqlite_connection_close(tsqlite_connection* conn){
try_sqlite3(sqlite3_close(conn));
return RESULT_VOID;
}

151
src/errors.c Normal file
View File

@@ -0,0 +1,151 @@
#include "tsqlite.h"
#include "tlibc/string/StringBuilder.h"
#define PRIMARY_CODE_X(X)\
X(SQLITE_OK)\
X(SQLITE_ERROR)\
X(SQLITE_INTERNAL)\
X(SQLITE_PERM)\
X(SQLITE_ABORT)\
X(SQLITE_BUSY)\
X(SQLITE_LOCKED)\
X(SQLITE_NOMEM)\
X(SQLITE_READONLY)\
X(SQLITE_INTERRUPT)\
X(SQLITE_IOERR)\
X(SQLITE_CORRUPT)\
X(SQLITE_NOTFOUND)\
X(SQLITE_FULL)\
X(SQLITE_CANTOPEN)\
X(SQLITE_PROTOCOL)\
X(SQLITE_EMPTY)\
X(SQLITE_SCHEMA)\
X(SQLITE_TOOBIG)\
X(SQLITE_CONSTRAINT)\
X(SQLITE_MISMATCH)\
X(SQLITE_MISUSE)\
X(SQLITE_NOLFS)\
X(SQLITE_AUTH)\
X(SQLITE_FORMAT)\
X(SQLITE_RANGE)\
X(SQLITE_NOTADB)\
X(SQLITE_NOTICE)\
X(SQLITE_WARNING)\
X(SQLITE_ROW)\
X(SQLITE_DONE)\
#define EXTENDED_CODE_X(X)\
X(SQLITE_ERROR_MISSING_COLLSEQ)\
X(SQLITE_ERROR_RETRY)\
X(SQLITE_ERROR_SNAPSHOT)\
X(SQLITE_ERROR_RESERVESIZE)\
X(SQLITE_ERROR_KEY)\
X(SQLITE_ERROR_UNABLE)\
X(SQLITE_IOERR_READ)\
X(SQLITE_IOERR_SHORT_READ)\
X(SQLITE_IOERR_WRITE)\
X(SQLITE_IOERR_FSYNC)\
X(SQLITE_IOERR_DIR_FSYNC)\
X(SQLITE_IOERR_TRUNCATE)\
X(SQLITE_IOERR_FSTAT)\
X(SQLITE_IOERR_UNLOCK)\
X(SQLITE_IOERR_RDLOCK)\
X(SQLITE_IOERR_DELETE)\
X(SQLITE_IOERR_BLOCKED)\
X(SQLITE_IOERR_NOMEM)\
X(SQLITE_IOERR_ACCESS)\
X(SQLITE_IOERR_CHECKRESERVEDLOCK)\
X(SQLITE_IOERR_LOCK)\
X(SQLITE_IOERR_CLOSE)\
X(SQLITE_IOERR_DIR_CLOSE)\
X(SQLITE_IOERR_SHMOPEN)\
X(SQLITE_IOERR_SHMSIZE)\
X(SQLITE_IOERR_SHMLOCK)\
X(SQLITE_IOERR_SHMMAP)\
X(SQLITE_IOERR_SEEK)\
X(SQLITE_IOERR_DELETE_NOENT)\
X(SQLITE_IOERR_MMAP)\
X(SQLITE_IOERR_GETTEMPPATH)\
X(SQLITE_IOERR_CONVPATH)\
X(SQLITE_IOERR_VNODE)\
X(SQLITE_IOERR_AUTH)\
X(SQLITE_IOERR_BEGIN_ATOMIC)\
X(SQLITE_IOERR_COMMIT_ATOMIC)\
X(SQLITE_IOERR_ROLLBACK_ATOMIC)\
X(SQLITE_IOERR_DATA)\
X(SQLITE_IOERR_CORRUPTFS)\
X(SQLITE_IOERR_IN_PAGE)\
X(SQLITE_IOERR_BADKEY)\
X(SQLITE_IOERR_CODEC)\
X(SQLITE_LOCKED_SHAREDCACHE)\
X(SQLITE_LOCKED_VTAB)\
X(SQLITE_BUSY_RECOVERY)\
X(SQLITE_BUSY_SNAPSHOT)\
X(SQLITE_BUSY_TIMEOUT)\
X(SQLITE_CANTOPEN_NOTEMPDIR)\
X(SQLITE_CANTOPEN_ISDIR)\
X(SQLITE_CANTOPEN_FULLPATH)\
X(SQLITE_CANTOPEN_CONVPATH)\
X(SQLITE_CANTOPEN_DIRTYWAL)\
X(SQLITE_CANTOPEN_SYMLINK)\
X(SQLITE_CORRUPT_VTAB)\
X(SQLITE_CORRUPT_SEQUENCE)\
X(SQLITE_CORRUPT_INDEX)\
X(SQLITE_READONLY_RECOVERY)\
X(SQLITE_READONLY_CANTLOCK)\
X(SQLITE_READONLY_ROLLBACK)\
X(SQLITE_READONLY_DBMOVED)\
X(SQLITE_READONLY_CANTINIT)\
X(SQLITE_READONLY_DIRECTORY)\
X(SQLITE_ABORT_ROLLBACK)\
X(SQLITE_CONSTRAINT_CHECK)\
X(SQLITE_CONSTRAINT_COMMITHOOK)\
X(SQLITE_CONSTRAINT_FOREIGNKEY)\
X(SQLITE_CONSTRAINT_FUNCTION)\
X(SQLITE_CONSTRAINT_NOTNULL)\
X(SQLITE_CONSTRAINT_PRIMARYKEY)\
X(SQLITE_CONSTRAINT_TRIGGER)\
X(SQLITE_CONSTRAINT_UNIQUE)\
X(SQLITE_CONSTRAINT_VTAB)\
X(SQLITE_CONSTRAINT_ROWID)\
X(SQLITE_CONSTRAINT_PINNED)\
X(SQLITE_CONSTRAINT_DATATYPE)\
X(SQLITE_NOTICE_RECOVER_WAL)\
X(SQLITE_NOTICE_RECOVER_ROLLBACK)\
X(SQLITE_NOTICE_RBU)\
X(SQLITE_WARNING_AUTOINDEX)\
X(SQLITE_AUTH_USER)\
X(SQLITE_OK_LOAD_PERMANENTLY)\
X(SQLITE_OK_SYMLINK)\
#define PRIMARY_CODE_CASE(C) case C: return STR(#C);
static str PrimaryCode_toStr(int code){
switch(code & 0xff){
default: return STR("!! ERROR: INVALID SQLITE_CODE !!");
PRIMARY_CODE_X(PRIMARY_CODE_CASE)
}
}
#define EXTENDED_CODE_IF(C) \
if(C & code) {\
if(multiple_extended_codes){\
StringBuilder_append_char(&sb, ',');\
StringBuilder_append_char(&sb, ' ');\
}\
else multiple_extended_codes = true;\
StringBuilder_append_str(&sb, STR(#C));\
}\
str tsqlite_ResultCode_toStr(int code){
StringBuilder sb = StringBuilder_alloc(128);
bool multiple_extended_codes = false;
StringBuilder_append_str(&sb, PrimaryCode_toStr(code));
StringBuilder_append_char(&sb, ':');
StringBuilder_append_char(&sb, ' ');
EXTENDED_CODE_X(EXTENDED_CODE_IF);
return StringBuilder_getStr(&sb);
}

109
src/statement.c Normal file
View File

@@ -0,0 +1,109 @@
#include "tsqlite.h"
Result(tsqlite_statement*) tsqlite_statement_prepare(sqlite3* conn, str sql_code){
sqlite3_stmt* st = NULL;
i32 flags = SQLITE_PREPARE_PERSISTENT;
try_sqlite3(sqlite3_prepare_v3(conn, sql_code.data, sql_code.len, flags, &st, NULL));
tsqlite_statement* self = malloc(sizeof(*self));
zeroStruct(self);
self->st = st;
return RESULT_VALUE(p, self);
}
void tsqlite_statement_free(tsqlite_statement* self){
if(!self)
return;
sqlite3_finalize(self->st);
free(self);
}
Result(void) tsqlite_statement_reset(tsqlite_statement* self){
try_sqlite3(sqlite3_reset(self->st));
self->bind_arg_pos = 0;
self->result_row = 0;
self->result_col = 0;
return RESULT_VOID;
}
Result(void) tsqlite_statement_bind_null(tsqlite_statement* self){
try_sqlite3(sqlite3_bind_null(self->st, self->bind_arg_pos));
self->bind_arg_pos++;
return RESULT_VOID;
}
Result(void) tsqlite_statement_bind_i32(tsqlite_statement* self, i32 v){
try_sqlite3(sqlite3_bind_int(self->st, self->bind_arg_pos, v));
self->bind_arg_pos++;
return RESULT_VOID;
}
Result(void) tsqlite_statement_bind_i64(tsqlite_statement* self, i64 v){
try_sqlite3(sqlite3_bind_int64(self->st, self->bind_arg_pos, v));
self->bind_arg_pos++;
return RESULT_VOID;
}
Result(void) tsqlite_statement_bind_f64(tsqlite_statement* self, f64 v){
try_sqlite3(sqlite3_bind_double(self->st, self->bind_arg_pos, v));
self->bind_arg_pos++;
return RESULT_VOID;
}
Result(void) tsqlite_statement_bind_str(tsqlite_statement* self, str v, NULLABLE(Destructor_t) d){
try_sqlite3(sqlite3_bind_text(self->st, self->bind_arg_pos, v.data, v.len, d));
self->bind_arg_pos++;
return RESULT_VOID;
}
Result(void) tsqlite_statement_bind_blob(tsqlite_statement* self, Array(u8) v, NULLABLE(Destructor_t) d){
try_sqlite3(sqlite3_bind_blob(self->st, self->bind_arg_pos, v.data, v.len, d));
self->bind_arg_pos++;
return RESULT_VOID;
}
Result(void) tsqlite_statement_bind_zeroblob(tsqlite_statement* self, i32 size){
try_sqlite3(sqlite3_bind_zeroblob(self->st, self->bind_arg_pos, size));
self->bind_arg_pos++;
return RESULT_VOID;
}
Result(bool) sqlite3_statement_moveNext(tsqlite_statement* self){
int r = sqlite3_step(self->st);
if(r == SQLITE_ROW){
return RESULT_VALUE(i, true);
}
if(r == SQLITE_DONE){
return RESULT_VALUE(i, false);
}
return RESULT_ERROR_SQLITE_CODE(r);
}
Result(i64) tsqlite_statement_getResult_i64(tsqlite_statement* self){
i64 r = sqlite3_column_int64(self->st, self->result_col);
// TODO: error checking in sqlite3_column
self->result_col++;
return RESULT_VALUE(i, r);
}
Result(i64) tsqlite_statement_getResult_f64(tsqlite_statement* self){
f64 r = sqlite3_column_double(self->st, self->result_col);
// TODO: error checking in sqlite3_column
self->result_col++;
return RESULT_VALUE(f, r);
}
Result(void) tsqlite_statement_getResult_str(tsqlite_statement* self, str* out_v){
(void)self;
(void)out_v;
// TODO: tsqlite_statement_getResult_str
return RESULT_VOID;
}
Result(void) tsqlite_statement_getResult_blob(tsqlite_statement* self, Array(u8)* out_v){
(void)self;
(void)out_v;
// TODO: tsqlite_statement_getResult_blob
return RESULT_VOID;
}

15
src/tsqlite.c Normal file
View File

@@ -0,0 +1,15 @@
#include "tsqlite.h"
ErrorCodePage_define(SQLITE);
Result(void) tsqlite_init(){
Deferral(4);
ErrorCodePage_register(SQLITE);
Return RESULT_VOID;
}
void tsqlite_deinit(){
}