fixed PostgreSQL tests
This commit is contained in:
parent
7cb64515bd
commit
a79d50e6e8
|
|
@ -252,9 +252,10 @@ utils::result<std::vector<object::attribute>, utils::error> postgres_connection:
|
|||
}
|
||||
|
||||
utils::result<bool, utils::error> postgres_connection::exists(const std::string &schema_name, const std::string &table_name) {
|
||||
const std::string stmt(
|
||||
"SELECT 1 FROM information_schema.tables WHERE table_schema = '" + schema_name + "' AND table_name = '" + table_name
|
||||
+ "'");
|
||||
std::string stmt( "SELECT 1 FROM information_schema.tables WHERE table_name = '" + table_name + "'");
|
||||
if (!schema_name.empty()) {
|
||||
stmt += " AND table_schema = '" + schema_name + "'";
|
||||
}
|
||||
|
||||
PGresult *res = PQexec(conn_, stmt.c_str());
|
||||
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ template<typename ValueType>
|
|||
void object_generator::on_primary_key(const char *id, ValueType &x, const utils::primary_key_attribute& attr) {
|
||||
auto &ref = emplace_attribute<ValueType>(id, { attr.size(), utils::constraints::PrimaryKey }, null_option_type::NotNull);
|
||||
prepare_primary_key(ref, utils::identifier(x));
|
||||
create_pk_constraint(id);
|
||||
// create_pk_constraint(id);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
|
|
|
|||
|
|
@ -84,15 +84,7 @@ private:
|
|||
};
|
||||
class session final : public sql::executor {
|
||||
public:
|
||||
explicit session(session_context &&ctx);
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &table_name) const;
|
||||
template<typename Type, typename SuperType>
|
||||
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &table_name) const;
|
||||
|
||||
utils::result<void, utils::error> create_schema() const;
|
||||
utils::result<void, utils::error> drop_schema() const;
|
||||
session(session_context &&ctx, const query::schema &scm);
|
||||
|
||||
/**
|
||||
* Insert the given object into the session.
|
||||
|
|
@ -138,35 +130,24 @@ private:
|
|||
friend class query_select;
|
||||
|
||||
static query::fetchable_query build_select_query(entity_query_data &&data);
|
||||
static sql::query_context build_add_constraint_context(const std::string& table_name, const class object::restriction& cons, const sql::connection_ptr &conn) ;
|
||||
|
||||
private:
|
||||
mutable sql::statement_cache cache_;
|
||||
const sql::dialect &dialect_;
|
||||
|
||||
std::unique_ptr<query::schema> schema_;
|
||||
const query::schema& schema_;
|
||||
mutable std::unordered_map<std::string, std::vector<object::attribute>> prototypes_;
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] utils::result<void, utils::error> session::attach(const std::string &table_name) const {
|
||||
return schema_->attach<Type>(table_name);
|
||||
}
|
||||
|
||||
template<typename Type, typename SuperType>
|
||||
utils::result<void, utils::error> session::attach( const std::string& table_name ) const {
|
||||
return schema_->attach<Type, SuperType>(table_name);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
utils::result<object::object_ptr<Type>, utils::error> session::insert(Type *obj) {
|
||||
auto info = schema_->repo().info<Type>();
|
||||
auto info = schema_.repo().info<Type>();
|
||||
if (!info) {
|
||||
return utils::failure(info.err());
|
||||
}
|
||||
|
||||
auto res = query::query::insert()
|
||||
.into(info->get().name(), query::generator::columns<Type>(*schema_))
|
||||
.into(info->get().name(), query::generator::columns<Type>(schema_))
|
||||
.values(query::generator::placeholders<Type>())
|
||||
.prepare(*this);
|
||||
if (!res) {
|
||||
|
|
@ -233,7 +214,7 @@ private:
|
|||
|
||||
template<typename Type>
|
||||
utils::result<object::object_ptr<Type>, utils::error> session::update( const object::object_ptr<Type>& obj ) {
|
||||
auto info = schema_->repo().info<Type>();
|
||||
auto info = schema_.repo().info<Type>();
|
||||
if (!info) {
|
||||
return utils::failure(info.err());
|
||||
}
|
||||
|
|
@ -259,7 +240,7 @@ utils::result<object::object_ptr<Type>, utils::error> session::update( const obj
|
|||
|
||||
template<typename Type>
|
||||
utils::result<void, utils::error> session::remove( const object::object_ptr<Type>& obj ) {
|
||||
auto info = schema_->repo().info<Type>();
|
||||
auto info = schema_.repo().info<Type>();
|
||||
if (!info) {
|
||||
return utils::failure(info.err());
|
||||
}
|
||||
|
|
@ -284,8 +265,8 @@ utils::result<void, utils::error> session::remove( const object::object_ptr<Type
|
|||
|
||||
template<typename Type, typename PrimaryKeyType>
|
||||
utils::result<object::object_ptr<Type>, utils::error> session::find(const PrimaryKeyType& pk) {
|
||||
const auto it = schema_->find(typeid(Type));
|
||||
if (it == schema_->end()) {
|
||||
const auto it = schema_.find(typeid(Type));
|
||||
if (it == schema_.end()) {
|
||||
return utils::failure(make_error(error_code::UnknownType, "Failed to determine requested type."));
|
||||
}
|
||||
const auto& info = it->second.node().info();
|
||||
|
|
@ -296,7 +277,7 @@ utils::result<object::object_ptr<Type>, utils::error> session::find(const Primar
|
|||
return utils::failure(make_error(error_code::NoPrimaryKey, "Type hasn't primary key."));
|
||||
}
|
||||
|
||||
session_query_builder eqb(*schema_, *this);
|
||||
session_query_builder eqb(schema_, *this);
|
||||
const query::table_column c(&it->second.table(),info.primary_key_attribute()->name());
|
||||
using namespace matador::query;
|
||||
auto data = eqb.build<Type>(c == utils::_);
|
||||
|
|
@ -318,12 +299,12 @@ utils::result<object::object_ptr<Type>, utils::error> session::find(const Primar
|
|||
|
||||
template<typename Type>
|
||||
utils::result<sql::query_result<Type>, utils::error> session::find(query::criteria_ptr clause) {
|
||||
auto info = schema_->repo().info<Type>();
|
||||
auto info = schema_.repo().info<Type>();
|
||||
if (!info) {
|
||||
return utils::failure(make_error(error_code::UnknownType, "Failed to determine requested type."));
|
||||
}
|
||||
|
||||
session_query_builder eqb(*schema_, *this);
|
||||
session_query_builder eqb(schema_, *this);
|
||||
auto data = eqb.build<Type>(std::move(clause));
|
||||
if (!data.is_ok()) {
|
||||
return utils::failure(make_error(error_code::FailedToBuildQuery, "Failed to build query for type " + info->get().name() + "."));
|
||||
|
|
@ -339,7 +320,7 @@ utils::result<sql::query_result<Type>, utils::error> session::find(query::criter
|
|||
|
||||
template<typename Type>
|
||||
utils::result<void, utils::error> session::drop_table() {
|
||||
auto info = schema_->repo().info<Type>();
|
||||
auto info = schema_.repo().info<Type>();
|
||||
if (info) {
|
||||
return drop_table(info->get().name());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,13 @@
|
|||
#define META_TABLE(TABLE_NAME, VARIABLE_NAME, ...) \
|
||||
namespace matador::query::meta { \
|
||||
namespace internal { \
|
||||
class TABLE_NAME##_table : public table { \
|
||||
class TABLE_NAME##_table : public typed_table<TABLE_NAME##_table> { \
|
||||
public: \
|
||||
TABLE_NAME##_table()\
|
||||
: table(#TABLE_NAME, {MAP(FIELD_STRING, __VA_ARGS__)}) \
|
||||
: TABLE_NAME##_table("") \
|
||||
{} \
|
||||
TABLE_NAME##_table(const std::string& alias) \
|
||||
: typed_table(#TABLE_NAME, alias, {MAP(FIELD_STRING, __VA_ARGS__)}) \
|
||||
MAP(INIT_FIELD, __VA_ARGS__) \
|
||||
{} \
|
||||
MAP(FIELD, __VA_ARGS__) \
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ public:
|
|||
protected:
|
||||
static const table_column& create_column(class table& tab, const std::string& name);
|
||||
|
||||
private:
|
||||
table(std::string name, std::string alias, const std::vector<table_column>& columns);
|
||||
|
||||
private:
|
||||
|
|
@ -55,6 +54,13 @@ private:
|
|||
|
||||
table operator ""_tab(const char *name, size_t len);
|
||||
|
||||
template<typename Type>
|
||||
class typed_table : public table {
|
||||
public:
|
||||
using table::table;
|
||||
|
||||
Type as(std::string alias) const { return Type{std::move(alias)}; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif //QUERY_TABLE_HPP
|
||||
|
|
|
|||
|
|
@ -24,15 +24,18 @@ public:
|
|||
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);
|
||||
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& operator=(const table_column& other);
|
||||
table_column(const table_column& other);
|
||||
table_column(const table_column& other) = default;
|
||||
table_column(table_column&& other) noexcept = default;
|
||||
~table_column() = default;
|
||||
|
||||
[[nodiscard]] bool equals(const table_column &x) const;
|
||||
|
||||
table_column as(std::string a);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] std::string canonical_name() const;
|
||||
[[nodiscard]] const std::string& alias() const;
|
||||
[[nodiscard]] utils::basic_type type() const;
|
||||
[[nodiscard]] utils::field_attributes attributes() const;
|
||||
|
|
|
|||
|
|
@ -12,116 +12,10 @@ utils::error make_error(const error_code ec, const std::string &msg) {
|
|||
return utils::error(ec, msg);
|
||||
}
|
||||
|
||||
session::session(session_context&& ctx)
|
||||
session::session(session_context&& ctx, const query::schema &scm)
|
||||
: cache_(ctx.bus, ctx.pool, ctx.cache_size)
|
||||
, dialect_(sql::backend_provider::instance().connection_dialect(ctx.pool.info().type))
|
||||
, schema_(std::make_unique<query::schema>(dialect_.default_schema_name())) {
|
||||
}
|
||||
|
||||
utils::result<void, utils::error> session::create_schema() const {
|
||||
// Step 1: Build dependency graph
|
||||
// std::unordered_map<std::string, std::vector<std::string> > dependency_graph;
|
||||
// std::unordered_map<std::string, std::pair<int,object::repository::node_ptr>> in_degree;
|
||||
|
||||
// for (const auto &node: *schema_) {
|
||||
// for (auto it = node->info().endpoint_begin(); it != node->info().endpoint_end(); ++it) {
|
||||
// dependency_graph[node->name()].push_back(it->second->node().name());
|
||||
//
|
||||
// if (const auto dit = in_degree.find(it->second->node().name()); dit == in_degree.end()) {
|
||||
// in_degree[it->second->node().name()] = std::make_pair(1, it->second->node_ptr());
|
||||
// } else {
|
||||
// in_degree[it->second->node().name()].first++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Ensure the current node exists in the graph representation
|
||||
// if (in_degree.find(node->name()) == in_degree.end()) {
|
||||
// in_degree[node->name()] = std::make_pair(0, node);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (const auto &it : dependency_graph) {
|
||||
// std::cout << "Dependency graph " << it.first << std::endl;
|
||||
// for (const auto &neighbor: it.second) {
|
||||
// std::cout << " " << neighbor << std::endl;
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
// }
|
||||
|
||||
auto c = cache_.pool().acquire();
|
||||
for (const auto &node: schema_->repo()) {
|
||||
auto ctx = query::query::create()
|
||||
.table(node->name())
|
||||
.columns(node->info().attributes())
|
||||
.compile(*c);
|
||||
|
||||
std::cout << ctx.sql << std::endl;
|
||||
if (auto result = c->execute(ctx.sql); !result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
}
|
||||
|
||||
// create table constraints
|
||||
for (const auto &node: schema_->repo()) {
|
||||
for (const auto& cons : node->info().constraints()) {
|
||||
auto ctx = build_add_constraint_context(node->name(), cons, c);
|
||||
|
||||
std::cout << ctx.sql << std::endl;
|
||||
if (auto result = c->execute(ctx.sql); !result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return utils::ok<void>();
|
||||
}
|
||||
|
||||
sql::query_context session::build_add_constraint_context(const std::string& table_name, const class object::restriction& cons, const sql::connection_ptr &conn) {
|
||||
if (cons.is_foreign_key_constraint()) {
|
||||
return query::query::alter()
|
||||
.table(table_name)
|
||||
.add_constraint(cons)
|
||||
.compile(*conn);
|
||||
}
|
||||
if (cons.is_primary_key_constraint()) {
|
||||
return query::query::alter()
|
||||
.table(table_name)
|
||||
.add_constraint(cons)
|
||||
.compile(*conn);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
utils::result<void, utils::error> session::drop_schema() const {
|
||||
auto c = cache_.pool().acquire();
|
||||
// drop table constraints
|
||||
for (const auto &node: schema_->repo()) {
|
||||
for (const auto& cons : node->info().constraints()) {
|
||||
auto ctx = query::query::alter()
|
||||
.table(node->name())
|
||||
.drop_constraint(cons)
|
||||
.compile(*c);
|
||||
|
||||
std::cout << ctx.sql << std::endl;
|
||||
if (auto result = c->execute(ctx.sql); !result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// drop table
|
||||
for (const auto &node: schema_->repo()) {
|
||||
auto ctx = query::query::drop()
|
||||
.table(node->name())
|
||||
.compile(*c);
|
||||
|
||||
std::cout << ctx.sql << std::endl;
|
||||
if (auto result = c->execute(ctx.sql); !result) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
}
|
||||
|
||||
return utils::ok<void>();
|
||||
, schema_(scm) {
|
||||
}
|
||||
|
||||
utils::result<void, utils::error> session::drop_table(const std::string &table_name) const {
|
||||
|
|
@ -191,7 +85,7 @@ const class sql::dialect &session::dialect() const {
|
|||
}
|
||||
|
||||
void session::dump_schema(std::ostream &os) const {
|
||||
schema_->repo().dump(os);
|
||||
schema_.repo().dump(os);
|
||||
}
|
||||
|
||||
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> session::fetch(const sql::query_context& ctx) const {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ table_column alias(const std::string &column, const std::string &as) {
|
|||
|
||||
table_column alias(table_column &&col, const std::string &as) {
|
||||
col.as(as);
|
||||
return std::move(col);
|
||||
return col;
|
||||
}
|
||||
|
||||
table_column count(const std::string &column) {
|
||||
|
|
|
|||
|
|
@ -39,10 +39,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.name());
|
||||
ctx.prototype.emplace_back(col.has_alias() ? col.alias() : col.canonical_name());
|
||||
ctx.prototype.back().change_type(utils::basic_type::Int32);
|
||||
} else {
|
||||
ctx.prototype.emplace_back(col.name());
|
||||
ctx.prototype.emplace_back(col.canonical_name());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -128,7 +128,8 @@ void query_compiler::visit(internal::query_drop_key_constraint_part_by_name& par
|
|||
query_.sql += " " + dialect_->token_at(part.token()) + " " + part.name();
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_drop_key_constraint_part_by_constraint& /*part*/) {
|
||||
void query_compiler::visit(internal::query_drop_key_constraint_part_by_constraint& part) {
|
||||
query_.sql += " " + build_drop_constraint_string(part.constraint());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_select_part &part) {
|
||||
|
|
|
|||
|
|
@ -56,12 +56,14 @@ table_column::table_column(const class table* tab,
|
|||
std::string name,
|
||||
std::string alias,
|
||||
utils::basic_type type,
|
||||
const utils::field_attributes &attributes)
|
||||
const utils::field_attributes &attributes,
|
||||
const sql::sql_function_t func)
|
||||
: table_(tab)
|
||||
, name_(std::move(name))
|
||||
, alias_(std::move(alias))
|
||||
, type_(type)
|
||||
, attributes_(attributes) {}
|
||||
, attributes_(attributes)
|
||||
, function_(func) {}
|
||||
|
||||
table_column & table_column::operator=(const table_column &other) {
|
||||
if (this == &other) {
|
||||
|
|
@ -72,17 +74,10 @@ table_column & table_column::operator=(const table_column &other) {
|
|||
alias_ = other.alias_;
|
||||
type_ = other.type_;
|
||||
attributes_ = other.attributes_;
|
||||
function_ = other.function_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
table_column::table_column(const table_column &other)
|
||||
: table_(other.table_)
|
||||
, name_(other.name_)
|
||||
, alias_(other.alias_)
|
||||
, type_(other.type_)
|
||||
, attributes_(other.attributes_) {
|
||||
}
|
||||
|
||||
bool table_column::equals(const table_column &x) const {
|
||||
if (table_ != nullptr && x.table_ != nullptr) {
|
||||
return *table_ == *x.table_ &&
|
||||
|
|
@ -98,13 +93,17 @@ bool table_column::equals(const table_column &x) const {
|
|||
|
||||
table_column table_column::as(std::string a) {
|
||||
alias_ = std::move(a);
|
||||
return {table_, name_, alias_, type_, attributes_};
|
||||
return {table_, name_, alias_, type_, attributes_, function_};
|
||||
}
|
||||
|
||||
const std::string& table_column::name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
std::string table_column::canonical_name() const {
|
||||
return table_ ? table_->name() + "." + name_ : name_;
|
||||
}
|
||||
|
||||
const std::string& table_column::alias() const {
|
||||
return alias_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,8 +35,7 @@ field &field::operator=(field &&x) noexcept {
|
|||
return *this;
|
||||
}
|
||||
|
||||
const std::string &field::name() const
|
||||
{
|
||||
const std::string &field::name() const {
|
||||
return name_;
|
||||
}
|
||||
|
||||
|
|
@ -44,59 +43,48 @@ utils::constraints field::type() const {
|
|||
return type_;
|
||||
}
|
||||
|
||||
size_t field::size() const
|
||||
{
|
||||
size_t field::size() const {
|
||||
return value_.size();
|
||||
}
|
||||
|
||||
int field::index() const
|
||||
{
|
||||
int field::index() const {
|
||||
return index_;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const field &col)
|
||||
{
|
||||
std::ostream &operator<<(std::ostream &out, const field &col) {
|
||||
out << col.str();
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string field::str() const
|
||||
{
|
||||
std::string field::str() const {
|
||||
return as<std::string>().value_or("");
|
||||
}
|
||||
|
||||
bool field::is_integer() const
|
||||
{
|
||||
bool field::is_integer() const {
|
||||
return value_.is_integer();
|
||||
}
|
||||
|
||||
bool field::is_floating_point() const
|
||||
{
|
||||
bool field::is_floating_point() const {
|
||||
return value_.is_floating_point();
|
||||
}
|
||||
|
||||
bool field::is_bool() const
|
||||
{
|
||||
bool field::is_bool() const {
|
||||
return value_.is_bool();
|
||||
}
|
||||
|
||||
bool field::is_string() const
|
||||
{
|
||||
bool field::is_string() const {
|
||||
return value_.is_string();
|
||||
}
|
||||
|
||||
bool field::is_varchar() const
|
||||
{
|
||||
bool field::is_varchar() const {
|
||||
return value_.is_varchar();
|
||||
}
|
||||
|
||||
bool field::is_blob() const
|
||||
{
|
||||
bool field::is_blob() const {
|
||||
return value_.is_blob();
|
||||
}
|
||||
|
||||
bool field::is_null() const
|
||||
{
|
||||
bool field::is_null() const {
|
||||
return value_.is_null();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,16 +5,14 @@
|
|||
|
||||
namespace matador::sql {
|
||||
|
||||
record::record(std::initializer_list<field> columns)
|
||||
{
|
||||
record::record(const std::initializer_list<field> columns) {
|
||||
for (auto &&col :columns) {
|
||||
const auto it = fields_by_name_.emplace(col.name(), field_index_pair {col, fields_.size()});
|
||||
fields_.push_back(std::ref(it.first->second.first));
|
||||
}
|
||||
}
|
||||
|
||||
record::record(const std::vector<field> &columns)
|
||||
{
|
||||
record::record(const std::vector<field> &columns) {
|
||||
for (auto &&col :columns) {
|
||||
const auto it = fields_by_name_.emplace(col.name(), field_index_pair {col, fields_.size()});
|
||||
fields_.push_back(std::ref(it.first->second.first));
|
||||
|
|
@ -23,7 +21,6 @@ record::record(const std::vector<field> &columns)
|
|||
|
||||
record::record(const record &x)
|
||||
: fields_by_name_(x.fields_by_name_)
|
||||
//, pk_index_(x.pk_index_)
|
||||
{
|
||||
for (auto& col : x.fields_) {
|
||||
auto &it = fields_by_name_.at(col.get().name());
|
||||
|
|
@ -47,25 +44,10 @@ record &record::operator=(const record &x)
|
|||
return *this;
|
||||
}
|
||||
|
||||
const std::vector<record::field_ref> &record::columns() const
|
||||
{
|
||||
const std::vector<record::field_ref> &record::columns() const {
|
||||
return fields_;
|
||||
}
|
||||
|
||||
//bool record::has_primary_key() const
|
||||
//{
|
||||
// return pk_index_ > -1;
|
||||
//}
|
||||
//
|
||||
//std::optional<field> record::primary_key() const
|
||||
//{
|
||||
// if (!has_primary_key()) {
|
||||
// return std::nullopt;
|
||||
// }
|
||||
//
|
||||
// return columns_[pk_index_];
|
||||
//}
|
||||
|
||||
const field &record::at(const std::string &name) const {
|
||||
const auto &res = fields_by_name_.at(name);
|
||||
const auto &f = res.first;
|
||||
|
|
@ -88,8 +70,7 @@ record::const_iterator record::find(const std::string &column_name) const {
|
|||
return it != fields_by_name_.end() ? fields_.begin() + it->second.second : fields_.end();
|
||||
}
|
||||
|
||||
void record::append(const field &col)
|
||||
{
|
||||
void record::append(const field &col) {
|
||||
const auto it = fields_by_name_.emplace(col.name(), field_index_pair {col, fields_.size()});
|
||||
fields_.push_back(std::ref(it.first->second.first));
|
||||
}
|
||||
|
|
@ -140,13 +121,6 @@ void record::clear()
|
|||
fields_by_name_.clear();
|
||||
}
|
||||
|
||||
//bool record::unknown() const
|
||||
//{
|
||||
// return std::all_of(std::begin(columns_), std::end(columns_), [](const auto &col) {
|
||||
// return col.type() == data_type_t::type_unknown;
|
||||
// });
|
||||
//}
|
||||
|
||||
void record::init()
|
||||
{
|
||||
size_t index{0};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "matador/query/criteria.hpp"
|
||||
#include "matador/query/generator.hpp"
|
||||
#include "matador/query/query.hpp"
|
||||
#include "matador/query/meta_table_macro.hpp"
|
||||
|
||||
#include "QueryFixture.hpp"
|
||||
|
||||
|
|
@ -17,6 +18,12 @@ using namespace matador::query;
|
|||
using namespace matador::sql;
|
||||
using namespace matador::test;
|
||||
|
||||
META_TABLE(recipes, RECIPE, id, name);
|
||||
META_TABLE(ingredients, INGREDIENT, id, name);
|
||||
META_TABLE(recipe_ingredients, RECIPE_INGREDIENT, recipe_id, ingredient_id);
|
||||
META_TABLE(airplanes, AIRPLANE, id, brand, model);
|
||||
META_TABLE(flights, FLIGHT, id, airplane_id, pilot_name);
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, "Create table with foreign key relation", "[query][foreign][relation]") {
|
||||
auto result = repo.attach<airplane>("airplane")
|
||||
.and_then( [this] { return repo.attach<flight>("flight");} );
|
||||
|
|
@ -80,13 +87,13 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with where clause", "[q
|
|||
|
||||
for (const auto &i: *result_record) {
|
||||
REQUIRE(i.size() == 4);
|
||||
REQUIRE(i.at(0).name() == "id");
|
||||
REQUIRE(i.at(0).name() == "person.id");
|
||||
REQUIRE(i.at(0).is_integer());
|
||||
REQUIRE(i.at(0).as<uint32_t>() == george.id);
|
||||
REQUIRE(i.at(1).name() == "name");
|
||||
REQUIRE(i.at(1).name() == "person.name");
|
||||
REQUIRE(i.at(1).is_varchar());
|
||||
REQUIRE(i.at(1).as<std::string>() == george.name);
|
||||
REQUIRE(i.at(2).name() == "age");
|
||||
REQUIRE(i.at(2).name() == "person.age");
|
||||
REQUIRE(i.at(2).is_integer());
|
||||
REQUIRE(i.at(2).as<uint32_t>() == george.age);
|
||||
}
|
||||
|
|
@ -221,11 +228,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key", "[query][for
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left", "[query][foreign][join_left]") {
|
||||
auto result = repo.attach<airplane>("airplane")
|
||||
.and_then( [this] { return repo.attach<flight>("flight");} );
|
||||
auto result = repo.attach<airplane>("airplanes")
|
||||
.and_then( [this] { return repo.attach<flight>("flights");} );
|
||||
REQUIRE(result.is_ok());
|
||||
|
||||
auto obj = object_generator::generate<airplane>(repo.repo(), "airplane");
|
||||
auto obj = object_generator::generate<airplane>(repo.repo(), "airplanes");
|
||||
auto res = query::create()
|
||||
.table(obj->name())
|
||||
.columns(obj->attributes())
|
||||
|
|
@ -234,10 +241,10 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
|||
REQUIRE(res.is_ok());
|
||||
REQUIRE(*res == 0);
|
||||
|
||||
REQUIRE(db.exists("airplane"));
|
||||
tables_to_drop.emplace("airplane");
|
||||
REQUIRE(db.exists("airplanes"));
|
||||
tables_to_drop.emplace("airplanes");
|
||||
|
||||
obj = object_generator::generate<flight>(repo.repo(), "flight");
|
||||
obj = object_generator::generate<flight>(repo.repo(), "flights");
|
||||
res = query::create()
|
||||
.table(obj->name())
|
||||
.columns(obj->attributes())
|
||||
|
|
@ -246,8 +253,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
|||
REQUIRE(res.is_ok());
|
||||
REQUIRE(*res == 0);
|
||||
|
||||
REQUIRE(db.exists("flight"));
|
||||
tables_to_drop.emplace("flight");
|
||||
REQUIRE(db.exists("flights"));
|
||||
tables_to_drop.emplace("flights");
|
||||
|
||||
std::vector planes{
|
||||
object_ptr(new airplane{1, "Airbus", "A380"}),
|
||||
|
|
@ -257,7 +264,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
|||
|
||||
for (const auto &plane: planes) {
|
||||
res = query::insert()
|
||||
.into("airplane", generator::columns<airplane>(repo))
|
||||
.into("airplanes", generator::columns<airplane>(repo))
|
||||
.values(*plane)
|
||||
.execute(db);
|
||||
REQUIRE(res.is_ok());
|
||||
|
|
@ -265,7 +272,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
|||
}
|
||||
|
||||
auto count = query::select({count_all()})
|
||||
.from("airplane")
|
||||
.from("airplanes")
|
||||
.fetch_value<int>(db).value();
|
||||
REQUIRE(count == 3);
|
||||
|
||||
|
|
@ -278,27 +285,31 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
|||
|
||||
for (const auto &f: flights) {
|
||||
res = query::insert()
|
||||
.into("flight", {"id", "airplane_id", "pilot_name"})
|
||||
.into("flights", {"id", "airplane_id", "pilot_name"})
|
||||
.values(*f)
|
||||
.execute(db);
|
||||
REQUIRE(res.is_ok());
|
||||
REQUIRE(*res == 1);
|
||||
}
|
||||
|
||||
auto f = query::select(generator::columns<flight>(repo))
|
||||
.from("flight")
|
||||
auto flight_result = query::select(generator::columns<flight>(repo))
|
||||
.from("flights")
|
||||
.fetch_one(db);
|
||||
REQUIRE(f.is_ok());
|
||||
REQUIRE(f->has_value());
|
||||
REQUIRE(f.value()->at(0).as<uint32_t>() == 4);
|
||||
REQUIRE(f.value()->at(1).as<uint32_t>() == 1);
|
||||
REQUIRE(f.value()->at(2).as<std::string>() == "hans");
|
||||
REQUIRE(flight_result.is_ok());
|
||||
REQUIRE(flight_result->has_value());
|
||||
REQUIRE(flight_result.value()->at(0).as<uint32_t>() == 4);
|
||||
REQUIRE(flight_result.value()->at(1).as<uint32_t>() == 1);
|
||||
REQUIRE(flight_result.value()->at(2).as<std::string>() == "hans");
|
||||
|
||||
auto select_result = query::select({"f.id", "ap.brand", "ap.model", "f.pilot_name"})
|
||||
.from("flight"_tab.as("f"))
|
||||
.join_left("airplane"_tab.as("ap"))
|
||||
.on("f.airplane_id"_col == "ap.id"_col)
|
||||
.order_by("f.id").asc()
|
||||
using namespace matador::query::meta;
|
||||
const auto f = FLIGHT.as("f");
|
||||
const auto ap = AIRPLANE.as("ap");
|
||||
|
||||
auto select_result = query::select({f.id, ap.brand, ap.model, f.pilot_name})
|
||||
.from(f)
|
||||
.join_left(ap)
|
||||
.on(f.airplane_id == ap.id)
|
||||
.order_by(f.id).asc()
|
||||
.fetch_all(db);
|
||||
REQUIRE(select_result.is_ok());
|
||||
|
||||
|
|
@ -317,11 +328,11 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and join_left"
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single entity", "[query][join_left][find]") {
|
||||
auto result = repo.attach<airplane>("airplane")
|
||||
.and_then( [this] { return repo.attach<flight>("flight");} );
|
||||
auto result = repo.attach<airplane>("airplanes")
|
||||
.and_then( [this] { return repo.attach<flight>("flights");} );
|
||||
REQUIRE(result.is_ok());
|
||||
|
||||
auto obj = object_generator::generate<airplane>(repo.repo(), "airplane");
|
||||
auto obj = object_generator::generate<airplane>(repo.repo(), "airplanes");
|
||||
auto res = query::create()
|
||||
.table(obj->name())
|
||||
.columns(obj->attributes())
|
||||
|
|
@ -330,10 +341,10 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
|||
REQUIRE(res.is_ok());
|
||||
REQUIRE(*res == 0);
|
||||
|
||||
REQUIRE(db.exists("airplane"));
|
||||
tables_to_drop.emplace("airplane");
|
||||
REQUIRE(db.exists("airplanes"));
|
||||
tables_to_drop.emplace("airplanes");
|
||||
|
||||
obj = object_generator::generate<flight>(repo.repo(), "flight");
|
||||
obj = object_generator::generate<flight>(repo.repo(), "flights");
|
||||
res = query::create()
|
||||
.table(obj->name())
|
||||
.columns(obj->attributes())
|
||||
|
|
@ -342,8 +353,8 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
|||
REQUIRE(res.is_ok());
|
||||
REQUIRE(*res == 0);
|
||||
|
||||
REQUIRE(db.exists("flight"));
|
||||
tables_to_drop.emplace("flight");
|
||||
REQUIRE(db.exists("flights"));
|
||||
tables_to_drop.emplace("flights");
|
||||
|
||||
std::vector planes{
|
||||
object_ptr(new airplane{1, "Airbus", "A380"}),
|
||||
|
|
@ -353,7 +364,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
|||
|
||||
for (const auto &plane: planes) {
|
||||
res = query::insert()
|
||||
.into("airplane", generator::columns<airplane>(repo))
|
||||
.into("airplanes", generator::columns<airplane>(repo))
|
||||
.values(*plane)
|
||||
.execute(db);
|
||||
REQUIRE(res.is_ok());
|
||||
|
|
@ -361,7 +372,7 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
|||
}
|
||||
|
||||
auto count = query::select({count_all()})
|
||||
.from("airplane")
|
||||
.from("airplanes")
|
||||
.fetch_value<int>(db);
|
||||
REQUIRE(count.is_ok());
|
||||
REQUIRE(count->has_value());
|
||||
|
|
@ -376,27 +387,31 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with foreign key and for single
|
|||
|
||||
for (const auto &f: flights) {
|
||||
res = query::insert()
|
||||
.into("flight", generator::columns<flight>(repo))
|
||||
.into("flights", generator::columns<flight>(repo))
|
||||
.values(*f)
|
||||
.execute(db);
|
||||
REQUIRE(res.is_ok());
|
||||
REQUIRE(*res == 1);
|
||||
}
|
||||
|
||||
auto f = query::select(generator::columns<flight>(repo))
|
||||
.from("flight")
|
||||
auto flight_result = query::select(generator::columns<flight>(repo))
|
||||
.from("flights")
|
||||
.fetch_one(db);
|
||||
REQUIRE(f.is_ok());
|
||||
REQUIRE(f->has_value());
|
||||
REQUIRE(f.value()->at(0).as<uint32_t>() == 4);
|
||||
REQUIRE(f.value()->at(1).as<uint32_t>() == 1);
|
||||
REQUIRE(f.value()->at(2).as<std::string>() == "hans");
|
||||
REQUIRE(flight_result.is_ok());
|
||||
REQUIRE(flight_result->has_value());
|
||||
REQUIRE(flight_result.value()->at(0).as<uint32_t>() == 4);
|
||||
REQUIRE(flight_result.value()->at(1).as<uint32_t>() == 1);
|
||||
REQUIRE(flight_result.value()->at(2).as<std::string>() == "hans");
|
||||
|
||||
auto select_result = query::select({"f.id", "f.airplane_id", "ap.brand", "ap.model", "f.pilot_name"})
|
||||
.from("flight"_tab.as("f"))
|
||||
.join_left("airplane"_tab.as("ap"))
|
||||
.on("f.airplane_id"_col == "ap.id"_col)
|
||||
.where("f.id"_col == 4)
|
||||
using namespace matador::query::meta;
|
||||
const auto f = FLIGHT.as("f");
|
||||
const auto ap = AIRPLANE.as("ap");
|
||||
|
||||
auto select_result = query::select({f.id, f.airplane_id, ap.brand, ap.model, f.pilot_name})
|
||||
.from(f)
|
||||
.join_left(ap)
|
||||
.on(f.airplane_id == ap.id)
|
||||
.where(f.id == 4)
|
||||
.fetch_one<flight>(db);
|
||||
|
||||
auto expected_flight = flights[0];
|
||||
|
|
@ -506,10 +521,16 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
|||
REQUIRE(*res == 1);
|
||||
}
|
||||
|
||||
auto select_result = query::select({"r.id", "r.name", "ri.ingredient_id"})
|
||||
.from("recipes"_tab.as("r"))
|
||||
.join_left("recipe_ingredients"_tab.as("ri"))
|
||||
.on("r.id"_col == "ri.recipe_id"_col)
|
||||
using namespace matador::query::meta;
|
||||
|
||||
const auto r = RECIPE.as("r");
|
||||
const auto ri= RECIPE_INGREDIENT.as("ri");
|
||||
const auto i = INGREDIENT.as("i");
|
||||
|
||||
auto select_result = query::select({ r.id, r.name, ri.ingredient_id})
|
||||
.from(r)
|
||||
.join_left(ri)
|
||||
.on(r.id == ri.recipe_id)
|
||||
.fetch_all(db);
|
||||
REQUIRE(select_result.is_ok());
|
||||
|
||||
|
|
@ -524,20 +545,20 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
|||
{9, "Fruit Salad", 3}
|
||||
};
|
||||
size_t index{0};
|
||||
for (const auto &r: *select_result) {
|
||||
REQUIRE(r.size() == 3);
|
||||
REQUIRE(r.at(0).as<uint32_t>().value() == std::get<0>(expected_result_one_join[index]));
|
||||
REQUIRE(r.at(1).as<std::string>().value() == std::get<1>(expected_result_one_join[index]));
|
||||
REQUIRE(r.at(2).as<uint32_t>().value() == std::get<2>(expected_result_one_join[index]));
|
||||
for (const auto &row: *select_result) {
|
||||
REQUIRE(row.size() == 3);
|
||||
REQUIRE(row.at(0).as<uint32_t>().value() == std::get<0>(expected_result_one_join[index]));
|
||||
REQUIRE(row.at(1).as<std::string>().value() == std::get<1>(expected_result_one_join[index]));
|
||||
REQUIRE(row.at(2).as<uint32_t>().value() == std::get<2>(expected_result_one_join[index]));
|
||||
++index;
|
||||
}
|
||||
|
||||
select_result = query::select({"r.id", "r.name", "ri.ingredient_id", "i.name"})
|
||||
.from("recipes"_tab.as("r"))
|
||||
.join_left("recipe_ingredients"_tab.as("ri"))
|
||||
.on("r.id"_col == "ri.recipe_id"_col)
|
||||
.join_left("ingredients"_tab.as("i"))
|
||||
.on("ri.ingredient_id"_col == "i.id"_col)
|
||||
select_result = query::select({r.id, r.name, ri.ingredient_id, i.name})
|
||||
.from(r)
|
||||
.join_left(ri)
|
||||
.on(r.id == ri.recipe_id)
|
||||
.join_left(i)
|
||||
.on(ri.ingredient_id == i.id)
|
||||
.fetch_all(db);
|
||||
REQUIRE(result.is_ok());
|
||||
|
||||
|
|
@ -552,32 +573,32 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
|||
{9, "Fruit Salad", 3, "Pineapple"}
|
||||
};
|
||||
index = 0;
|
||||
for (const auto &r: *select_result) {
|
||||
REQUIRE(r.size() == 4);
|
||||
REQUIRE(r.at(0).as<uint32_t>().value() == std::get<0>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(1).as<std::string>().value() == std::get<1>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(2).as<uint32_t>().value() == std::get<2>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(3).as<std::string>().value() == std::get<3>(expected_result_two_joins[index]));
|
||||
for (const auto &row: *select_result) {
|
||||
REQUIRE(row.size() == 4);
|
||||
REQUIRE(row.at(0).as<uint32_t>().value() == std::get<0>(expected_result_two_joins[index]));
|
||||
REQUIRE(row.at(1).as<std::string>().value() == std::get<1>(expected_result_two_joins[index]));
|
||||
REQUIRE(row.at(2).as<uint32_t>().value() == std::get<2>(expected_result_two_joins[index]));
|
||||
REQUIRE(row.at(3).as<std::string>().value() == std::get<3>(expected_result_two_joins[index]));
|
||||
++index;
|
||||
}
|
||||
|
||||
select_result = query::select({"r.id", "r.name", "ri.ingredient_id", "i.name"})
|
||||
.from("recipes"_tab.as("r"))
|
||||
.join_left("recipe_ingredients"_tab.as("ri"))
|
||||
.on("r.id"_col == "ri.recipe_id"_col)
|
||||
.join_left("ingredients"_tab.as("i"))
|
||||
.on("ri.ingredient_id"_col == "i.id"_col)
|
||||
.where("r.id"_col == 8)
|
||||
select_result = query::select({r.id, r.name, ri.ingredient_id, i.name})
|
||||
.from(r)
|
||||
.join_left(ri)
|
||||
.on(r.id == ri.recipe_id)
|
||||
.join_left(i)
|
||||
.on(ri.ingredient_id == i.id)
|
||||
.where(r.id == 8)
|
||||
.fetch_all(db);
|
||||
REQUIRE(result.is_ok());
|
||||
|
||||
index = 3;
|
||||
for (const auto &r: *select_result) {
|
||||
REQUIRE(r.size() == 4);
|
||||
REQUIRE(r.at(0).as<uint32_t>().value() == std::get<0>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(1).as<std::string>().value() == std::get<1>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(2).as<uint32_t>().value() == std::get<2>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(3).as<std::string>().value() == std::get<3>(expected_result_two_joins[index]));
|
||||
for (const auto &row: *select_result) {
|
||||
REQUIRE(row.size() == 4);
|
||||
REQUIRE(row.at(0).as<uint32_t>().value() == std::get<0>(expected_result_two_joins[index]));
|
||||
REQUIRE(row.at(1).as<std::string>().value() == std::get<1>(expected_result_two_joins[index]));
|
||||
REQUIRE(row.at(2).as<uint32_t>().value() == std::get<2>(expected_result_two_joins[index]));
|
||||
REQUIRE(row.at(3).as<std::string>().value() == std::get<3>(expected_result_two_joins[index]));
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,18 @@
|
|||
#include "SessionFixture.hpp"
|
||||
|
||||
#include "connection.hpp"
|
||||
|
||||
#include "catch2/catch_test_macros.hpp"
|
||||
|
||||
namespace matador::test {
|
||||
|
||||
SessionFixture::SessionFixture()
|
||||
: pool(connection::dns, 4)
|
||||
, ses({bus, pool}) {}
|
||||
, ses({bus, pool}, schema) {}
|
||||
|
||||
SessionFixture::~SessionFixture() {
|
||||
const auto result = ses.drop_schema();
|
||||
const auto conn = pool.acquire();
|
||||
const auto result = schema.drop(*conn);
|
||||
REQUIRE(result.is_ok());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
#include "matador/utils/message_bus.hpp"
|
||||
|
||||
#include "connection.hpp"
|
||||
|
||||
#include <stack>
|
||||
|
||||
namespace matador::test {
|
||||
|
|
@ -21,6 +19,8 @@ protected:
|
|||
orm::session ses;
|
||||
utils::message_bus bus;
|
||||
|
||||
query::schema schema;
|
||||
|
||||
private:
|
||||
void drop_table_if_exists(const std::string &table_name) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,11 @@ using namespace matador::object;
|
|||
using namespace matador::test;
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Session insert test", "[session][insert]") {
|
||||
const auto result = ses.attach<airplane>("airplanes")
|
||||
.and_then([this] { return ses.create_schema(); } );
|
||||
const auto result = schema.attach<airplane>("airplanes")
|
||||
.and_then([this] {
|
||||
const auto conn = pool.acquire();
|
||||
return schema.create(*conn);
|
||||
} );
|
||||
REQUIRE(result.is_ok());
|
||||
|
||||
auto plane = ses.insert<airplane>(1, "Boeing", "A380");
|
||||
|
|
@ -32,8 +35,11 @@ TEST_CASE_METHOD(SessionFixture, "Session insert test", "[session][insert]") {
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Session update test", "[session][update]") {
|
||||
const auto res = ses.attach<airplane>("airplanes")
|
||||
.and_then([this] { return ses.create_schema(); } );
|
||||
const auto res = schema.attach<airplane>("airplanes")
|
||||
.and_then([this] {
|
||||
const auto conn = pool.acquire();
|
||||
return schema.create(*conn);
|
||||
} );
|
||||
REQUIRE(res.is_ok());
|
||||
|
||||
auto result = ses.insert<airplane>(1, "Boeing", "747");
|
||||
|
|
@ -62,8 +68,11 @@ TEST_CASE_METHOD(SessionFixture, "Session update test", "[session][update]") {
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Session delete test", "[session][delete]") {
|
||||
const auto res = ses.attach<airplane>("airplanes")
|
||||
.and_then([this] { return ses.create_schema(); } );
|
||||
const auto res = schema.attach<airplane>("airplanes")
|
||||
.and_then([this] {
|
||||
const auto conn = pool.acquire();
|
||||
return schema.create(*conn);
|
||||
} );
|
||||
REQUIRE(res.is_ok());
|
||||
|
||||
auto result = ses.insert<airplane>(1, "Boeing", "747");
|
||||
|
|
@ -83,9 +92,12 @@ TEST_CASE_METHOD(SessionFixture, "Session delete test", "[session][delete]") {
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Session relation test", "[session][relation]") {
|
||||
const auto result = ses.attach<airplane>("airplanes")
|
||||
.and_then([this] { return ses.attach<flight>("flights"); } )
|
||||
.and_then([this] { return ses.create_schema(); } );
|
||||
const auto result = schema.attach<airplane>("airplanes")
|
||||
.and_then([this] { return schema.attach<flight>("flights"); } )
|
||||
.and_then([this] {
|
||||
const auto conn = pool.acquire();
|
||||
return schema.create(*conn);
|
||||
} );
|
||||
REQUIRE(result.is_ok());
|
||||
|
||||
auto plane = ses.insert<airplane>(1, "Boeing", "A380");
|
||||
|
|
@ -105,8 +117,11 @@ TEST_CASE_METHOD(SessionFixture, "Session relation test", "[session][relation]")
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Use session to find object with id", "[session][find]") {
|
||||
const auto result = ses.attach<airplane>("airplanes")
|
||||
.and_then([this] { return ses.create_schema(); } );
|
||||
const auto result = schema.attach<airplane>("airplanes")
|
||||
.and_then([this] {
|
||||
const auto conn = pool.acquire();
|
||||
return schema.create(*conn);
|
||||
} );
|
||||
REQUIRE(result.is_ok());
|
||||
|
||||
auto a380 = ses.insert<airplane>(1, "Boeing", "A380");
|
||||
|
|
@ -124,8 +139,11 @@ TEST_CASE_METHOD(SessionFixture, "Use session to find object with id", "[session
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Use session to find all objects", "[session][find]") {
|
||||
const auto result = ses.attach<airplane>("airplanes")
|
||||
.and_then([this] { return ses.create_schema(); } );
|
||||
const auto result = schema.attach<airplane>("airplanes")
|
||||
.and_then([this] {
|
||||
const auto conn = pool.acquire();
|
||||
return schema.create(*conn);
|
||||
} );
|
||||
REQUIRE(result.is_ok());
|
||||
|
||||
std::vector<std::unique_ptr<airplane>> planes;
|
||||
|
|
@ -157,9 +175,12 @@ TEST_CASE_METHOD(SessionFixture, "Use session to find all objects", "[session][f
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Use session to find all objects with one-to-many lazy relation", "[session][find][one-to-many][eager]") {
|
||||
auto result = ses.attach<author>("authors")
|
||||
.and_then( [this] { return ses.attach<book>("books"); } )
|
||||
.and_then( [this] { return ses.create_schema(); } );
|
||||
auto result = schema.attach<author>("authors")
|
||||
.and_then( [this] { return schema.attach<book>("books"); } )
|
||||
.and_then([this] {
|
||||
const auto conn = pool.acquire();
|
||||
return schema.create(*conn);
|
||||
} );
|
||||
|
||||
std::vector<std::unique_ptr<author>> authors;
|
||||
authors.emplace_back(new author{1, "Michael", "Crichton", "23.10.1942", 1975, true, {}});
|
||||
|
|
@ -207,9 +228,12 @@ TEST_CASE_METHOD(SessionFixture, "Use session to find all objects with one-to-ma
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Use session to find all objects with one-to-many eager relation", "[session][find][one-to-many][eager]") {
|
||||
auto result = ses.attach<department>("departments")
|
||||
.and_then( [this] { return ses.attach<employee>("employees"); } )
|
||||
.and_then( [this] { return ses.create_schema(); } );
|
||||
auto result = schema.attach<department>("departments")
|
||||
.and_then( [this] { return schema.attach<employee>("employees"); } )
|
||||
.and_then([this] {
|
||||
const auto conn = pool.acquire();
|
||||
return schema.create(*conn);
|
||||
} );
|
||||
|
||||
std::vector<std::unique_ptr<department>> departments;
|
||||
departments.emplace_back(new department{1, "Insurance", {}});
|
||||
|
|
@ -260,9 +284,12 @@ TEST_CASE_METHOD(SessionFixture, "Use session to find all objects with one-to-ma
|
|||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Use session to find all objects with many-to-many eager relation", "[session][find][many-to-many][eager]") {
|
||||
auto result = ses.attach<recipe>("recipes")
|
||||
.and_then( [this] { return ses.attach<ingredient>("ingredients"); } )
|
||||
.and_then( [this] { return ses.create_schema(); } );
|
||||
auto result = schema.attach<recipe>("recipes")
|
||||
.and_then( [this] { return schema.attach<ingredient>("ingredients"); } )
|
||||
.and_then([this] {
|
||||
const auto conn = pool.acquire();
|
||||
return schema.create(*conn);
|
||||
} );
|
||||
|
||||
std::vector<std::unique_ptr<ingredient>> ingredients;
|
||||
ingredients.push_back(std::make_unique<ingredient>(1, "Apple"));
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@ TEST_CASE("Generate object from type", "[object][generate]") {
|
|||
const auto obj = object::object_generator::generate<test::book>(repo, "books");
|
||||
REQUIRE(obj->name() == "books");
|
||||
REQUIRE(obj->attributes().size() == 4);
|
||||
REQUIRE(obj->constraints().size() == 2);
|
||||
REQUIRE(obj->constraints().size() == 1);
|
||||
REQUIRE(obj->has_primary_key());
|
||||
}
|
||||
Loading…
Reference in New Issue