Mercurial
view deita/d_sqlite.c @ 279:b3b547563ec7
Add Google connector service and agent wiki
Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 22:22:36 -0700 |
| parents | 1f9877b637e9 |
| children |
line wrap: on
line source
#include "deita_internal.h" #include <stdio.h> #include <stdlib.h> #include <string.h> Deita_Connection* deita__sqlite_connection_create(const char *connection_string) { Deita_Connection *p_connection = (Deita_Connection*)malloc(sizeof(Deita_Connection)); if (!p_connection) { fprintf(stderr, "deita__sqlite_connection_create: Failed to allocate connection\n"); return NULL; } p_connection->database_type = DEITA_DATABASE_TYPE_SQLITE3; p_connection->native_handle = NULL; p_connection->is_open = FALSE; sqlite3 *p_db = NULL; int32 result = sqlite3_open(connection_string, &p_db); if (result != SQLITE_OK) { fprintf(stderr, "deita__sqlite_connection_create: Failed to open database: %s\n", sqlite3_errmsg(p_db)); sqlite3_close(p_db); free(p_connection); return NULL; } result = sqlite3_busy_timeout(p_db, 5000); if (result != SQLITE_OK) { fprintf( stderr, "deita__sqlite_connection_create: Failed to set busy timeout: %s\n", sqlite3_errmsg(p_db)); sqlite3_close(p_db); free(p_connection); return NULL; } p_connection->native_handle = p_db; p_connection->is_open = TRUE; return p_connection; } void deita__sqlite_connection_close(Deita_Connection *p_connection) { if (!p_connection) return; if (p_connection->native_handle) { sqlite3 *p_db = (sqlite3*)p_connection->native_handle; sqlite3_close(p_db); p_connection->native_handle = NULL; } p_connection->is_open = FALSE; free(p_connection); } boolean deita__sqlite_connection_is_open(Deita_Connection *p_connection) { if (!p_connection) return FALSE; return p_connection->is_open; } Deita_Result_Set* deita__sqlite_query_execute( Deita_Connection *p_connection, const char *query, Dowa_Arena *p_arena) { if (!p_connection || !p_connection->native_handle || !query) return NULL; sqlite3 *p_db = (sqlite3*)p_connection->native_handle; sqlite3_stmt *p_stmt = NULL; int32 result = sqlite3_prepare_v2(p_db, query, -1, &p_stmt, NULL); if (result != SQLITE_OK) { fprintf(stderr, "deita__sqlite_query_execute: Failed to prepare statement: %s\n", sqlite3_errmsg(p_db)); return NULL; } Deita_Result_Set *p_result_set = (Deita_Result_Set*)Dowa_Arena_Allocate(p_arena, sizeof(Deita_Result_Set)); if (!p_result_set) { fprintf(stderr, "deita__sqlite_query_execute: Failed to allocate result set\n"); sqlite3_finalize(p_stmt); return NULL; } p_result_set->database_type = DEITA_DATABASE_TYPE_SQLITE3; p_result_set->native_result = p_stmt; p_result_set->column_count = sqlite3_column_count(p_stmt); p_result_set->has_data = FALSE; p_result_set->is_done = FALSE; p_result_set->has_error = FALSE; return p_result_set; } Deita_Result_Set* deita__sqlite_query_execute_prepared( Deita_Connection *p_connection, const char *query, int32 parameter_count, const char **parameter_values, Dowa_Arena *p_arena) { if (!p_connection || !p_connection->native_handle || !query) return NULL; sqlite3 *p_db = (sqlite3*)p_connection->native_handle; sqlite3_stmt *p_stmt = NULL; int32 result = sqlite3_prepare_v2(p_db, query, -1, &p_stmt, NULL); if (result != SQLITE_OK) { fprintf(stderr, "deita__sqlite_query_execute_prepared: Failed to prepare statement: %s\n", sqlite3_errmsg(p_db)); return NULL; } for (int32 i = 0; i < parameter_count; i++) { result = sqlite3_bind_text(p_stmt, i + 1, parameter_values[i], -1, SQLITE_TRANSIENT); if (result != SQLITE_OK) { fprintf(stderr, "deita__sqlite_query_execute_prepared: Failed to bind parameter %d: %s\n", i, sqlite3_errmsg(p_db)); sqlite3_finalize(p_stmt); return NULL; } } Deita_Result_Set *p_result_set = (Deita_Result_Set*)Dowa_Arena_Allocate(p_arena, sizeof(Deita_Result_Set)); if (!p_result_set) { fprintf(stderr, "deita__sqlite_query_execute_prepared: Failed to allocate result set\n"); sqlite3_finalize(p_stmt); return NULL; } p_result_set->database_type = DEITA_DATABASE_TYPE_SQLITE3; p_result_set->native_result = p_stmt; p_result_set->column_count = sqlite3_column_count(p_stmt); p_result_set->has_data = FALSE; p_result_set->is_done = FALSE; p_result_set->has_error = FALSE; return p_result_set; } int32 deita__sqlite_query_execute_update( Deita_Connection *p_connection, const char *query) { if (!p_connection || !p_connection->native_handle || !query) return -1; sqlite3 *p_db = (sqlite3*)p_connection->native_handle; char *error_message = NULL; int32 result = sqlite3_exec(p_db, query, NULL, NULL, &error_message); if (result != SQLITE_OK) { fprintf(stderr, "deita__sqlite_query_execute_update: Failed to execute: %s\n", error_message); sqlite3_free(error_message); return -1; } return sqlite3_changes(p_db); } int32 deita__sqlite_query_execute_update_prepared( Deita_Connection *p_connection, const char *query, int32 parameter_count, const char **parameter_values) { if (!p_connection || !p_connection->native_handle || !query) return -1; sqlite3 *p_db = (sqlite3*)p_connection->native_handle; sqlite3_stmt *p_stmt = NULL; int32 result = sqlite3_prepare_v2(p_db, query, -1, &p_stmt, NULL); if (result != SQLITE_OK) { fprintf(stderr, "deita__sqlite_query_execute_update_prepared: Failed to prepare statement: %s\n", sqlite3_errmsg(p_db)); return -1; } for (int32 i = 0; i < parameter_count; i++) { result = sqlite3_bind_text(p_stmt, i + 1, parameter_values[i], -1, SQLITE_TRANSIENT); if (result != SQLITE_OK) { fprintf(stderr, "deita__sqlite_query_execute_update_prepared: Failed to bind parameter %d: %s\n", i, sqlite3_errmsg(p_db)); sqlite3_finalize(p_stmt); return -1; } } result = sqlite3_step(p_stmt); if (result != SQLITE_DONE) { fprintf(stderr, "deita__sqlite_query_execute_update_prepared: Failed to execute: %s\n", sqlite3_errmsg(p_db)); sqlite3_finalize(p_stmt); return -1; } int32 changes = sqlite3_changes(p_db); sqlite3_finalize(p_stmt); return changes; } boolean deita__sqlite_result_set_next(Deita_Result_Set *p_result_set) { if (!p_result_set || !p_result_set->native_result || p_result_set->is_done) return FALSE; sqlite3_stmt *p_stmt = (sqlite3_stmt*)p_result_set->native_result; int32 result = sqlite3_step(p_stmt); if (result == SQLITE_ROW) { p_result_set->has_data = TRUE; return TRUE; } else if (result == SQLITE_DONE) { p_result_set->has_data = FALSE; p_result_set->is_done = TRUE; return FALSE; } else { fprintf(stderr, "deita__sqlite_result_set_next: Error stepping through results\n"); p_result_set->has_data = FALSE; p_result_set->is_done = TRUE; p_result_set->has_error = TRUE; return FALSE; } } int32 deita__sqlite_result_set_get_column_count(Deita_Result_Set *p_result_set) { if (!p_result_set) return 0; return p_result_set->column_count; } const char* deita__sqlite_result_set_get_column_name( Deita_Result_Set *p_result_set, int32 column_index) { if (!p_result_set || !p_result_set->native_result) return NULL; sqlite3_stmt *p_stmt = (sqlite3_stmt*)p_result_set->native_result; return sqlite3_column_name(p_stmt, column_index); } Deita_Column_Type deita__sqlite_result_set_get_column_type( Deita_Result_Set *p_result_set, int32 column_index) { if (!p_result_set || !p_result_set->native_result) return DEITA_COLUMN_TYPE_NULL; sqlite3_stmt *p_stmt = (sqlite3_stmt*)p_result_set->native_result; int32 sqlite_type = sqlite3_column_type(p_stmt, column_index); switch (sqlite_type) { case SQLITE_INTEGER: return DEITA_COLUMN_TYPE_INTEGER; case SQLITE_FLOAT: return DEITA_COLUMN_TYPE_REAL; case SQLITE_TEXT: return DEITA_COLUMN_TYPE_TEXT; case SQLITE_BLOB: return DEITA_COLUMN_TYPE_BLOB; case SQLITE_NULL: default: return DEITA_COLUMN_TYPE_NULL; } } const char* deita__sqlite_result_set_get_text( Deita_Result_Set *p_result_set, int32 column_index) { if (!p_result_set || !p_result_set->native_result) return NULL; sqlite3_stmt *p_stmt = (sqlite3_stmt*)p_result_set->native_result; const unsigned char *text = sqlite3_column_text(p_stmt, column_index); return (const char*)text; } int64 deita__sqlite_result_set_get_integer( Deita_Result_Set *p_result_set, int32 column_index) { if (!p_result_set || !p_result_set->native_result) return 0; sqlite3_stmt *p_stmt = (sqlite3_stmt*)p_result_set->native_result; return sqlite3_column_int64(p_stmt, column_index); } double deita__sqlite_result_set_get_real( Deita_Result_Set *p_result_set, int32 column_index) { if (!p_result_set || !p_result_set->native_result) return 0.0; sqlite3_stmt *p_stmt = (sqlite3_stmt*)p_result_set->native_result; return sqlite3_column_double(p_stmt, column_index); } void deita__sqlite_result_set_free(Deita_Result_Set *p_result_set) { if (!p_result_set) return; if (p_result_set->native_result) { sqlite3_stmt *p_stmt = (sqlite3_stmt*)p_result_set->native_result; sqlite3_finalize(p_stmt); p_result_set->native_result = NULL; } }