/* * db.c * * Created on: 13 июл. 2022 г. * Author: alexander */ #include "sqlite3.h" //#include #include #include #include #include "db.h" #include "node_settings.h" char* getPathDB(char *path) { static char *current = NULL; if (path && !current) { current = path; } return current; } static sqlite3* dbGetBase(char *path) { sqlite3 *db = NULL; if (sqlite3_open(path, &db) != SQLITE_OK) { fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return NULL; } return db; } /* * 0 - parameter * 1 - key * 2 - set_key * 3 - single * 4 - value * 5 - current (data) * 6 - set_val * 7 - dependence * 8 - conflict */ static int dbLoad(void *NotUsed, int argc, char **argv, char **azColName) { if (!getParameter(atoi(argv[0]))) { addParameterKey(atoi(argv[0]), argv[1], atoi(argv[2]), atoi(argv[3]), (argv[7] ? getParameter(atoi(argv[7])) : NULL), (argv[8] ? getParameter(atoi(argv[8])) : NULL)); } if (argv[4] && argv[5]) { addParameterValue(atoi(argv[0]), atoi(argv[4]), argv[5], atoi(argv[6])); } return 0; } bool dbLoadData() { sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return false; } char *err_msg = 0; char *sql = "SELECT `parameters`.`id` as `parameter`, `parameters`.`data` as `key`, `parameters`.`set` as `set_key`, `parameters`.`single` as `single`, `values`.`id` as `value`, `values`.`data` as `current`, `values`.`set` as `set_val`,`dependencies`.`dependence` as `dependence`, `conflicts`.`conflict` as `conflict` \ FROM `parameters` as `parameters` \ LEFT JOIN `arguments` as `arguments` ON `parameters`.`id` = `arguments`.`parameter` \ LEFT JOIN `values` as `values` ON `arguments`.`value` = `values`.`id` \ LEFT JOIN `dependencies` as `dependencies` ON `dependencies`.`parameter` = `parameters`.`id` \ LEFT JOIN `conflicts` as `conflicts` ON `conflicts`.`parameter` = `parameters`.`id`"; if (sqlite3_exec(db, sql, dbLoad, 0, &err_msg) != SQLITE_OK) { fprintf(stderr, "Ошибка выполнения запроса: %s\n", err_msg); sqlite3_free(err_msg); sqlite3_close(db); return false; } sqlite3_close(db); return true; } static int dbCreateHostsList(void *answer, int argc, char **argv, char **azColName) { Hosts *hosts = *(Hosts**) answer; Host *host = (Host*) malloc(sizeof(Host)); host->data = (char**) malloc(sizeof(char*) * argc); host->size = argc; for (int i = 0; i < argc; i++) { size_t size = strlen(argv[i]) + 1; host->data[i] = (char*) malloc(sizeof(char) * size); strncpy(host->data[i], argv[i], size); } Host **tmp = hosts->host; hosts->host = (Host**) malloc(sizeof(Host*) * ++hosts->size); for (size_t i = 0; i < hosts->size - 1; ++i) { hosts->host[i] = tmp[i]; } if (tmp) { free(tmp); } hosts->host[hosts->size - 1] = host; return 0; } Hosts* dbGetHostsList() { sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return false; } char *err_msg = 0; char *sql = "SELECT ROW_NUMBER () OVER (ORDER BY `hosts`.`ip`) `item`, `hosts`.`dns` as `dns`, `hosts`.`set` as `set` FROM `hosts` as `hosts`"; Hosts *hosts = (Hosts*) malloc(sizeof(Hosts)); hosts->size = 0; hosts->host = NULL; if (sqlite3_exec(db, sql, dbCreateHostsList, &hosts, &err_msg) != SQLITE_OK) { fprintf(stderr, "Ошибка выполнения запроса: %s\n", err_msg); sqlite3_free(err_msg); sqlite3_close(db); exit(-1); } sqlite3_close(db); return hosts; } void dbFreeHosts(Hosts *hosts) { for (size_t i = 0; i < hosts->size; ++i) { for (size_t j = 0; j < hosts->host[i]->size; ++j) { free(hosts->host[i]->data[j]); } free(hosts->host[i]->data); free(hosts->host[i]); } free(hosts); } bool dbWriteParameter(Parameter name, bool set) { sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return false; } sqlite3_stmt *res; char *sql = "UPDATE `parameters` set `set` = ? where id = ?"; if (sqlite3_prepare_v2(db, sql, -1, &res, 0) == SQLITE_OK) { sqlite3_bind_int(res, 1, set); sqlite3_bind_int(res, 2, name); } if (sqlite3_step(res) == SQLITE_BUSY) { fprintf(stderr, "[ЗАНЯТО] %s - \"%s\"\n", set ? "включено" : "выключено", getParameter(name)->key); } if (sqlite3_step(res) == SQLITE_ERROR) { fprintf(stderr, "[ОШИБКА] %s - \"%s\"\n", set ? "включено" : "выключено", getParameter(name)->key); } if (sqlite3_step(res) == SQLITE_DONE) { fprintf(stdout, "[УСПЕШНО] %s - \"%s\"\n", set ? "включено" : "выключено", getParameter(name)->key); } sqlite3_finalize(res); sqlite3_close(db); return true; } bool dbWriteValue(Value name, bool set) { sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return false; } sqlite3_stmt *res; char *sql = "UPDATE `values` set `set` = ? where id = ?"; if (sqlite3_prepare_v2(db, sql, -1, &res, 0) == SQLITE_OK) { sqlite3_bind_int(res, 1, set); sqlite3_bind_int(res, 2, name); } if (sqlite3_step(res) == SQLITE_BUSY) { fprintf(stderr, "[ЗАНЯТО] %s - \"%s\"\n", set ? "включено" : "выключено", getValue(name)->current); } if (sqlite3_step(res) == SQLITE_ERROR) { fprintf(stderr, "[ОШИБКА] %s - \"%s\"\n", set ? "включено" : "выключено", getValue(name)->current); } if (sqlite3_step(res) == SQLITE_DONE) { fprintf(stdout, "[УСПЕШНО] %s - \"%s\"\n", set ? "включено" : "выключено", getValue(name)->current); } sqlite3_finalize(res); sqlite3_close(db); return true; } int dbAddServer(char *ip, char *dns) { int result = 0; if (!(ip && strlen(ip) && dns && strlen(dns))) return -1; sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return -2; } sqlite3_stmt *res; char *sql = "SELECT * FROM `hosts` WHERE `ip` = ? OR `dns` = ?"; if (sqlite3_prepare_v2(db, sql, -1, &res, 0) == SQLITE_OK) { sqlite3_bind_text(res, 1, ip, -1, 0); sqlite3_bind_text(res, 2, dns, -1, 0); } else { sqlite3_finalize(res); sqlite3_close(db); return -3; } if (sqlite3_step(res) == SQLITE_ROW) { int id = atoi((const char*) sqlite3_column_text(res, 0)); sqlite3_finalize(res); sql = "UPDATE `hosts` set `set` = 0"; if (sqlite3_exec(db, sql, NULL, NULL, NULL) == SQLITE_OK) { sql = "UPDATE `hosts` set `dns` = ?, `ip` = ?, `set` = 1 where id = ?"; if (sqlite3_prepare_v2(db, sql, -1, &res, 0) == SQLITE_OK) { sqlite3_bind_text(res, 1, dns, -1, 0); sqlite3_bind_text(res, 2, ip, -1, 0); sqlite3_bind_int(res, 3, id); } if (sqlite3_step(res) == SQLITE_BUSY) { fprintf(stderr, "[ЗАНЯТО] %s - \"%s\"\n", dns ? "установлено" : "очищено", ip); result = 5; } if (sqlite3_step(res) == SQLITE_ERROR) { fprintf(stderr, "[ОШИБКА] %s - \"%s\"\n", dns ? "установлено" : "очищено", ip); result = 4; } if (sqlite3_step(res) == SQLITE_DONE) { fprintf(stdout, "[УСПЕШНО] %s - \"%s\"\n", dns ? "установлено" : "очищено", ip); result = 3; } } else { result = -5; } } else if (sqlite3_step(res) == SQLITE_DONE) { sqlite3_finalize(res); sql = "UPDATE `hosts` set `set` = 0"; if (sqlite3_exec(db, sql, NULL, NULL, NULL) == SQLITE_OK) { sql = "INSERT INTO `hosts` (`ip`, `dns`, `set`) VALUES (?, ?, 1)"; if (sqlite3_prepare_v2(db, sql, -1, &res, 0) == SQLITE_OK) { sqlite3_bind_text(res, 1, ip, -1, 0); sqlite3_bind_text(res, 2, dns, -1, 0); } if (sqlite3_step(res) == SQLITE_BUSY) { fprintf(stderr, "[ЗАНЯТО] %s - \"%s\"\n", dns ? "установлено" : "очищено", ip); result = 2; } if (sqlite3_step(res) == SQLITE_ERROR) { fprintf(stderr, "[ОШИБКА] %s - \"%s\"\n", dns ? "установлено" : "очищено", ip); result = 1; } if (sqlite3_step(res) == SQLITE_DONE) { fprintf(stdout, "[УСПЕШНО] %s - \"%s\"\n", dns ? "установлено" : "очищено", ip); result = 0; } } else { result = -6; } } else { result = -4; } sqlite3_finalize(res); sqlite3_close(db); return result; } bool dbSetUserNameCurrent(char *current) { sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return false; } char *text = strlen(current) ? current : NULL; sqlite3_stmt *res; char *sql = "UPDATE `values` set `data` = ?, `set` = ? where id = ?"; if (sqlite3_prepare_v2(db, sql, -1, &res, 0) == SQLITE_OK) { sqlite3_bind_text(res, 1, text, -1, 0); sqlite3_bind_int(res, 2, text ? true : false); sqlite3_bind_int(res, 3, VALUE_USERNAME); } if (sqlite3_step(res) == SQLITE_BUSY) { fprintf(stderr, "[ЗАНЯТО] %s - \"%s\"\n", text ? "установлено" : "очищено", text ? getValue(VALUE_USERNAME)->current : ""); } if (sqlite3_step(res) == SQLITE_ERROR) { fprintf(stderr, "[ОШИБКА] %s - \"%s\"\n", text ? "установлено" : "очищено", text ? getValue(VALUE_USERNAME)->current : ""); } if (sqlite3_step(res) == SQLITE_DONE) { fprintf(stdout, "[УСПЕШНО] %s - \"%s\"\n", text ? "установлено" : "очищено", text ? getValue(VALUE_USERNAME)->current : ""); } sqlite3_finalize(res); sqlite3_close(db); return true; } static int dbCreateMonitorsList(void *answer, int argc, char **argv, char **azColName) { Monitors *monitors = *(Monitors**) answer; Monitor *monitor = (Monitor*) malloc(sizeof(Monitor)); monitor->data = (char**) malloc(sizeof(char*) * argc); monitor->size = argc; for (int i = 0; i < argc; i++) { size_t size = strlen(argv[i]) + 1; monitor->data[i] = (char*) malloc(sizeof(char) * size); strncpy(monitor->data[i], argv[i], size); } Monitor **tmp = monitors->monitor; monitors->monitor = (Monitor**) malloc(sizeof(Monitor*) * ++monitors->size); for (size_t i = 0; i < monitors->size - 1; ++i) { monitors->monitor[i] = tmp[i]; } if (tmp) { free(tmp); } monitors->monitor[monitors->size - 1] = monitor; return 0; } Monitors* dbGetMonitorsList() { sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { exit(-1); } char *err_msg = 0; char *sql = "SELECT ROW_NUMBER () OVER (ORDER BY `monitors`.`set` DESC) `item`, `monitors`.`name` as `name`, `monitors`.`set` as `set`, (ROW_NUMBER () OVER (ORDER BY `monitors`.`id`)) - 1 `item` FROM `monitors` as `monitors`"; Monitors *monitors = (Monitors*) malloc(sizeof(Monitors)); monitors->size = 0; monitors->monitor = NULL; if (sqlite3_exec(db, sql, dbCreateMonitorsList, &monitors, &err_msg) != SQLITE_OK) { fprintf(stderr, "Получение списка мониторов. Ошибка выполнения запроса: %s\n", err_msg); sqlite3_free(err_msg); sqlite3_close(db); exit(-2); } sqlite3_close(db); return monitors; } void dbFreeMonitors(Monitors *monitors) { for (size_t i = 0; i < monitors->size; ++i) { for (size_t j = 0; j < monitors->monitor[i]->size; ++j) { free(monitors->monitor[i]->data[j]); } free(monitors->monitor[i]->data); free(monitors->monitor[i]); } free(monitors); } bool deleteAllMonitors() { sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return false; } bool result = false; char *sql = "DELETE FROM `monitors`"; if (sqlite3_exec(db, sql, NULL, NULL, NULL) == SQLITE_OK) { result = true; } sqlite3_close(db); return result; } int dbAddMonitor(char *monitor, bool set) { if (!(monitor && strlen(monitor))) return -1; sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return -2; } sqlite3_stmt *res; char *sql = "INSERT INTO `monitors` (`name`, `set`) VALUES (?, ?)"; if (sqlite3_prepare_v2(db, sql, -1, &res, 0) == SQLITE_OK) { sqlite3_bind_text(res, 1, monitor, -1, 0); sqlite3_bind_int(res, 2, set); } // if (sqlite3_step(res) == SQLITE_BUSY) // { // fprintf(stderr, "[ЗАНЯТО] %s - \"%s\"\n", text ? "установлено" : "очищено", text ? getValue(VALUE_USERNAME)->current : ""); // } // if (sqlite3_step(res) == SQLITE_ERROR) // { // fprintf(stderr, "[ОШИБКА] %s - \"%s\"\n", text ? "установлено" : "очищено", text ? getValue(VALUE_USERNAME)->current : ""); // } if (sqlite3_step(res) == SQLITE_DONE) { fprintf(stdout, "[УСПЕШНО] %s - \"%s\"\n", monitor ? "установлено" : "очищено", monitor ? monitor : ""); return 0; } sqlite3_finalize(res); sqlite3_close(db); return -3; } int dbSaveMonitors(char *name) { int result = 0; if (!(name && strlen(name))) return -1; sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return -2; } char *sql = "UPDATE `monitors` set `set` = 0"; if (sqlite3_exec(db, sql, NULL, NULL, NULL) == SQLITE_OK) { sqlite3_stmt *res; sql = "UPDATE `monitors` SET `set` = 1 WHERE `name` = ?"; if (sqlite3_prepare_v2(db, sql, -1, &res, 0) == SQLITE_OK) { sqlite3_bind_text(res, 1, name, -1, 0); } if (sqlite3_step(res) == SQLITE_BUSY) { fprintf(stderr, "[ЗАНЯТО] %s - \"%s\"\n", name ? "установлено" : "очищено", name); result = 2; } if (sqlite3_step(res) == SQLITE_ERROR) { fprintf(stderr, "[ОШИБКА] %s - \"%s\"\n", name ? "установлено" : "очищено", name); result = 1; } if (sqlite3_step(res) == SQLITE_DONE) { fprintf(stdout, "[УСПЕШНО] %s - \"%s\"\n", name ? "установлено" : "очищено", name); result = 0; } sqlite3_finalize(res); } sqlite3_close(db); return result; } int dbInsertHistory(char *login, char *host) { int result = 0; if (!(login && strlen(login)) || !(host && strlen(host))) return -1; sqlite3 *db = dbGetBase(getPathDB(NULL)); if (!db) { return -2; } sqlite3_stmt *res; char *sql = "INSERT INTO `history` (`login`, `host`, `time`) VALUES (?, ?, ?)"; if (sqlite3_prepare_v2(db, sql, -1, &res, 0) == SQLITE_OK) { sqlite3_bind_text(res, 1, login, -1, 0); sqlite3_bind_text(res, 2, host, -1, 0); sqlite3_bind_int(res, 3, (unsigned)time(NULL)); } if (sqlite3_step(res) == SQLITE_DONE) { sqlite3_finalize(res); sqlite3_close(db); return 0; } sqlite3_finalize(res); sqlite3_close(db); return result; }