diff --git a/demo/work.cpp b/demo/work.cpp index 3140da0..9f68414 100644 --- a/demo/work.cpp +++ b/demo/work.cpp @@ -218,4 +218,52 @@ int main() { // query.addBindValue( columnFilterValue ); return 0; -} \ No newline at end of file +} + +/* +SELECT + "tasks"."payload", "payloads"."id" +FROM + "public"."tasks", "public"."payloads" +WHERE + "payloads"."id" = "tasks"."payload" + +SELECT + "iPT"."payload_id" FROM "public"."id_payloads" "iPT" +LEFT JOIN + "public"."payloads" "pT" +ON + "iPT"."id" = "pT"."id" +WHERE ("pT"."id" IN ( + SELECT + "jobs"."payload" + FROM + "public"."jobs" + WHERE + "jobs"."state" = $1 + ) AND "iPT"."payload_id" IN ( + SELECT + "ID" + FROM "public"."TempTable" + ) +) + +SELECT + "login_histories"."client" +FROM + "public"."login_histories" +LEFT JOIN ( + SELECT + "login_histories"."client", MAX(login_time) AS lastSuccessfulLogin + FROM + "public"."login_histories" + WHERE + "login_histories"."fail_reason" = $1 + GROUP BY + "login_histories"."client" + ) +ON + "login_histories"."client" = 'll.client' +WHERE + ("lastSuccessfulLogin" IS NULL AND "login_histories"."login_time" < 'll.lastSuccessfulLogin') +*/ \ No newline at end of file diff --git a/include/matador/query/internal/string_builder_utils.hpp b/include/matador/query/internal/string_builder_utils.hpp new file mode 100644 index 0000000..94caeda --- /dev/null +++ b/include/matador/query/internal/string_builder_utils.hpp @@ -0,0 +1,14 @@ +#ifndef MATADOR_STRING_BUILDER_UTILS_HPP +#define MATADOR_STRING_BUILDER_UTILS_HPP + +#include + +namespace matador::sql { +class dialect; +} + +namespace matador::query { +void prepare_identifier_string_append(std::string& out, std::string_view col, const sql::dialect &d); +} + +#endif // MATADOR_STRING_BUILDER_UTILS_HPP diff --git a/include/matador/query/query.hpp b/include/matador/query/query.hpp index 5595a54..172797f 100644 --- a/include/matador/query/query.hpp +++ b/include/matador/query/query.hpp @@ -14,8 +14,8 @@ table_column count(const std::string &column); table_column count_all(); table_column sum(const std::string &column); table_column avg(const std::string &column); -table_column max(const std::string &column); -table_column min(const std::string &column); +table_column maximum(const std::string &column); +table_column minimum(const std::string &column); class query { diff --git a/include/matador/query/table_column.hpp b/include/matador/query/table_column.hpp index c3b37c8..4dc0d09 100644 --- a/include/matador/query/table_column.hpp +++ b/include/matador/query/table_column.hpp @@ -16,13 +16,19 @@ class table; class table_column { public: table_column(const char *name); // NOLINT(*-explicit-constructor) - table_column(std::string name); // NOLINT(*-explicit-constructor) - table_column(std::string name, std::string alias); - table_column(sql::sql_function_t func, std::string name); - table_column(const class table* tab, std::string name); - table_column(const class table* tab, std::string name, std::string alias); - table_column(const class table* tab, std::string name, utils::basic_type type, const utils::field_attributes& attributes); - table_column(const class table*, std::string name, std::string alias, utils::basic_type type, const utils::field_attributes& attributes, sql::sql_function_t func = sql::sql_function_t::None); + table_column(const std::string& name); // NOLINT(*-explicit-constructor) + table_column(const std::string& name, const std::string& alias); + table_column(sql::sql_function_t func, const std::string& name); + table_column(const class table* tab, const std::string& name); + table_column(const class table* tab, const std::string& name, + const std::string& alias); + table_column(const class table* tab, const std::string& name, utils::basic_type type, const utils::field_attributes& attributes); + table_column(const class table*, + const std::string& name, + const std::string& alias, + utils::basic_type type, + const utils::field_attributes& attributes, + sql::sql_function_t func = sql::sql_function_t::None); table_column& operator=(const table_column& other); table_column(const table_column& other) = default; table_column(table_column&& other) noexcept = default; @@ -30,10 +36,11 @@ public: [[nodiscard]] bool equals(const table_column &x) const; - table_column as(const std::string& alias) const; + [[nodiscard]] table_column as(const std::string& alias) const; [[nodiscard]] const std::string& name() const; - [[nodiscard]] std::string canonical_name() const; + [[nodiscard]] const std::string& column_name() const; + [[nodiscard]] const std::string& canonical_name() const; [[nodiscard]] const std::string& alias() const; [[nodiscard]] utils::basic_type type() const; [[nodiscard]] utils::field_attributes attributes() const; @@ -49,11 +56,15 @@ public: // ReSharper disable once CppNonExplicitConversionOperator operator const std::string&() const; // NOLINT(*-explicit-constructor) +private: + static std::string build_column_name(const class table *tab, const std::string& name); + private: friend class table; const class table* table_{nullptr}; std::string name_; + std::string column_name_; std::string alias_; utils::basic_type type_{utils::basic_type::Unknown}; utils::field_attributes attributes_{}; diff --git a/include/matador/sql/dialect.hpp b/include/matador/sql/dialect.hpp index dcbb26b..cf1f285 100644 --- a/include/matador/sql/dialect.hpp +++ b/include/matador/sql/dialect.hpp @@ -53,7 +53,6 @@ public: * @return The prepared string */ [[nodiscard]] std::string prepare_identifier_string(const std::string &col) const; - [[nodiscard]] std::string table_name(const std::string &table, const std::string &schema_name) const; [[nodiscard]] const std::string& to_string(bool val) const; diff --git a/source/orm/CMakeLists.txt b/source/orm/CMakeLists.txt index fe0771c..052bfb1 100644 --- a/source/orm/CMakeLists.txt +++ b/source/orm/CMakeLists.txt @@ -48,6 +48,7 @@ add_library(matador-orm STATIC ../../include/matador/query/internal/basic_type_to_string_visitor.hpp ../../include/matador/query/internal/column_value_pair.hpp ../../include/matador/query/internal/query_parts.hpp + ../../include/matador/query/internal/string_builder_utils.hpp ../../include/matador/query/join_data.hpp ../../include/matador/query/key_value_generator.hpp ../../include/matador/query/meta_table_macro.hpp @@ -142,6 +143,7 @@ add_library(matador-orm STATIC query/internal/column_value_pair.cpp query/internal/query_parts.cpp query/internal/query_result_impl.cpp + query/internal/string_builder_utils.cpp query/key_value_generator.cpp query/query.cpp query/query_builder.cpp diff --git a/source/orm/query/criteria_evaluator.cpp b/source/orm/query/criteria_evaluator.cpp index 0c9dcdb..e513ee2 100644 --- a/source/orm/query/criteria_evaluator.cpp +++ b/source/orm/query/criteria_evaluator.cpp @@ -40,7 +40,7 @@ std::string criteria_evaluator::evaluate(const abstract_criteria &node) { void criteria_evaluator::visit(const between_criteria &node) { query_.bind_vars.emplace_back(node.col().name()); query_.bind_vars.emplace_back(node.col().name()); - clause_ += prepare_identifier(dialect_, node.col()) + " " + dialect_.token_at(sql::dialect_token::Between) + " "; + clause_ += prepare_identifier(dialect_, node.col()) + " " + dialect_.between() + " "; evaluate_value(node.minimum()); clause_ += " " + dialect_.token_at(sql::dialect_token::And) + " "; evaluate_value(node.maximum()); @@ -94,12 +94,12 @@ void criteria_evaluator::visit(const collection_criteria &node) { void criteria_evaluator::visit(const collection_query_criteria &node) { clause_ += prepare_identifier(dialect_, node.col()) + - (node.operand() == collection_operator::Out ? " " + dialect_.token_at(sql::dialect_token::Not) + " " : " ") + - dialect_.token_at(sql::dialect_token::In) + " (" + node.query().str( dialect_ ) + ")"; + (node.operand() == collection_operator::Out ? " " + dialect_.not_() + " " : " ") + + dialect_.in() + " (" + node.query().str( dialect_ ) + ")"; } void criteria_evaluator::visit(const like_criteria &node) { - clause_ += prepare_criteria(dialect_, node.col()) + " " + dialect_.token_at(sql::dialect_token::Like) + + clause_ += prepare_criteria(dialect_, node.col()) + " " + dialect_.like() + " " + dialect_.token_at(sql::dialect_token::BeginStringData) + node.pattern() + dialect_.token_at( sql::dialect_token::EndStringData); } diff --git a/source/orm/query/internal/string_builder_utils.cpp b/source/orm/query/internal/string_builder_utils.cpp new file mode 100644 index 0000000..9074dc3 --- /dev/null +++ b/source/orm/query/internal/string_builder_utils.cpp @@ -0,0 +1,40 @@ +#include "matador/query/internal/string_builder_utils.hpp" + +#include "matador/sql/dialect.hpp" + +namespace matador::query { +void prepare_identifier_string_append(std::string& out, const std::string_view col, const sql::dialect &d) { + bool first_part = true; + + const char sq = d.start_quote()[0]; + const char eq = d.end_quote()[0]; + + std::size_t i = 0; + while (true) { + const std::size_t start = i; + + // find end of part + while (i < col.size() && col[i] != '.') { + ++i; + } + const std::size_t end = i; // [start, end) is the part + + if (!first_part) { + out.push_back('.'); + } + first_part = false; + + // quote_identifier(part) + escape_quotes_in_identifier(part), but streaming: + out.push_back(sq); + for (std::size_t j = start; j < end; ++j) { + const char c = col[j]; + if (c == eq) out.push_back(eq); // escape " as "" + out.push_back(c); + } + out.push_back(eq); + + if (i >= col.size()) break; // done + ++i; // skip '.' + } +} +} \ No newline at end of file diff --git a/source/orm/query/query.cpp b/source/orm/query/query.cpp index 73629ee..730ec1c 100644 --- a/source/orm/query/query.cpp +++ b/source/orm/query/query.cpp @@ -15,10 +15,10 @@ table_column sum(const std::string& column) { table_column avg(const std::string& column) { return {sql::sql_function_t::Avg, column}; } -table_column max(const std::string& column) { +table_column maximum(const std::string& column) { return {sql::sql_function_t::Max, column}; } -table_column min(const std::string& column) { +table_column minimum(const std::string& column) { return {sql::sql_function_t::Min, column}; } diff --git a/source/orm/query/query_compiler.cpp b/source/orm/query/query_compiler.cpp index 7b4ba20..17dc1be 100644 --- a/source/orm/query/query_compiler.cpp +++ b/source/orm/query/query_compiler.cpp @@ -8,14 +8,13 @@ #include "matador/query/table_column.hpp" #include "matador/query/internal/basic_type_to_string_visitor.hpp" +#include "matador/query/internal/string_builder_utils.hpp" #include "matador/query/internal/query_parts.hpp" #include "matador/sql/query_context.hpp" #include "matador/sql/connection.hpp" #include "matador/sql/dialect.hpp" -#include "matador/utils/string.hpp" - namespace matador::query { sql::query_context query_compiler::compile(const query_data &data, @@ -39,10 +38,10 @@ sql::query_context query_compiler::compile(const query_data &data, std::string handle_column(sql::query_context &ctx, const sql::dialect *d, const query_data &data, const table_column &col) { if (col.is_function()) { - ctx.prototype.emplace_back(col.has_alias() ? col.alias() : col.canonical_name()); + ctx.prototype.emplace_back(col.name()); ctx.prototype.back().change_type(utils::basic_type::Int32); } else { - ctx.prototype.emplace_back(col.canonical_name()); + ctx.prototype.emplace_back(col.name()); } @@ -62,61 +61,30 @@ void query_compiler::visit(internal::query_alter_part& part) { void query_compiler::visit(internal::query_alter_table_part& part) { query_.command = sql::sql_command::SQL_ALTER_TABLE; query_.sql += " " + dialect_->token_at(part.token()) + " " + - dialect_->prepare_identifier_string(part.table().name()); + dialect_->prepare_identifier_string(part.table().name()); } void query_compiler::visit(internal::query_add_key_constraint_part& part) { query_.sql += " " + dialect_->add_constraint() + " " + part.name(); } +void build_columns(std::string &out, const std::vector &cols, const sql::dialect &d); + void query_compiler::visit(internal::query_add_foreign_key_constraint_part& part) { query_.sql += " " + dialect_->token_at(part.token()) + " ("; - - if (part.columns().size() < 2) { - for (const auto &col: part.columns()) { - query_.sql += dialect_->prepare_identifier_string(col.name()); - } - } else { - auto it = part.columns().begin(); - query_.sql += dialect_->prepare_identifier_string(it->name()); - for (; it != part.columns().end(); ++it) { - query_.sql += ", " + dialect_->prepare_identifier_string(it->name()); - } - } + build_columns(query_.sql, part.columns(), *dialect_); query_.sql += ")"; } void query_compiler::visit(internal::query_add_primary_key_constraint_part& part) { - query_.sql += " " + dialect_->primary_key() + " ("; - - if (part.columns().size() < 2) { - for (const auto &col: part.columns()) { - query_.sql += dialect_->prepare_identifier_string(col.name()); - } - } else { - auto it = part.columns().begin(); - query_.sql += dialect_->prepare_identifier_string(it->name()); - for (; it != part.columns().end(); ++it) { - query_.sql += ", " + dialect_->prepare_identifier_string(it->name()); - } - } - query_.sql += ")"; + query_.sql += " " + dialect_->primary_key() + " ("; + build_columns(query_.sql, part.columns(), *dialect_); + query_.sql += ")"; } void query_compiler::visit(internal::query_add_foreign_key_reference_part& part) { query_.sql += " " + dialect_->token_at(part.token()) + " " + part.table().name() + " ("; - - if (part.columns().size() < 2) { - for (const auto &col: part.columns()) { - query_.sql += dialect_->prepare_identifier_string(col.name()); - } - } else { - auto it = part.columns().begin(); - query_.sql += dialect_->prepare_identifier_string(it->name()); - for (; it != part.columns().end(); ++it) { - query_.sql += ", " + dialect_->prepare_identifier_string(it->name()); - } - } + build_columns(query_.sql, part.columns(), *dialect_); query_.sql += ")"; } @@ -198,7 +166,7 @@ void query_compiler::visit(internal::query_group_by_part &part) { query_.sql += " " + dialect_->group_by() + " "; if (part.columns().size() < 2) { for (const auto &col: part.columns()) { - query_.sql.append(dialect_->prepare_identifier_string(col.canonical_name())); + query_.sql.append(dialect_->prepare_identifier_string(col.name())); } } else { auto it = part.columns().begin(); @@ -250,23 +218,10 @@ void query_compiler::visit(internal::query_insert_part &/*insert_part*/) { void query_compiler::visit(internal::query_into_part &part) { query_.table_name = part.table().name(); query_.sql += " " + dialect_->into() + - " " + dialect_->prepare_identifier_string(part.table().name()); + " " + dialect_->prepare_identifier_string(part.table().name()) + " ("; - std::string result{"("}; - if (part.columns().size() < 2) { - for (const auto &col: part.columns()) { - result.append(dialect_->prepare_identifier_string(col.name())); - } - } else { - auto it = part.columns().begin(); - result.append(dialect_->prepare_identifier_string((it++)->name())); - for (; it != part.columns().end(); ++it) { - result.append(", "); - result.append(dialect_->prepare_identifier_string(it->name())); - } - } - result += (")"); - query_.sql += " " + result; + build_columns(query_.sql, part.columns(), *dialect_); + query_.sql += ")"/* + result*/; } struct value_visitor { @@ -341,7 +296,7 @@ void query_compiler::visit(internal::query_create_part &/*create_part*/) query_.sql = dialect_->create(); } -std::string build_create_column(const table_column &col, const sql::dialect &d); +void build_create_column(std::string &out, const table_column &col, const sql::dialect &d); std::string build_constraint(const table_constraint &cons, const sql::dialect &d); void query_compiler::visit(internal::query_create_table_part &part) @@ -353,22 +308,14 @@ void query_compiler::visit(internal::query_create_table_part &part) } void query_compiler::visit(internal::query_create_table_columns_part& part) { - std::string result; - - if (part.columns().size() < 2) { - for (const auto &col: part.columns()) { - result.append(build_create_column(col, *dialect_)); - } - } else { - auto it = part.columns().begin(); - result.append(build_create_column(*it++, *dialect_)); - for (; it != part.columns().end(); ++it) { - result.append(", "); - result.append(build_create_column(*it, *dialect_)); + bool first = true; + for (const auto& col : part.columns()) { + if (!first) { + query_.sql.append(", "); } + build_create_column(query_.sql, col, *dialect_); + first = false; } - - query_.sql += result; } void query_compiler::visit(internal::query_create_table_constraints_part& part) { @@ -425,22 +372,31 @@ void query_compiler::visit(internal::query_drop_table_part &part) { query_.sql += " " + build_table_name(part.token(), *dialect_, query_.table_name); } -std::string build_create_column(const table_column &col, const sql::dialect &d) { - std::string result = d.prepare_identifier_string(col.name()) + " " + d.data_type_at(col.type()); +void build_create_column(std::string &out, const table_column &col, const sql::dialect &d) { + prepare_identifier_string_append(out, col.canonical_name(), d); + out += " " + d.data_type_at(col.type()); if (col.attributes().size() > 0) { - result.append("(" + std::to_string(col.attributes().size()) + ")"); + out.append("(" + std::to_string(col.attributes().size()) + ")"); } if (!col.is_nullable()) { - result.append(" ").append(d.not_null()); + out.append(" ").append(d.not_null()); } if (is_constraint_set(col.attributes().options(), utils::constraints::Unique)) { - result.append(" ").append(d.unique()); + out.append(" ").append(d.unique()); } if (is_constraint_set(col.attributes().options(), utils::constraints::PrimaryKey)) { - result.append(" ").append(d.primary_key()); + out.append(" ").append(d.primary_key()); + } +} +void build_columns(std::string &out, const std::vector &cols, const sql::dialect &d) { + bool first = true; + for (const auto& col : cols) { + if (!first) { + out.append(", "); + } + prepare_identifier_string_append(out, col.name(), d); + first = false; } - - return result; } std::string build_constraint(const table_constraint& cons, const sql::dialect& d) { diff --git a/source/orm/query/query_utils.cpp b/source/orm/query/query_utils.cpp index 6544d05..de89994 100644 --- a/source/orm/query/query_utils.cpp +++ b/source/orm/query/query_utils.cpp @@ -1,31 +1,23 @@ #include "matador/query/query_utils.hpp" #include "matador/query/table.hpp" +#include "matador/query/internal/string_builder_utils.hpp" namespace matador::query { std::string prepare_identifier(const sql::dialect& d, const table_column& col) { std::string result; if (!col.is_function()) { - if (col.table()) { - result = d.prepare_identifier_string(col.table()->name()) + "."; - } - result += d.prepare_identifier_string(col.name()); + prepare_identifier_string_append(result, col.name(), d); } else { result = d.sql_function_at(col.function()) + "(" + col.name() + ")"; } - if (!col.alias().empty()) { - result += " AS " + col.alias(); - } return result; } std::string prepare_criteria(const sql::dialect& d, const table_column& col) { std::string result; if (!col.is_function()) { - if (col.table()) { - result = d.prepare_identifier_string(col.table()->name()) + "."; - } - result += d.prepare_identifier_string(col.name()); + prepare_identifier_string_append(result, col.name(), d); } else { result = d.sql_function_at(col.function()) + "(" + col.name() + ")"; } diff --git a/source/orm/query/table.cpp b/source/orm/query/table.cpp index e6e82eb..271d578 100644 --- a/source/orm/query/table.cpp +++ b/source/orm/query/table.cpp @@ -15,7 +15,7 @@ table::table(const std::string& name, const std::vector &columns) : table(name, name, columns) { } -table::table(std::string name, std::string alias, const std::vector &columns) +table::table(std::string name, std::string alias, const std::vector &columns) : name_(std::move(name)) , alias_(std::move(alias)) , columns_(columns) { @@ -91,7 +91,7 @@ const table_column* table::operator[](const std::string &column_name) const { const table_column * table::column_by_name(const table &tab, const std::string &column_name) { for (const auto &col : tab.columns_) { - if (col.name() == column_name) { + if (col.column_name() == column_name) { return &col; } } diff --git a/source/orm/query/table_column.cpp b/source/orm/query/table_column.cpp index adc0111..c11f885 100644 --- a/source/orm/query/table_column.cpp +++ b/source/orm/query/table_column.cpp @@ -25,42 +25,39 @@ table_column::table_column(const char *name) : table_column(std::string(name)) {} -table_column::table_column(std::string name) -: name_(std::move(name)) {} -table_column::table_column(std::string name, std::string alias) -: name_(std::move(name)) -, alias_(std::move(alias)) {} +table_column::table_column(const std::string& name) +: table_column(name, name) {} -table_column::table_column(const sql::sql_function_t func, std::string name) -: name_(std::move(name)) -, function_(func) {} +table_column::table_column(const std::string& name, const std::string& alias) +: table_column(nullptr, name, alias, utils::basic_type::Unknown, {}, sql::sql_function_t::None) +{} -table_column::table_column(const class table* tab, std::string name) -: table_(tab) -, name_(std::move(name)) {} +table_column::table_column(const sql::sql_function_t func, const std::string& name) +: table_column(nullptr, name, name, utils::basic_type::Unknown, {}, func) +{} -table_column::table_column(const class table* tab, std::string name, std::string alias) -: table_(tab) -, name_(std::move(name)) -, alias_(std::move(alias)) {} -table_column::table_column(const class table* tab, - std::string name, - const utils::basic_type type, - const utils::field_attributes& attributes) -: table_(tab) -, name_(std::move(name)) -, type_(type) -, attributes_(attributes) {} +table_column::table_column(const class table* tab, const std::string& name) +: table_column(tab, name, name, utils::basic_type::Unknown, {}, sql::sql_function_t::None) +{} + +table_column::table_column(const class table* tab, const std::string& name, const std::string& alias) +: table_column(tab, name, alias, utils::basic_type::Unknown, {}, sql::sql_function_t::None) +{} + +table_column::table_column(const class table* tab, const std::string& name, const utils::basic_type type, const utils::field_attributes& attributes) +: table_column(tab, name, name, type, attributes, sql::sql_function_t::None) +{} table_column::table_column(const class table* tab, - std::string name, - std::string alias, - utils::basic_type type, - const utils::field_attributes &attributes, - const sql::sql_function_t func) + const std::string& name, + const std::string& alias, + const utils::basic_type type, + const utils::field_attributes &attributes, + const sql::sql_function_t func) : table_(tab) -, name_(std::move(name)) -, alias_(std::move(alias)) +, name_(build_column_name(table_, name)) +, column_name_(name) +, alias_(alias) , type_(type) , attributes_(attributes) , function_(func) {} @@ -71,6 +68,7 @@ table_column & table_column::operator=(const table_column &other) { } table_ = other.table_; name_ = other.name_; + column_name_ = other.column_name_; alias_ = other.alias_; type_ = other.type_; attributes_ = other.attributes_; @@ -82,6 +80,7 @@ bool table_column::equals(const table_column &x) const { if (table_ != nullptr && x.table_ != nullptr) { return *table_ == *x.table_ && name_ == x.name_ && + column_name_ == x.column_name_ && alias_ == x.alias_ && function_ == x.function_; } @@ -92,15 +91,19 @@ bool table_column::equals(const table_column &x) const { } table_column table_column::as(const std::string& alias) const { - return {table_, name_, alias, type_, attributes_, function_}; + return {table_, column_name_, alias, type_, attributes_, function_}; } const std::string& table_column::name() const { - return name_; + return has_alias() ? alias_ : name_; } -std::string table_column::canonical_name() const { - return table_ ? table_->name() + "." + name_ : name_; +const std::string& table_column::column_name() const { + return column_name_; +} + +const std::string& table_column::canonical_name() const { + return name_; } const std::string& table_column::alias() const { @@ -128,7 +131,7 @@ sql::sql_function_t table_column::function() const { } bool table_column::has_alias() const { - return !alias_.empty(); + return alias_ != column_name_; } const class table* table_column::table() const { @@ -137,9 +140,14 @@ const class table* table_column::table() const { void table_column::table(const query::table* tab) { table_ = tab; + name_ = build_column_name(table_, column_name_); } table_column::operator const std::string&() const { - return name_; + return name(); } + +std::string table_column::build_column_name(const class query::table* tab, const std::string& name) { + return tab ? tab->name() + "." + name : name; } +} // namespace matador::query diff --git a/source/orm/sql/dialect.cpp b/source/orm/sql/dialect.cpp index 318b4c2..0a70b5d 100644 --- a/source/orm/sql/dialect.cpp +++ b/source/orm/sql/dialect.cpp @@ -18,16 +18,6 @@ const std::string &dialect::sql_function_at(const sql_function_t func) const { return sql_func_map_.at(func); } -std::string dialect::table_name(const std::string &table, const std::string &schema_name) const { - if (schema_name.empty() && default_schema_name_.empty()) { - return prepare_identifier_string(table); - } - if (schema_name.empty()) { - return prepare_identifier_string(default_schema_name_) + "." + prepare_identifier_string(table); - } - return prepare_identifier_string(schema_name) + "." + prepare_identifier_string(table); -} - const std::string &dialect::to_string(const bool val) const { return bool_strings_[static_cast(val)]; } @@ -89,7 +79,7 @@ dialect::escape_identifier_t dialect::identifier_escape_type() const { return identifier_escape_type_; } -void dialect::identifier_escape_type(escape_identifier_t escape_identifier) { +void dialect::identifier_escape_type(const escape_identifier_t escape_identifier) { identifier_escape_type_ = escape_identifier; } diff --git a/test/models/model_metas.hpp b/test/models/model_metas.hpp index bffec72..11b373d 100644 --- a/test/models/model_metas.hpp +++ b/test/models/model_metas.hpp @@ -15,5 +15,7 @@ META_TABLE(departments, DEPARTMENT, id, name) META_TABLE(employees, EMPLOYEE, id, first_name, last_name, dep_id) META_TABLE(authors, AUTHOR, id, first_name, last_name, date_of_birth, year_of_birth, distinguished) META_TABLE(books, BOOK, id, title, author_id, published_in) +META_TABLE(orders, ORDER, order_id, order_date, required_date, shipped_date, ship_via, freight, ship_name, ship_address, ship_city, ship_region, ship_postal_code, ship_country) +META_TABLE(courses, COURSE, id, title) #endif //MATADOR_MODEL_METAS_HPP \ No newline at end of file diff --git a/test/orm/orm/SessionQueryBuilderTest.cpp b/test/orm/orm/SessionQueryBuilderTest.cpp index 09b1ff0..d584f14 100644 --- a/test/orm/orm/SessionQueryBuilderTest.cpp +++ b/test/orm/orm/SessionQueryBuilderTest.cpp @@ -24,12 +24,14 @@ #include "../../models/recipe.hpp" #include "../../models/order.hpp" #include "../../models/student.hpp" +#include "../../models/model_metas.hpp" using namespace matador::object; using namespace matador::query; using namespace matador::utils; using namespace matador::sql; using namespace matador::test; + using namespace matador::query::meta; TEST_CASE("Create sql query data for entity with eager has one", "[query][entity][builder]") { using namespace matador::test; @@ -46,7 +48,7 @@ TEST_CASE("Create sql query data for entity with eager has one", "[query][entity const auto it = scm.find(typeid(flight)); REQUIRE(it != scm.end()); - const auto* col = it->second.table()["id"]; + const auto* col = it->second.table()[FLIGHT.id]; REQUIRE(col); auto data = eqb.build(*col == _); @@ -100,7 +102,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent const auto it = scm.find(typeid(book)); REQUIRE(it != scm.end()); - const auto* col = it->second.table()["id"]; + const auto* col = it->second.table()[BOOK.id]; REQUIRE(col); auto data = eqb.build(*col == _); @@ -172,7 +174,7 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q const auto it = scm.find(typeid(order)); REQUIRE(it != scm.end()); - const auto* col = it->second.table()["order_id"]; + const auto* col = it->second.table()[ORDER.order_id]; REQUIRE(col); auto data = eqb.build(*col == _); @@ -236,7 +238,7 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e const auto it = scm.find(typeid(ingredient)); REQUIRE(it != scm.end()); - const auto* col = it->second.table()["id"]; + const auto* col = it->second.table()[INGREDIENT.id]; REQUIRE(col); auto data = eqb.build(*col == _); @@ -290,7 +292,7 @@ TEST_CASE("Create sql query data for entity with eager many to many (inverse par const auto it = scm.find(typeid(course)); REQUIRE(it != scm.end()); - const auto* col = it->second.table()["id"]; + const auto* col = it->second.table()[COURSE.id]; REQUIRE(col); auto data = eqb.build(*col == _); diff --git a/test/orm/query/ColumnGeneratorTest.cpp b/test/orm/query/ColumnGeneratorTest.cpp index 193d781..f22ab48 100644 --- a/test/orm/query/ColumnGeneratorTest.cpp +++ b/test/orm/query/ColumnGeneratorTest.cpp @@ -47,7 +47,7 @@ TEST_CASE("Generate columns from object", "[column][generator]") { REQUIRE(columns.size() == expected_columns.size()); for (size_t i = 0; i != expected_columns.size(); ++i) { - REQUIRE(expected_columns[i] == columns[i].name()); + REQUIRE(expected_columns[i] == columns[i].column_name()); } } diff --git a/test/orm/query/CriteriaTests.cpp b/test/orm/query/CriteriaTests.cpp index 2a51651..9308286 100644 --- a/test/orm/query/CriteriaTests.cpp +++ b/test/orm/query/CriteriaTests.cpp @@ -2,9 +2,9 @@ #include "matador/query/criteria.hpp" #include "matador/query/criteria_evaluator.hpp" +#include "matador/query/query.hpp" #include "matador/sql/dialect_builder.hpp" -#include "matador/sql/query_context.hpp" #include "matador/utils/placeholder.hpp" @@ -79,7 +79,9 @@ TEST_CASE_METHOD(CriteriaFixture, "Test in query criteria", "[criteria][in query query_context sub_ctx; sub_ctx.sql = R"(SELECT "name" FROM "test")"; - auto clause = age_col != 7 && in(name_col, std::move(sub_ctx)); + auto q = query::select({name_col}).from("test"); + + auto clause = age_col != 7 && in(name_col, std::move(q)); } TEST_CASE_METHOD(CriteriaFixture, "Test out criteria", "[criteria][out]") { const auto age_col = "age"_col; @@ -88,12 +90,12 @@ TEST_CASE_METHOD(CriteriaFixture, "Test out criteria", "[criteria][out]") { criteria_evaluator evaluator(dlc, ctx); auto str = evaluator.evaluate(*clause); - REQUIRE(str == "(\"age\" <> 7 AND \"age\" NOT IN (7, 5, 5, 8))"); + REQUIRE(str == R"(("age" <> 7 AND "age" NOT IN (7, 5, 5, 8)))"); clause = age_col != 7 && out(age_col, {_, _, _}); str = evaluator.evaluate(*clause); - REQUIRE(str == "(\"age\" <> 7 AND \"age\" NOT IN (?, ?, ?))"); + REQUIRE(str == R"(("age" <> 7 AND "age" NOT IN (?, ?, ?)))"); } TEST_CASE_METHOD(CriteriaFixture, "Test between criteria", "[criteria][between]") { @@ -103,12 +105,12 @@ TEST_CASE_METHOD(CriteriaFixture, "Test between criteria", "[criteria][between]" criteria_evaluator evaluator(dlc, ctx); auto str = evaluator.evaluate(*clause); - REQUIRE(str == "(\"age\" <> 7 OR \"age\" BETWEEN 21 AND 30)"); + REQUIRE(str == R"(("age" <> 7 OR "age" BETWEEN 21 AND 30))"); clause = age_col != 7 || between(age_col, _, _); str = evaluator.evaluate(*clause); - REQUIRE(str == "(\"age\" <> 7 OR \"age\" BETWEEN ? AND ?)"); + REQUIRE(str == R"(("age" <> 7 OR "age" BETWEEN ? AND ?))"); } TEST_CASE_METHOD(CriteriaFixture, "Test like criteria", "[criteria][like]") { diff --git a/test/orm/query/SchemaTest.cpp b/test/orm/query/SchemaTest.cpp index 8816c1f..6fbca8d 100644 --- a/test/orm/query/SchemaTest.cpp +++ b/test/orm/query/SchemaTest.cpp @@ -7,7 +7,7 @@ using namespace matador::query; using namespace matador::test; -TEST_CASE("Test schema with belongs-to to has-many relation" "[schema][relation][belongs_to]") { +TEST_CASE("Test schema with belongs-to to has-many relation" "[schema][relation][belongsto]") { schema repo; auto result = repo.attach("packages") .and_then( [&repo] { return repo.attach("shipments"); } );