// SPDX-License-Identifier: GPL-3.0-or-later
#include <sqlite3.h>
#include "sqlite_functions.h"
struct dimension_list *global_dimensions = NULL;
sqlite3 *db = NULL;
sqlite3 *dbmem = NULL;
static void _uuid_parse(sqlite3_context *context, int argc, sqlite3_value **argv)
{
uuid_t uuid;
if (argc != 1) {
sqlite3_result_null(context);
return;
}
int rc = uuid_parse((const char *) sqlite3_value_text(argv[0]), uuid);
if (rc == -1) {
sqlite3_result_null(context);
return;
}
sqlite3_result_blob(context, &uuid, sizeof(uuid_t), SQLITE_TRANSIENT);
}
static void _uuid_unparse(sqlite3_context *context, int argc, sqlite3_value **argv)
{
char uuid_str[37];
if (argc != 1 || sqlite3_value_blob(argv[0]) == NULL) {
sqlite3_result_null(context);
return;
}
uuid_unparse_lower(sqlite3_value_blob(argv[0]), uuid_str);
sqlite3_result_text(context, uuid_str, 36, SQLITE_TRANSIENT);
}
int dim_callback(void *dim_ptr, int argc, char **argv, char **azColName)
{
UNUSED(azColName);
struct dimension *dimension_result = mallocz(sizeof(struct dimension));
for (int i = 0; i < argc; i++) {
if (i == 0) {
uuid_parse(argv[i], ((DIMENSION *)dimension_result)->dim_uuid);
strcpy(((DIMENSION *)dimension_result)->dim_str, argv[i]);
}
if (i == 1)
((DIMENSION *)dimension_result)->id = strdupz(argv[i]);
if (i == 2)
((DIMENSION *)dimension_result)->name = strdupz(argv[i]);
}
//info("[%s] [%s] [%s]", ((DIMENSION *)dimension_result)->dim_str, ((DIMENSION *)dimension_result)->id,
// ((DIMENSION *)dimension_result)->name);
struct dimension **dimension_root = (void *)dim_ptr;
dimension_result->next = *dimension_root;
*dimension_root = dimension_result;
return 0;
}
/*
* Initialize a database
*/
int sql_init_database()
{
char *err_msg = NULL;
int rc = sqlite3_open("/tmp/database", &db);
info("SQLite Database initialized (rc = %d)", rc);
char *sql = "PRAGMA synchronous=1 ; PRAGMA journal_mode=WAL; CREATE TABLE IF NOT EXISTS dimension(dim_uuid blob PRIMARY KEY, chart_uuid blob, id text, name text, multiplier int, divisor int , algorithm int, archived int, options text);";
rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error("SQL error: %s", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
}
rc = sqlite3_exec(db, "create index if not exists ind_chart_uuid on dimension (chart_uuid);", 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error("SQL error: %s", err_msg);
sqlite3_free(err_msg);
}
rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS datafile (fileno integer primary key, path text, file_size int); delete from datafile;", 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error("SQL error: %s", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
}
rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS page (dim_uuid blob, page int , page_size int, start_date int, end_date int, fileno int, offset int, size int); delete from page;", 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error("SQL error: %s", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
}
rc = sqlite3_exec(db, "create unique index if not exists ind_page on page (dim_uuid, start_date);", 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error("SQL error: %s", err_msg);
sqlite3_free(err_msg);
}
// EXAMPLE -- Creating RAM database and attaching
// rc = sqlite3_exec(db, "ATTACH ':memory:' as ram;", 0, 0, &err_msg);
// if (rc != SQLITE_OK) {
// error("SQL error: %s", err_msg);
// sqlite3_free(err_msg);
// }
//
// rc = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS ram.chart_dim(chart_uuid blob, dim_uuid blob, id text, name text); create index ram.ind_dim_uuid on chart_dim (dim_uuid); create index if not exists ram.ind_chart_uuid on chart