/* dblayer.c - Database layer for ck -----------------------------------*- C -*- * * This file is part of ck, the config keeper * * ----------------------------------------------------------------------------- * * Copyright (C) 2018 Anastasis Grammenos * GPLv3 (see LICENCE for the full notice) * * ----------------------------------------------------------------------------- * * Give access to the database. * * -------------------------------------------------------------------------- */ #include #include #include #include "dblayer.h" #include "ckutil.h" const char * const DB_NAME = "/ckdb"; /* figure out the database name */ void make_db_name(char *ret, const char *confPath) { char db_path[200]; strcpy(db_path, confPath); strcat(db_path, DB_NAME); strcpy(ret, db_path); } /* Check if the db file exists*/ int db_exists(const UserOpt *opt) { char db_path[200]; make_db_name(db_path, opt->confDir); return util_is_file_rw(db_path); } /* check if db has the correct tables */ int check_initialized_DB(sqlite3 *db) { char *sql = "SELECT * FROM SQLITE_MASTER WHERE type='table';"; sqlite3_stmt *stmt; int rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL); int program_table_ok, config_table_ok, rel_table_ok = 0; while (sqlite3_step(stmt) != SQLITE_DONE) { const unsigned char *tmpbuf = sqlite3_column_text(stmt, 1); if (strcmp((char *)tmpbuf, "PROGRAM") == 0) { program_table_ok = 1; } if (strcmp((char *)tmpbuf, "CONFIG") == 0) { config_table_ok = 1; } if (strcmp((char *)tmpbuf, "REL") == 0) { rel_table_ok = 1; } } if (!program_table_ok || !config_table_ok || !rel_table_ok ) { return 1; } sqlite3_finalize(stmt); return 0; } DB empty_DB(SqlError err) { return (DB){ .ptr = NULL, .error = err }; } DB new_DB(sqlite3 *db) { return (DB){ .ptr = db, .error = SQL_NO_ERR }; } void close_DB(DB *db) { sqlite3_close(db->ptr); } DB init_make_DB(const UserOpt *opt) { sqlite3 *db; char db_path[200]; int rc; make_db_name(db_path, opt->confDir); rc = sqlite3_open(db_path, &db); if (rc != SQLITE_OK) { return empty_DB(SQL_ERR_NO_DB_FILE); } return new_DB(db); } DB open_DB(const UserOpt *opt) { sqlite3 *db; int rc; char db_path[200]; make_db_name(db_path, opt->confDir); rc = sqlite3_open(db_path, &db); if (rc) { return empty_DB(SQL_ERR_NO_DB_FILE); } if (check_initialized_DB(db)) { return empty_DB(SQL_ERR_NO_TABLES); } return new_DB(db); } void init_make_tables(DB *db) { char * sql = "CREATE TABLE REL(" "pId INT NOT NULL," "cId INT NOT NULL);" "CREATE TABLE PROGRAM(" "id INT NOT NULL PRIMARY KEY," "name TEXT NOT NULL);" "CREATE TABLE CONFIG(" "id INT NOT NULL PRIMARY KEY," "path TEXT NOT NULL," "secret INT NOT NULL," "prime INT NOT NULL);"; char *err_msg = NULL; int rc = sqlite3_exec(db->ptr, sql, 0, 0, &err_msg); if (rc != SQLITE_OK ) { printf("SQL error: %s\n", err_msg); sqlite3_free(err_msg); db->error = SQL_ERR_SQLITE; return; } } int get_next_valid_id_from_table(DB *db, const char* tableName) { sqlite3_stmt *stmt; int rc; char sql[100] = "SELECT id FROM "; strcat(sql, tableName); strcat(sql, " ORDER BY id;"); rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); if (rc != SQLITE_OK) { return -1; } sqlite3_bind_text(stmt, 1, tableName, strlen(tableName), 0); int id = 0; while (sqlite3_step(stmt) == SQLITE_ROW) { int a = sqlite3_column_int(stmt, 0); if (a != id) { break; } id++; } sqlite3_finalize(stmt); return id; } void insert_to_program_table(DB *db, const char *name) { sqlite3_stmt *stmt; int rc; char * sql = "INSERT INTO PROGRAM VALUES(?, ?);"; rc = sqlite3_prepare_v2(db->ptr, sql, -1, &stmt, 0); if (rc != SQLITE_OK) { printf("Error\n"); return; } int id = get_next_valid_id_from_table(db, "PROGRAM"); if (id == -1) { db->error = SQL_ERR_SQLITE; return; } sqlite3_bind_int(stmt, 1, id); sqlite3_bind_text(stmt, 2, name, strlen(name), 0); if (sqlite3_step(stmt) != SQLITE_DONE) { printf("Error\n"); return; } sqlite3_finalize(stmt); } int add_insert_program_to_db(DB *db, const char *name) { insert_to_program_table(db,name); return 0; }