From 7f3fc9a99fe49579033e7ce1456215b4ebe4a102 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 20 Sep 2022 14:26:32 +0200 Subject: [PATCH] add new functions --- .../Database/Connection/ConnectionAbstract.h | 46 ++++ .../Database/Connection/ConnectionFacotry.h | 43 ++++ .../Database/Connection/DbConnectionConfig.h | 36 ++++ .../Database/Connection/MysqlConnection.h | 88 ++++++++ .../Database/Connection/SQLiteConnection.h | 73 +++++++ DataStorage/Database/DatabaseStatus.h | 26 +++ DataStorage/Database/DatabaseType.h | 25 +++ Stdlib/AssocArray.h | 74 ------- Stdlib/HashTable.h | 203 ++++++++++++++++++ Utils/Rng/StringUtils.h | 40 ++++ 10 files changed, 580 insertions(+), 74 deletions(-) create mode 100644 DataStorage/Database/Connection/ConnectionAbstract.h create mode 100644 DataStorage/Database/Connection/ConnectionFacotry.h create mode 100644 DataStorage/Database/Connection/DbConnectionConfig.h create mode 100644 DataStorage/Database/Connection/MysqlConnection.h create mode 100644 DataStorage/Database/Connection/SQLiteConnection.h create mode 100644 DataStorage/Database/DatabaseStatus.h create mode 100644 DataStorage/Database/DatabaseType.h delete mode 100644 Stdlib/AssocArray.h create mode 100644 Stdlib/HashTable.h create mode 100644 Utils/Rng/StringUtils.h diff --git a/DataStorage/Database/Connection/ConnectionAbstract.h b/DataStorage/Database/Connection/ConnectionAbstract.h new file mode 100644 index 0000000..0b7ae40 --- /dev/null +++ b/DataStorage/Database/Connection/ConnectionAbstract.h @@ -0,0 +1,46 @@ +/** + * Karaka + * + * @package Utils + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef DATASTORAGE_DATBASE_CONNECTION_ABSTRACT_H +#define DATASTORAGE_DATBASE_CONNECTION_ABSTRACT_H + +#include +#include + +#include "DbConnectionConfig.h" +#include "DatabaseType.h" +#include "DatabaseStatus.h" + +namespace DataStorage { + namespace Database { + struct ConnectionAbstract { + void *con = NULL; + + DbConnectionConfig dbdata; + + DatabaseType type = DatabaseType::UNDEFINED; + + DatabaseStatus status = DatabaseStatus::CLOSED; + + virtual void connect(DbConnectionConfig *dbdata = NULL); + + virtual void close() + { + if (this->con != NULL) { + free(con); + } + + this->con = NULL; + this->status = DatabaseStatus::CLOSED; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/DataStorage/Database/Connection/ConnectionFacotry.h b/DataStorage/Database/Connection/ConnectionFacotry.h new file mode 100644 index 0000000..386b0ca --- /dev/null +++ b/DataStorage/Database/Connection/ConnectionFacotry.h @@ -0,0 +1,43 @@ +/** + * Karaka + * + * @package Utils + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef DATASTORAGE_DATBASE_CONNECTION_FACTORY_H +#define DATASTORAGE_DATBASE_CONNECTION_FACTORY_H + +#include +#include + +#include "../DatabaseType.h" + +#include "ConnectionAbstract.h" +#include "DbConnectionConfig.h" +#include "MysqlConnection.h" +#include "SQLiteConnection.h" + +namespace DataStorage { + namespace Database { + ConnectionAbstract *create_connection(DbConnectionConfig dbdata) + { + switch (dbdata.db) { + case DatabaseType::MYSQL: + return new MysqlConnection(dbdata); + case DatabaseType::PGSQL: + return NULL; + case DatabaseType::SQLSRV: + return NULL; + case DatabaseType::SQLITE: + return new SQLiteConnection(dbdata); + default: + return NULL; + } + } + } +} + +#endif \ No newline at end of file diff --git a/DataStorage/Database/Connection/DbConnectionConfig.h b/DataStorage/Database/Connection/DbConnectionConfig.h new file mode 100644 index 0000000..facfb10 --- /dev/null +++ b/DataStorage/Database/Connection/DbConnectionConfig.h @@ -0,0 +1,36 @@ +/** + * Karaka + * + * @package Utils + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef DATASTORAGE_DATABASE_CONNECTION_H +#define DATASTORAGE_DATABASE_CONNECTION_H + +#include +#include + +#include "../DatabaseType.h" + +namespace DataStorage { + namespace Database { + typedef struct { + DatabaseType db = DatabaseType::UNDEFINED; + + char *database = NULL; + + char *host = NULL; + + int port = 0; + + char *login = NULL; + + char *password = NULL; + } DbConnectionConfig; + } +} + +#endif \ No newline at end of file diff --git a/DataStorage/Database/Connection/MysqlConnection.h b/DataStorage/Database/Connection/MysqlConnection.h new file mode 100644 index 0000000..fbc8ef7 --- /dev/null +++ b/DataStorage/Database/Connection/MysqlConnection.h @@ -0,0 +1,88 @@ +/** + * Karaka + * + * @package Utils + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef DATASTORAGE_DATABASE_MYSQL_CONNECTION_H +#define DATASTORAGE_DATABASE_MYSQL_CONNECTION_H + +#include +#include + +#include + +#include "ConnectionAbstract.h" +#include "DbConnectionConfig.h" +#include "../DatabaseType.h" +#include "../DatabaseStatus.h" + +namespace DataStorage { + namespace Database { + struct MysqlConnection : ConnectionAbstract { + MysqlConnection(DbConnectionConfig dbdata) + { + this->type = DatabaseType::MYSQL; + this->dbdata = dbdata; + } + + void connect(DbConnectionConfig *dbdata = NULL) + { + this->dbdata = dbdata == NULL ? this->dbdata : *dbdata; + + if (this->dbdata.db == NULL + || this->dbdata.host == NULL + || this->dbdata.port == 0 + || this->dbdata.database == NULL + || this->dbdata.login == NULL + || this->dbdata.password == NULL + ) { + this->status = DatabaseStatus::FAILURE; + + if (this->dbdata.password != NULL) { + free(this->dbdata.password); + this->dbdata.password = NULL; + } + } + + this->close(); + + this->con = mysql_init(NULL); + + ::MYSQL *stat = mysql_real_connect( + (::MYSQL *) this->con, + this->dbdata.host, + this->dbdata.login, + this->dbdata.password, + this->dbdata.database, + this->dbdata.port, + NULL, 0 + ); + + if (!stat) { + this->status = DatabaseStatus::MISSING_DATABASE; + + mysql_close((::MYSQL *) this->con); + this->con = NULL; + + if (this->dbdata.password != NULL) { + free(this->dbdata.password); + this->dbdata.password = NULL; + } + } + } + + void close() + { + mysql_close((::MYSQL *) this->con); + this->con = NULL; + this->status = DatabaseStatus::CLOSED; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/DataStorage/Database/Connection/SQLiteConnection.h b/DataStorage/Database/Connection/SQLiteConnection.h new file mode 100644 index 0000000..83ea7d8 --- /dev/null +++ b/DataStorage/Database/Connection/SQLiteConnection.h @@ -0,0 +1,73 @@ +/** + * Karaka + * + * @package Utils + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef DATASTORAGE_DATABASE_SQLITE_CONNECTION_H +#define DATASTORAGE_DATABASE_SQLITE_CONNECTION_H + +#include +#include + +#include + +#include "ConnectionAbstract.h" +#include "DbConnectionConfig.h" +#include "../DatabaseType.h" +#include "../DatabaseStatus.h" + +namespace DataStorage { + namespace Database { + struct SQLiteConnection : ConnectionAbstract { + SQLiteConnection(DbConnectionConfig dbdata) + { + this->type = DatabaseType::MYSQL; + this->dbdata = dbdata; + } + + void connect(DbConnectionConfig *dbdata = NULL) + { + this->dbdata = dbdata == NULL ? this->dbdata : *dbdata; + + if (this->dbdata.db == NULL + || this->dbdata.database == NULL + ) { + this->status = DatabaseStatus::FAILURE; + + if (this->dbdata.password != NULL) { + free(this->dbdata.password); + this->dbdata.password = NULL; + } + } + + this->close(); + + int stat = sqlite3_open(this->dbdata.host, (sqlite3 **) &this->con); + if (stat != SQLITE_OK) { + this->status = DatabaseStatus::MISSING_DATABASE; + + sqlite3_close((sqlite3 *) this->con); + this->con = NULL; + + if (this->dbdata.password != NULL) { + free(this->dbdata.password); + this->dbdata.password = NULL; + } + } + } + + void close() + { + sqlite3_close((sqlite3 *) this->con); + this->con = NULL; + this->status = DatabaseStatus::CLOSED; + } + }; + } +} + +#endif \ No newline at end of file diff --git a/DataStorage/Database/DatabaseStatus.h b/DataStorage/Database/DatabaseStatus.h new file mode 100644 index 0000000..cf64440 --- /dev/null +++ b/DataStorage/Database/DatabaseStatus.h @@ -0,0 +1,26 @@ +/** + * Karaka + * + * @package Models + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef DATASTORAGE_DATABASE_STATUS_H +#define DATASTORAGE_DATABASE_STATUS_H + +namespace DataStorage { + namespace Database { + typedef enum { + OK = 0, + MISSING_DATABASE = 1, + MISSING_TABLE = 2, + FAILURE = 3, + READONLY = 4, + CLOSED = 5 + } DatabaseStatus; + } +} + +#endif \ No newline at end of file diff --git a/DataStorage/Database/DatabaseType.h b/DataStorage/Database/DatabaseType.h new file mode 100644 index 0000000..54ce96e --- /dev/null +++ b/DataStorage/Database/DatabaseType.h @@ -0,0 +1,25 @@ +/** + * Karaka + * + * @package Models + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef DATASTORAGE_DATABASE_TYPE_H +#define DATASTORAGE_DATABASE_TYPE_H + +namespace DataStorage { + namespace Database { + typedef enum { + MYSQL = 0, + SQLITE = 1, + PGSQL = 2, + SQLSRV = 3, + UNDEFINED = 4 + } DatabaseType; + } +} + +#endif \ No newline at end of file diff --git a/Stdlib/AssocArray.h b/Stdlib/AssocArray.h deleted file mode 100644 index 85654bd..0000000 --- a/Stdlib/AssocArray.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Karaka - * - * @package Stdlib - * @copyright Dennis Eichhorn - * @license OMS License 1.0 - * @version 1.0.0 - * @link https://karaka.app - */ -#ifndef STDLIB_ASSOC_ARRAY_H -#define STDLIB_ASSOC_ARRAY_H - -#include -#include -#include - -namespace Stdlib { - class AssocArray { - private: - - public: - typedef struct { - int size; - void **keys; - void **values; - } assoc_arr; - - static - assoc_arr *hash_new(int size) - { - assoc_arr *h = (assoc_arr *) calloc(1, sizeof(assoc_arr)); - h->keys = (void **) calloc(size, sizeof(void *)); - h->values = (void **) calloc(size, sizeof(void *)); - h->size = size; - - return h; - } - - static - int hash_index(assoc_arr *h, void *key) - { - int i = (*((int *) key)) % h->size; - while (h->keys[i] && h->keys[i] != key) { - i = (i + 1) % h->size; - } - - return i; - } - - static - void hash_insert(assoc_arr *h, void *key, void *value) - { - int i = hash_index(h, key); - h->keys[i] = key; - h->values[i] = value; - } - - static - void *hash_lookup(assoc_arr *h, void *key) - { - int i = hash_index(h, key); - - return h->values[i]; - } - - static - void hash_free(assoc_arr *h) - { - free(h); - } - }; -} - -#endif \ No newline at end of file diff --git a/Stdlib/HashTable.h b/Stdlib/HashTable.h new file mode 100644 index 0000000..85f3bd5 --- /dev/null +++ b/Stdlib/HashTable.h @@ -0,0 +1,203 @@ +/** + * Karaka + * + * @package Stdlib + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef STDLIB_HASH_TABLE_H +#define STDLIB_HASH_TABLE_H + +#include +#include +#include +#include + +namespace Stdlib { + namespace HashTable { + typedef struct { + const char *key; + void *value; + } entry; + + struct ht { + entry *entries; + size_t max; + size_t size; + }; + + typedef struct { + const char *key; + void *value; + + ht *table; + size_t index; + } it; + + inline + unsigned long long hash_key(const char *key) + { + unsigned long long hash = 14695981039346656037UL; + for (const char *p = key; *p; ++p) { + hash ^= (unsigned long long)(unsigned char)(*p); + hash *= 1099511628211UL; + } + + return hash; + } + + ht *create_table(void) + { + ht *table = malloc(sizeof(ht)); + if (table == NULL) { + return NULL; + } + + table->size = 0; + table->max = 16; + + table->entries = calloc(table->max, sizeof(entry)); + if (table->entries == NULL) { + free(table); + return NULL; + } + + return table; + } + + void *get_entry(ht *table, const char *key) + { + unsigned long long hash = hash_key(key); + size_t index = (size_t)(hash & (unsigned long long)(table->max - 1)); + + while (table->entries[index].key != NULL) { + if (strcmp(key, table->entries[index].key) == 0) { + return table->entries[index].value; + } + + ++index; + if (index >= table->max) { + index = 0; + } + } + + return NULL; + } + + const char *_set_entry(entry *entries, size_t max, const char *key, void *value, size_t *size) + { + unsigned long long hash = hash_key(key); + size_t index = (size_t)(hash & (unsigned long long)(max - 1)); + + while (entries[index].key != NULL) { + if (strcmp(key, entries[index].key) == 0) { + entries[index].value = value; + + return entries[index].key; + } + + ++index; + if (index >= max) { + index = 0; + } + } + + if (size != NULL) { + key = strdup(key); + if (key == NULL) { + return NULL + } + + ++(*size); + } + + entries[index].key = (char *) key; + entries[index].value = value; + + return key; + } + + bool expand_table(ht *table) + { + size_t new_max = table->max * 2; + if (new_max < table->max) { + return false; + } + + entry *new_entries = calloc(new_max, sizeof(entry)); + if (new_entries == NULL) { + return false; + } + + for (size_t i = 0; i < table->max; ++i) { + entry tmp = table->entries[i]; + if (tmp.key != NULL) { + _set_entry(new_entries, new_max, tmp.key, tmp.value, NULL); + } + } + + free(table->entries); + table->entries = new_entries; + table->max = new_max; + + return true; + } + + const char *set_entry(ht *table, const char *key, void *value) + { + if (value == NULL) { + return NULL; + } + + if (table->size >= table->max / 2) { + if (!expand_table(table)) { + return NULL; + } + } + + return _set_entry(table->entries, table->max, key, value, &table->size); + } + + it table_iterator(ht *table) + { + it it; + it.table = table; + it.index = 0; + + return it; + } + + bool next(it *it) + { + ht *table = it->table; + while (it->index < table->max) { + size_t i = it->index; + ++(it->index); + + if (table->entries[i].key != NULL) { + entry tmp = table->entries[i]; + it->key = tmp.key; + it->value = tmp.value; + + return true; + } + } + + return false; + } + + void free_table(ht *table) + { + for (size_t i = 0; i < table->max; ++i) { + free((void *) table->entries[i].key); + } + + free(table->entries); + free(table); + } + }; +} + +#endif \ No newline at end of file diff --git a/Utils/Rng/StringUtils.h b/Utils/Rng/StringUtils.h new file mode 100644 index 0000000..e8112fd --- /dev/null +++ b/Utils/Rng/StringUtils.h @@ -0,0 +1,40 @@ +/** + * Karaka + * + * @package Utils + * @copyright Dennis Eichhorn + * @license OMS License 1.0 + * @version 1.0.0 + * @link https://karaka.app + */ +#ifndef UTILS_RNG_STRING_UTILS_H +#define UTILS_RNG_STRING_UTILS_H + +#include +#include +#include + +namespace Utils { + namespace Rng { + namespace StringUtils { + inline + char* generate_string( + size_t min = 10, size_t max = 10, + char* charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", int charsetLength = 62 + ) { + srand(time(0)); + + size_t length = (rand() % (max - min + 1)) + min; + char* randomString = malloc(length + 1); + + for (size_t i = 0; i < length; ++i) { + randomString[i] = charset[rand() % charsetLength]; + } + + randomString[length] = '\0'; + + return randomString; + } + } + } +} \ No newline at end of file