added sqlite db backend progress

This commit is contained in:
2023-11-09 19:55:59 +01:00
parent 8b5859d858
commit ae236746ad
24 changed files with 303 additions and 72 deletions
+4 -2
View File
@@ -10,7 +10,8 @@ set(SQL_SOURCES
sql/connection_info.cpp
sql/connection_impl.cpp
sql/session.cpp
sql/backend_provider.cpp)
sql/backend_provider.cpp
sql/query_result_impl.cpp)
set(SQL_HEADER
../include/matador/sql/dialect.hpp
@@ -29,7 +30,8 @@ set(SQL_HEADER
../include/matador/sql/connection_info.hpp
../include/matador/sql/connection_pool.hpp
../include/matador/sql/session.hpp
../include/matador/sql/backend_provider.hpp)
../include/matador/sql/backend_provider.hpp
../include/matador/sql/query_result_impl.hpp)
set(UTILS_HEADER
../include/matador/utils/field_attributes.hpp
+25 -9
View File
@@ -1,35 +1,51 @@
#include "matador/sql/backend_provider.hpp"
#include "matador/utils/os.hpp"
#include <cstdint>
#include <stdexcept>
#include <utility>
namespace matador::sql {
backend_provider::backend_provider(std::string backends_path)
: backends_path_(std::move(backends_path)) {}
backend_provider::backend_provider()
: backends_path_(utils::os::getenv("MATADOR_BACKENDS_PATH"))
{}
connection_impl *backend_provider::create_connection(const std::string &connection_type)
backend_provider &backend_provider::instance() {
static backend_provider provider;
return provider;
}
connection_impl *backend_provider::create_connection(const std::string &connection_type, const connection_info &info)
{
auto it = backends_.find(connection_type);
if (it == backends_.end()) {
it = backends_.emplace(connection_type, backend_context{connection_type, backends_path_}).first;
it = backends_.emplace(connection_type, std::make_unique<backend_context>(connection_type, backends_path_)).first;
}
return (*it->second.create_connection)();
return (*it->second->create_connection)(info);
}
void backend_provider::destroy_connection(const std::string &connection_type, connection_impl *c)
{
auto it = backends_.find(connection_type);
if (it == backends_.end()) {
it = backends_.emplace(connection_type, std::make_unique<backend_context>(connection_type, backends_path_)).first;
}
(*it->second->destroy_connection)(c);
}
const dialect &backend_provider::connection_dialect(const std::string &connection_type)
{
auto it = backends_.find(connection_type);
if (it == backends_.end()) {
it = backends_.emplace(connection_type, backend_context{connection_type, backends_path_}).first;
it = backends_.emplace(connection_type, std::make_unique<backend_context>(connection_type, backends_path_)).first;
}
return *(*it->second.get_dialect)();
return *(*it->second->get_dialect)();
}
backend_provider::backend_context::backend_context(const std::string &connection_type,
const std::string &backends_path)
{
if (!lib.load(backends_path + "matador-" + connection_type)) {
if (!lib.load("matador-" + connection_type)) {
throw std::runtime_error("couldn't load library '" + connection_type + "'");
}
+28 -9
View File
@@ -1,30 +1,49 @@
#include <utility>
#include "matador/sql/connection.hpp"
#include "matador/sql/backend_provider.hpp"
#include "matador/sql/connection_impl.hpp"
#include <utility>
namespace matador::sql {
connection::connection(std::string dns)
: dns_(std::move(dns)) {}
connection::connection(connection_info info)
: connection_info_(std::move(info))
{
connection_ = backend_provider::instance().create_connection(connection_info_.type, connection_info_);
}
connection::connection(const std::string& dns)
: connection(connection_info::parse(dns))
{}
connection::~connection()
{
if (connection_->is_open()) {
connection_->close();
}
backend_provider::instance().destroy_connection(connection_info_.type, connection_);
connection_ = nullptr;
}
void connection::open()
{
is_open_ = true;
connection_->open();
}
void connection::close()
{
is_open_ = false;
connection_->close();
}
bool connection::is_open() const
{
return is_open_;
return connection_->is_open();
}
const std::string &connection::dns() const
const connection_info &connection::info() const
{
return dns_;
return connection_info_;
}
query_result<record> connection::fetch(const std::string &sql)
+2 -4
View File
@@ -1,11 +1,9 @@
#include <utility>
#include "matador/sql/connection_impl.hpp"
namespace matador::sql {
connection_impl::connection_impl(connection_info info)
: info_(std::move(info)){}
connection_impl::connection_impl(const connection_info &info)
: info_(info){}
const connection_info &connection_impl::info() const {
return info_;
+25
View File
@@ -0,0 +1,25 @@
#include "matador/sql/query_result_impl.hpp"
namespace matador::sql {
void query_result_impl::on_primary_key(const char *id, std::string &value, size_t size)
{
read_value(id, column_index_++, value, size);
}
void query_result_impl::on_revision(const char *id, unsigned long long int &rev)
{
read_value(id, column_index_++, rev);
}
void query_result_impl::on_attribute(const char *id, char *value, const utils::field_attributes &attr)
{
read_value(id, column_index_++, value, attr.size());
}
void query_result_impl::on_attribute(const char *id, std::string &value, const utils::field_attributes &attr)
{
read_value(id, column_index_++, value, attr.size());
}
}
+3 -1
View File
@@ -1,12 +1,14 @@
#include "matador/sql/session.hpp"
#include "matador/sql/backend_provider.hpp"
#include <stdexcept>
namespace matador::sql {
session::session(connection_pool<connection> &pool)
: pool_(pool)
, query_(dialect_) {}
, query_(backend_provider::instance().connection_dialect(pool.info().type)) {}
query_create_intermediate session::create()
{
+9 -3
View File
@@ -1,4 +1,5 @@
#include "matador/utils/library.hpp"
#include "matador/utils/os.hpp"
namespace matador::utils {
@@ -13,16 +14,20 @@ library::~library()
bool library::load()
{
auto path = os::getenv("MATADOR_BACKENDS_PATH");
#if defined(_MSC_VER) || defined(__MINGW32__)
handle_ = LoadLibrary((lib_ + ".dll").c_str());
auto cookie = AddDllDirectory(std::wstring(path.begin(), path.end()).c_str());
handle_ = LoadLibraryExA((lib_ + ".dll").c_str(), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
RemoveDllDirectory(cookie);
#elif defined(__APPLE__)
handle_ = dlopen(std::string("lib" + lib_ + ".dylib").c_str(), RTLD_LAZY);
#else
handle_ = dlopen(std::string("./lib" + lib_ + ".so").c_str(), RTLD_LAZY);
handle_ = dlopen((path + "/lib" + lib_ + ".so").c_str(), RTLD_LAZY);
#endif
if (!handle_) {
#if defined(_MSC_VER) || defined(__MINGW32__)
DWORD errorMessageID = ::GetLastError();
auto errstr = utils::os::error_string(errorMessageID);
#else
// TODO: handle win32 and linux error
fprintf(stdout, "dlopen error: %s", dlerror());
@@ -61,7 +66,8 @@ bool library::unload()
func_ptr library::function(const std::string &f) const
{
#if defined(_MSC_VER) || defined(__MINGW32__)
return GetProcAddress(handle_, f.c_str());
auto *addr = GetProcAddress(handle_, f.c_str());
return addr;
#else
return dlsym(handle_, f.c_str());
#endif
+25 -1
View File
@@ -2,6 +2,10 @@
#include <stdexcept>
#ifdef _WIN32
#include <windows.h>
#endif
namespace matador::utils::os {
std::string getenv(const char *name) {
@@ -10,8 +14,9 @@ std::string getenv(const char *name) {
size_t len{};
const auto error = getenv_s(&len, var, 1024, name);
if (error > 0) {
throw std::logic_error("failed to get environment variable");
throw std::logic_error(error_string(error));
};
return var;
#else
return ::getenv(name);
@@ -21,4 +26,23 @@ std::string getenv(const char *name) {
[[maybe_unused]] std::string getenv(const std::string &name) {
return getenv(name.c_str());
}
#ifdef _WIN32
std::string error_string(unsigned long error) {
char* lpMsgBuf;
auto bufLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
nullptr);
std::string result;
if (bufLen) {
result.append(lpMsgBuf, lpMsgBuf+bufLen);
LocalFree(lpMsgBuf);
}
return result;
}
#endif
}