column, placeholder and column_value generator progress
This commit is contained in:
parent
1d84b112f1
commit
9e76203bc9
|
|
@ -6,28 +6,69 @@
|
||||||
#include <matador/utils/field_attributes.hpp>
|
#include <matador/utils/field_attributes.hpp>
|
||||||
#include <matador/utils/foreign_attributes.hpp>
|
#include <matador/utils/foreign_attributes.hpp>
|
||||||
|
|
||||||
|
#include "matador/object/repository.hpp"
|
||||||
|
|
||||||
#include "matador/query/fk_value_extractor.hpp"
|
#include "matador/query/fk_value_extractor.hpp"
|
||||||
#include "matador/query/internal/column_value_pair.hpp"
|
#include "matador/query/internal/column_value_pair.hpp"
|
||||||
|
|
||||||
|
#include "matador/sql/table.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace matador::query::generator {
|
namespace matador::query::generator {
|
||||||
class column_generator final {
|
enum class column_generator_options {
|
||||||
|
None = 0,
|
||||||
|
GenerateAlias = 1 << 0,
|
||||||
|
ForceLazy = 1 << 1
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename EnumType>
|
||||||
|
class enum_flags {
|
||||||
public:
|
public:
|
||||||
|
explicit enum_flags(EnumType value) : value_(value) {}
|
||||||
|
private:
|
||||||
|
EnumType value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline column_generator_options operator|(column_generator_options a, column_generator_options b) { return static_cast<column_generator_options>(static_cast<unsigned int>(a) | static_cast<unsigned int>(b)); }
|
||||||
|
inline column_generator_options operator&(column_generator_options a, column_generator_options b) { return static_cast<column_generator_options>(static_cast<unsigned int>(a) & static_cast<unsigned int>(b)); }
|
||||||
|
inline column_generator_options& operator|= (column_generator_options& a, column_generator_options b) { return reinterpret_cast<column_generator_options&>(reinterpret_cast<int&>(a) |= static_cast<int>(b)); }
|
||||||
|
inline column_generator_options& operator&= (column_generator_options& a, column_generator_options b) { return reinterpret_cast<column_generator_options&>(reinterpret_cast<int&>(a) &= static_cast<int>(b)); }
|
||||||
|
|
||||||
|
inline bool is_column_generator_option_set(const column_generator_options source, const column_generator_options needle) { return static_cast<int>(source & needle) > 0; }
|
||||||
|
|
||||||
|
constexpr auto default_column_generator_options = column_generator_options::ForceLazy;
|
||||||
|
|
||||||
|
class column_generator2 {
|
||||||
|
public:
|
||||||
|
explicit column_generator2(const std::string &table_name = "",
|
||||||
|
column_generator_options options = default_column_generator_options);
|
||||||
|
explicit column_generator2(const object::repository &repo,
|
||||||
|
const std::string &table_name = "",
|
||||||
|
column_generator_options options = default_column_generator_options);
|
||||||
|
|
||||||
|
template< class Type >
|
||||||
|
std::vector<sql::column> generate() {
|
||||||
|
Type obj;
|
||||||
|
return generate(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
template< class Type >
|
||||||
|
std::vector<sql::column> generate(const Type &obj) {
|
||||||
|
result_.clear();
|
||||||
|
access::process(*this, obj);
|
||||||
|
|
||||||
|
return result_;
|
||||||
|
}
|
||||||
|
|
||||||
template < class V >
|
template < class V >
|
||||||
void on_primary_key(const char *id, V &, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
|
void on_primary_key(const char *id, V &, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
|
||||||
if (has_many_to_many_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
push(id);
|
push(id);
|
||||||
}
|
}
|
||||||
void on_revision(const char *id, uint64_t &/*rev*/);
|
void on_revision(const char *id, uint64_t &/*rev*/);
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes) {
|
void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes) {
|
||||||
if (has_many_to_many_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
push(id);
|
push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,32 +83,29 @@ public:
|
||||||
|
|
||||||
template<class ContainerType>
|
template<class ContainerType>
|
||||||
void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {
|
void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {
|
||||||
if (has_many_to_many_) {
|
if (attr.fetch() == utils::fetch_type::LAZY || is_column_generator_option_set(options_, column_generator_options::ForceLazy)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (attr.fetch() == utils::fetch_type::LAZY || force_lazy_) {
|
if (!repo_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto info = table_schema_.info<typename ContainerType::value_type::value_type>();
|
const auto info = repo_->get().info<typename ContainerType::value_type::value_type>();
|
||||||
if (!info) {
|
if (!info) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (seen_tables.count(info->get().name()) == 0) {
|
if (seen_tables.count(info->get().name()) == 0) {
|
||||||
auto it = seen_tables.insert(info->get().name()).first;
|
auto it = seen_tables.insert(info->get().name()).first;
|
||||||
table_name_stack_.push(info.value().get().name());
|
table_stack_.push(std::make_shared<sql::table>(info.value().get().name()));
|
||||||
typename ContainerType::value_type::value_type obj;
|
typename ContainerType::value_type::value_type obj;
|
||||||
access::process(*this, obj);
|
access::process(*this, obj);
|
||||||
table_name_stack_.pop();
|
table_stack_.pop();
|
||||||
seen_tables.erase(it);
|
seen_tables.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ContainerType>
|
template<class ContainerType>
|
||||||
void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &/*attr*/) {
|
void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &/*attr*/) {
|
||||||
if (!has_many_to_many_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
push(join_column);
|
push(join_column);
|
||||||
push(inverse_join_column);
|
push(inverse_join_column);
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +113,41 @@ public:
|
||||||
template<class ContainerType>
|
template<class ContainerType>
|
||||||
static void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const utils::foreign_attributes &/*attr*/) {}
|
static void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const utils::foreign_attributes &/*attr*/) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<class Pointer>
|
||||||
|
void on_foreign_key(const char *id, Pointer &, const utils::foreign_attributes &attr) {
|
||||||
|
if (attr.fetch() == utils::fetch_type::LAZY || is_column_generator_option_set(options_, column_generator_options::ForceLazy)) {
|
||||||
|
push(id);
|
||||||
|
} else {
|
||||||
|
if (!repo_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto info = repo_->get().info<typename Pointer::value_type>();
|
||||||
|
if (!info) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (seen_tables.count(info->get().name()) == 0) {
|
||||||
|
auto it = seen_tables.insert(info->get().name()).first;
|
||||||
|
table_stack_.push(std::make_shared<sql::table>(info.value().get().name()));
|
||||||
|
typename Pointer::value_type obj;
|
||||||
|
access::process(*this, obj);
|
||||||
|
table_stack_.pop();
|
||||||
|
seen_tables.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void push(const std::string &column_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<std::reference_wrapper<const object::repository>> repo_;
|
||||||
|
std::vector<sql::column> result_;
|
||||||
|
std::stack<std::shared_ptr<sql::table>> table_stack_;
|
||||||
|
std::unordered_set<std::string> seen_tables;
|
||||||
|
int column_index{0};
|
||||||
|
column_generator_options options_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
class placeholder_generator final {
|
class placeholder_generator final {
|
||||||
public:
|
public:
|
||||||
template< class Type >
|
template< class Type >
|
||||||
|
|
@ -174,17 +246,43 @@ std::vector<utils::placeholder> placeholders(const Type &obj) {
|
||||||
return generator.generate(obj);
|
return generator.generate(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type>
|
|
||||||
std::vector<internal::column_value_pair> column_value_pairs() {
|
|
||||||
column_value_generator generator;
|
|
||||||
return generator.generate<Type>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
std::vector<internal::column_value_pair> column_value_pairs(const Type &obj) {
|
std::vector<internal::column_value_pair> column_value_pairs(const Type &obj) {
|
||||||
column_value_generator generator;
|
column_value_generator generator;
|
||||||
return generator.generate(obj);
|
return generator.generate(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
std::vector<sql::column> columns(const object::repository &repo,
|
||||||
|
const std::string &table_name = "",
|
||||||
|
const column_generator_options options = default_column_generator_options) {
|
||||||
|
column_generator2 generator(repo, table_name, options);
|
||||||
|
return generator.generate<Type>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
std::vector<sql::column> columns(const Type &obj,
|
||||||
|
const object::repository &repo,
|
||||||
|
const std::string &table_name = "",
|
||||||
|
const column_generator_options options = default_column_generator_options) {
|
||||||
|
column_generator2 generator(repo, table_name, options);
|
||||||
|
return generator.generate(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
std::vector<sql::column> columns(const std::string &table_name = "",
|
||||||
|
const column_generator_options options = default_column_generator_options) {
|
||||||
|
column_generator2 generator(table_name, options);
|
||||||
|
return generator.generate<Type>();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type>
|
||||||
|
std::vector<sql::column> columns(const Type &obj,
|
||||||
|
const std::string &table_name = "",
|
||||||
|
const column_generator_options options = default_column_generator_options) {
|
||||||
|
column_generator2 generator(table_name, options);
|
||||||
|
return generator.generate(obj);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif //MATADOR_GENERATOR_HPP
|
#endif //MATADOR_GENERATOR_HPP
|
||||||
|
|
@ -15,11 +15,14 @@ public:
|
||||||
column_value_pair(const char *name, utils::database_type value);
|
column_value_pair(const char *name, utils::database_type value);
|
||||||
column_value_pair(const char *name, utils::placeholder p);
|
column_value_pair(const char *name, utils::placeholder p);
|
||||||
|
|
||||||
[[nodiscard]] const std::string& name() const;
|
friend bool operator==(const column_value_pair &lhs, const column_value_pair &rhs);
|
||||||
|
friend bool operator!=(const column_value_pair &lhs, const column_value_pair &rhs);
|
||||||
|
|
||||||
|
[[nodiscard]] const sql::column& col() const;
|
||||||
[[nodiscard]] const std::variant<utils::placeholder, utils::database_type>& value() const;
|
[[nodiscard]] const std::variant<utils::placeholder, utils::database_type>& value() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
sql::column column_;
|
||||||
std::variant<utils::placeholder, utils::database_type> value_;
|
std::variant<utils::placeholder, utils::database_type> value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -320,7 +320,7 @@ class query_set_part final : public query_part
|
||||||
public:
|
public:
|
||||||
explicit query_set_part(const std::vector<internal::column_value_pair>& key_value_pairs);
|
explicit query_set_part(const std::vector<internal::column_value_pair>& key_value_pairs);
|
||||||
|
|
||||||
[[nodiscard]] const std::vector<internal::column_value_pair>& key_values() const;
|
[[nodiscard]] const std::vector<internal::column_value_pair>& column_values() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void accept(query_part_visitor &visitor) override;
|
void accept(query_part_visitor &visitor) override;
|
||||||
|
|
|
||||||
|
|
@ -40,19 +40,6 @@ public:
|
||||||
|
|
||||||
static std::vector<column> generate(const object::repository &scm, const std::string &name, bool force_lazy = false);
|
static std::vector<column> generate(const object::repository &scm, const std::string &name, bool force_lazy = false);
|
||||||
|
|
||||||
template < class Type >
|
|
||||||
static std::vector<column> generate_has_many_to_many(const object::repository &scm, const bool force_lazy = false) {
|
|
||||||
const auto info = scm.info<Type>();
|
|
||||||
if (!info) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
std::vector<column> columns;
|
|
||||||
column_generator gen(columns, scm, info.value().get().name(), force_lazy);
|
|
||||||
Type obj;
|
|
||||||
access::process(gen, obj);
|
|
||||||
return columns;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < class V >
|
template < class V >
|
||||||
void on_primary_key(const char *id, V &, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
|
void on_primary_key(const char *id, V &, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
|
||||||
push(id);
|
push(id);
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ void session_query_builder::append_join(const sql::column &left, const sql::colu
|
||||||
using namespace matador::query;
|
using namespace matador::query;
|
||||||
entity_query_data_.joins.push_back({
|
entity_query_data_.joins.push_back({
|
||||||
{right.table_},
|
{right.table_},
|
||||||
left == right
|
std::make_unique<binary_column_criteria>(left, binary_operator::EQUALS, right)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,31 @@
|
||||||
#include "matador/query/generator.hpp"
|
#include "matador/query/generator.hpp"
|
||||||
|
|
||||||
namespace matador::query::generator {
|
namespace matador::query::generator {
|
||||||
|
column_generator2::column_generator2( const std::string& table_name, const column_generator_options options)
|
||||||
|
: options_(options) {
|
||||||
|
table_stack_.push(table_name.empty() ? std::make_shared<sql::table>() : std::make_shared<sql::table>(table_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
column_generator2::column_generator2(const object::repository& repo, const std::string& table_name, const column_generator_options options)
|
||||||
|
: repo_(std::cref(repo))
|
||||||
|
, options_(options) {
|
||||||
|
table_stack_.push(table_name.empty() ? std::make_shared<sql::table>() : std::make_shared<sql::table>(table_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
void column_generator2::on_revision( const char* id, uint64_t& ) {
|
||||||
|
push(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void column_generator2::push( const std::string& column_name ) {
|
||||||
|
if (is_column_generator_option_set(options_, column_generator_options::GenerateAlias)) {
|
||||||
|
char str[4];
|
||||||
|
snprintf(str, 4, "c%02d", ++column_index);
|
||||||
|
result_.emplace_back(table_stack_.top(), column_name, str);
|
||||||
|
} else {
|
||||||
|
result_.emplace_back(table_stack_.top(), column_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void placeholder_generator::on_revision(const char* /*id*/, uint64_t&) {
|
void placeholder_generator::on_revision(const char* /*id*/, uint64_t&) {
|
||||||
result_.emplace_back(utils::_);
|
result_.emplace_back(utils::_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,29 +5,37 @@
|
||||||
namespace matador::query::internal {
|
namespace matador::query::internal {
|
||||||
|
|
||||||
column_value_pair::column_value_pair(std::string name, utils::database_type value)
|
column_value_pair::column_value_pair(std::string name, utils::database_type value)
|
||||||
: name_(std::move(name))
|
: column_(std::move(name))
|
||||||
, value_(std::move(value)) {
|
, value_(std::move(value)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
column_value_pair::column_value_pair(const sql::column &col, utils::database_type value)
|
column_value_pair::column_value_pair(const sql::column &col, utils::database_type value)
|
||||||
: name_(col.name)
|
: column_(col)
|
||||||
, value_(std::move(value)) {
|
, value_(std::move(value)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
column_value_pair::column_value_pair(const char *name, utils::database_type value)
|
column_value_pair::column_value_pair(const char *name, utils::database_type value)
|
||||||
: name_(name)
|
: column_(name)
|
||||||
, value_(std::move(value)) {
|
, value_(std::move(value)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
column_value_pair::column_value_pair( const char* name, utils::placeholder p )
|
column_value_pair::column_value_pair( const char* name, utils::placeholder p )
|
||||||
: name_(name)
|
: column_(name)
|
||||||
, value_(p) {}
|
, value_(p) {}
|
||||||
|
|
||||||
const std::string &column_value_pair::name() const {
|
const sql::column &column_value_pair::col() const {
|
||||||
return name_;
|
return column_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::variant<utils::placeholder, utils::database_type>& column_value_pair::value() const {
|
const std::variant<utils::placeholder, utils::database_type>& column_value_pair::value() const {
|
||||||
return value_;
|
return value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==( const column_value_pair& lhs, const column_value_pair& rhs ) {
|
||||||
|
return lhs.column_.equals(rhs.column_) && lhs.value_ == rhs.value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=( const column_value_pair& lhs, const column_value_pair& rhs ) {
|
||||||
|
return !( lhs == rhs );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -304,7 +304,7 @@ query_set_part::query_set_part(const std::vector<column_value_pair>& key_value_p
|
||||||
: query_part(sql::dialect_token::Set)
|
: query_part(sql::dialect_token::Set)
|
||||||
, key_value_pairs_(key_value_pairs) {}
|
, key_value_pairs_(key_value_pairs) {}
|
||||||
|
|
||||||
const std::vector<column_value_pair> &query_set_part::key_values() const
|
const std::vector<column_value_pair> &query_set_part::column_values() const
|
||||||
{
|
{
|
||||||
return key_value_pairs_;
|
return key_value_pairs_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -363,18 +363,18 @@ void query_compiler::visit(internal::query_set_part &part) {
|
||||||
attribute_string_writer writer(*dialect_, connection_);
|
attribute_string_writer writer(*dialect_, connection_);
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
||||||
value_visitor visitor(writer, query_); if (part.key_values().size() < 2) {
|
value_visitor visitor(writer, query_); if (part.column_values().size() < 2) {
|
||||||
for (const auto &col: part.key_values()) {
|
for (const auto &column_value: part.column_values()) {
|
||||||
result.append(dialect_->prepare_identifier_string(col.name()) + "=");
|
result.append(dialect_->prepare_identifier_string(column_value.col().name) + "=");
|
||||||
result.append(determine_value(visitor, col.value()));
|
result.append(determine_value(visitor, column_value.value()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto it = part.key_values().begin();
|
auto it = part.column_values().begin();
|
||||||
result.append(dialect_->prepare_identifier_string(it->name()) + "=");
|
result.append(dialect_->prepare_identifier_string(it->col().name) + "=");
|
||||||
result.append(determine_value(visitor, (it++)->value()));
|
result.append(determine_value(visitor, (it++)->value()));
|
||||||
for (; it != part.key_values().end(); ++it) {
|
for (; it != part.column_values().end(); ++it) {
|
||||||
result.append(", ");
|
result.append(", ");
|
||||||
result.append(dialect_->prepare_identifier_string(it->name()) + "=");
|
result.append(dialect_->prepare_identifier_string(it->col().name) + "=");
|
||||||
result.append(determine_value(visitor, it->value()));
|
result.append(determine_value(visitor, it->value()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ 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
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(OrmTests matador-orm matador-core Catch2::Catch2WithMain)
|
target_link_libraries(OrmTests matador-orm matador-core Catch2::Catch2WithMain)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "matador/query/generator.hpp"
|
||||||
|
|
||||||
|
#include "matador/sql/column.hpp"
|
||||||
|
|
||||||
|
#include "../../models/airplane.hpp"
|
||||||
|
#include "../../models/flight.hpp"
|
||||||
|
|
||||||
|
using namespace matador::utils;
|
||||||
|
using namespace matador::query;
|
||||||
|
using namespace matador::sql;
|
||||||
|
using namespace matador::test;
|
||||||
|
|
||||||
|
TEST_CASE("Test placeholder generator", "[generator][placeholder]") {
|
||||||
|
REQUIRE(generator::placeholders<airplane>() == std::vector{_, _, _});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test column value generator", "[generator][column_value]") {
|
||||||
|
SECTION("Test column value generator for simple table") {
|
||||||
|
const airplane a380{1, "Airbus", "A380"};
|
||||||
|
const auto pairs = generator::column_value_pairs(a380);
|
||||||
|
const std::vector<internal::column_value_pair> expected_result{
|
||||||
|
{ "id", 1U },
|
||||||
|
{ "brand", std::string{"Airbus"} },
|
||||||
|
{ "model", std::string{"A380"} }
|
||||||
|
};
|
||||||
|
REQUIRE(pairs.size() == 3);
|
||||||
|
REQUIRE(pairs == expected_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Test column value generator for table with foreign key") {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test column generator", "[generator][column]") {
|
||||||
|
SECTION("Test column generator for simple table") {
|
||||||
|
const std::vector expected_columns {
|
||||||
|
column("id"),
|
||||||
|
column("brand"),
|
||||||
|
column("model"),
|
||||||
|
};
|
||||||
|
const auto result = generator::columns<airplane>();
|
||||||
|
REQUIRE(result.size() == expected_columns.size());
|
||||||
|
auto it = result.begin();
|
||||||
|
for (const auto& c : expected_columns) {
|
||||||
|
REQUIRE(c.equals( *it++));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue