added any type visitor and converter
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
#include "matador/sql/any_type_to_visitor.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
void convert(std::string &dest, bool source)
|
||||
{
|
||||
dest = source ? "true" : "false";
|
||||
}
|
||||
|
||||
void convert(std::string &dest, const char *source)
|
||||
{
|
||||
dest = source;
|
||||
}
|
||||
|
||||
long long to_long_long(const char *source)
|
||||
{
|
||||
if (strlen(source) == 0) {
|
||||
return{};
|
||||
}
|
||||
char *end;
|
||||
const auto result = strtoll(source, &end, 10);
|
||||
if (end == nullptr) {
|
||||
// Todo: check error
|
||||
throw std::logic_error("couldn't convert value to number");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long long to_unsigned_long_long(const char *source)
|
||||
{
|
||||
if (strlen(source) == 0) {
|
||||
return{};
|
||||
}
|
||||
char *end;
|
||||
const auto result = strtoull(source, &end, 10);
|
||||
if (end == nullptr) {
|
||||
// Todo: check error
|
||||
throw std::logic_error("couldn't convert value to number");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
long double to_double(const char *source)
|
||||
{
|
||||
if (strlen(source) == 0) {
|
||||
return{};
|
||||
}
|
||||
char *end;
|
||||
const auto result = strtold(source, &end);
|
||||
if (end == nullptr) {
|
||||
// Todo: check error
|
||||
throw std::logic_error("couldn't convert value to number");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+15
-2
@@ -29,8 +29,9 @@ column::column(std::string name, data_type_t type, utils::field_attributes attr)
|
||||
, type_(type)
|
||||
, attributes_(attr) {}
|
||||
|
||||
column::column(std::string name, data_type_t type, std::string ref_table, std::string ref_column, utils::field_attributes attr)
|
||||
column::column(std::string name, data_type_t type, size_t index, std::string ref_table, std::string ref_column, utils::field_attributes attr)
|
||||
: name_(std::move(name))
|
||||
, index_(index)
|
||||
, type_(type)
|
||||
, attributes_(attr)
|
||||
, ref_table_(std::move(ref_table))
|
||||
@@ -41,6 +42,11 @@ const std::string &column::name() const
|
||||
return name_;
|
||||
}
|
||||
|
||||
size_t column::index() const
|
||||
{
|
||||
return index_;
|
||||
}
|
||||
|
||||
const utils::field_attributes &column::attributes() const
|
||||
{
|
||||
return attributes_;
|
||||
@@ -61,6 +67,13 @@ const std::string &column::ref_column() const
|
||||
return ref_column_;
|
||||
}
|
||||
|
||||
std::string column::str() const
|
||||
{
|
||||
any_type_to_visitor<std::string> visitor;
|
||||
std::visit(visitor, const_cast<any_type&>(value_));
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
column operator "" _col(const char *name, size_t len)
|
||||
{
|
||||
return column(std::string(name, len));
|
||||
@@ -86,6 +99,6 @@ column make_pk_column<std::string>( const std::string& name, size_t size )
|
||||
template<>
|
||||
[[maybe_unused]] column make_fk_column<std::string>(const std::string& name, size_t size, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<std::string>::builtin_type(size), ref_table, ref_column, { size, utils::constraints::PRIMARY_KEY | utils::constraints::NOT_NULL}};
|
||||
return {name, data_type_traits<std::string>::builtin_type(size), 0, ref_table, ref_column, { size, utils::constraints::PRIMARY_KEY | utils::constraints::NOT_NULL}};
|
||||
}
|
||||
}
|
||||
@@ -68,6 +68,11 @@ record connection::describe(const std::string &table_name) const
|
||||
return std::move(connection_->describe(table_name));
|
||||
}
|
||||
|
||||
bool connection::exists(const std::string &table_name) const
|
||||
{
|
||||
return connection_->exists(table_name);
|
||||
}
|
||||
|
||||
query_result<record> connection::fetch(const std::string &sql) const
|
||||
{
|
||||
auto rec = connection_->describe("person");
|
||||
|
||||
@@ -141,6 +141,7 @@ query_builder& query_builder::insert() {
|
||||
query_builder& query_builder::update(const std::string &table) {
|
||||
initialize(command_t::UPDATE, state_t::QUERY_UPDATE);
|
||||
|
||||
query_.table_name = table;
|
||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::UPDATE) + " " + dialect_.prepare_identifier(table));
|
||||
|
||||
return *this;
|
||||
@@ -178,6 +179,7 @@ query_builder &query_builder::table(const std::string &table, const std::vector<
|
||||
transition_to(state_t::QUERY_TABLE_CREATE);
|
||||
|
||||
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table) + " ");
|
||||
query_.table_name = table;
|
||||
|
||||
std::string result = "(";
|
||||
|
||||
@@ -215,6 +217,7 @@ query_builder& query_builder::table(const std::string &table) {
|
||||
transition_to(state_t::QUERY_TABLE_DROP);
|
||||
|
||||
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table));
|
||||
query_.table_name = table;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -229,6 +232,7 @@ query_builder &query_builder::into(const std::string &table, const std::vector<s
|
||||
transition_to(state_t::QUERY_INTO);
|
||||
|
||||
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::INTO) + " " + dialect_.prepare_identifier(table) + " ");
|
||||
query_.table_name = table;
|
||||
|
||||
std::string result{"("};
|
||||
if (column_names.size() < 2) {
|
||||
@@ -290,6 +294,7 @@ query_builder& query_builder::from(const std::string &table, const std::string &
|
||||
transition_to(state_t::QUERY_FROM);
|
||||
|
||||
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::FROM) + " " + dialect_.prepare_identifier(table) + (as.empty() ? "" : " " + as));
|
||||
query_.table_name = table;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -398,12 +403,11 @@ query_builder& query_builder::limit( size_t count ) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string query_builder::compile() {
|
||||
std::string result;
|
||||
query query_builder::compile() {
|
||||
for (const auto &part : query_parts_) {
|
||||
result.append(part);
|
||||
query_.sql.append(part);
|
||||
}
|
||||
return result;
|
||||
return query_;
|
||||
}
|
||||
|
||||
void query_builder::transition_to(query_builder::state_t next)
|
||||
|
||||
@@ -2,145 +2,173 @@
|
||||
#include "matador/sql/session.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
session &query_intermediate::db()
|
||||
{
|
||||
return db_;
|
||||
}
|
||||
|
||||
query_builder &query_intermediate::query()
|
||||
{
|
||||
return query_;
|
||||
}
|
||||
|
||||
query_result<record> query_select_finish::fetch_all()
|
||||
{
|
||||
return db().fetch(query().compile());
|
||||
return session_.fetch(builder_.compile());
|
||||
}
|
||||
|
||||
record query_select_finish::fetch_one()
|
||||
{
|
||||
return *db().fetch(query().compile()).begin().get();
|
||||
return *session_.fetch(builder_.compile()).begin().get();
|
||||
}
|
||||
|
||||
std::unique_ptr<query_result_impl> query_select_finish::fetch()
|
||||
{
|
||||
return db().call_fetch(query().compile());
|
||||
return session_.call_fetch(builder_.compile().sql);
|
||||
}
|
||||
|
||||
query_intermediate::query_intermediate(session &db, query_builder &query)
|
||||
: db_(db), query_(query) {}
|
||||
: session_(db), builder_(query) {}
|
||||
|
||||
query_offset_intermediate query_order_direction_intermediate::offset(size_t offset)
|
||||
{
|
||||
return {db(), query()};
|
||||
return {session_, builder_};
|
||||
}
|
||||
|
||||
query_limit_intermediate query_offset_intermediate::limit(size_t limit)
|
||||
{
|
||||
return {db(), query()};
|
||||
return {session_, builder_};
|
||||
}
|
||||
|
||||
query_limit_intermediate query_order_direction_intermediate::limit(size_t limit)
|
||||
{
|
||||
return {db(), query()};
|
||||
return {session_, builder_};
|
||||
}
|
||||
|
||||
query_order_by_intermediate query_group_by_intermediate::order_by(const std::string &name)
|
||||
{
|
||||
return {db(), query().order_by(name)};
|
||||
return {session_, builder_.order_by(name)};
|
||||
}
|
||||
|
||||
query_order_direction_intermediate query_order_by_intermediate::asc()
|
||||
{
|
||||
return {db(), query().asc()};
|
||||
return {session_, builder_.asc()};
|
||||
}
|
||||
|
||||
query_order_direction_intermediate query_order_by_intermediate::desc()
|
||||
{
|
||||
return {db(), query().desc()};
|
||||
return {session_, builder_.desc()};
|
||||
}
|
||||
|
||||
query_group_by_intermediate query_from_intermediate::group_by(const std::string &name)
|
||||
{
|
||||
return {db(), query().group_by(name)};
|
||||
return {session_, builder_.group_by(name)};
|
||||
}
|
||||
|
||||
query_order_by_intermediate query_from_intermediate::order_by(const std::string &name)
|
||||
{
|
||||
return {db(), query().order_by(name)};
|
||||
return {session_, builder_.order_by(name)};
|
||||
}
|
||||
|
||||
query_group_by_intermediate query_where_intermediate::group_by(const std::string &name)
|
||||
{
|
||||
return {db(), query().group_by(name)};
|
||||
return {session_, builder_.group_by(name)};
|
||||
}
|
||||
|
||||
query_order_by_intermediate query_where_intermediate::order_by(const std::string &name)
|
||||
{
|
||||
return {db(), query().order_by(name)};
|
||||
return {session_, builder_.order_by(name)};
|
||||
}
|
||||
|
||||
query_where_intermediate query_from_intermediate::where(const basic_condition &cond)
|
||||
{
|
||||
return query_where_intermediate{db(), query().where(cond)};
|
||||
return query_where_intermediate{session_, builder_.where(cond)};
|
||||
}
|
||||
|
||||
query_select_intermediate::query_select_intermediate(session &s, std::vector<std::string> column_names)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
builder_.select(std::move(column_names));
|
||||
}
|
||||
|
||||
query_from_intermediate query_select_intermediate::from(const std::string &table, const std::string &as)
|
||||
{
|
||||
return {db(), query().from(table, as)};
|
||||
return {session_, builder_.from(table, as)};
|
||||
}
|
||||
|
||||
query_insert_intermediate::query_insert_intermediate(session &s)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
builder_.insert();
|
||||
}
|
||||
|
||||
query_into_intermediate query_insert_intermediate::into(const std::string &table, std::initializer_list<std::string> column_names)
|
||||
{
|
||||
return {db(), query().into(table, column_names)};
|
||||
return {session_, builder_.into(table, column_names)};
|
||||
}
|
||||
|
||||
std::pair<size_t, std::string> query_execute_finish::execute()
|
||||
{
|
||||
return db().execute(query().compile());
|
||||
return session_.execute(builder_.compile().sql);
|
||||
}
|
||||
|
||||
query_execute_finish query_into_intermediate::values(std::initializer_list<any_type> values)
|
||||
{
|
||||
return {db(), query().values(values)};
|
||||
return {session_, builder_.values(values)};
|
||||
}
|
||||
|
||||
query_create_intermediate::query_create_intermediate(session &db, query_builder &query, table_repository &repo)
|
||||
: query_intermediate(db, query)
|
||||
, repository_(repo) {}
|
||||
query_create_intermediate::query_create_intermediate(session &s, table_repository &repo)
|
||||
: query_start_intermediate(s)
|
||||
, repository_(repo) {
|
||||
builder_.create();
|
||||
}
|
||||
|
||||
query_execute_finish query_create_intermediate::table(const std::string &table, std::initializer_list<column> columns)
|
||||
{
|
||||
return {db(), query().table(table, columns)};
|
||||
return {session_, builder_.table(table, columns)};
|
||||
}
|
||||
|
||||
query_drop_intermediate::query_drop_intermediate(session &s)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
builder_.drop();
|
||||
}
|
||||
|
||||
query_execute_finish query_drop_intermediate::table(const std::string &table)
|
||||
{
|
||||
return {db(), query().table(table)};
|
||||
return {session_, builder_.table(table)};
|
||||
}
|
||||
|
||||
query_execute_finish query_execute_where_intermediate::limit(int limit)
|
||||
{
|
||||
return {db(), query().limit(limit)};
|
||||
return {session_, builder_.limit(limit)};
|
||||
}
|
||||
|
||||
query_execute_where_intermediate query_set_intermediate::where(const basic_condition &cond)
|
||||
{
|
||||
return {db(), query().where(cond)};
|
||||
return {session_, builder_.where(cond)};
|
||||
}
|
||||
|
||||
query_update_intermediate::query_update_intermediate(session &s, std::string table_name)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
builder_.update(std::move(table_name));
|
||||
}
|
||||
|
||||
query_set_intermediate query_update_intermediate::set(std::initializer_list<key_value_pair> columns)
|
||||
{
|
||||
return {db(), query().set(columns)};
|
||||
return {session_, builder_.set(columns)};
|
||||
}
|
||||
|
||||
query_execute_where_intermediate query_delete_from_intermediate::where(const basic_condition &cond)
|
||||
{
|
||||
return {db(), query().where(cond)};
|
||||
return {session_, builder_.where(cond)};
|
||||
}
|
||||
|
||||
query_delete_intermediate::query_delete_intermediate(session &s)
|
||||
: query_start_intermediate(s)
|
||||
{
|
||||
builder_.remove();
|
||||
}
|
||||
|
||||
query_delete_from_intermediate query_delete_intermediate::from(const std::string &table)
|
||||
{
|
||||
return {db(), query().from(table)};
|
||||
return {session_, builder_.from(table)};
|
||||
}
|
||||
|
||||
query_start_intermediate::query_start_intermediate(session &s)
|
||||
: session_(s)
|
||||
, builder_(s.dialect())
|
||||
{}
|
||||
}
|
||||
+28
-11
@@ -8,46 +8,58 @@ namespace matador::sql {
|
||||
|
||||
session::session(connection_pool<connection> &pool)
|
||||
: pool_(pool)
|
||||
, query_(backend_provider::instance().connection_dialect(pool.info().type)) {}
|
||||
, dialect_(backend_provider::instance().connection_dialect(pool_.info().type)) {}
|
||||
|
||||
query_create_intermediate session::create()
|
||||
{
|
||||
return query_create_intermediate{*this, query_.create(), table_repository_};
|
||||
return query_create_intermediate{*this, table_repository_};
|
||||
}
|
||||
|
||||
query_drop_intermediate session::drop()
|
||||
{
|
||||
return query_drop_intermediate{*this, query_.drop()};
|
||||
return query_drop_intermediate{*this};
|
||||
}
|
||||
|
||||
query_select_intermediate session::select(std::initializer_list<std::string> column_names)
|
||||
{
|
||||
|
||||
return query_select_intermediate{*this, query_.select(column_names)};
|
||||
return query_select_intermediate{*this, column_names};
|
||||
}
|
||||
|
||||
query_insert_intermediate session::insert()
|
||||
{
|
||||
return query_insert_intermediate{*this, query_.insert()};
|
||||
return query_insert_intermediate{*this};
|
||||
}
|
||||
|
||||
query_update_intermediate session::update(const std::string &table)
|
||||
{
|
||||
return query_update_intermediate{*this, query_.update(table)};
|
||||
return query_update_intermediate{*this, table};
|
||||
}
|
||||
|
||||
query_delete_intermediate session::remove()
|
||||
{
|
||||
return query_delete_intermediate{*this, query_.remove()};
|
||||
return query_delete_intermediate{*this};
|
||||
}
|
||||
|
||||
query_result<record> session::fetch(const std::string &sql) const
|
||||
query_result<record> session::fetch(const query &q) const
|
||||
{
|
||||
auto res = call_fetch(sql);
|
||||
auto proto = res->prototype();
|
||||
return query_result<record>{std::move(res), [proto]() { return new record(proto); }};
|
||||
auto c = pool_.acquire();
|
||||
if (!c.valid()) {
|
||||
throw std::logic_error("no database connection available");
|
||||
}
|
||||
auto it = prototypes_.find(q.table_name);
|
||||
if (it == prototypes_.end()) {
|
||||
it = prototypes_.emplace(q.table_name, c->describe(q.table_name)).first;
|
||||
}
|
||||
auto res = c->call_fetch(q.sql);
|
||||
return query_result<record>{std::move(res), [it]() { return new record(it->second); }};
|
||||
}
|
||||
|
||||
//query_result<record> session::fetch(const std::string &sql) const
|
||||
//{
|
||||
// return query_result<record>(std::unique_ptr());
|
||||
//}
|
||||
|
||||
std::pair<size_t, std::string> session::execute(const std::string &sql) const {
|
||||
auto c = pool_.acquire();
|
||||
if (!c.valid()) {
|
||||
@@ -61,6 +73,11 @@ const table_repository& session::tables() const
|
||||
return table_repository_;
|
||||
}
|
||||
|
||||
const class dialect &session::dialect() const
|
||||
{
|
||||
return dialect_;
|
||||
}
|
||||
|
||||
std::unique_ptr<query_result_impl> session::call_fetch(const std::string &sql) const
|
||||
{
|
||||
auto c = pool_.acquire();
|
||||
|
||||
Reference in New Issue
Block a user