|
#ifndef DB_UTILS_H
|
|
#define DB_UTILS_H
|
|
|
|
#include "r.h"
|
|
#include "utils.h"
|
|
#include <json-c/json.h>
|
|
#include <sqlite3.h>
|
|
|
|
json_object *db_execute(const char *query);
|
|
|
|
char *db_file_expanded() {
|
|
char *expanded = expand_home_directory(DB_FILE);
|
|
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;
|
|
int rc = sqlite3_open(db_file_expanded(), &db);
|
|
|
|
if (rc != SQLITE_OK) {
|
|
return;
|
|
}
|
|
|
|
db_execute("CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value TEXT);");
|
|
db_execute("CREATE TABLE IF NOT EXISTS file_version_history ( id INTEGER PRIMARY KEY AUTOINCREMENT,"
|
|
"path TEXT NOT NULL,"
|
|
"content TEXT,"
|
|
"date DATETIME DEFAULT CURRENT_TIMESTAMP"
|
|
");");
|
|
|
|
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;
|
|
}
|
|
|
|
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);
|
|
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;
|
|
|
|
if (strncmp(query, "SELECT", 6)) {
|
|
return db_execute(query);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
void db_store_file_version(const char * path) {
|
|
char * expanded = expand_home_directory(path);
|
|
|
|
char * content = read_file(expanded);
|
|
if(!content) {
|
|
return;
|
|
}
|
|
fprintf(stderr, "Creating backup:: %s\n", expanded);
|
|
char * formatted = sqlite3_mprintf("INSERT INTO file_version_history (path, content) VALUES (%Q, %Q)", expanded, content);
|
|
db_execute(formatted);
|
|
sqlite3_free(formatted);
|
|
free(content);
|
|
}
|
|
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
|