603 lines
16 KiB
C
603 lines
16 KiB
C
/*
|
||
* db.c
|
||
*
|
||
* Created on: 13 июл. 2022 г.
|
||
* Author: alexander
|
||
*/
|
||
|
||
#include "sqlite3.h"
|
||
//#include <sqlite3.h>
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <time.h>
|
||
|
||
#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;
|
||
}
|