From 3a528c00c216fac23148e90226c6ed5ad363146a Mon Sep 17 00:00:00 2001 From: Timerix Date: Mon, 15 Dec 2025 14:10:51 +0500 Subject: [PATCH] simplified error message generation --- include/tsqlite.h | 14 ++-- src/errors.c | 164 ---------------------------------------------- src/statement.c | 4 +- src/tsqlite.c | 12 ++++ 4 files changed, 20 insertions(+), 174 deletions(-) delete mode 100644 src/errors.c diff --git a/include/tsqlite.h b/include/tsqlite.h index 12e25e2..b52907e 100644 --- a/include/tsqlite.h +++ b/include/tsqlite.h @@ -8,12 +8,16 @@ void tsqlite_deinit(); ErrorCodePage_declare(SQLITE); -#define RESULT_ERROR_SQLITE_CODE(CONN, SHORT_CODE) RESULT_ERROR_CODE(SQLITE, SHORT_CODE, tsqlite_error_toStr(CONN, SHORT_CODE), true) +/// @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(CONN, _rname(N));\ + return RESULT_ERROR_SQLITE_CODE(_rname(N), sqlite3_errmsg(CONN));\ }\ } while(0) @@ -29,12 +33,6 @@ 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); -/// @param conn a database connection with error code and error message -/// @return heap-allocated string -str tsqlite_error_toStr(tsqlite_connection* conn, i32 short_code); - -void tsqlite_resultCode_append(StringBuilder* sb, i32 short_code, i32 extended_code); -void tsqlite_resultCodeAndMsg_append(StringBuilder* sb, i32 short_code, i32 extended_code, str msg); typedef struct tsqlite_statement { tsqlite_connection* conn; diff --git a/src/errors.c b/src/errors.c deleted file mode 100644 index bf8c92b..0000000 --- a/src/errors.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "tsqlite.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(i32 code){ - switch(code & 0xff){ - default: return STR("!! ERROR: INVALID SQLITE_CODE !!"); - PRIMARY_CODE_X(PRIMARY_CODE_CASE) - } -} - -#define EXTENDED_CODE_IF(C) \ - if(C & extended_code_part) {\ - if(multiple_extended_codes){\ - StringBuilder_append_char(sb, ',');\ - StringBuilder_append_char(sb, ' ');\ - }\ - else multiple_extended_codes = true;\ - StringBuilder_append_str(sb, STR(#C));\ - }\ - -void tsqlite_resultCode_append(StringBuilder* sb, i32 short_code, i32 extended_code){ - i32 extended_code_part = extended_code ^ (extended_code & 0xff); - if(extended_code_part == 0){ - StringBuilder_append_str(sb, PrimaryCode_toStr(short_code)); - } - else { - bool multiple_extended_codes = false; - EXTENDED_CODE_X(EXTENDED_CODE_IF); - } -} - -; -void tsqlite_resultCodeAndMsg_append(StringBuilder* sb, i32 short_code, i32 extended_code, str msg){ - tsqlite_resultCode_append(sb, short_code, extended_code); - StringBuilder_append_char(sb, ':'); - StringBuilder_append_char(sb, ' '); - StringBuilder_append_str(sb, msg); -} - -str tsqlite_error_toStr(tsqlite_connection* conn, i32 short_code){ - i32 extended_code = sqlite3_extended_errcode(conn); - str msg = str_from_cstr(sqlite3_errmsg(conn)); - StringBuilder sb = StringBuilder_alloc(64 + msg.len); - tsqlite_resultCodeAndMsg_append(&sb, short_code, extended_code, msg); - return StringBuilder_getStr(&sb); -} diff --git a/src/statement.c b/src/statement.c index f64d53a..62e7f5d 100644 --- a/src/statement.c +++ b/src/statement.c @@ -91,13 +91,13 @@ Result(bool) tsqlite_statement_execNext(tsqlite_statement* self){ return RESULT_VALUE(i, false); } - return RESULT_ERROR_SQLITE_CODE(self->conn, r); + return RESULT_ERROR_SQLITE_CODE(r, sqlite3_errmsg(self->conn)); } #define validate_column()\ i32 errcode = sqlite3_errcode(self->conn);\ if(errcode != SQLITE_OK && errcode != SQLITE_ROW){\ - return RESULT_ERROR_SQLITE_CODE(self->conn, errcode);\ + return RESULT_ERROR_SQLITE_CODE(errcode, sqlite3_errmsg(self->conn));\ } Result(i64) tsqlite_statement_getResult_i64(tsqlite_statement* self){ diff --git a/src/tsqlite.c b/src/tsqlite.c index 44d85c6..0856aee 100644 --- a/src/tsqlite.c +++ b/src/tsqlite.c @@ -13,3 +13,15 @@ Result(void) tsqlite_init(){ void tsqlite_deinit(){ } + +str tsqlite_error_toStr(i32 code, cstr msg_cstr){ + str msg = str_from_cstr(msg_cstr); + StringBuilder sb = StringBuilder_alloc(64 + msg.len); + + StringBuilder_append_cstr(&sb, sqlite3_errstr(code)); + StringBuilder_append_char(&sb, ':'); + StringBuilder_append_char(&sb, ' '); + StringBuilder_append_str(&sb, msg); + + return StringBuilder_getStr(&sb); +}