2025-03-22 03:15:49 +01:00
# ifndef DB_UTILS_H
# define DB_UTILS_H
2025-03-28 06:55:22 +01:00
# include "r.h"
2025-03-22 03:15:49 +01:00
# include <sqlite3.h>
# include <json-c/json.h>
# include "utils.h"
2025-03-28 06:55:22 +01:00
2025-03-22 03:15:49 +01:00
2025-03-28 05:37:22 +01:00
json_object * db_execute ( const char * query ) ;
2025-03-22 03:15:49 +01:00
char * db_file_expanded ( ) {
2025-03-28 06:55:22 +01:00
char * expanded = expand_home_directory ( DB_FILE ) ;
2025-03-22 03:15:49 +01:00
static char result [ 4096 ] ;
result [ 0 ] = 0 ;
strcpy ( result , expanded ) ;
free ( expanded ) ;
return result ;
}
void db_initialize ( ) ;
json_object * db_set ( const char * key , const char * value ) ;
json_object * db_get ( const char * key ) ;
json_object * db_query ( const char * query ) ;
void db_initialize ( ) {
sqlite3 * db ;
char * err_msg = 0 ;
int rc = sqlite3_open ( db_file_expanded ( ) , & db ) ;
if ( rc ! = SQLITE_OK ) {
return ;
}
const char * sql = " CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value TEXT); " ;
rc = sqlite3_exec ( db , sql , 0 , 0 , & err_msg ) ;
if ( rc ! = SQLITE_OK ) {
sqlite3_free ( err_msg ) ;
}
sqlite3_close ( db ) ;
}
json_object * db_set ( const char * key , const char * value ) {
sqlite3 * db ;
char * err_msg = 0 ;
int rc = sqlite3_open ( db_file_expanded ( ) , & db ) ;
if ( rc ! = SQLITE_OK ) {
return NULL ;
}
2025-03-28 05:37:22 +01:00
char * sql = sqlite3_mprintf ( " INSERT INTO kv_store (key, value) VALUES (%Q, %Q) ON CONFLICT(key) DO UPDATE SET value = %Q WHERE key = %Q " , key , value , value , key ) ;
2025-03-22 03:15:49 +01:00
rc = sqlite3_exec ( db , sql , 0 , 0 , & err_msg ) ;
sqlite3_free ( sql ) ;
if ( rc ! = SQLITE_OK ) {
sqlite3_free ( err_msg ) ;
sqlite3_close ( db ) ;
return NULL ;
}
sqlite3_close ( db ) ;
return json_object_new_string ( " Success " ) ;
}
json_object * db_get ( const char * key ) {
sqlite3 * db ;
sqlite3_stmt * stmt ;
json_object * result = json_object_new_object ( ) ;
const char * value = NULL ;
int rc = sqlite3_open ( db_file_expanded ( ) , & db ) ;
if ( rc ! = SQLITE_OK ) {
return NULL ;
}
const char * sql = " SELECT value FROM kv_store WHERE key = ? " ;
sqlite3_prepare_v2 ( db , sql , - 1 , & stmt , NULL ) ;
sqlite3_bind_text ( stmt , 1 , key , - 1 , SQLITE_STATIC ) ;
if ( sqlite3_step ( stmt ) = = SQLITE_ROW ) {
value = ( const char * ) sqlite3_column_text ( stmt , 0 ) ;
}
if ( value ) {
json_object_object_add ( result , " value " , json_object_new_string ( value ) ) ;
} else {
json_object_object_add ( result , " error " , json_object_new_string ( " Key not found " ) ) ;
}
sqlite3_finalize ( stmt ) ;
sqlite3_close ( db ) ;
return result ;
}
json_object * db_query ( const char * query ) {
sqlite3 * db ;
sqlite3_stmt * stmt ;
2025-03-28 05:37:22 +01:00
if ( strncmp ( query , " SELECT " , 6 ) ) {
return db_execute ( query ) ;
}
2025-03-22 03:15:49 +01:00
json_object * result = json_object_new_array ( ) ;
int rc = sqlite3_open ( db_file_expanded ( ) , & db ) ;
if ( rc ! = SQLITE_OK ) {
return NULL ;
}
sqlite3_prepare_v2 ( db , query , - 1 , & stmt , NULL ) ;
while ( sqlite3_step ( stmt ) = = SQLITE_ROW ) {
json_object * row = json_object_new_object ( ) ;
for ( int i = 0 ; i < sqlite3_column_count ( stmt ) ; i + + ) {
const char * col_name = sqlite3_column_name ( stmt , i ) ;
switch ( sqlite3_column_type ( stmt , i ) ) {
case SQLITE_INTEGER :
json_object_object_add ( row , col_name , json_object_new_int64 ( sqlite3_column_int64 ( stmt , i ) ) ) ;
break ;
case SQLITE_FLOAT :
json_object_object_add ( row , col_name , json_object_new_double ( sqlite3_column_double ( stmt , i ) ) ) ;
break ;
case SQLITE_TEXT :
json_object_object_add ( row , col_name , json_object_new_string ( ( const char * ) sqlite3_column_text ( stmt , i ) ) ) ;
break ;
case SQLITE_BLOB :
json_object_object_add ( row , col_name , json_object_new_string_len ( ( const char * ) sqlite3_column_blob ( stmt , i ) , sqlite3_column_bytes ( stmt , i ) ) ) ;
break ;
case SQLITE_NULL :
default :
json_object_object_add ( row , col_name , json_object_new_string ( " NULL " ) ) ;
break ;
}
}
json_object_array_add ( result , row ) ;
}
sqlite3_finalize ( stmt ) ;
sqlite3_close ( db ) ;
return result ;
}
2025-03-28 05:37:22 +01:00
json_object * db_execute ( const char * query ) {
sqlite3 * db ;
char * err_msg = 0 ;
int rc = sqlite3_open ( db_file_expanded ( ) , & db ) ;
json_object * result = json_object_new_object ( ) ;
if ( rc ! = SQLITE_OK ) {
json_object_object_add ( result , " error " , json_object_new_string ( " Cannot open database " ) ) ;
return result ;
}
rc = sqlite3_exec ( db , query , 0 , 0 , & err_msg ) ;
if ( rc ! = SQLITE_OK ) {
json_object_object_add ( result , " error " , json_object_new_string ( err_msg ) ) ;
sqlite3_free ( err_msg ) ;
} else {
json_object_object_add ( result , " success " , json_object_new_string ( " Query executed successfully " ) ) ;
}
sqlite3_close ( db ) ;
return result ;
}
char * db_get_schema ( ) {
json_object * tables = db_query ( " SELECT * FROM sqlite_master WHERE type='table' " ) ;
char * result = strdup ( json_object_get_string ( tables ) ) ;
json_object_put ( tables ) ;
return result ;
}
# endif