implemented prepared statement for postgres and sqlite

This commit is contained in:
2023-12-09 11:08:03 +01:00
parent 8ba70cc79e
commit da423ea8bb
59 changed files with 1769 additions and 314 deletions
+13 -13
View File
@@ -3,21 +3,21 @@
namespace matador::sql {
condition<column, placeholder, std::enable_if<true>::type>::condition(const column &fld, basic_condition::operand_t op, const placeholder &val)
: basic_column_condition(fld, op)
, value(val)
{ }
std::string condition<column, placeholder, std::enable_if<true>::type>::evaluate(dialect &d) const {
d.add_host_var(field_.name());
return d.prepare_identifier(field_.name()) + " " + operand + " " + d.next_placeholder();
}
condition<column, query>::condition(column col, basic_condition::operand_t op, query &q)
: basic_column_condition(std::move(col), op)
, query_(q)
: basic_column_condition(fld, op), value(val)
{}
std::string condition<column, query>::evaluate(dialect &d) const {
std::string condition<column, placeholder, std::enable_if<true>::type>::evaluate(dialect &d, query_context &query) const
{
query.bind_vars.emplace_back(field_.name());
return d.prepare_identifier(field_.name()) + " " + operand + " " + d.next_placeholder(query.bind_vars);
}
condition<column, query_context>::condition(column col, basic_condition::operand_t op, query_context &q)
: basic_column_condition(std::move(col), op), query_(q)
{}
std::string condition<column, query_context>::evaluate(dialect &d, query_context &query) const
{
std::string result(d.prepare_identifier(field_.name()) + " " + operand + " (");
result += (")");
return result;
+5
View File
@@ -88,4 +88,9 @@ std::unique_ptr<query_result_impl> connection::fetch(const std::string &sql) con
return connection_->fetch(sql);
}
statement connection::prepare(query_context &&query) const
{
return statement(connection_->prepare(std::move(query)), logger_);
}
}
+4 -38
View File
@@ -5,25 +5,6 @@
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
{
return tokens_.at(token);
@@ -85,29 +66,14 @@ dialect::escape_identifier_t dialect::identifier_escape_type() const
return dialect::escape_identifier_t::ESCAPE_BOTH_SAME;
}
std::string dialect::next_placeholder() const
std::string dialect::next_placeholder(const std::vector<std::string> &bind_vars) const
{
return "?";
return placeholder_func_(bind_vars.size());
}
void dialect::add_host_var(const std::string &host_var)
std::string dialect::default_schema_name() const
{
host_vars_.emplace_back(host_var);
}
void dialect::add_column(const std::string &column)
{
columns_.emplace_back(column);
}
const std::vector<std::string> &dialect::host_vars() const
{
return host_vars_;
}
const std::vector<std::string> &dialect::columns() const
{
return columns_;
return default_schema_name_;
}
}
+52
View File
@@ -0,0 +1,52 @@
#include "matador/sql/dialect_builder.hpp"
namespace matador::sql {
dialect_builder &dialect_builder::builder()
{
static dialect_builder instance;
return instance;
}
dialect_builder &dialect_builder::create()
{
dialect_ = {};
return *this;
}
dialect_builder& dialect_builder::with_token_replace_map(const dialect::token_to_string_map &token_replace_map)
{
for (const auto &token : token_replace_map) {
dialect_.tokens_[token.first] = token.second;
}
return *this;
}
dialect_builder& dialect_builder::with_data_type_replace_map(const dialect::data_type_to_string_map &data_type_replace_map)
{
for (const auto &data_type : data_type_replace_map) {
dialect_.data_types_[data_type.first] = data_type.second;
}
return *this;
}
dialect_builder& dialect_builder::with_placeholder_func(const dialect::next_placeholder_func &func)
{
dialect_.placeholder_func_ = func;
return *this;
}
dialect_builder &dialect_builder::with_default_schema_name(const std::string &schema_name)
{
dialect_.default_schema_name_ = schema_name;
return *this;
}
dialect dialect_builder::build()
{
return dialect_;
}
}
+24
View File
@@ -0,0 +1,24 @@
#include "matador/sql/object_binder.hpp"
#include "matador/sql/parameter_binder.hpp"
namespace matador::sql {
object_binder::object_binder(parameter_binder &binder)
: binder_(binder) {}
void object_binder::reset()
{
index_ = 0;
}
void object_binder::on_primary_key(const char *id, std::string &val, size_t)
{
binder_.bind(index_++, val);
}
void object_binder::on_revision(const char *id, unsigned long long int &rev)
{
binder_.bind(index_++, rev);
}
}
+15
View File
@@ -0,0 +1,15 @@
#include "matador/sql/placeholder_generator.hpp"
namespace matador::sql {
void placeholder_generator::on_primary_key(const char *id, std::string &, size_t)
{
placeholder_values.emplace_back(_);
}
void placeholder_generator::on_revision(const char *id, unsigned long long int &)
{
placeholder_values.emplace_back(_);
}
}
+153 -114
View File
@@ -9,6 +9,9 @@ namespace matador::sql {
namespace detail {
any_type_to_string_visitor::any_type_to_string_visitor(const dialect &d, query_context &query)
: d(d), query(query) {}
void any_type_to_string_visitor::to_string(const char *val)
{
result = "'" + d.prepare_literal(val) + "'";
@@ -19,69 +22,76 @@ void any_type_to_string_visitor::to_string(std::string &val)
result = "'" + d.prepare_literal(val) + "'";
}
void any_type_to_string_visitor::to_string(placeholder &/*val*/)
{
query.bind_vars.emplace_back("unknown");
result = d.next_placeholder(query.bind_vars);
}
}
// poor mens state machine
// but does the job for query
query_builder::query_state_transition_map query_builder::transitions_{
{state_t::QUERY_INIT, {state_t::QUERY_CREATE, state_t::QUERY_DROP, state_t::QUERY_SELECT, state_t::QUERY_INSERT, state_t::QUERY_UPDATE, state_t::QUERY_DELETE}},
{state_t::QUERY_CREATE, {state_t::QUERY_TABLE_CREATE}},
{state_t::QUERY_DROP, {state_t::QUERY_TABLE_DROP}},
{state_t::QUERY_SELECT, {state_t::QUERY_FROM}},
{state_t::QUERY_INSERT, {state_t::QUERY_INTO}},
{state_t::QUERY_UPDATE, {state_t::QUERY_SET}},
{state_t::QUERY_DELETE, {state_t::QUERY_FROM}},
{state_t::QUERY_TABLE_CREATE, {state_t::QUERY_FINISH}},
{state_t::QUERY_TABLE_DROP, {state_t::QUERY_FINISH}},
{state_t::QUERY_FROM, {state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_WHERE, state_t::QUERY_ORDER_BY, state_t::QUERY_GROUP_BY, state_t::QUERY_FINISH}},
{state_t::QUERY_SET, {state_t::QUERY_WHERE, state_t::QUERY_FINISH}},
{state_t::QUERY_INTO, {state_t::QUERY_VALUES}},
{state_t::QUERY_WHERE, {state_t::QUERY_ORDER_BY, state_t::QUERY_GROUP_BY, state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_FINISH}},
{state_t::QUERY_ORDER_BY, {state_t::QUERY_ORDER_DIRECTION}},
{state_t::QUERY_ORDER_DIRECTION, {state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_FINISH}},
{state_t::QUERY_GROUP_BY, {state_t::QUERY_ORDER_BY, state_t::QUERY_FINISH}},
{state_t::QUERY_OFFSET, {state_t::QUERY_LIMIT}},
{state_t::QUERY_LIMIT, {state_t::QUERY_FINISH}},
{state_t::QUERY_VALUES, {state_t::QUERY_FINISH}},
{state_t::QUERY_FINISH, {}},
{state_t::QUERY_INIT, {state_t::QUERY_CREATE, state_t::QUERY_DROP, state_t::QUERY_SELECT, state_t::QUERY_INSERT, state_t::QUERY_UPDATE, state_t::QUERY_DELETE}},
{state_t::QUERY_CREATE, {state_t::QUERY_TABLE_CREATE}},
{state_t::QUERY_DROP, {state_t::QUERY_TABLE_DROP}},
{state_t::QUERY_SELECT, {state_t::QUERY_FROM}},
{state_t::QUERY_INSERT, {state_t::QUERY_INTO}},
{state_t::QUERY_UPDATE, {state_t::QUERY_SET}},
{state_t::QUERY_DELETE, {state_t::QUERY_FROM}},
{state_t::QUERY_TABLE_CREATE, {state_t::QUERY_FINISH}},
{state_t::QUERY_TABLE_DROP, {state_t::QUERY_FINISH}},
{state_t::QUERY_FROM, {state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_WHERE, state_t::QUERY_ORDER_BY, state_t::QUERY_GROUP_BY, state_t::QUERY_FINISH}},
{state_t::QUERY_SET, {state_t::QUERY_WHERE, state_t::QUERY_FINISH}},
{state_t::QUERY_INTO, {state_t::QUERY_VALUES}},
{state_t::QUERY_WHERE, {state_t::QUERY_ORDER_BY, state_t::QUERY_GROUP_BY, state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_FINISH}},
{state_t::QUERY_ORDER_BY, {state_t::QUERY_ORDER_DIRECTION}},
{state_t::QUERY_ORDER_DIRECTION, {state_t::QUERY_OFFSET, state_t::QUERY_LIMIT, state_t::QUERY_FINISH}},
{state_t::QUERY_GROUP_BY, {state_t::QUERY_ORDER_BY, state_t::QUERY_FINISH}},
{state_t::QUERY_OFFSET, {state_t::QUERY_LIMIT}},
{state_t::QUERY_LIMIT, {state_t::QUERY_FINISH}},
{state_t::QUERY_VALUES, {state_t::QUERY_FINISH}},
{state_t::QUERY_FINISH, {}},
};
query_builder::query_state_to_string_map query_builder::state_strings_ {
{ state_t::QUERY_INIT, "init" },
{ state_t::QUERY_CREATE, "create" },
{ state_t::QUERY_DROP, "drop" },
{ state_t::QUERY_SELECT, "select" },
{ state_t::QUERY_INSERT, "insert" },
{ state_t::QUERY_UPDATE, "update" },
{ state_t::QUERY_DELETE, "delete" },
{ state_t::QUERY_TABLE_CREATE, "table" },
{ state_t::QUERY_TABLE_DROP, "table" },
{ state_t::QUERY_FROM, "from" },
{ state_t::QUERY_SET, "set" },
{ state_t::QUERY_INTO, "into" },
{ state_t::QUERY_WHERE, "where" },
{ state_t::QUERY_ORDER_BY, "order_by" },
{ state_t::QUERY_GROUP_BY, "group_by" },
{ state_t::QUERY_OFFSET, "offset" },
{ state_t::QUERY_LIMIT, "limit" },
{ state_t::QUERY_FINISH, "finish" },
query_builder::query_state_to_string_map query_builder::state_strings_{
{state_t::QUERY_INIT, "init"},
{state_t::QUERY_CREATE, "create"},
{state_t::QUERY_DROP, "drop"},
{state_t::QUERY_SELECT, "select"},
{state_t::QUERY_INSERT, "insert"},
{state_t::QUERY_UPDATE, "update"},
{state_t::QUERY_DELETE, "delete"},
{state_t::QUERY_TABLE_CREATE, "table"},
{state_t::QUERY_TABLE_DROP, "table"},
{state_t::QUERY_FROM, "from"},
{state_t::QUERY_SET, "set"},
{state_t::QUERY_INTO, "into"},
{state_t::QUERY_WHERE, "where"},
{state_t::QUERY_ORDER_BY, "order_by"},
{state_t::QUERY_GROUP_BY, "group_by"},
{state_t::QUERY_OFFSET, "offset"},
{state_t::QUERY_LIMIT, "limit"},
{state_t::QUERY_FINISH, "finish"},
};
query_builder::query_command_to_string_map query_builder::command_strings_ {
{ command_t::UNKNOWN, "unknown" },
{ command_t::CREATE, "create" },
{ command_t::DROP, "drop" },
{ command_t::SELECT, "select" },
{ command_t::INSERT, "insert" },
{ command_t::UPDATE, "update" },
{ command_t::REMOVE, "remove" },
query_builder::query_command_to_string_map query_builder::command_strings_{
{command_t::UNKNOWN, "unknown"},
{command_t::CREATE, "create"},
{command_t::DROP, "drop"},
{command_t::SELECT, "select"},
{command_t::INSERT, "insert"},
{command_t::UPDATE, "update"},
{command_t::REMOVE, "remove"},
};
query_builder::query_builder(const dialect &d)
: dialect_(d)
, value_to_string_(d) {}
: dialect_(d), value_to_string_(d, query_)
{}
query_builder& query_builder::create() {
query_builder &query_builder::create()
{
initialize(command_t::CREATE, state_t::QUERY_CREATE);
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::CREATE));
@@ -89,7 +99,8 @@ query_builder& query_builder::create() {
return *this;
}
query_builder& query_builder::drop() {
query_builder &query_builder::drop()
{
initialize(command_t::DROP, state_t::QUERY_DROP);
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::DROP));
@@ -97,7 +108,7 @@ query_builder& query_builder::drop() {
return *this;
}
query_builder& query_builder::select(std::initializer_list<column> columns)
query_builder &query_builder::select(std::initializer_list<column> columns)
{
return select(std::vector<column>{columns});
}
@@ -112,7 +123,7 @@ query_builder &query_builder::select(const std::vector<column> &columns)
std::string result;
if (columns.size() < 2) {
for (const auto &col : columns) {
for (const auto &col: columns) {
result.append(dialect_.prepare_identifier(col));
query_.prototype.append(col);
}
@@ -131,7 +142,8 @@ query_builder &query_builder::select(const std::vector<column> &columns)
return *this;
}
query_builder& query_builder::insert() {
query_builder &query_builder::insert()
{
initialize(command_t::INSERT, state_t::QUERY_INSERT);
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::INSERT));
@@ -139,7 +151,8 @@ query_builder& query_builder::insert() {
return *this;
}
query_builder& query_builder::update(const std::string &table) {
query_builder &query_builder::update(const std::string &table)
{
initialize(command_t::UPDATE, state_t::QUERY_UPDATE);
query_.table_name = table;
@@ -148,7 +161,8 @@ query_builder& query_builder::update(const std::string &table) {
return *this;
}
query_builder& query_builder::remove() {
query_builder &query_builder::remove()
{
initialize(command_t::REMOVE, state_t::QUERY_DELETE);
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::REMOVE));
@@ -156,7 +170,7 @@ query_builder& query_builder::remove() {
return *this;
}
query_builder& query_builder::table(const std::string &table, std::initializer_list<column> columns)
query_builder &query_builder::table(const std::string &table, std::initializer_list<column> columns)
{
return this->table(table, std::vector<column>{columns});
}
@@ -176,7 +190,8 @@ struct column_context
std::string build_create_column(const column &col, const dialect &d, column_context &context);
query_builder &query_builder::table(const std::string &table, const std::vector<column> &columns) {
query_builder &query_builder::table(const std::string &table, const std::vector<column> &columns)
{
transition_to(state_t::QUERY_TABLE_CREATE);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table) + " ");
@@ -187,7 +202,7 @@ query_builder &query_builder::table(const std::string &table, const std::vector<
column_context context;
if (columns.size() < 2) {
for (const auto &col : columns) {
for (const auto &col: columns) {
result.append(build_create_column(col, dialect_, context));
}
} else {
@@ -202,7 +217,7 @@ query_builder &query_builder::table(const std::string &table, const std::vector<
if (!context.primary_keys.empty()) {
result.append(", CONSTRAINT PK_" + table + " PRIMARY KEY (" + utils::join(context.primary_keys, ", ") + ")");
}
for (const auto &fk : context.foreign_contexts) {
for (const auto &fk: context.foreign_contexts) {
result += ", CONSTRAINT FK_" + table;
result += "_" + fk.column;
result += " FOREIGN KEY (" + fk.column + ")";
@@ -214,7 +229,8 @@ query_builder &query_builder::table(const std::string &table, const std::vector<
return *this;
}
query_builder& query_builder::table(const std::string &table) {
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));
@@ -223,7 +239,7 @@ query_builder& query_builder::table(const std::string &table) {
return *this;
}
query_builder& query_builder::into(const std::string &table, std::initializer_list<std::string> column_names)
query_builder &query_builder::into(const std::string &table, std::initializer_list<std::string> column_names)
{
return into(table, std::vector<std::string>{column_names});
}
@@ -237,7 +253,7 @@ query_builder &query_builder::into(const std::string &table, const std::vector<s
std::string result{"("};
if (column_names.size() < 2) {
for (const auto &col : column_names) {
for (const auto &col: column_names) {
result.append(dialect_.prepare_identifier(col));
}
} else {
@@ -254,19 +270,20 @@ query_builder &query_builder::into(const std::string &table, const std::vector<s
return *this;
}
query_builder& query_builder::values(std::initializer_list<any_type> values)
query_builder &query_builder::values(std::initializer_list<any_type> values)
{
return this->values(std::vector<any_type>{values});
}
query_builder& query_builder::values(const std::vector<any_type> &values) {
query_builder &query_builder::values(const std::vector<any_type> &values)
{
transition_to(state_t::QUERY_VALUES);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::VALUES) + " ");
std::string result{"("};
if (values.size() < 2) {
for (auto val : values) {
for (auto val: values) {
query_.host_vars.push_back(val);
std::visit(value_to_string_, val);
result.append(value_to_string_.result);
@@ -291,10 +308,20 @@ query_builder& query_builder::values(const std::vector<any_type> &values) {
return *this;
}
query_builder& query_builder::from(const std::string &table, const std::string &as) {
query_builder &query_builder::from(const std::string &table, const std::string &as)
{
transition_to(state_t::QUERY_FROM);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::FROM) + " " + dialect_.prepare_identifier(table) + (as.empty() ? "" : " " + as));
if (dialect_.default_schema_name().empty()) {
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::FROM) +
" " + dialect_.prepare_identifier(table) +
(as.empty() ? "" : " " + as));
} else {
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::FROM) +
" " + dialect_.prepare_identifier(dialect_.default_schema_name()) +
"." + dialect_.prepare_identifier(table) +
(as.empty() ? "" : " " + as));
}
query_.table_name = table;
return *this;
@@ -315,14 +342,15 @@ query_builder &query_builder::set(std::initializer_list<key_value_pair> key_valu
return set(std::vector<key_value_pair>{key_values});
}
query_builder& query_builder::set(const std::vector<key_value_pair> &key_values) {
query_builder &query_builder::set(const std::vector<key_value_pair> &key_values)
{
transition_to(state_t::QUERY_SET);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::SET) + " ");
std::string result;
if (key_values.size() < 2) {
for (const auto &col : key_values) {
for (const auto &col: key_values) {
result.append(dialect_.prepare_identifier(col.name()) + "=");
auto var = col.value();
std::visit(value_to_string_, var);
@@ -347,67 +375,76 @@ query_builder& query_builder::set(const std::vector<key_value_pair> &key_values)
return *this;
}
query_builder& query_builder::where(const basic_condition &cond) {
query_builder &query_builder::where(const basic_condition &cond)
{
transition_to(state_t::QUERY_WHERE);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::WHERE) + " ");
query_parts_.emplace_back(cond.evaluate(const_cast<dialect &>(dialect_)));
query_parts_.emplace_back(cond.evaluate(const_cast<dialect &>(dialect_), query_));
return *this;
}
query_builder& query_builder::order_by(const std::string& column) {
transition_to(state_t::QUERY_ORDER_BY);
query_builder &query_builder::order_by(const std::string &column)
{
transition_to(state_t::QUERY_ORDER_BY);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::ORDER_BY) + " " + dialect_.prepare_identifier(column));
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::ORDER_BY) + " " + dialect_.prepare_identifier(column));
return *this;
return *this;
}
query_builder& query_builder::group_by(const std::string& column) {
transition_to(state_t::QUERY_GROUP_BY);
query_builder &query_builder::group_by(const std::string &column)
{
transition_to(state_t::QUERY_GROUP_BY);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::GROUP_BY) + " " + dialect_.prepare_identifier(column));
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::GROUP_BY) + " " + dialect_.prepare_identifier(column));
return *this;
return *this;
}
query_builder& query_builder::asc() {
transition_to(state_t::QUERY_ORDER_DIRECTION);
query_builder &query_builder::asc()
{
transition_to(state_t::QUERY_ORDER_DIRECTION);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::ASC));
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::ASC));
return *this;
return *this;
}
query_builder& query_builder::desc() {
transition_to(state_t::QUERY_ORDER_DIRECTION);
query_builder &query_builder::desc()
{
transition_to(state_t::QUERY_ORDER_DIRECTION);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::DESC));
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::DESC));
return *this;
return *this;
}
query_builder& query_builder::offset( size_t count ) {
transition_to(state_t::QUERY_OFFSET);
query_builder &query_builder::offset(size_t count)
{
transition_to(state_t::QUERY_OFFSET);
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::OFFSET) + " " + std::to_string(count));
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::OFFSET) + " " + std::to_string(count));
return *this;
return *this;
}
query_builder& query_builder::limit( size_t count ) {
transition_to(state_t::QUERY_LIMIT);
query_builder &query_builder::limit(size_t count)
{
transition_to(state_t::QUERY_LIMIT);
query_parts_.emplace_back( " " + dialect_.token_at(dialect::token_t::LIMIT) + " " + std::to_string( count));
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::LIMIT) + " " + std::to_string(count));
return *this;
return *this;
}
query query_builder::compile() {
for (const auto &part : query_parts_) {
query_context query_builder::compile()
{
for (const auto &part: query_parts_) {
query_.sql.append(part);
}
query_.command_name = command_strings_[command_];
return query_;
}
@@ -427,22 +464,23 @@ void query_builder::initialize(query_builder::command_t cmd, query_builder::stat
query_parts_.clear();
}
std::string build_create_column(const column &col, const dialect &d, column_context &context) {
std::string result = d.prepare_identifier(col.name()) + " " + d.data_type_at(col.type());
if (col.attributes().size() > 0) {
result.append("(" + std::to_string(col.attributes().size()) +")");
}
if (is_constraint_set(col.attributes().options(), utils::constraints::NOT_NULL)) {
result.append(" NOT NULL");
}
if (is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
context.primary_keys.emplace_back(col.name());
}
if (is_constraint_set(col.attributes().options(), utils::constraints::FOREIGN_KEY)) {
context.foreign_contexts.push_back({col.name(), col.ref_table(), col.ref_column()});
}
std::string build_create_column(const column &col, const dialect &d, column_context &context)
{
std::string result = d.prepare_identifier(col.name()) + " " + d.data_type_at(col.type());
if (col.attributes().size() > 0) {
result.append("(" + std::to_string(col.attributes().size()) + ")");
}
if (is_constraint_set(col.attributes().options(), utils::constraints::NOT_NULL)) {
result.append(" NOT NULL");
}
if (is_constraint_set(col.attributes().options(), utils::constraints::PRIMARY_KEY)) {
context.primary_keys.emplace_back(col.name());
}
if (is_constraint_set(col.attributes().options(), utils::constraints::FOREIGN_KEY)) {
context.foreign_contexts.push_back({col.name(), col.ref_table(), col.ref_column()});
}
return result;
return result;
}
column alias(const std::string &column, const std::string &as)
@@ -450,7 +488,8 @@ column alias(const std::string &column, const std::string &as)
return {column, as};
}
column alias(column &&col, const std::string &as) {
column alias(column &&col, const std::string &as)
{
col.alias(as);
return std::move(col);
}
+12 -2
View File
@@ -18,6 +18,11 @@ std::unique_ptr<query_result_impl> query_select_finish::fetch()
return session_.fetch(builder_.compile().sql);
}
statement query_select_finish::prepare()
{
return session_.prepare(builder_.compile());
}
query_intermediate::query_intermediate(session &db, query_builder &query)
: session_(db), builder_(query) {}
@@ -103,6 +108,11 @@ std::pair<size_t, std::string> query_execute_finish::execute()
return session_.execute(builder_.compile().sql);
}
statement query_execute_finish::prepare()
{
return session_.prepare(builder_.compile());
}
query_execute_finish query_into_intermediate::values(std::initializer_list<any_type> values)
{
return {session_, builder_.values(values)};
@@ -140,10 +150,10 @@ query_execute_where_intermediate query_set_intermediate::where(const basic_condi
return {session_, builder_.where(cond)};
}
query_update_intermediate::query_update_intermediate(session &s, std::string table_name)
query_update_intermediate::query_update_intermediate(session &s, const std::string& table_name)
: query_start_intermediate(s)
{
builder_.update(std::move(table_name));
builder_.update(table_name);
}
query_set_intermediate query_update_intermediate::set(std::initializer_list<key_value_pair> columns)
+10 -1
View File
@@ -40,7 +40,7 @@ query_delete_intermediate session::remove()
return query_delete_intermediate{*this};
}
query_result<record> session::fetch(const query &q) const
query_result<record> session::fetch(const query_context &q) const
{
auto c = pool_.acquire();
if (!c.valid()) {
@@ -73,6 +73,15 @@ std::pair<size_t, std::string> session::execute(const std::string &sql) const {
return c->execute(sql);
}
statement session::prepare(query_context q) const
{
auto c = pool_.acquire();
if (!c.valid()) {
throw std::logic_error("no database connection available");
}
return c->prepare(std::move(q));
}
record session::describe_table(const std::string &table_name) const
{
auto c = pool_.acquire();
+34
View File
@@ -0,0 +1,34 @@
#include "matador/sql/statement.hpp"
namespace matador::sql {
statement::statement(std::unique_ptr<statement_impl> impl, const utils::logger &logger)
: statement_(std::move(impl))
, logger_(logger)
, object_binder_(statement_->binder())
{}
statement &statement::bind(size_t pos, std::string &val, size_t size)
{
statement_->bind(pos, val, size);
return *this;
}
size_t statement::execute()
{
logger_.info(statement_->query_.sql);
return statement_->execute();
}
query_result<record> statement::fetch()
{
logger_.info(statement_->query_.sql);
return query_result<record>(statement_->fetch());
}
void statement::reset()
{
statement_->reset();
}
}
+17
View File
@@ -0,0 +1,17 @@
#include "matador/sql/statement_cache.hpp"
namespace matador::sql {
statement &statement_cache::acquire(const std::string &stmt, const connection &conn) {
std::lock_guard<std::mutex> guard(mutex_);
auto key = hash_(stmt);
auto it = statement_map_.find(key);
if (it == statement_map_.end()) {
}
return *it->second.statement_;
}
void statement_cache::release(const statement &stmt) {
}
}
+9
View File
@@ -0,0 +1,9 @@
#include "matador/sql/statement_impl.hpp"
namespace matador::sql {
statement_impl::statement_impl(query_context query)
: query_(std::move(query))
{}
}