From 5587a18e4edf1de84b443048a1f817ac6cde80b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Al=D0=B5x=D0=B0nder=20Lysik=D0=BEv?= <alexander.lysikov@demlabs.net> Date: Fri, 24 May 2019 21:32:04 +0500 Subject: [PATCH] added files dap_chain_global_db_driver.h/c and dap_chain_global_db_driver_sqlite.h/c --- CMakeLists.txt | 2 +- dap_chain_global_db.c | 22 ++-- dap_chain_global_db_driver.c | 65 ++++++++++ dap_chain_global_db_driver.h | 66 ++++++++++ dap_chain_global_db_driver_sqlite.c | 191 ++++++++++++++++++++++++++++ dap_chain_global_db_driver_sqlite.h | 36 ++++++ dap_chain_global_db_pvt.h | 4 +- 7 files changed, 374 insertions(+), 12 deletions(-) create mode 100644 dap_chain_global_db_driver.c create mode 100644 dap_chain_global_db_driver.h create mode 100644 dap_chain_global_db_driver_sqlite.c create mode 100644 dap_chain_global_db_driver_sqlite.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ba5ba0..3c18ded 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ file(GLOB DAP_CHAIN_GLOBAL_DB_HDR *.h) add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_GLOBAL_DB_SRC} ${DAP_CHAIN_GLOBAL_DB_HDR}) -target_link_libraries(dap_chain_global_db dap_core dap_crypto dap_chain dap_chain_crypto ldb talloc tevent) +target_link_libraries(dap_chain_global_db dap_core dap_crypto dap_chain dap_chain_crypto ldb talloc tevent sqlite3) target_include_directories(dap_chain_global_db INTERFACE .) set(${PROJECT_NAME}_DEFINITIONS CACHE INTERNAL "${PROJECT_NAME}: Definitions" FORCE) diff --git a/dap_chain_global_db.c b/dap_chain_global_db.c index 76d669f..661bd10 100755 --- a/dap_chain_global_db.c +++ b/dap_chain_global_db.c @@ -9,7 +9,8 @@ #include "dap_hash.h" #include "dap_chain_common.h" #include "dap_strfuncs.h" -#include "dap_chain_global_db_pvt.h" +//#include "dap_chain_global_db_pvt.h" +#include "dap_chain_global_db_driver.h" #include "dap_chain_global_db_hist.h" #include "dap_chain_global_db.h" @@ -138,14 +139,14 @@ void dap_chain_global_db_objs_delete(dap_global_db_obj_t **objs) */ int dap_chain_global_db_init(dap_config_t * g_config) { - const char *a_storage_path = dap_config_get_item_str(g_config, "resources", "dap_global_db_path"); - if(a_storage_path){ - lock(); - int res = dap_db_init(a_storage_path); - unlock(); - return res; - } - return -1; + const char *l_storage_path = dap_config_get_item_str(g_config, "resources", "dap_global_db_path"); + const char *l_driver_name = dap_config_get_item_str_default(g_config, "resources", "dap_global_db_driver", + "sqlite"); + lock(); + int res = dap_db_driver_init(l_driver_name, l_storage_path); + //int res = dap_db_init(a_storage_path); + unlock(); + return res; } /** @@ -154,7 +155,8 @@ int dap_chain_global_db_init(dap_config_t * g_config) void dap_chain_global_db_deinit(void) { lock(); - dap_db_deinit(); + dap_db_driver_deinit(); + //dap_db_deinit(); unlock(); history_group_item_t * l_item = NULL, *l_item_tmp = NULL; HASH_ITER(hh, s_history_group_items, l_item, l_item_tmp){ diff --git a/dap_chain_global_db_driver.c b/dap_chain_global_db_driver.c new file mode 100644 index 0000000..ab0ddcb --- /dev/null +++ b/dap_chain_global_db_driver.c @@ -0,0 +1,65 @@ +/* + * Authors: + * Alexander Lysikov <alexander.lysikov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2019 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stddef.h> +#include <stdint.h> +#include "dap_common.h" +#include "dap_strfuncs.h" + +#include "dap_chain_global_db_driver_sqlite.h" +#include "dap_chain_global_db_driver.h" + +static char *s_used_driver = NULL; +/** + * Select driver + * driver_name may be "ldb", "sqlite" + * + * return 0 OK, <0 Error + */ +int dap_db_driver_init(const char *a_driver_name, const char *a_filename_db) +{ + if(s_used_driver) + dap_db_driver_deinit(); + s_used_driver = dap_strdup(a_driver_name); + if(!dap_strcmp(s_used_driver, "ldb")) + return -1; + if(!dap_strcmp(s_used_driver, "sqlite")) + return dap_db_driver_sqlite_init(a_filename_db); + return -1; +} + +/** + * Shutting down the db library + */ + +void dap_db_driver_deinit(void) +{ +// if(!dap_strcmp(s_used_driver, "ldb")) +// ; + if(!dap_strcmp(s_used_driver, "sqlite")) + dap_db_driver_sqlite_deinit(); + DAP_DELETE(s_used_driver); + s_used_driver = NULL; +} + diff --git a/dap_chain_global_db_driver.h b/dap_chain_global_db_driver.h new file mode 100644 index 0000000..76e5d97 --- /dev/null +++ b/dap_chain_global_db_driver.h @@ -0,0 +1,66 @@ +/* + * Authors: + * Alexander Lysikov <alexander.lysikov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2019 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _GLOBAL_DB_DRIVER_H_ +#define _GLOBAL_DB_DRIVER_H_ + +#include <stddef.h> +#include <stdint.h> +//#include <ctime> +#include "dap_common.h" + +typedef struct dap_store_obj { + time_t timestamp; + uint8_t type; +// char *section; + char *group; + char *key; + uint8_t *value; + size_t value_len; +}DAP_ALIGN_PACKED dap_store_obj_t, *pdap_store_obj_t; + +typedef struct dap_store_obj_pkt { + time_t timestamp; + size_t data_size; + uint8_t data[]; +}__attribute__((packed)) dap_store_obj_pkt_t; + +int dap_db_driver_init(const char *driver_name, const char *a_filename_db); +void dap_db_driver_deinit(void); + +int dap_db_add(pdap_store_obj_t a_store_obj, size_t a_store_count); +int dap_db_delete(pdap_store_obj_t a_store_obj, size_t a_store_count); + +pdap_store_obj_t dap_db_read_data(const char *a_query, size_t *a_count); +pdap_store_obj_t dap_db_read_file_data(const char *a_path, const char *a_group); // state of emergency only, if LDB database is inaccessible +dap_store_obj_pkt_t *dap_store_packet_single(pdap_store_obj_t a_store_obj); +dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t a_store_obj, + time_t a_timestamp, size_t a_store_obj_count); +dap_store_obj_t *dap_store_unpacket(const dap_store_obj_pkt_t *a_pkt, + size_t *a_store_obj_count); + +void dab_db_free_pdap_store_obj_t(pdap_store_obj_t a_store_data, + size_t a_count); + +#endif //_GLOBAL_DB_DRIVER_H_ diff --git a/dap_chain_global_db_driver_sqlite.c b/dap_chain_global_db_driver_sqlite.c new file mode 100644 index 0000000..c7dade1 --- /dev/null +++ b/dap_chain_global_db_driver_sqlite.c @@ -0,0 +1,191 @@ +/* + * Authors: + * Alexander Lysikov <alexander.lysikov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2019 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stddef.h> +#include "dap_common.h" +#include "dap_chain_global_db_driver.h" +#include "dap_chain_global_db_driver_sqlite.h" + +#define LOG_TAG "db_sqlite" + +static sqlite3 *s_db = NULL; + +/** + * SQLite library initialization, no thread safe + * + * return 0 if Ok, else error code >0 + */ +int dap_db_driver_sqlite_init(const char *a_filename_db) +{ + int l_ret = -1; + if(sqlite3_threadsafe() && !sqlite3_config(SQLITE_CONFIG_SERIALIZED)) + l_ret = sqlite3_initialize(); + if(l_ret != SQLITE_OK) { + log_it(L_ERROR, "Can't init sqlite err=%d", l_ret); + return l_ret; + } + char *l_error_message = NULL; + s_db = dap_db_driver_sqlite_open(a_filename_db, SQLITE_OPEN_READWRITE, &l_error_message); + if(!s_db) { + log_it(L_ERROR, "Can't init sqlite err=%d", l_error_message); + dap_db_driver_sqlite_free(l_error_message); + } + return l_ret; +} + +int dap_db_driver_sqlite_deinit(void) +{ + return sqlite3_shutdown(); +} + + +/** + * Open SQLite database + * a_filename_utf8 - database file name + * a_flags - database access flags (SQLITE_OPEN_READONLY, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) + * a_error_message[out] - Error messages (the memory requires deletion via sqlite_free ()) + * + * return: database identifier, NULL when an error occurs. + */ +sqlite3* dap_db_driver_sqlite_open(const char *a_filename_utf8, int a_flags, char **a_error_message) +{ + sqlite3 *l_db = NULL; + + int l_rc = sqlite3_open_v2(a_filename_utf8, &l_db, a_flags | SQLITE_OPEN_FULLMUTEX, NULL); + // if unable to open the database file + if(l_rc == SQLITE_CANTOPEN) { + // try to create database + l_rc = sqlite3_open_v2(a_filename_utf8, &l_db, a_flags | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_CREATE, NULL); + } + if(l_rc != SQLITE_OK) + { + if(a_error_message) + *a_error_message = sqlite3_mprintf("Can't open database: %s\n", sqlite3_errmsg(l_db)); + sqlite3_close(l_db); + return NULL; + } + return l_db; +} + +/** + * Close the database + */ +void dap_db_driver_sqlite_close(sqlite3 *l_db) +{ + if(l_db) + sqlite3_close(l_db); +} +/* + * Clear the memory allocated via sqlite3_mprintf() + */ +void dap_db_driver_sqlite_free(char *memory) +{ + if(memory) + sqlite3_free(memory); +} + +/** + * Execute SQL query to database that does not return data + * + * return 0 if Ok, else error code >0 + */ +static int dap_db_driver_sqlite_exec(sqlite3 *l_db, const char *l_query, char **l_error_message) +{ + char *l_zErrMsg = NULL; + int l_rc = sqlite3_exec(l_db, l_query, NULL, 0, &l_zErrMsg); + if(l_rc != SQLITE_OK) + { + if(l_error_message && l_zErrMsg) + *l_error_message = sqlite3_mprintf("SQL error: %s", l_zErrMsg); + if(l_zErrMsg) + sqlite3_free(l_zErrMsg); + return l_rc; + } + if(l_zErrMsg) + sqlite3_free(l_zErrMsg); + return l_rc; +} + +/* + * Add multiple entries received from remote node to local database. + * Since we don't know the size, it must be supplied too + * + * dap_store_size the count records + * return 0 if Ok, else error code >0 + */ +int dap_db_add1(dap_store_obj_t *a_store_obj, size_t a_store_count) +{ + int l_ret = 0; + /* if(a_store_obj == NULL) { + log_it(L_ERROR, "Invalid Dap store objects passed"); + return -1; + } + if(ldb_connect(s_ldb, dap_db_path, 0, NULL) != LDB_SUCCESS) { + log_it(L_ERROR, "Couldn't connect to database"); + return -2; + } + //log_it(L_INFO, "We're about to put %d records into database", a_store_count); + struct ldb_message *l_msg; + if(a_store_count == 0) { + a_store_count = 1; + } + for(size_t q = 0; q < a_store_count; q++) { + // level 3: leased address, single whitelist entity + + // if it is marked, don't save + if(a_store_obj[q].timestamp == (time_t) -1) + continue; + + l_msg = ldb_msg_new(s_ldb); + char dn[256]; + memset(dn, '\0', 256); + strcat(dn, "cn="); + strcat(dn, a_store_obj[q].key); + //strcat(dn, ",ou=addrs_leased,dc=kelvin_nodes"); + strcat(dn, ",ou="); + strcat(dn, a_store_obj[q].group); + strcat(dn, ",dc=kelvin_nodes"); + l_msg->dn = ldb_dn_new(s_mem_ctx, s_ldb, dn); + int l_res = ldb_msg_add_string(l_msg, "cn", a_store_obj[q].key); + ldb_msg_add_string(l_msg, "objectClass", a_store_obj[q].group); + ldb_msg_add_string(l_msg, "section", "kelvin_nodes"); + ldb_msg_add_string(l_msg, "description", "Approved Kelvin node"); + + struct ldb_val l_val; + struct ldb_message_element *return_el; + l_val.data = (uint8_t*) &a_store_obj[q].timestamp; + l_val.length = sizeof(time_t); + l_res = ldb_msg_add_value(l_msg, "time", &l_val, &return_el); + + l_val.data = a_store_obj[q].value; + l_val.length = a_store_obj[q].value_len; + l_res = ldb_msg_add_value(l_msg, "val", &l_val, &return_el); + + l_ret += dap_db_add_msg(l_msg); // accumulation error codes + talloc_free(l_msg->dn); + talloc_free(l_msg); + }*/ + return l_ret; +} + diff --git a/dap_chain_global_db_driver_sqlite.h b/dap_chain_global_db_driver_sqlite.h new file mode 100644 index 0000000..35ae58c --- /dev/null +++ b/dap_chain_global_db_driver_sqlite.h @@ -0,0 +1,36 @@ +/* + * Authors: + * Alexander Lysikov <alexander.lysikov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2019 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "sqlite3.h" + + +int dap_db_driver_sqlite_init(const char *a_filename_db); +int dap_db_driver_sqlite_deinit(void); + +sqlite3* dap_db_driver_sqlite_open(const char *a_filename_utf8, int a_flags, char **error_message); +void dap_db_driver_sqlite_close(sqlite3 *l_db); + +void dap_db_driver_sqlite_free(char *memory); + + diff --git a/dap_chain_global_db_pvt.h b/dap_chain_global_db_pvt.h index 7fab7e3..f9be991 100755 --- a/dap_chain_global_db_pvt.h +++ b/dap_chain_global_db_pvt.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef _GLOBAL_DB_DRIVER_H_ +#define _GLOBAL_DB_DRIVER_H_ #include <stdint.h> #include "dap_common.h" @@ -39,3 +40,4 @@ dap_store_obj_t *dap_store_unpacket(const dap_store_obj_pkt_t *a_pkt, size_t *a_ void dab_db_free_pdap_store_obj_t(pdap_store_obj_t a_store_data, size_t a_count); +#endif // #ifndef _GLOBAL_DB_DRIVER_H_ -- GitLab