added sqlite connection class (progress)
This commit is contained in:
parent
715f4dff8f
commit
8b5859d858
|
|
@ -1,11 +1,13 @@
|
||||||
set(HEADER
|
set(HEADER
|
||||||
include/sqlite_connection.hpp
|
include/sqlite_connection.hpp
|
||||||
include/sqlite_error.hpp
|
include/sqlite_error.hpp
|
||||||
|
include/sqlite_dialect.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
src/sqlite_connection.cpp
|
src/sqlite_connection.cpp
|
||||||
src/sqlite_error.cpp
|
src/sqlite_error.cpp
|
||||||
|
src/sqlite_dialect.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(matador-sqlite SHARED ${SOURCES} ${HEADER})
|
add_library(matador-sqlite SHARED ${SOURCES} ${HEADER})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef QUERY_SQLITE_DIALECT_HPP
|
||||||
|
#define QUERY_SQLITE_DIALECT_HPP
|
||||||
|
|
||||||
|
#include "matador/sql/dialect.hpp"
|
||||||
|
|
||||||
|
namespace matador::backends::sqlite {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" [[maybe_unused]] const matador::sql::dialect* get_dialect();
|
||||||
|
|
||||||
|
#endif //QUERY_SQLITE_DIALECT_HPP
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "sqlite_dialect.hpp"
|
||||||
|
|
||||||
|
[[maybe_unused]] const matador::sql::dialect* get_dialect() {
|
||||||
|
using namespace matador::sql;
|
||||||
|
static dialect d {{
|
||||||
|
{ dialect::token_t::BEGIN, "BEGIN TRANSACTION"},
|
||||||
|
{ dialect::token_t::COMMIT, "COMMIT TRANSACTION"},
|
||||||
|
{ dialect::token_t::ROLLBACK, "ROLLBACK TRANSACTION"}
|
||||||
|
}};
|
||||||
|
return &d;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef QUERY_BACKEND_PROVIDER_HPP
|
||||||
|
#define QUERY_BACKEND_PROVIDER_HPP
|
||||||
|
|
||||||
|
#include "matador/utils/library.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
class connection_impl;
|
||||||
|
class dialect;
|
||||||
|
|
||||||
|
class backend_provider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit backend_provider(std::string backends_path);
|
||||||
|
|
||||||
|
connection_impl* create_connection(const std::string &connection_type);
|
||||||
|
const dialect& connection_dialect(const std::string &connection_type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct backend_context {
|
||||||
|
backend_context(const std::string &connection_type,
|
||||||
|
const std::string &backends_path);
|
||||||
|
~backend_context();
|
||||||
|
|
||||||
|
typedef connection_impl*(*create_func)();
|
||||||
|
typedef void (*destroy_func)(connection_impl*);
|
||||||
|
typedef const dialect*(*dialect_func)();
|
||||||
|
|
||||||
|
create_func create_connection{};
|
||||||
|
destroy_func destroy_connection{};
|
||||||
|
dialect_func get_dialect{};
|
||||||
|
utils::library lib;
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
using backends_t = std::unordered_map<std::string, backend_context>;
|
||||||
|
backends_t backends_;
|
||||||
|
std::string backends_path_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif //QUERY_BACKEND_PROVIDER_HPP
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
class [[nodiscard]] dialect
|
class dialect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class token_t : uint8_t
|
enum class token_t : uint8_t
|
||||||
|
|
@ -59,7 +59,15 @@ public:
|
||||||
ESCAPE_CLOSING_BRACKET /**< The escape quotes differ; escape the closing one */
|
ESCAPE_CLOSING_BRACKET /**< The escape quotes differ; escape the closing one */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using token_to_string_map = std::unordered_map<token_t, std::string>;
|
||||||
|
using data_type_to_string_map = std::unordered_map<data_type_t, std::string>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
dialect() = default;
|
||||||
|
dialect(const token_to_string_map &token_replace_map, const data_type_to_string_map &data_type_replace_map);
|
||||||
|
explicit dialect(const data_type_to_string_map &data_type_replace_map);
|
||||||
|
explicit dialect(const token_to_string_map &token_replace_map);
|
||||||
|
|
||||||
const std::string& token_at(token_t token) const;
|
const std::string& token_at(token_t token) const;
|
||||||
const std::string& data_type_at(data_type_t type) const;
|
const std::string& data_type_at(data_type_t type) const;
|
||||||
|
|
||||||
|
|
@ -124,8 +132,6 @@ public:
|
||||||
const std::vector<std::string>& columns() const;
|
const std::vector<std::string>& columns() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using token_to_string_map = std::unordered_map<token_t, std::string>;
|
|
||||||
|
|
||||||
std::vector<std::string> host_vars_;
|
std::vector<std::string> host_vars_;
|
||||||
std::vector<std::string> columns_;
|
std::vector<std::string> columns_;
|
||||||
|
|
||||||
|
|
@ -167,7 +173,6 @@ private:
|
||||||
{token_t::NONE, ""}
|
{token_t::NONE, ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
using data_type_to_string_map = std::unordered_map<data_type_t, std::string>;
|
|
||||||
data_type_to_string_map data_types_ {
|
data_type_to_string_map data_types_ {
|
||||||
{data_type_t::type_char, "TINYINT"},
|
{data_type_t::type_char, "TINYINT"},
|
||||||
{data_type_t::type_short, "SMALLINT"},
|
{data_type_t::type_short, "SMALLINT"},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef QUERY_OS_HPP
|
||||||
|
#define QUERY_OS_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace matador::utils::os {
|
||||||
|
|
||||||
|
std::string getenv(const char* name);
|
||||||
|
|
||||||
|
[[maybe_unused]] std::string getenv(const std::string &name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //QUERY_OS_HPP
|
||||||
26
main.cpp
26
main.cpp
|
|
@ -1,21 +1,17 @@
|
||||||
#include <matador/sql/dialect.hpp>
|
#include <cstdlib>
|
||||||
#include <matador/sql/query_builder.hpp>
|
|
||||||
#include <matador/sql/types.hpp>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
using namespace matador;
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
sql::dialect d;
|
const std::string env_var {"MATADOR_BACKENDS_PATH"};
|
||||||
|
|
||||||
sql::query_builder query(d);
|
|
||||||
|
|
||||||
std::cout << query.create().table("person", {
|
|
||||||
{ "id", sql::data_type_traits<unsigned long>::builtin_type() },
|
|
||||||
{ "name", sql::data_type_traits<std::string>::builtin_type(255), 255 },
|
|
||||||
{ "id", sql::data_type_traits<unsigned long>::builtin_type() }
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
|
// char var[1024];
|
||||||
|
// size_t len{};
|
||||||
|
// const auto error = getenv_s(&len, var, 1024, env_var.c_str());
|
||||||
|
// if (error > 0) {
|
||||||
|
// std::cout << "error: unknown env var " << env_var << "\n";
|
||||||
|
// } else {
|
||||||
|
// std::cout << "env var: " << var << "\n";
|
||||||
|
// }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ set(SQL_SOURCES
|
||||||
sql/record.cpp
|
sql/record.cpp
|
||||||
sql/connection_info.cpp
|
sql/connection_info.cpp
|
||||||
sql/connection_impl.cpp
|
sql/connection_impl.cpp
|
||||||
sql/session.cpp)
|
sql/session.cpp
|
||||||
|
sql/backend_provider.cpp)
|
||||||
|
|
||||||
set(SQL_HEADER
|
set(SQL_HEADER
|
||||||
../include/matador/sql/dialect.hpp
|
../include/matador/sql/dialect.hpp
|
||||||
|
|
@ -27,19 +28,22 @@ set(SQL_HEADER
|
||||||
../include/matador/sql/connection_impl.hpp
|
../include/matador/sql/connection_impl.hpp
|
||||||
../include/matador/sql/connection_info.hpp
|
../include/matador/sql/connection_info.hpp
|
||||||
../include/matador/sql/connection_pool.hpp
|
../include/matador/sql/connection_pool.hpp
|
||||||
../include/matador/sql/session.hpp)
|
../include/matador/sql/session.hpp
|
||||||
|
../include/matador/sql/backend_provider.hpp)
|
||||||
|
|
||||||
set(UTILS_HEADER
|
set(UTILS_HEADER
|
||||||
../include/matador/utils/field_attributes.hpp
|
../include/matador/utils/field_attributes.hpp
|
||||||
../include/matador/utils/string.hpp
|
../include/matador/utils/string.hpp
|
||||||
../include/matador/utils/constraints.hpp
|
../include/matador/utils/constraints.hpp
|
||||||
../include/matador/utils/library.hpp)
|
../include/matador/utils/library.hpp
|
||||||
|
../include/matador/utils/os.hpp)
|
||||||
|
|
||||||
set(UTILS_SOURCES
|
set(UTILS_SOURCES
|
||||||
utils/field_attributes.cpp
|
utils/field_attributes.cpp
|
||||||
utils/string.cpp
|
utils/string.cpp
|
||||||
sql/condition.cpp
|
sql/condition.cpp
|
||||||
utils/library.cpp)
|
utils/library.cpp
|
||||||
|
utils/os.cpp)
|
||||||
|
|
||||||
add_library(matador STATIC ${SQL_SOURCES} ${SQL_HEADER} ${UTILS_SOURCES} ${UTILS_HEADER})
|
add_library(matador STATIC ${SQL_SOURCES} ${SQL_HEADER} ${UTILS_SOURCES} ${UTILS_HEADER})
|
||||||
target_include_directories(matador PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
target_include_directories(matador PUBLIC ${PROJECT_SOURCE_DIR}/include)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "matador/sql/backend_provider.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
backend_provider::backend_provider(std::string backends_path)
|
||||||
|
: backends_path_(std::move(backends_path)) {}
|
||||||
|
|
||||||
|
connection_impl *backend_provider::create_connection(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;
|
||||||
|
}
|
||||||
|
return (*it->second.create_connection)();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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)) {
|
||||||
|
throw std::runtime_error("couldn't load library '" + connection_type + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
create_connection = reinterpret_cast<create_func>(reinterpret_cast<std::uintptr_t>(lib.function("create_database")));
|
||||||
|
destroy_connection = reinterpret_cast<destroy_func>(reinterpret_cast<std::uintptr_t>(lib.function("destroy_database")));
|
||||||
|
get_dialect = reinterpret_cast<dialect_func >(reinterpret_cast<std::uintptr_t>(lib.function("get_dialect")));
|
||||||
|
}
|
||||||
|
|
||||||
|
backend_provider::backend_context::~backend_context()
|
||||||
|
{
|
||||||
|
lib.unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,26 @@
|
||||||
#include "matador/utils/string.hpp"
|
#include "matador/utils/string.hpp"
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
|
dialect::dialect(const dialect::token_to_string_map &token_replace_map, const dialect::data_type_to_string_map &data_type_replace_map)
|
||||||
|
{
|
||||||
|
for (const auto &token : token_replace_map) {
|
||||||
|
tokens_[token.first] = token.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &data_type : data_type_replace_map) {
|
||||||
|
data_types_[data_type.first] = data_type.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialect::dialect(const dialect::data_type_to_string_map &data_type_replace_map)
|
||||||
|
: dialect({}, data_type_replace_map)
|
||||||
|
{}
|
||||||
|
|
||||||
|
dialect::dialect(const dialect::token_to_string_map &token_replace_map)
|
||||||
|
: dialect(token_replace_map, {})
|
||||||
|
{}
|
||||||
|
|
||||||
const std::string& dialect::token_at(dialect::token_t token) const
|
const std::string& dialect::token_at(dialect::token_t token) const
|
||||||
{
|
{
|
||||||
return tokens_.at(token);
|
return tokens_.at(token);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "matador/utils/os.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace matador::utils::os {
|
||||||
|
|
||||||
|
std::string getenv(const char *name) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
char var[1024];
|
||||||
|
size_t len{};
|
||||||
|
const auto error = getenv_s(&len, var, 1024, name);
|
||||||
|
if (error > 0) {
|
||||||
|
throw std::logic_error("failed to get environment variable");
|
||||||
|
};
|
||||||
|
return var;
|
||||||
|
#else
|
||||||
|
return ::getenv(name);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] std::string getenv(const std::string &name) {
|
||||||
|
return getenv(name.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,11 @@ add_executable(tests builder.cpp
|
||||||
session.cpp
|
session.cpp
|
||||||
record.cpp
|
record.cpp
|
||||||
connection_pool.cpp
|
connection_pool.cpp
|
||||||
query.cpp)
|
query.cpp
|
||||||
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain matador)
|
backend_provider.cpp)
|
||||||
|
target_link_libraries(tests PRIVATE
|
||||||
|
Catch2::Catch2WithMain
|
||||||
|
matador
|
||||||
|
${CMAKE_DL_LIBS}
|
||||||
|
${SQLite3_LIBRARIES})
|
||||||
target_include_directories(tests PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>/include)
|
target_include_directories(tests PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>/include)
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "matador/sql/backend_provider.hpp"
|
||||||
|
|
||||||
|
#include "matador/utils/os.hpp"
|
||||||
|
|
||||||
|
using namespace matador::sql;
|
||||||
|
|
||||||
|
TEST_CASE("Load backend", "[backend provider]") {
|
||||||
|
auto path = matador::utils::os::getenv("MATADOR_BACKENDS_PATH");
|
||||||
|
if (path.back() != '\\') {
|
||||||
|
path.push_back('\\');
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(!path.empty());
|
||||||
|
|
||||||
|
backend_provider provider(path);
|
||||||
|
|
||||||
|
const auto &d = provider.connection_dialect("sqlite");
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue