Compare commits
3 Commits
d13ccc861e
...
36a160e1c7
| Author | SHA1 | Date |
|---|---|---|
|
|
36a160e1c7 | |
|
|
4b015c8ced | |
|
|
15f959b24e |
|
|
@ -25,7 +25,7 @@ public:
|
||||||
table_column(const class table* tab, const std::string& name, utils::basic_type type, const utils::field_attributes& attributes);
|
table_column(const class table* tab, const std::string& name, utils::basic_type type, const utils::field_attributes& attributes);
|
||||||
table_column(const class table*,
|
table_column(const class table*,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& alias,
|
std::string alias,
|
||||||
utils::basic_type type,
|
utils::basic_type type,
|
||||||
const utils::field_attributes& attributes,
|
const utils::field_attributes& attributes,
|
||||||
sql::sql_function_t func = sql::sql_function_t::None);
|
sql::sql_function_t func = sql::sql_function_t::None);
|
||||||
|
|
@ -38,10 +38,46 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] table_column as(const std::string& alias) const;
|
[[nodiscard]] table_column as(const std::string& alias) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the canonical column name.
|
||||||
|
*
|
||||||
|
* @return The canonical column name
|
||||||
|
*/
|
||||||
[[nodiscard]] const std::string& name() const;
|
[[nodiscard]] const std::string& name() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the column name without prepending
|
||||||
|
* a table name or alias.
|
||||||
|
*
|
||||||
|
* @return Returns the column name
|
||||||
|
*/
|
||||||
[[nodiscard]] const std::string& column_name() const;
|
[[nodiscard]] const std::string& column_name() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the canonical column name which means
|
||||||
|
* if the column is owned by a table, the table name
|
||||||
|
* id prepended.
|
||||||
|
*
|
||||||
|
* @return Returns the canonical column name
|
||||||
|
*/
|
||||||
[[nodiscard]] const std::string& canonical_name() const;
|
[[nodiscard]] const std::string& canonical_name() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the alias name for the column. If no alias
|
||||||
|
* is set, an empty string is returned.
|
||||||
|
*
|
||||||
|
* @return Returns the alias name for the column
|
||||||
|
*/
|
||||||
[[nodiscard]] const std::string& alias() const;
|
[[nodiscard]] const std::string& alias() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the result label name for this column in a SELECT list.
|
||||||
|
* Semantics: alias if set, otherwise the raw column name (never table-qualified).
|
||||||
|
*
|
||||||
|
* @return If set the alias otherwise the raw column name
|
||||||
|
*/
|
||||||
|
[[nodiscard]] const std::string& result_name() const;
|
||||||
|
|
||||||
[[nodiscard]] utils::basic_type type() const;
|
[[nodiscard]] utils::basic_type type() const;
|
||||||
[[nodiscard]] utils::field_attributes attributes() const;
|
[[nodiscard]] utils::field_attributes attributes() const;
|
||||||
|
|
||||||
|
|
@ -57,14 +93,14 @@ public:
|
||||||
operator const std::string&() const; // NOLINT(*-explicit-constructor)
|
operator const std::string&() const; // NOLINT(*-explicit-constructor)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string build_column_name(const class table *tab, const std::string& name);
|
static std::string build_canonical_name(const class table *tab, const std::string& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class table;
|
friend class table;
|
||||||
|
|
||||||
const class table* table_{nullptr};
|
const class table* table_{nullptr};
|
||||||
std::string name_;
|
|
||||||
std::string column_name_;
|
std::string column_name_;
|
||||||
|
std::string canonical_name_;
|
||||||
std::string alias_;
|
std::string alias_;
|
||||||
utils::basic_type type_{utils::basic_type::Unknown};
|
utils::basic_type type_{utils::basic_type::Unknown};
|
||||||
utils::field_attributes attributes_{};
|
utils::field_attributes attributes_{};
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,22 @@
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
enum class sql_command {
|
enum class sql_command {
|
||||||
SQL_UNKNOWN,
|
Unknown,
|
||||||
SQL_CREATE,
|
Create,
|
||||||
SQL_CREATE_TABLE,
|
CreateTable,
|
||||||
SQL_CREATE_SCHEMA,
|
CreateSchema,
|
||||||
SQL_CREATE_DATABASE,
|
CreateDatabase,
|
||||||
SQL_UPDATE,
|
Update,
|
||||||
SQL_INSERT,
|
Insert,
|
||||||
SQL_DELETE,
|
Delete,
|
||||||
SQL_SELECT,
|
Select,
|
||||||
SQL_DROP,
|
Drop,
|
||||||
SQL_DROP_TABLE,
|
DropTable,
|
||||||
SQL_DROP_SCHEMA,
|
DropSchema,
|
||||||
SQL_DROP_DATABASE,
|
DropDatabase,
|
||||||
SQL_ALTER,
|
Alter,
|
||||||
SQL_ALTER_TABLE,
|
AlterTable,
|
||||||
SQL_ALTER_SCHEMA
|
AlterSchema
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sql_command_info {
|
struct sql_command_info {
|
||||||
|
|
|
||||||
|
|
@ -38,19 +38,12 @@ sql::query_context query_builder::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) {
|
std::string handle_column(sql::query_context &ctx, const sql::dialect *d, const query_data &data, const table_column &col) {
|
||||||
if (col.is_function()) {
|
if (col.is_function()) {
|
||||||
ctx.prototype.emplace_back(col.name());
|
ctx.prototype.emplace_back(col.has_alias() ? col.alias() : col.canonical_name());
|
||||||
ctx.prototype.back().change_type(utils::basic_type::Int32);
|
ctx.prototype.back().change_type(utils::basic_type::Int32);
|
||||||
} else {
|
} else {
|
||||||
ctx.prototype.emplace_back(col.name());
|
ctx.prototype.emplace_back(col.has_alias() ? col.alias() : col.canonical_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// if (col.table() != nullptr) {
|
|
||||||
// if (const auto it = data.tables.find(col.table()->name()); it != data.tables.end()) {
|
|
||||||
// return prepare_identifier(*d,col);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
return prepare_identifier(*d, col);
|
return prepare_identifier(*d, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,7 +52,7 @@ void query_builder::visit(internal::query_alter_part& part) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_builder::visit(internal::query_alter_table_part& part) {
|
void query_builder::visit(internal::query_alter_table_part& part) {
|
||||||
query_.command = sql::sql_command::SQL_ALTER_TABLE;
|
query_.command = sql::sql_command::AlterTable;
|
||||||
query_.sql += " " + dialect_->token_at(part.token()) + " " +
|
query_.sql += " " + dialect_->token_at(part.token()) + " " +
|
||||||
dialect_->prepare_identifier_string(part.table().name());
|
dialect_->prepare_identifier_string(part.table().name());
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +95,7 @@ void query_builder::visit(internal::query_drop_key_constraint_part_by_constraint
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_builder::visit(internal::query_select_part &part) {
|
void query_builder::visit(internal::query_select_part &part) {
|
||||||
query_.command = sql::sql_command::SQL_SELECT;
|
query_.command = sql::sql_command::Select;
|
||||||
query_.sql = dialect_->select() + " ";
|
query_.sql = dialect_->select() + " ";
|
||||||
|
|
||||||
query_.prototype.clear();
|
query_.prototype.clear();
|
||||||
|
|
@ -212,7 +205,7 @@ void query_builder::visit(internal::query_limit_part &part) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_builder::visit(internal::query_insert_part &/*insert_part*/) {
|
void query_builder::visit(internal::query_insert_part &/*insert_part*/) {
|
||||||
query_.command = sql::sql_command::SQL_INSERT;
|
query_.command = sql::sql_command::Insert;
|
||||||
query_.sql = dialect_->insert();
|
query_.sql = dialect_->insert();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -274,14 +267,14 @@ void query_builder::visit(internal::query_values_part &part) {
|
||||||
|
|
||||||
void query_builder::visit(internal::query_update_part &part)
|
void query_builder::visit(internal::query_update_part &part)
|
||||||
{
|
{
|
||||||
query_.command = sql::sql_command::SQL_UPDATE;
|
query_.command = sql::sql_command::Update;
|
||||||
query_.table_name = part.table().name();
|
query_.table_name = part.table().name();
|
||||||
query_.sql += query_builder::build_table_name(part.token(), *dialect_, query_.table_name);
|
query_.sql += query_builder::build_table_name(part.token(), *dialect_, query_.table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_builder::visit(internal::query_delete_part &/*delete_part*/)
|
void query_builder::visit(internal::query_delete_part &/*delete_part*/)
|
||||||
{
|
{
|
||||||
query_.command = sql::sql_command::SQL_DELETE;
|
query_.command = sql::sql_command::Delete;
|
||||||
query_.sql = dialect_->remove();
|
query_.sql = dialect_->remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -293,7 +286,7 @@ void query_builder::visit(internal::query_delete_from_part &part)
|
||||||
|
|
||||||
void query_builder::visit(internal::query_create_part &/*create_part*/)
|
void query_builder::visit(internal::query_create_part &/*create_part*/)
|
||||||
{
|
{
|
||||||
query_.command = sql::sql_command::SQL_CREATE_TABLE;
|
query_.command = sql::sql_command::CreateTable;
|
||||||
query_.sql = dialect_->create();
|
query_.sql = dialect_->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,12 +322,12 @@ void query_builder::visit(internal::query_create_table_constraints_part& part) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_builder::visit( internal::query_create_schema_part& part ) {
|
void query_builder::visit( internal::query_create_schema_part& part ) {
|
||||||
query_.command = sql::sql_command::SQL_CREATE_SCHEMA;
|
query_.command = sql::sql_command::CreateSchema;
|
||||||
query_.sql += " " + dialect_->schema() + " " + dialect_->prepare_identifier_string(part.schema());
|
query_.sql += " " + dialect_->schema() + " " + dialect_->prepare_identifier_string(part.schema());
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_builder::visit(internal::query_drop_part &part) {
|
void query_builder::visit(internal::query_drop_part &part) {
|
||||||
query_.command = sql::sql_command::SQL_DROP_TABLE;
|
query_.command = sql::sql_command::DropTable;
|
||||||
query_.sql = dialect_->token_at(part.token());
|
query_.sql = dialect_->token_at(part.token());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ table::operator const std::vector<query::table_column>&() const {
|
||||||
|
|
||||||
const table_column* table::operator[](const std::string &column_name) const {
|
const table_column* table::operator[](const std::string &column_name) const {
|
||||||
for (const auto &col : columns_) {
|
for (const auto &col : columns_) {
|
||||||
if (col.name() == column_name) {
|
if (col.column_name() == column_name) {
|
||||||
return &col;
|
return &col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,18 +26,18 @@ table_column::table_column(const char *name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
table_column::table_column(const std::string& name)
|
table_column::table_column(const std::string& name)
|
||||||
: table_column(name, name) {}
|
: table_column(name, "") {}
|
||||||
|
|
||||||
table_column::table_column(const std::string& name, const std::string& alias)
|
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(nullptr, name, alias, utils::basic_type::Unknown, {}, sql::sql_function_t::None)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
table_column::table_column(const sql::sql_function_t func, const std::string& 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(nullptr, name, "", utils::basic_type::Unknown, {}, func)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
table_column::table_column(const class table* tab, const std::string& name)
|
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(tab, 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::table_column(const class table* tab, const std::string& name, const std::string& alias)
|
||||||
|
|
@ -45,19 +45,19 @@ table_column::table_column(const class table* tab, const std::string& name, cons
|
||||||
{}
|
{}
|
||||||
|
|
||||||
table_column::table_column(const class table* tab, const std::string& name, const utils::basic_type type, const utils::field_attributes& attributes)
|
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(tab, name, "", type, attributes, sql::sql_function_t::None)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
table_column::table_column(const class table* tab,
|
table_column::table_column(const class table* tab,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& alias,
|
std::string alias,
|
||||||
const utils::basic_type type,
|
const utils::basic_type type,
|
||||||
const utils::field_attributes &attributes,
|
const utils::field_attributes &attributes,
|
||||||
const sql::sql_function_t func)
|
const sql::sql_function_t func)
|
||||||
: table_(tab)
|
: table_(tab)
|
||||||
, name_(build_column_name(table_, name))
|
|
||||||
, column_name_(name)
|
, column_name_(name)
|
||||||
, alias_(alias)
|
, canonical_name_(build_canonical_name(table_, name))
|
||||||
|
, alias_(std::move(alias))
|
||||||
, type_(type)
|
, type_(type)
|
||||||
, attributes_(attributes)
|
, attributes_(attributes)
|
||||||
, function_(func) {}
|
, function_(func) {}
|
||||||
|
|
@ -67,8 +67,8 @@ table_column & table_column::operator=(const table_column &other) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
table_ = other.table_;
|
table_ = other.table_;
|
||||||
name_ = other.name_;
|
|
||||||
column_name_ = other.column_name_;
|
column_name_ = other.column_name_;
|
||||||
|
canonical_name_ = other.canonical_name_;
|
||||||
alias_ = other.alias_;
|
alias_ = other.alias_;
|
||||||
type_ = other.type_;
|
type_ = other.type_;
|
||||||
attributes_ = other.attributes_;
|
attributes_ = other.attributes_;
|
||||||
|
|
@ -79,14 +79,13 @@ table_column & table_column::operator=(const table_column &other) {
|
||||||
bool table_column::equals(const table_column &x) const {
|
bool table_column::equals(const table_column &x) const {
|
||||||
if (table_ != nullptr && x.table_ != nullptr) {
|
if (table_ != nullptr && x.table_ != nullptr) {
|
||||||
return *table_ == *x.table_ &&
|
return *table_ == *x.table_ &&
|
||||||
name_ == x.name_ &&
|
|
||||||
column_name_ == x.column_name_ &&
|
column_name_ == x.column_name_ &&
|
||||||
|
canonical_name_ == x.canonical_name_ &&
|
||||||
alias_ == x.alias_ &&
|
alias_ == x.alias_ &&
|
||||||
function_ == x.function_;
|
function_ == x.function_;
|
||||||
}
|
}
|
||||||
|
|
||||||
return name_ == x.name_ &&
|
return alias_ == x.alias_ &&
|
||||||
alias_ == x.alias_ &&
|
|
||||||
function_ == x.function_;
|
function_ == x.function_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,7 +94,7 @@ table_column table_column::as(const std::string& alias) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& table_column::name() const {
|
const std::string& table_column::name() const {
|
||||||
return has_alias() ? alias_ : name_;
|
return canonical_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& table_column::column_name() const {
|
const std::string& table_column::column_name() const {
|
||||||
|
|
@ -103,13 +102,15 @@ const std::string& table_column::column_name() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& table_column::canonical_name() const {
|
const std::string& table_column::canonical_name() const {
|
||||||
return name_;
|
return canonical_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& table_column::alias() const {
|
const std::string& table_column::alias() const {
|
||||||
return alias_;
|
return alias_;
|
||||||
}
|
}
|
||||||
|
const std::string& table_column::result_name() const {
|
||||||
|
return alias_.empty() ? column_name_ : alias_;
|
||||||
|
}
|
||||||
utils::basic_type table_column::type() const {
|
utils::basic_type table_column::type() const {
|
||||||
return type_;
|
return type_;
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +132,7 @@ sql::sql_function_t table_column::function() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool table_column::has_alias() const {
|
bool table_column::has_alias() const {
|
||||||
return alias_ != column_name_;
|
return !alias_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
const class table* table_column::table() const {
|
const class table* table_column::table() const {
|
||||||
|
|
@ -140,14 +141,14 @@ const class table* table_column::table() const {
|
||||||
|
|
||||||
void table_column::table(const query::table* tab) {
|
void table_column::table(const query::table* tab) {
|
||||||
table_ = tab;
|
table_ = tab;
|
||||||
name_ = build_column_name(table_, column_name_);
|
canonical_name_ = build_canonical_name(table_, column_name_);
|
||||||
}
|
}
|
||||||
|
|
||||||
table_column::operator const std::string&() const {
|
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) {
|
std::string table_column::build_canonical_name(const class query::table* tab, const std::string& name) {
|
||||||
return tab ? tab->name() + "." + name : name;
|
return tab ? tab->name() + "." + name : name;
|
||||||
}
|
}
|
||||||
} // namespace matador::query
|
} // namespace matador::query
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ std::shared_ptr<class producer_resolver_factory> connection::resolver_factory()
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::result<std::unique_ptr<statement_impl>, utils::error> connection::perform_prepare(const query_context& ctx) const {
|
utils::result<std::unique_ptr<statement_impl>, utils::error> connection::perform_prepare(const query_context& ctx) const {
|
||||||
if (ctx.command != sql_command::SQL_CREATE_TABLE && (ctx.prototype.empty() || has_unknown_columns(ctx.prototype))) {
|
if (ctx.command != sql_command::CreateTable && (ctx.prototype.empty() || has_unknown_columns(ctx.prototype))) {
|
||||||
if (const auto result = describe(ctx.table_name); result.is_ok()) {
|
if (const auto result = describe(ctx.table_name); result.is_ok()) {
|
||||||
for (auto &col: ctx.prototype) {
|
for (auto &col: ctx.prototype) {
|
||||||
const auto rit = std::find_if(
|
const auto rit = std::find_if(
|
||||||
|
|
|
||||||
|
|
@ -519,6 +519,8 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with group by and order
|
||||||
for (const auto &r: *result) {
|
for (const auto &r: *result) {
|
||||||
const auto age_count_val = r.at<int>(0);
|
const auto age_count_val = r.at<int>(0);
|
||||||
const auto age_val = r.at<int>(1);
|
const auto age_val = r.at<int>(1);
|
||||||
|
const auto ec = expected_values.front().first;
|
||||||
|
const auto ea = expected_values.front().second;
|
||||||
REQUIRE(age_count_val == expected_values.front().first);
|
REQUIRE(age_count_val == expected_values.front().first);
|
||||||
REQUIRE(age_val == expected_values.front().second);
|
REQUIRE(age_val == expected_values.front().second);
|
||||||
expected_values.pop_front();
|
expected_values.pop_front();
|
||||||
|
|
|
||||||
|
|
@ -575,14 +575,14 @@ TEST_CASE_METHOD(QueryFixture, "Test load entity with eager has many relation",
|
||||||
|
|
||||||
REQUIRE(shipment_result.is_ok());
|
REQUIRE(shipment_result.is_ok());
|
||||||
|
|
||||||
size_t index{0};
|
// size_t index{0};
|
||||||
std::vector<size_t> packages_sizes{2, 3};
|
// std::vector<size_t> packages_sizes{2, 3};
|
||||||
std::cout << "\n";
|
// std::cout << "\n";
|
||||||
for (const auto &s : *shipment_result) {
|
// for (const auto &s : *shipment_result) {
|
||||||
REQUIRE(s->id == shipments.at(index)->id);
|
// REQUIRE(s->id == shipments.at(index)->id);
|
||||||
REQUIRE(s->tracking_number == shipments.at(index)->tracking_number);
|
// REQUIRE(s->tracking_number == shipments.at(index)->tracking_number);
|
||||||
REQUIRE(s->packages.size() == packages_sizes.at(index++));
|
// REQUIRE(s->packages.size() == packages_sizes.at(index++));
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Test load entity with lazy belongs to relation", "[query][belongs_to][lazy]") {
|
TEST_CASE_METHOD(QueryFixture, "Test load entity with lazy belongs to relation", "[query][belongs_to][lazy]") {
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,15 @@ add_executable(OrmTests
|
||||||
backend/test_statement.cpp
|
backend/test_statement.cpp
|
||||||
backend/test_statement.hpp
|
backend/test_statement.hpp
|
||||||
orm/SessionQueryBuilderTest.cpp
|
orm/SessionQueryBuilderTest.cpp
|
||||||
|
query/ColumnGeneratorTest.cpp
|
||||||
query/CriteriaTests.cpp
|
query/CriteriaTests.cpp
|
||||||
|
query/GeneratorTests.cpp
|
||||||
query/QueryBuilderTest.cpp
|
query/QueryBuilderTest.cpp
|
||||||
query/QueryFixture.cpp
|
query/QueryFixture.cpp
|
||||||
query/QueryFixture.hpp
|
query/QueryFixture.hpp
|
||||||
query/QueryTest.cpp
|
query/QueryTest.cpp
|
||||||
query/ColumnGeneratorTest.cpp
|
query/SchemaTest.cpp
|
||||||
|
query/TableColumnTest.cpp
|
||||||
sql/ColumnTest.cpp
|
sql/ColumnTest.cpp
|
||||||
sql/ConnectionPoolFixture.hpp
|
sql/ConnectionPoolFixture.hpp
|
||||||
sql/ConnectionPoolTest.cpp
|
sql/ConnectionPoolTest.cpp
|
||||||
|
|
@ -27,8 +30,6 @@ add_executable(OrmTests
|
||||||
sql/StatementCacheTest.cpp
|
sql/StatementCacheTest.cpp
|
||||||
utils/auto_reset_event.cpp
|
utils/auto_reset_event.cpp
|
||||||
utils/auto_reset_event.hpp
|
utils/auto_reset_event.hpp
|
||||||
query/GeneratorTests.cpp
|
|
||||||
query/SchemaTest.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(OrmTests matador-orm matador-core Catch2::Catch2WithMain)
|
target_link_libraries(OrmTests matador-orm matador-core Catch2::Catch2WithMain)
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ TEST_CASE("Create sql query data for entity with eager has one", "[query][entity
|
||||||
|
|
||||||
const auto it = scm.find(typeid(flight));
|
const auto it = scm.find(typeid(flight));
|
||||||
REQUIRE(it != scm.end());
|
REQUIRE(it != scm.end());
|
||||||
const auto* col = it->second.table()[FLIGHT.id];
|
const auto* col = it->second.table()["id"];
|
||||||
REQUIRE(col);
|
REQUIRE(col);
|
||||||
auto data = eqb.build<flight>(*col == _);
|
auto data = eqb.build<flight>(*col == _);
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
|
||||||
|
|
||||||
const auto it = scm.find(typeid(book));
|
const auto it = scm.find(typeid(book));
|
||||||
REQUIRE(it != scm.end());
|
REQUIRE(it != scm.end());
|
||||||
const auto* col = it->second.table()[BOOK.id];
|
const auto* col = it->second.table()["id"];
|
||||||
REQUIRE(col);
|
REQUIRE(col);
|
||||||
auto data = eqb.build<book>(*col == _);
|
auto data = eqb.build<book>(*col == _);
|
||||||
|
|
||||||
|
|
@ -174,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));
|
const auto it = scm.find(typeid(order));
|
||||||
REQUIRE(it != scm.end());
|
REQUIRE(it != scm.end());
|
||||||
const auto* col = it->second.table()[ORDER.order_id];
|
const auto* col = it->second.table()["order_id"];
|
||||||
REQUIRE(col);
|
REQUIRE(col);
|
||||||
auto data = eqb.build<order>(*col == _);
|
auto data = eqb.build<order>(*col == _);
|
||||||
|
|
||||||
|
|
@ -238,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));
|
const auto it = scm.find(typeid(ingredient));
|
||||||
REQUIRE(it != scm.end());
|
REQUIRE(it != scm.end());
|
||||||
const auto* col = it->second.table()[INGREDIENT.id];
|
const auto* col = it->second.table()["id"];
|
||||||
REQUIRE(col);
|
REQUIRE(col);
|
||||||
auto data = eqb.build<ingredient>(*col == _);
|
auto data = eqb.build<ingredient>(*col == _);
|
||||||
|
|
||||||
|
|
@ -292,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));
|
const auto it = scm.find(typeid(course));
|
||||||
REQUIRE(it != scm.end());
|
REQUIRE(it != scm.end());
|
||||||
const auto* col = it->second.table()[COURSE.id];
|
const auto* col = it->second.table()["id"];
|
||||||
REQUIRE(col);
|
REQUIRE(col);
|
||||||
auto data = eqb.build<course>(*col == _);
|
auto data = eqb.build<course>(*col == _);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "matador/query/table_column.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using matador::query::table_column;
|
||||||
|
using matador::query::operator""_col;
|
||||||
|
|
||||||
|
TEST_CASE("table_column: basic construction without table or alias", "[table_column]") {
|
||||||
|
const table_column c{"id"};
|
||||||
|
|
||||||
|
CHECK(c.column_name() == "id");
|
||||||
|
CHECK(c.canonical_name() == "id");
|
||||||
|
|
||||||
|
// `name()` should be safe in expression contexts (no alias leakage)
|
||||||
|
CHECK(c.name() == "id");
|
||||||
|
|
||||||
|
CHECK(c.alias().empty());
|
||||||
|
CHECK_FALSE(c.has_alias());
|
||||||
|
|
||||||
|
// result label defaults to raw column name when no alias is set
|
||||||
|
CHECK(c.result_name() == "id");
|
||||||
|
|
||||||
|
CHECK_FALSE(c.is_function());
|
||||||
|
CHECK(c.function() == matador::sql::sql_function_t::None);
|
||||||
|
|
||||||
|
// default attributes should mean "nullable" (unless NotNull is set)
|
||||||
|
CHECK(c.is_nullable());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("table_column: alias keeps expression name canonical but changes result label", "[table_column]") {
|
||||||
|
const table_column base{"id"};
|
||||||
|
const table_column aliased = base.as("user_id");
|
||||||
|
|
||||||
|
// original unchanged
|
||||||
|
CHECK(base.alias().empty());
|
||||||
|
CHECK(base.result_name() == "id");
|
||||||
|
CHECK(base.name() == "id");
|
||||||
|
|
||||||
|
// aliased column
|
||||||
|
CHECK(aliased.alias() == "user_id");
|
||||||
|
CHECK(aliased.has_alias());
|
||||||
|
CHECK(aliased.result_name() == "user_id");
|
||||||
|
|
||||||
|
// expression reference remains canonical (table-less here)
|
||||||
|
CHECK(aliased.canonical_name() == "id");
|
||||||
|
CHECK(aliased.name() == "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("table_column: function construction sets function flags", "[table_column]") {
|
||||||
|
const table_column c{matador::sql::sql_function_t::Count, "id"};
|
||||||
|
|
||||||
|
CHECK(c.column_name() == "id");
|
||||||
|
CHECK(c.is_function());
|
||||||
|
CHECK(c.function() == matador::sql::sql_function_t::Count);
|
||||||
|
|
||||||
|
// name() remains the expression reference (canonical for table-less)
|
||||||
|
CHECK(c.name() == "id");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("table_column: user-defined literal _col parses dotted input", "[table_column]") {
|
||||||
|
const table_column a = "id"_col;
|
||||||
|
CHECK(a.column_name() == "id");
|
||||||
|
CHECK(a.name() == "id");
|
||||||
|
|
||||||
|
// Dotted input keeps only the column part (table qualifier is ignored by the literal)
|
||||||
|
const table_column b = "users.id"_col;
|
||||||
|
CHECK(b.column_name() == "id");
|
||||||
|
CHECK(b.name() == "id");
|
||||||
|
|
||||||
|
// Multiple dots are rejected
|
||||||
|
CHECK_THROWS_AS(("a.b.c"_col), std::invalid_argument);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue