added where condition
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
#include "matador/sql/basic_condition.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
std::unordered_map<basic_condition::operand_t, std::string> basic_condition::operands{
|
||||
{operand_t::EQUAL, "="},
|
||||
{operand_t::NOT_EQUAL, "<>"},
|
||||
{operand_t::LESS, "<"},
|
||||
{operand_t::LESS_EQUAL, "<="},
|
||||
{operand_t::GREATER, ">"},
|
||||
{operand_t::GREATER_EQUAL, ">="},
|
||||
{operand_t::OR, "OR"},
|
||||
{operand_t::AND, "AND"},
|
||||
{operand_t::NOT, "NOT"},
|
||||
{operand_t::IN_LIST, "IN"},
|
||||
{operand_t::LIKE, "LIKE"}
|
||||
};
|
||||
|
||||
basic_column_condition::basic_column_condition(column fld, basic_condition::operand_t op)
|
||||
: field_(std::move(fld)), operand(basic_condition::operands[op])
|
||||
{ }
|
||||
|
||||
basic_in_condition::basic_in_condition(column fld)
|
||||
: field_(std::move(fld))
|
||||
{ }
|
||||
}
|
||||
@@ -20,4 +20,28 @@ data_type_t column::type() const {
|
||||
return type_;
|
||||
}
|
||||
|
||||
column operator "" _col(const char *name, size_t len)
|
||||
{
|
||||
return column(std::string(name, len));
|
||||
}
|
||||
|
||||
column make_column( const std::string& name, data_type_t type, utils::field_attributes attr )
|
||||
{
|
||||
return {name, type, attr};
|
||||
}
|
||||
|
||||
template<>
|
||||
column make_column<std::string>( const std::string& name, utils::field_attributes attr ) {
|
||||
return make_column(name, data_type_traits<std::string>::builtin_type(attr.size()), attr);
|
||||
}
|
||||
|
||||
template<>
|
||||
column make_fk_column<std::string>( const std::string& name, size_t size ) {
|
||||
return make_column<std::string>(name, { size, utils::constraints::FOREIGN_KEY });
|
||||
}
|
||||
|
||||
template<>
|
||||
column make_pk_column<std::string>( const std::string& name, size_t size ) {
|
||||
return make_column<std::string>(name, { size, utils::constraints::PRIMARY_KEY | utils::constraints::NOT_NULL});
|
||||
}
|
||||
}
|
||||
+32
-1
@@ -52,8 +52,39 @@ void dialect::escape_quotes_in_literals(std::string &str) const
|
||||
utils::replace_all(str, single_quote, double_quote);
|
||||
}
|
||||
|
||||
dialect::escape_identifier_t dialect::identifier_escape_type() const {
|
||||
dialect::escape_identifier_t dialect::identifier_escape_type() const
|
||||
{
|
||||
return dialect::escape_identifier_t::ESCAPE_BOTH_SAME;
|
||||
}
|
||||
|
||||
std::string dialect::next_placeholder() const
|
||||
{
|
||||
return "?";
|
||||
}
|
||||
|
||||
dialect::compile_type_t dialect::compile_type() const
|
||||
{
|
||||
return compile_type_;
|
||||
}
|
||||
|
||||
void dialect::add_host_var(const std::string &host_var)
|
||||
{
|
||||
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_;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "matador/sql/key_value_pair.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
key_value_pair::key_value_pair(const std::string &name, any_type value)
|
||||
: name_(name)
|
||||
, value_(std::move(value)) {
|
||||
}
|
||||
|
||||
key_value_pair::key_value_pair(const char *name, any_type value)
|
||||
: name_(name)
|
||||
, value_(std::move(value)) {
|
||||
}
|
||||
|
||||
const std::string &key_value_pair::name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
const any_type& key_value_pair::value() const {
|
||||
return value_;
|
||||
}
|
||||
}
|
||||
+207
-25
@@ -5,17 +5,33 @@
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
namespace detail {
|
||||
|
||||
void any_type_to_string_visitor::to_string(const char *val)
|
||||
{
|
||||
result = "'" + d.prepare_literal(val) + "'";
|
||||
}
|
||||
|
||||
void any_type_to_string_visitor::to_string(std::string &val)
|
||||
{
|
||||
result = "'" + d.prepare_literal(val) + "'";
|
||||
}
|
||||
|
||||
}
|
||||
std::string build_create_column(const column &col, const dialect &d);
|
||||
|
||||
// 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}},
|
||||
{state_t::QUERY_DROP, {state_t::QUERY_TABLE}},
|
||||
{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, {state_t::QUERY_FINISH}},
|
||||
{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_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}},
|
||||
@@ -36,7 +52,8 @@ query_builder::query_state_to_string_map query_builder::state_strings_ {
|
||||
{ state_t::QUERY_INSERT, "insert" },
|
||||
{ state_t::QUERY_UPDATE, "update" },
|
||||
{ state_t::QUERY_DELETE, "delete" },
|
||||
{ state_t::QUERY_TABLE, "table" },
|
||||
{ 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" },
|
||||
@@ -58,35 +75,90 @@ query_builder::query_command_to_string_map query_builder::command_strings_ {
|
||||
};
|
||||
|
||||
query_builder::query_builder(const dialect &d)
|
||||
: dialect_(d) {}
|
||||
: dialect_(d)
|
||||
, value_to_string_(d) {}
|
||||
|
||||
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) + " ");
|
||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::CREATE));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder query_builder::drop() {
|
||||
initialize(command_t::DROP, state_t::QUERY_DROP);
|
||||
|
||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::DROP));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder query_builder::select(std::initializer_list<std::string> column_names) {
|
||||
initialize(command_t::SELECT, state_t::QUERY_SELECT);
|
||||
|
||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::SELECT) + " ");
|
||||
|
||||
std::string result;
|
||||
if (column_names.size() < 2) {
|
||||
for (const auto &col : column_names) {
|
||||
result.append(dialect_.prepare_identifier(col));
|
||||
}
|
||||
} else {
|
||||
auto it = column_names.begin();
|
||||
result.append(dialect_.prepare_identifier(*it++));
|
||||
for (it; it != column_names.end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(dialect_.prepare_identifier(*it));
|
||||
}
|
||||
}
|
||||
|
||||
query_parts_.emplace_back(result);
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder query_builder::insert() {
|
||||
initialize(command_t::INSERT, state_t::QUERY_INSERT);
|
||||
|
||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::INSERT));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder query_builder::update(const std::string &table) {
|
||||
initialize(command_t::UPDATE, state_t::QUERY_UPDATE);
|
||||
|
||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::UPDATE) + " " + dialect_.prepare_identifier(table));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder query_builder::remove() {
|
||||
initialize(command_t::REMOVE, state_t::QUERY_DELETE);
|
||||
|
||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::REMOVE));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder &query_builder::table(const std::string &table, std::initializer_list<column> columns) {
|
||||
transition_to(state_t::QUERY_TABLE);
|
||||
transition_to(state_t::QUERY_TABLE_CREATE);
|
||||
|
||||
query_parts_.emplace_back(dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table) + " ");
|
||||
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table) + " ");
|
||||
|
||||
std::string result = "(";
|
||||
|
||||
for (const auto &col : columns) {
|
||||
result.append(dialect_.prepare_identifier(col.name()) + " " + dialect_.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)) {
|
||||
result.append(" PRIMARY KEY");
|
||||
}
|
||||
result.append(", ");
|
||||
if (columns.size() < 2) {
|
||||
for (const auto &col : columns) {
|
||||
result.append(build_create_column(col, dialect_));
|
||||
}
|
||||
} else {
|
||||
auto it = columns.begin();
|
||||
result.append(build_create_column(*it++, dialect_));
|
||||
for (it; it != columns.end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(build_create_column(*it, dialect_));
|
||||
}
|
||||
}
|
||||
|
||||
result += ")";
|
||||
@@ -94,22 +166,117 @@ query_builder &query_builder::table(const std::string &table, std::initializer_l
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder &query_builder::select(std::initializer_list<std::string> column_names) {
|
||||
initialize(command_t::SELECT, state_t::QUERY_SELECT);
|
||||
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::SELECT) + " ");
|
||||
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::TABLE) + " " + dialect_.prepare_identifier(table));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder &query_builder::into(const std::string &table, std::initializer_list<std::string> column_names) {
|
||||
transition_to(state_t::QUERY_INTO);
|
||||
|
||||
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::INTO) + " " + dialect_.prepare_identifier(table) + " ");
|
||||
|
||||
std::string result{"("};
|
||||
if (column_names.size() < 2) {
|
||||
for (const auto &col : column_names) {
|
||||
result.append(dialect_.prepare_identifier(col));
|
||||
}
|
||||
} else {
|
||||
auto it = column_names.begin();
|
||||
result.append(dialect_.prepare_identifier(*it++));
|
||||
for (it; it != column_names.end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(dialect_.prepare_identifier(*it));
|
||||
}
|
||||
}
|
||||
result += (")");
|
||||
|
||||
query_parts_.emplace_back(result);
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder &query_builder::values(std::initializer_list<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) {
|
||||
std::visit(value_to_string_, val);
|
||||
result.append(value_to_string_.result);
|
||||
}
|
||||
} else {
|
||||
auto it = values.begin();
|
||||
auto val = *it++;
|
||||
std::visit(value_to_string_, val);
|
||||
result.append(value_to_string_.result);
|
||||
for (; it != values.end(); ++it) {
|
||||
result.append(", ");
|
||||
val = *it;
|
||||
std::visit(value_to_string_, val);
|
||||
result.append(value_to_string_.result);
|
||||
}
|
||||
}
|
||||
result += (")");
|
||||
|
||||
query_parts_.emplace_back(result);
|
||||
return *this;
|
||||
}
|
||||
|
||||
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::TABLE) + " " + (as.empty() ? "" : as + " "));
|
||||
query_parts_.emplace_back(" " + dialect_.token_at(dialect::token_t::FROM) + " " + dialect_.prepare_identifier(table) + (as.empty() ? "" : " " + as));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
query_builder &query_builder::set(std::initializer_list<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) {
|
||||
result.append(dialect_.prepare_identifier(col.name()) + "=");
|
||||
auto var = col.value();
|
||||
std::visit(value_to_string_, var);
|
||||
result.append(value_to_string_.result);
|
||||
}
|
||||
} else {
|
||||
auto it = key_values.begin();
|
||||
result.append(dialect_.prepare_identifier(it->name()) + "=");
|
||||
auto var = (it++)->value();
|
||||
std::visit(value_to_string_, var);
|
||||
result.append(value_to_string_.result);
|
||||
for (; it != key_values.end(); ++it) {
|
||||
result.append(", ");
|
||||
result.append(dialect_.prepare_identifier((*it).name()) + "=");
|
||||
var = it->value();
|
||||
std::visit(value_to_string_, var);
|
||||
result.append(value_to_string_.result);
|
||||
}
|
||||
}
|
||||
|
||||
query_parts_.emplace_back(result);
|
||||
return *this;
|
||||
}
|
||||
|
||||
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_)));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
std::string query_builder::compile() {
|
||||
std::string result;
|
||||
for (const auto &part : query_parts_) {
|
||||
@@ -133,4 +300,19 @@ 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) {
|
||||
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)) {
|
||||
result.append(" PRIMARY KEY");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user