From d02d86aedc49884e7387541edf95c7c641bc1862 Mon Sep 17 00:00:00 2001 From: Relintai Date: Wed, 6 Jul 2022 22:14:37 +0200 Subject: [PATCH] Fully cleaned and added the sqlite database backend to the build. --- modules/database/database.h | 3 - modules/database/query_builder.cpp | 36 ++- modules/database/query_builder.h | 5 +- modules/database/query_result.cpp | 12 +- modules/database/query_result.h | 3 +- modules/database/table_builder.cpp | 5 +- modules/database_sqlite/SCsub | 10 +- modules/database_sqlite/config.py | 7 +- .../database_sqlite/sqlite3_connection.cpp | 100 +++++++ modules/database_sqlite/sqlite3_connection.h | 33 +++ modules/database_sqlite/sqlite3_database.cpp | 94 +------ modules/database_sqlite/sqlite3_database.h | 39 +-- .../database_sqlite/sqlite3_query_builder.cpp | 260 ++++++++++-------- .../database_sqlite/sqlite3_query_builder.h | 48 ++-- .../database_sqlite/sqlite3_query_result.cpp | 28 +- .../database_sqlite/sqlite3_query_result.h | 30 +- .../database_sqlite/sqlite3_table_builder.cpp | 71 +++-- .../database_sqlite/sqlite3_table_builder.h | 43 ++- 18 files changed, 446 insertions(+), 381 deletions(-) create mode 100644 modules/database_sqlite/sqlite3_connection.cpp create mode 100644 modules/database_sqlite/sqlite3_connection.h diff --git a/modules/database/database.h b/modules/database/database.h index b439a957f..d6f3e0fc1 100644 --- a/modules/database/database.h +++ b/modules/database/database.h @@ -5,9 +5,6 @@ #include "core/reference.h" -class QueryBuilder; -class TableBuilder; -class QueryResult; class DatabaseConnection; class Database : public Reference { diff --git a/modules/database/query_builder.cpp b/modules/database/query_builder.cpp index feb45966f..96c33fb36 100644 --- a/modules/database/query_builder.cpp +++ b/modules/database/query_builder.cpp @@ -2,6 +2,13 @@ #include "query_result.h" +String QueryBuilder::get_result() { + return query_result; +} +void QueryBuilder::set_result(const String &val) { + query_result = val; +} + QueryBuilder *QueryBuilder::select() { return this; } @@ -280,12 +287,6 @@ Ref QueryBuilder::run() { void QueryBuilder::run_query() { } -String QueryBuilder::get_result() { - end_command(); - - return query_result; -} - void QueryBuilder::print() { //printf("%s\n", query_result.c_str()); ERR_PRINT(query_result); @@ -298,6 +299,10 @@ QueryBuilder::~QueryBuilder() { } void QueryBuilder::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_result"), &QueryBuilder::get_result); + ClassDB::bind_method(D_METHOD("set_result", "value"), &QueryBuilder::set_result); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "result"), "set_result", "get_result"); + ClassDB::bind_method(D_METHOD("cvalues"), &QueryBuilder::_cvalues_bind); ClassDB::bind_method(D_METHOD("next_value"), &QueryBuilder::_next_value_bind); @@ -381,6 +386,9 @@ void QueryBuilder::_bind_methods() { ClassDB::bind_method(D_METHOD("end_command"), &QueryBuilder::_end_command_bind); ClassDB::bind_method(D_METHOD("reset"), &QueryBuilder::_reset_bind); + + ClassDB::bind_method(D_METHOD("run"), &QueryBuilder::run); + ClassDB::bind_method(D_METHOD("run_query"), &QueryBuilder::run_query); } Ref QueryBuilder::_cvalues_bind() { @@ -409,26 +417,26 @@ Ref QueryBuilder::_cstr_bind() { } Ref QueryBuilder::_select_bind(const String ¶ms) { - return Ref(select()); + return Ref(select(params)); } Ref QueryBuilder::_update_bind(const String ¶ms) { - return Ref(update()); + return Ref(update(params)); } Ref QueryBuilder::_del_bind(const String ¶ms) { - return Ref(del()); + return Ref(del(params)); } Ref QueryBuilder::_where_bind(const String ¶ms) { - return Ref(where()); + return Ref(where(params)); } Ref QueryBuilder::_from_bind(const String ¶ms) { - return Ref(from()); + return Ref(from(params)); } Ref QueryBuilder::_insert_bind(const String &table_name, const String &columns) { - return Ref(insert()); + return Ref(insert(table_name, columns)); } Ref QueryBuilder::_values_bind(const String ¶ms_str) { - return Ref(values()); + return Ref(values(params_str)); } Ref QueryBuilder::_val_bind() { return Ref(val()); @@ -450,7 +458,7 @@ Ref QueryBuilder::_vald_bind(const double param) { } Ref QueryBuilder::_like_bind(const String &str) { - return Ref(like()); + return Ref(like(str)); } Ref QueryBuilder::_sets_bind() { diff --git a/modules/database/query_builder.h b/modules/database/query_builder.h index b210e5fb5..2cef27936 100644 --- a/modules/database/query_builder.h +++ b/modules/database/query_builder.h @@ -13,6 +13,9 @@ class QueryBuilder : public Reference { GDCLASS(QueryBuilder, Reference); public: + String get_result(); + void set_result(const String &val); + virtual QueryBuilder *select(); virtual QueryBuilder *update(); virtual QueryBuilder *del(); @@ -113,8 +116,6 @@ public: virtual Ref run(); virtual void run_query(); - String get_result(); - void print(); QueryBuilder(); diff --git a/modules/database/query_result.cpp b/modules/database/query_result.cpp index 1c41e581a..5f2d7e27a 100644 --- a/modules/database/query_result.cpp +++ b/modules/database/query_result.cpp @@ -6,12 +6,8 @@ bool QueryResult::next_row() { return false; } -const char *QueryResult::get_cell_chr(const int index) { - return ""; -} - String QueryResult::get_cell(const int index) { - return String(get_cell_chr(index)); + return String(); } bool QueryResult::get_cell_bool(const int index) { @@ -49,6 +45,10 @@ int QueryResult::get_last_insert_rowid() { return 0; } +String QueryResult::get_error_message() { + return ""; +} + QueryResult::QueryResult() { } @@ -67,4 +67,6 @@ void QueryResult::_bind_methods() { ClassDB::bind_method(D_METHOD("is_cell_null", "index"), &QueryResult::is_cell_null); ClassDB::bind_method(D_METHOD("get_last_insert_rowid"), &QueryResult::get_last_insert_rowid); + + ClassDB::bind_method(D_METHOD("get_error_message"), &QueryResult::get_error_message); } diff --git a/modules/database/query_result.h b/modules/database/query_result.h index 66de95726..884b669ae 100644 --- a/modules/database/query_result.h +++ b/modules/database/query_result.h @@ -10,7 +10,6 @@ class QueryResult : public Reference { public: virtual bool next_row(); - virtual const char *get_cell_chr(const int index); virtual String get_cell(const int index); virtual bool get_cell_bool(const int index); virtual int get_cell_int(const int index); @@ -21,6 +20,8 @@ public: virtual int get_last_insert_rowid(); + virtual String get_error_message(); + QueryResult(); virtual ~QueryResult(); diff --git a/modules/database/table_builder.cpp b/modules/database/table_builder.cpp index 8f1c06a15..e32defd42 100644 --- a/modules/database/table_builder.cpp +++ b/modules/database/table_builder.cpp @@ -143,6 +143,9 @@ void TableBuilder::_bind_methods() { ClassDB::bind_method(D_METHOD("foreign_key", "name"), &TableBuilder::_foreign_key_bind); ClassDB::bind_method(D_METHOD("references", "table", "name"), &TableBuilder::_references_bind); + + ClassDB::bind_method(D_METHOD("run"), &TableBuilder::run); + ClassDB::bind_method(D_METHOD("run_query"), &TableBuilder::run_query); } Ref TableBuilder::_create_table_bind(const String &name) { @@ -170,7 +173,7 @@ Ref TableBuilder::_date_bind(const String &name) { } Ref TableBuilder::_varchar_bind(const String &name, const int length) { - return Ref(varchar(name)); + return Ref(varchar(name, length)); } Ref TableBuilder::_text_bind(const String &name) { return Ref(text(name)); diff --git a/modules/database_sqlite/SCsub b/modules/database_sqlite/SCsub index f25c5991b..d0415046b 100644 --- a/modules/database_sqlite/SCsub +++ b/modules/database_sqlite/SCsub @@ -22,16 +22,20 @@ module_env = env.Clone() sources = [ "register_types.cpp", - "sqlite/sqlite3.c" + "sqlite/sqlite3.c", "sqlite3_database.cpp", - "sqlite3_database_connection.cpp", - "sqlite3_database_manager.cpp", + "sqlite3_connection.cpp", "sqlite3_query_builder.cpp", "sqlite3_query_result.cpp", "sqlite3_table_builder.cpp", ] +# sqlite has a few warnings, disable werrors for this module for now +# it should be patched later. +if module_env["werror"]: + module_env["werror"] = False + if ARGUMENTS.get('custom_modules_shared', 'no') == 'yes': # Shared lib compilation module_env.Append(CCFLAGS=['-fPIC']) diff --git a/modules/database_sqlite/config.py b/modules/database_sqlite/config.py index 8f65f5cee..ce252bea3 100644 --- a/modules/database_sqlite/config.py +++ b/modules/database_sqlite/config.py @@ -4,7 +4,7 @@ import sys def can_build(env, platform): - return False + return True def _can_build(): @@ -26,8 +26,6 @@ def _can_build(): # #todo # return False - #print("sqlite3 built in!") - return True @@ -48,8 +46,7 @@ def _configure(env): def get_doc_classes(): return [ - #"", - "Sqlite3Database", + "SQLite3Database ", ] def get_doc_path(): diff --git a/modules/database_sqlite/sqlite3_connection.cpp b/modules/database_sqlite/sqlite3_connection.cpp new file mode 100644 index 000000000..d134bfa5f --- /dev/null +++ b/modules/database_sqlite/sqlite3_connection.cpp @@ -0,0 +1,100 @@ +#include "sqlite3_connection.h" + +#include "core/print_string.h" +#include "core/ustring.h" +#include "sqlite3_query_builder.h" +#include "sqlite3_query_result.h" +#include "sqlite3_table_builder.h" + +#include "./sqlite/sqlite3.h" + +#include + +Ref SQLite3DatabaseConnection::get_query_builder() { + Ref b; + b.instance(); + b->_connection.reference_ptr(this); + + return b; +} + +Ref SQLite3DatabaseConnection::get_table_builder() { + Ref b; + b.instance(); + b->_connection.reference_ptr(this); + + return b; +} + +void SQLite3DatabaseConnection::database_connect(const String &connection_str) { + int ret = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); + if (ret != SQLITE_OK) { + ERR_PRINT("SQLITE3 multithreading is not supported!\n"); + } + + //CharString cstr = connection_str.ascii(); + CharString cstr = connection_str.utf8(); + + ret = sqlite3_open(cstr.get_data(), &conn); +} + +Ref SQLite3DatabaseConnection::query(const String &query) { + Ref res; + res.instance(); + + res->query(query, conn); + + return res; +} + +void SQLite3DatabaseConnection::query_run(const String &query) { + char *err_msg; + + CharString q = query.utf8(); + + if (sqlite3_exec(conn, q.get_data(), NULL, NULL, &err_msg) != SQLITE_OK) { + ERR_PRINT("SQLite3Database::query_run error:"); + ERR_PRINT("Query: " + query); + ERR_PRINT("Error: " + String(err_msg)); + sqlite3_free(err_msg); + } +} + +String SQLite3DatabaseConnection::escape(const String &str) { + char *ret; + + CharString q = str.utf8(); + + ret = sqlite3_mprintf("%q", q.get_data()); + + if (ret) { + String res(ret); + + sqlite3_free(ret); + + return res; + } + + return ""; +} +void SQLite3DatabaseConnection::escape_to(const String &str, String *to) { + char *ret; + + ret = sqlite3_mprintf("%q", str.c_str()); + + if (ret) { + to->operator=(ret); + + sqlite3_free(ret); + } +} + +SQLite3DatabaseConnection::SQLite3DatabaseConnection() { + conn = nullptr; +} + +SQLite3DatabaseConnection::~SQLite3DatabaseConnection() { + if (conn) { + sqlite3_close(conn); + } +} diff --git a/modules/database_sqlite/sqlite3_connection.h b/modules/database_sqlite/sqlite3_connection.h new file mode 100644 index 000000000..b412aac40 --- /dev/null +++ b/modules/database_sqlite/sqlite3_connection.h @@ -0,0 +1,33 @@ +#ifndef SQLITE3_DATABASE_CONNECTION_H +#define SQLITE3_DATABASE_CONNECTION_H + +#include "../database/database_connection.h" + +#include "./sqlite/sqlite3.h" + +class QueryBuilder; +class TableBuilder; +class QueryResult; +class Database; +struct sqlite3; + +class SQLite3DatabaseConnection : public DatabaseConnection { +public: + void database_connect(const String &connection_str); + Ref query(const String &query); + void query_run(const String &query); + + Ref get_query_builder(); + Ref get_table_builder(); + + String escape(const String &str); + void escape_to(const String &str, String *to); + + SQLite3DatabaseConnection(); + ~SQLite3DatabaseConnection(); + +protected: + sqlite3 *conn; +}; + +#endif diff --git a/modules/database_sqlite/sqlite3_database.cpp b/modules/database_sqlite/sqlite3_database.cpp index abeb3ae5e..2b3926729 100644 --- a/modules/database_sqlite/sqlite3_database.cpp +++ b/modules/database_sqlite/sqlite3_database.cpp @@ -1,95 +1,17 @@ #include "sqlite3_database.h" -#include "database/database_manager.h" +#include "sqlite3_connection.h" -#include "sqlite3_query_builder.h" -#include "sqlite3_query_result.h" -#include "sqlite3_table_builder.h" - -Database *SQLite3Database::_creation_func() { - return new SQLite3Database(); +Ref SQLite3Database::_allocate_connection() { + Ref dbc; + dbc.instance(); + dbc->set_owner(this); + dbc->database_connect(_connection_string); + return dbc; } -void SQLite3Database::_register() { - DatabaseManager::_register_db_creation_func("sqlite", SQLite3Database::_creation_func); -} - -void SQLite3Database::_unregister() { - DatabaseManager::_unregister_db_creation_func("sqlite"); -} - -Ref SQLite3Database::get_query_builder() { - SQLite3QueryBuilder *b = new SQLite3QueryBuilder(); - b->_db = this; - - return b; -} - -Ref SQLite3Database::get_table_builder() { - SQLite3TableBuilder *b = new SQLite3TableBuilder(); - b->_db = this; - - return b; -} - -void SQLite3Database::connect(const String &connection_str) { - int ret = sqlite3_config(SQLITE_CONFIG_MULTITHREAD); - if (ret != SQLITE_OK) { - printf("SQLITE3 multithreading is not supported!\n"); - } - - ret = sqlite3_open(connection_str.c_str(), &conn); -} - -Ref SQLite3Database::query(const String &query) { - Sqlite3QueryResult *res = new Sqlite3QueryResult(); - - res->query(query, conn); - - return res; -} - -void SQLite3Database::query_run(const String &query) { - char *err_msg; - - if (sqlite3_exec(conn, query.c_str(), NULL, NULL, &err_msg) != SQLITE_OK) { - printf("SQLite3Database::query_run error: \nQuery: %s \n Error:\n %s\n", query.c_str(), err_msg); - sqlite3_free(err_msg); - } -} - -String SQLite3Database::escape(const String str) { - char *ret; - - ret = sqlite3_mprintf("%q", str.c_str()); - - if (ret) { - String res(ret); - - sqlite3_free(ret); - - return res; - } - - return ""; -} -void SQLite3Database::escape(const String str, String *to) { - char *ret; - - ret = sqlite3_mprintf("%q", str.c_str()); - - if (ret) { - to->operator=(ret); - - sqlite3_free(ret); - } -} - -SQLite3Database::SQLite3Database() : - Database() { +SQLite3Database::SQLite3Database() { } SQLite3Database::~SQLite3Database() { - if (conn) - sqlite3_close(conn); } diff --git a/modules/database_sqlite/sqlite3_database.h b/modules/database_sqlite/sqlite3_database.h index 6771dc227..ed31aa609 100644 --- a/modules/database_sqlite/sqlite3_database.h +++ b/modules/database_sqlite/sqlite3_database.h @@ -1,40 +1,17 @@ -#ifndef SQLITE3_CONNECTION -#define SQLITE3_CONNECTION +#ifndef SQLITE3_DATABASE_H +#define SQLITE3_DATABASE_H -#include "database/database.h" +#include "../database/database_single_threaded.h" -//Brynet has it aswell, and because of using namespace it is defined here aswell -//later this will be fixed better -//#ifdef IS_NUM -//#undef IS_NUM -//#endif +class SQLite3Database : public DatabaseSingleThreaded { + GDCLASS(SQLite3Database, DatabaseSingleThreaded); -#include - -#include "./sqlite/sqlite3.h" - -class SQLite3Database : public Database { public: - static Database *_creation_func(); - static void _register(); - static void _unregister(); - - Ref get_query_builder(); - Ref get_table_builder(); - - void connect(const String &connection_str); - Ref query(const String &query); - void query_run(const String &query); - - String escape(const String str); - void escape(const String str, String *to); - SQLite3Database(); ~SQLite3Database(); - sqlite3 *conn; +protected: + Ref _allocate_connection(); }; -//#undef IS_NUM - -#endif \ No newline at end of file +#endif diff --git a/modules/database_sqlite/sqlite3_query_builder.cpp b/modules/database_sqlite/sqlite3_query_builder.cpp index 5dc8ba6f4..3b4477203 100644 --- a/modules/database_sqlite/sqlite3_query_builder.cpp +++ b/modules/database_sqlite/sqlite3_query_builder.cpp @@ -1,10 +1,9 @@ #include "sqlite3_query_builder.h" +#include "sqlite3_connection.h" #include "sqlite3_database.h" #include "sqlite3_query_result.h" -#include - QueryBuilder *SQLite3QueryBuilder::select() { query_result += "SELECT "; @@ -21,34 +20,14 @@ QueryBuilder *SQLite3QueryBuilder::del() { return this; } -QueryBuilder *SQLite3QueryBuilder::where() { - query_result += "WHERE "; - - return this; -} -QueryBuilder *SQLite3QueryBuilder::from() { - query_result += "FROM "; - - return this; -} -QueryBuilder *SQLite3QueryBuilder::insert() { - query_result += "INSERT INTO "; - - return this; -} -QueryBuilder *SQLite3QueryBuilder::values() { - query_result += "VALUES("; - - return this; -} QueryBuilder *SQLite3QueryBuilder::cvalues() { - query_result[query_result.size() - 2] = ' '; + query_result[query_result.length() - 2] = ' '; query_result += ") "; return this; } QueryBuilder *SQLite3QueryBuilder::next_value() { - query_result[query_result.size() - 2] = ' '; + query_result[query_result.length() - 2] = ' '; query_result += "), ("; return this; @@ -76,52 +55,83 @@ QueryBuilder *SQLite3QueryBuilder::cstr() { return this; } -QueryBuilder *SQLite3QueryBuilder::like() { - query_result += "LIKE "; +QueryBuilder *SQLite3QueryBuilder::like(const String &str) { + if (str == "") { + query_result += "LIKE "; + } else { + nlike(escape(str)); + } return this; } QueryBuilder *SQLite3QueryBuilder::nselect(const String ¶ms) { - query_result += "SELECT " + params + " "; + query_result += "SELECT "; + query_result += params; + query_result += " "; return this; } QueryBuilder *SQLite3QueryBuilder::nupdate(const String ¶ms) { - query_result += "UPDATE " + params + " "; + query_result += "UPDATE "; + query_result += params; + query_result += " "; return this; } QueryBuilder *SQLite3QueryBuilder::ndel(const String ¶ms) { - query_result += "DELETE FROM " + params + " "; + query_result += "DELETE FROM "; + query_result += params; + query_result += " "; return this; } QueryBuilder *SQLite3QueryBuilder::nwhere(const String ¶ms) { - query_result += "WHERE " + params + " "; + query_result += "WHERE "; + + if (params != "") { + query_result += params; + query_result += " "; + } return this; } QueryBuilder *SQLite3QueryBuilder::nfrom(const String ¶ms) { - query_result += "FROM " + params + " "; + query_result += "FROM "; + + if (params != "") { + query_result += params; + query_result += " "; + } return this; } -QueryBuilder *SQLite3QueryBuilder::insert(const String &table_name) { - query_result += "INSERT INTO " + table_name + " "; - - return this; -} QueryBuilder *SQLite3QueryBuilder::insert(const String &table_name, const String &columns) { - query_result += "INSERT INTO " + table_name + "(" + columns + ") "; + query_result += "INSERT INTO "; + + if (table_name != "") { + query_result += table_name; + query_result += " "; + } + + if (columns != "") { + query_result += "("; + query_result += columns; + query_result += ") "; + } return this; } QueryBuilder *SQLite3QueryBuilder::nvalues(const String ¶ms_str) { - query_result += "VALUES(" + params_str + ") "; + query_result += "VALUES("; + + if (params_str != "") { + query_result += params_str; + query_result += ") "; + } return this; } @@ -133,160 +143,174 @@ QueryBuilder *SQLite3QueryBuilder::val() { } QueryBuilder *SQLite3QueryBuilder::nval(const String ¶m) { - query_result += "'" + param + "', "; + query_result += "'"; + query_result += param; + query_result += "', "; return this; } -QueryBuilder *SQLite3QueryBuilder::val(const char *param) { - query_result += "'" + String(param) + "', "; +QueryBuilder *SQLite3QueryBuilder::vals(const String ¶m) { + query_result += "'"; + query_result += param; + query_result += "', "; + + return this; +} +QueryBuilder *SQLite3QueryBuilder::vals(const char *param) { + query_result += "'"; + query_result += String(param); + query_result += "', "; return this; } -QueryBuilder *SQLite3QueryBuilder::val(const int param) { - //todo add a better way - std::stringstream ss; - ss << param; - - query_result += ss.str() + ", "; +QueryBuilder *SQLite3QueryBuilder::vali(const int param) { + query_result += itos(param); + query_result += ", "; return this; } -QueryBuilder *SQLite3QueryBuilder::val(const bool param) { - if (param) +QueryBuilder *SQLite3QueryBuilder::valb(const bool param) { + if (param) { query_result += "1, "; - else + } else { query_result += "0, "; + } return this; } QueryBuilder *SQLite3QueryBuilder::valf(const float param) { - //todo add a better way - std::stringstream ss; - ss << param; - - query_result += ss.str() + ", "; + query_result += String::num(param); + query_result += ", "; return this; } QueryBuilder *SQLite3QueryBuilder::vald(const double param) { - //todo add a better way - std::stringstream ss; - ss << param; - - query_result += ss.str() + ", "; + query_result += String::num(param); + query_result += ", "; return this; } QueryBuilder *SQLite3QueryBuilder::nlike(const String &str) { - query_result += "LIKE '" + str + "' "; + query_result += "LIKE '"; + query_result += str; + query_result += "' "; return this; } -QueryBuilder *SQLite3QueryBuilder::set() { +QueryBuilder *SQLite3QueryBuilder::sets() { query_result += "SET "; return this; } QueryBuilder *SQLite3QueryBuilder::cset() { - query_result[query_result.size() - 2] = ' '; + query_result[query_result.length() - 2] = ' '; return this; } QueryBuilder *SQLite3QueryBuilder::nsetp(const String &col, const String ¶m) { - query_result += col + "='" + param + "', "; + query_result += col + "='"; + query_result += col + param; + query_result += col + "', "; return this; } -QueryBuilder *SQLite3QueryBuilder::setp(const String &col, const char *param) { - query_result += col + "='" + String(param) + "', "; +QueryBuilder *SQLite3QueryBuilder::setps(const String &col, const char *param) { + query_result += col; + query_result += "='"; + query_result += String(param); + query_result += "', "; return this; } -QueryBuilder *SQLite3QueryBuilder::setp(const String &col, const int param) { - //todo add a better way - std::stringstream ss; - ss << param; - - query_result += col + "=" + ss.str() + ", "; +QueryBuilder *SQLite3QueryBuilder::setpi(const String &col, const int param) { + query_result += col; + query_result += "="; + query_result += itos(param); + query_result += ", "; return this; } -QueryBuilder *SQLite3QueryBuilder::setp(const String &col, const bool param) { - if (param) - query_result += col + "=1, "; - else - query_result += col + "=0, "; +QueryBuilder *SQLite3QueryBuilder::setpb(const String &col, const bool param) { + if (param) { + query_result += col; + query_result += "=1, "; + } else { + query_result += col; + query_result += "=0, "; + } return this; } QueryBuilder *SQLite3QueryBuilder::setpf(const String &col, const float param) { - //todo add a better way - std::stringstream ss; - ss << param; - - query_result += col + "=" + ss.str() + ", "; + query_result += col; + query_result += "="; + query_result += String::num(param); + query_result += ", "; return this; } QueryBuilder *SQLite3QueryBuilder::setpd(const String &col, const double param) { - //todo add a better way - std::stringstream ss; - ss << param; - - query_result += col + "=" + ss.str() + ", "; + query_result += col; + query_result += "="; + query_result += String::num(param); + query_result += ", "; return this; } QueryBuilder *SQLite3QueryBuilder::nwp(const String &col, const String ¶m) { - query_result += col + "='" + param + "' "; + query_result += col; + query_result += "='"; + query_result += param; + query_result += "' "; return this; } -QueryBuilder *SQLite3QueryBuilder::wp(const String &col, const char *param) { - query_result += col + "='" + String(param) + "' "; +QueryBuilder *SQLite3QueryBuilder::wps(const String &col, const char *param) { + query_result += col; + query_result += "='"; + query_result += String(param); + query_result += "' "; return this; } -QueryBuilder *SQLite3QueryBuilder::wp(const String &col, const int param) { - //todo add a better way - std::stringstream ss; - ss << param; - - query_result += col + "=" + ss.str() + " "; +QueryBuilder *SQLite3QueryBuilder::wpi(const String &col, const int param) { + query_result += col; + query_result += "="; + query_result += itos(param); + query_result += " "; return this; } -QueryBuilder *SQLite3QueryBuilder::wp(const String &col, const bool param) { - if (param) - query_result += col + "=1 "; - else - query_result += col + "=0 "; +QueryBuilder *SQLite3QueryBuilder::wpb(const String &col, const bool param) { + if (param) { + query_result += col; + query_result += "=1 "; + } else { + query_result += col; + query_result += "=0 "; + } return this; } QueryBuilder *SQLite3QueryBuilder::limit(const int num) { - //todo better way - std::stringstream ss; - ss << num; - - query_result += "LIMIT " + ss.str() + " "; + query_result += "LIMIT "; + query_result += itos(num); + query_result += " "; return this; } QueryBuilder *SQLite3QueryBuilder::offset(const int num) { - //todo better way - std::stringstream ss; - ss << num; - - query_result += "OFFSET " + ss.str() + " "; + query_result += "OFFSET "; + query_result += itos(num); + query_result += " "; return this; } @@ -309,13 +333,13 @@ QueryBuilder *SQLite3QueryBuilder::wildcard() { } String SQLite3QueryBuilder::escape(const String ¶ms) { - if (!_db) { + if (!_connection.is_valid()) { printf("SQLite3QueryBuilder::escape !db!\n"); return ""; } - return _db->escape(params); + return _connection->escape(params); } QueryBuilder *SQLite3QueryBuilder::prepare() { @@ -339,23 +363,23 @@ QueryBuilder *SQLite3QueryBuilder::end_command() { } Ref SQLite3QueryBuilder::run() { - if (!_db) { + if (!_connection.is_valid()) { printf("SQLite3QueryBuilder::run !db!\n"); return nullptr; } - return _db->query(query_result); + return _connection->query(query_result); } void SQLite3QueryBuilder::run_query() { - if (!_db) { + if (!_connection.is_valid()) { printf("SQLite3QueryBuilder::run_query !db!\n"); return; } - _db->query_run(query_result); + _connection->query_run(query_result); } QueryBuilder *SQLite3QueryBuilder::select_last_insert_id() { @@ -365,4 +389,4 @@ QueryBuilder *SQLite3QueryBuilder::select_last_insert_id() { SQLite3QueryBuilder::SQLite3QueryBuilder() { } SQLite3QueryBuilder::~SQLite3QueryBuilder() { -} \ No newline at end of file +} diff --git a/modules/database_sqlite/sqlite3_query_builder.h b/modules/database_sqlite/sqlite3_query_builder.h index 42925be22..21d170fc7 100644 --- a/modules/database_sqlite/sqlite3_query_builder.h +++ b/modules/database_sqlite/sqlite3_query_builder.h @@ -1,25 +1,20 @@ #ifndef SQLITE3_QUERY_BUILDER_H #define SQLITE3_QUERY_BUILDER_H -#include -#include +#include "core/ustring.h" -#include "database/query_builder.h" +#include "../database/query_builder.h" -class SQLite3Database; +class SQLite3DatabaseConnection; class SQLite3QueryBuilder : public QueryBuilder { - RCPP_OBJECT(SQLite3QueryBuilder, QueryBuilder); + GDCLASS(SQLite3QueryBuilder, QueryBuilder); public: QueryBuilder *select(); QueryBuilder *update(); QueryBuilder *del(); - QueryBuilder *where(); - QueryBuilder *from(); - QueryBuilder *insert(); - QueryBuilder *values(); QueryBuilder *cvalues(); QueryBuilder *next_value(); @@ -29,7 +24,7 @@ public: QueryBuilder *str(); QueryBuilder *cstr(); - QueryBuilder *like(); + QueryBuilder *like(const String &str = ""); QueryBuilder *nselect(const String ¶ms); QueryBuilder *nupdate(const String ¶ms); @@ -37,32 +32,37 @@ public: QueryBuilder *nwhere(const String ¶ms); QueryBuilder *nfrom(const String ¶ms); - QueryBuilder *insert(const String &table_name); - QueryBuilder *insert(const String &table_name, const String &columns); + + QueryBuilder *insert(const String &table_name = "", const String &columns = ""); QueryBuilder *nvalues(const String ¶ms_str); QueryBuilder *val(); QueryBuilder *nval(const String ¶m); - QueryBuilder *val(const char *param); - QueryBuilder *val(const int param); - QueryBuilder *val(const bool param); + + QueryBuilder *vals(const String ¶m); + QueryBuilder *vals(const char *param); + QueryBuilder *vali(const int param); + QueryBuilder *valb(const bool param); QueryBuilder *valf(const float param); QueryBuilder *vald(const double param); QueryBuilder *nlike(const String &str); - QueryBuilder *set(); + QueryBuilder *sets(); QueryBuilder *cset(); + QueryBuilder *nsetp(const String &col, const String ¶m); - QueryBuilder *setp(const String &col, const char *param); - QueryBuilder *setp(const String &col, const int param); - QueryBuilder *setp(const String &col, const bool param); + + QueryBuilder *setps(const String &col, const char *param); + QueryBuilder *setpi(const String &col, const int param); + QueryBuilder *setpb(const String &col, const bool param); QueryBuilder *setpf(const String &col, const float param); QueryBuilder *setpd(const String &col, const double param); QueryBuilder *nwp(const String &col, const String ¶m); - QueryBuilder *wp(const String &col, const char *param); - QueryBuilder *wp(const String &col, const int param); - QueryBuilder *wp(const String &col, const bool param); + + QueryBuilder *wps(const String &col, const char *param); + QueryBuilder *wpi(const String &col, const int param); + QueryBuilder *wpb(const String &col, const bool param); QueryBuilder *limit(const int num); QueryBuilder *offset(const int num); @@ -90,7 +90,7 @@ public: SQLite3QueryBuilder(); ~SQLite3QueryBuilder(); - SQLite3Database *_db; + Ref _connection; }; -#endif \ No newline at end of file +#endif diff --git a/modules/database_sqlite/sqlite3_query_result.cpp b/modules/database_sqlite/sqlite3_query_result.cpp index b6c638b25..005d9f83c 100644 --- a/modules/database_sqlite/sqlite3_query_result.cpp +++ b/modules/database_sqlite/sqlite3_query_result.cpp @@ -1,13 +1,16 @@ #include "sqlite3_query_result.h" +#include "./sqlite/sqlite3.h" +#include "core/print_string.h" +#include "core/ustring.h" #include bool Sqlite3QueryResult::next_row() { return ++current_row < rows.size(); } -const char *Sqlite3QueryResult::get_cell(const int index) { - return rows[current_row]->cells[index].data.c_str(); +String Sqlite3QueryResult::get_cell(const int index) { + return rows[current_row]->cells[index].data; } bool Sqlite3QueryResult::is_cell_null(const int index) { @@ -18,11 +21,19 @@ int Sqlite3QueryResult::get_last_insert_rowid() { return sqlite3_last_insert_rowid(_connection); } +String Sqlite3QueryResult::get_error_message() { + return String(err_msg); +} + void Sqlite3QueryResult::query(const String &query, sqlite3 *conn) { _connection = conn; - if (sqlite3_exec(conn, query.c_str(), Sqlite3QueryResult::run_query_finished, this, &err_msg) != SQLITE_OK) { - printf("SQLite3Database::query error: \nQuery: %s \n Error:\n %s\n", query.c_str(), err_msg); + CharString q = query.utf8(); + + if (sqlite3_exec(conn, q.get_data(), Sqlite3QueryResult::run_query_finished, this, &err_msg) != SQLITE_OK) { + ERR_PRINT("SQLite3Database::query error: "); + ERR_PRINT("Query: " + query); + ERR_PRINT("Error: " + String(err_msg)); sqlite3_free(err_msg); } } @@ -32,7 +43,7 @@ int Sqlite3QueryResult::run_query_finished(void *data, int argc, char **argv, ch //res->col_names = col_names; - Sqlite3QueryResultRow *r = new Sqlite3QueryResultRow(); + Sqlite3QueryResultRow *r = memnew(Sqlite3QueryResultRow); for (int i = 0; i < argc; ++i) { Cell c; @@ -51,14 +62,13 @@ int Sqlite3QueryResult::run_query_finished(void *data, int argc, char **argv, ch return 0; } -Sqlite3QueryResult::Sqlite3QueryResult() : - QueryResult() { +Sqlite3QueryResult::Sqlite3QueryResult() { err_msg = nullptr; current_row = -1; } Sqlite3QueryResult::~Sqlite3QueryResult() { for (int i = 0; i < rows.size(); ++i) { - delete rows[i]; + memdelete(rows[i]); } -} \ No newline at end of file +} diff --git a/modules/database_sqlite/sqlite3_query_result.h b/modules/database_sqlite/sqlite3_query_result.h index ebe4c8977..1838b9e87 100644 --- a/modules/database_sqlite/sqlite3_query_result.h +++ b/modules/database_sqlite/sqlite3_query_result.h @@ -1,23 +1,22 @@ -#ifndef MYSQL_QUERY_RESULT_H -#define MYSQL_QUERY_RESULT_H +#ifndef SQLITE3_QUERY_RESULT_H +#define SQLITE3_QUERY_RESULT_H -#include "core/string.h" -#include +#include "core/ustring.h" +#include "core/vector.h" -#include "database/query_result.h" +#include "../database/query_result.h" -#include "./sqlite/sqlite3.h" +struct sqlite3; class Sqlite3QueryResult : public QueryResult { - RCPP_OBJECT(Sqlite3QueryResult, QueryResult); + GDCLASS(Sqlite3QueryResult, QueryResult); public: bool next_row(); - const char* get_cell(const int index); - + String get_cell(const int index); bool is_cell_null(const int index); - int get_last_insert_rowid(); + String get_error_message(); void query(const String &query, sqlite3 *conn); @@ -26,9 +25,7 @@ public: Sqlite3QueryResult(); ~Sqlite3QueryResult(); - char* err_msg; - -public: +protected: struct Cell { bool null; String data; @@ -39,14 +36,15 @@ public: }; struct Sqlite3QueryResultRow { - std::vector cells; + Vector cells; }; char **col_names; - std::vector rows; + Vector rows; int current_row; + char *err_msg; sqlite3 *_connection; }; -#endif \ No newline at end of file +#endif diff --git a/modules/database_sqlite/sqlite3_table_builder.cpp b/modules/database_sqlite/sqlite3_table_builder.cpp index 2e0f53be1..5dd1139ab 100644 --- a/modules/database_sqlite/sqlite3_table_builder.cpp +++ b/modules/database_sqlite/sqlite3_table_builder.cpp @@ -1,8 +1,8 @@ #include "sqlite3_table_builder.h" -#include "database/query_result.h" +#include "../database/query_result.h" -#include "sqlite3_database.h" +#include "sqlite3_connection.h" TableBuilder *SQLite3TableBuilder::create_table(const String &name) { result += "CREATE TABLE " + name + " ( "; @@ -10,61 +10,52 @@ TableBuilder *SQLite3TableBuilder::create_table(const String &name) { return this; } -TableBuilder *SQLite3TableBuilder::integer(const String &name) { +TableBuilder *SQLite3TableBuilder::integer(const String &name, const int length) { result += name + " INTEGER "; - return this; -} -TableBuilder *SQLite3TableBuilder::integer(const String &name, const int length) { - result += name + " INTEGER("; - result += String::num(length); - result += ") "; + if (length != -1) { + result += "("; + result += itos(length); + result += ") "; + } return this; } -TableBuilder *SQLite3TableBuilder::tiny_integer(const String &name) { - result += name + " INTEGER(4) "; - - return this; -} TableBuilder *SQLite3TableBuilder::tiny_integer(const String &name, const int length) { result += name + " INTEGER("; - result += String::num(length); + + if (length == -1) { + result += "4"; + } else { + result += itos(length); + } + result += ") "; return this; } -TableBuilder *SQLite3TableBuilder::small_integer(const String &name) { - result += name + " INTEGER(6) "; - - return this; -} TableBuilder *SQLite3TableBuilder::small_integer(const String &name, const int length) { result += name + " INTEGER("; - result += String::num(length); + + if (length == -1) { + result += "6"; + } else { + result += itos(length); + } + result += ") "; return this; } -TableBuilder *SQLite3TableBuilder::real_float(const String &name) { - result += name + " FLOAT "; - - return this; -} TableBuilder *SQLite3TableBuilder::real_float(const String &name, const int size, const int d) { result += name + " FLOAT "; return this; } -TableBuilder *SQLite3TableBuilder::real_double(const String &name) { - result += name + " DOUBLE "; - - return this; -} TableBuilder *SQLite3TableBuilder::real_double(const String &name, const int size, const int d) { result += name + " DOUBLE "; @@ -78,7 +69,13 @@ TableBuilder *SQLite3TableBuilder::date(const String &name) { } TableBuilder *SQLite3TableBuilder::varchar(const String &name, const int length) { - result += name + " VARCHAR(" + std::to_string(length) + ") "; + result += name + " VARCHAR "; + + if (length != -1) { + result += "("; + result += itos(length); + result += ") "; + } return this; } @@ -177,27 +174,27 @@ TableBuilder *SQLite3TableBuilder::references(const String &table, const String } Ref SQLite3TableBuilder::run() { - if (!_db) { + if (!_connection.is_valid()) { printf("SQLite3TableBuilder::run !db!\n"); return nullptr; } - return _db->query(result); + return _connection->query(result); } void SQLite3TableBuilder::run_query() { - if (!_db) { + if (!_connection.is_valid()) { printf("SQLite3TableBuilder::run_query !db!\n"); return; } - _db->query_run(result); + _connection->query_run(result); } SQLite3TableBuilder::SQLite3TableBuilder() { } SQLite3TableBuilder::~SQLite3TableBuilder() { -} \ No newline at end of file +} diff --git a/modules/database_sqlite/sqlite3_table_builder.h b/modules/database_sqlite/sqlite3_table_builder.h index 421fe6d29..a4211ba21 100644 --- a/modules/database_sqlite/sqlite3_table_builder.h +++ b/modules/database_sqlite/sqlite3_table_builder.h @@ -1,63 +1,54 @@ #ifndef SQLITE3_TABLE_BUILDER_H #define SQLITE3_TABLE_BUILDER_H -#include "core/string.h" +#include "core/ustring.h" -#include "database/table_builder.h" +#include "../database/table_builder.h" -class SQLite3Database; +class SQLite3DatabaseConnection; class SQLite3TableBuilder : public TableBuilder { - RCPP_OBJECT(SQLite3TableBuilder, TableBuilder); + GDCLASS(SQLite3TableBuilder, TableBuilder); public: TableBuilder *create_table(const String &name); - TableBuilder *integer(const String &name); - TableBuilder *integer(const String &name, const int length); - - TableBuilder *tiny_integer(const String &name); - TableBuilder *tiny_integer(const String &name, const int length); - - TableBuilder *small_integer(const String &name); - TableBuilder *small_integer(const String &name, const int length); - - TableBuilder *real_float(const String &name); - TableBuilder *real_float(const String &name, const int size, const int d); - - TableBuilder *real_double(const String &name); - TableBuilder *real_double(const String &name, const int size, const int d); + TableBuilder *integer(const String &name, const int length = -1); + TableBuilder *tiny_integer(const String &name, const int length = -1); + TableBuilder *small_integer(const String &name, const int length = -1); + TableBuilder *real_float(const String &name, const int size = -1, const int d = -1); + TableBuilder *real_double(const String &name, const int size = -1, const int d = -1); TableBuilder *date(const String &name); - TableBuilder *varchar(const String &name, const int length); + TableBuilder *varchar(const String &name, const int length = -1); TableBuilder *text(const String &name); TableBuilder *not_null(); TableBuilder *null(); TableBuilder *defval(const String &val); TableBuilder *auto_increment(); - TableBuilder *primary_key(const String &name); + TableBuilder *primary_key(const String &name = ""); TableBuilder *primary_key(); TableBuilder *next_row(); TableBuilder *ccreate_table(); TableBuilder *drop_table(); TableBuilder *drop_table_if_exists(); - TableBuilder *drop_table(const String &name); + TableBuilder *drop_table(const String &name = ""); TableBuilder *drop_table_if_exists(const String &name); TableBuilder *cdrop_table(); TableBuilder *foreign_key(const String &name); TableBuilder *references(const String &table, const String &name); - virtual Ref run(); - virtual void run_query(); + Ref run(); + void run_query(); SQLite3TableBuilder(); - virtual ~SQLite3TableBuilder(); + ~SQLite3TableBuilder(); - SQLite3Database *_db; + Ref _connection; }; -#endif \ No newline at end of file +#endif