Compare commits

..

No commits in common. "936ba06458a0f7e2c2be579d3f1917f44577a89b" and "3d90d9d6ee0356b72cf143df596a3309fc202d80" have entirely different histories.

19 changed files with 62 additions and 108 deletions

View File

@ -3,13 +3,12 @@
#include "postgres_result_reader.hpp"
#include "postgres_statement.hpp"
#include "matador/object/attribute_definition.hpp"
#include "matador/sql/error_code.hpp"
#include "matador/sql/record.hpp"
#include "matador/sql/internal/query_result_impl.hpp"
#include <sstream>
namespace matador::backends::postgres {
@ -199,9 +198,9 @@ utils::result<std::vector<object::attribute_definition>, utils::error> postgres_
// Todo: extract size
auto type = (string2type(reader.column(2)));
end = nullptr;
object::null_option null_opt{object::null_option::NULLABLE};
sql::null_option null_opt{sql::null_option::NULLABLE};
if (strtoul(reader.column(4), &end, 10) == 0) {
null_opt = object::null_option::NOT_NULL;
null_opt = sql::null_option::NOT_NULL;
}
// f.default_value(res->column(4));
prototype.emplace_back(name, type, utils::null_attributes, null_opt, index);

View File

@ -18,7 +18,7 @@
#include <string>
struct author {
unsigned int id{};
unsigned long id{};
std::string first_name;
std::string last_name;
std::string date_of_birth;
@ -38,7 +38,7 @@ struct author {
};
struct book {
unsigned int id{};
unsigned long id{};
matador::object::object_ptr<author> book_author;
std::string title;
unsigned short published_in{};
@ -54,7 +54,7 @@ struct book {
};
struct payload {
unsigned int id{};
unsigned long id{};
template<typename Operator>
void process( Operator& op ) {
@ -77,7 +77,7 @@ struct job {
Background
};
unsigned int id{};
unsigned long id{};
matador::object::object_ptr<payload> payload;
std::string type;
std::string description;

View File

@ -42,7 +42,7 @@ public:
template<class Pointer>
void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
void on_has_many(ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
void on_has_many_to_many(const char *id, ContainerType &c, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
@ -93,7 +93,7 @@ public:
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
}
template<class ContainerType>
void on_has_many(const char *id, ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
void on_has_many(ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
void on_has_many_to_many(const char *id, ContainerType &c, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>

View File

@ -9,8 +9,8 @@ namespace matador::object {
class object_definition final {
private:
using column_by_index = std::vector<attribute_definition>;
using column_index_pair = std::pair<std::reference_wrapper<attribute_definition>, column_by_index::difference_type>;
using column_by_index = std::vector<object::attribute_definition>;
using column_index_pair = std::pair<std::reference_wrapper<object::attribute_definition>, column_by_index::difference_type>;
using column_by_name_map = std::unordered_map<std::string, column_index_pair>;
public:
@ -18,8 +18,8 @@ public:
using const_iterator = column_by_index::const_iterator;
object_definition() = default;
object_definition(std::initializer_list<attribute_definition> columns);
explicit object_definition(const std::vector<attribute_definition> &columns);
object_definition(std::initializer_list<object::attribute_definition> columns);
explicit object_definition(const std::vector<object::attribute_definition> &columns);
object_definition(const object_definition &x);
object_definition& operator=(const object_definition &x);
object_definition(object_definition&&) noexcept = default;
@ -27,7 +27,7 @@ public:
~object_definition() = default;
[[nodiscard]] bool has_primary_key() const;
[[nodiscard]] std::optional<attribute_definition> primary_key() const;
[[nodiscard]] std::optional<object::attribute_definition> primary_key() const;
template < typename Type >
void append(const std::string &name, long size = -1) {
@ -35,7 +35,7 @@ public:
}
void append(attribute_definition col);
[[nodiscard]] const std::vector<attribute_definition>& columns() const;
[[nodiscard]] const std::vector<object::attribute_definition>& columns() const;
[[nodiscard]] const attribute_definition& at(const std::string &name) const;
[[nodiscard]] const attribute_definition& at(size_t index) const;

View File

@ -2,9 +2,11 @@
#define QUERY_ENTITY_QUERY_BUILDER_HPP
#include "matador/query/condition.hpp"
#include "matador/query/query.hpp"
#include "matador/query/query_intermediates.hpp"
#include "matador/sql/connection.hpp"
#include "matador/sql/query_context.hpp"
#include "matador/object/schema.hpp"
@ -12,7 +14,6 @@
#include "matador/utils/value.hpp"
#include <stack>
#include <unordered_set>
namespace matador::orm {
@ -100,7 +101,6 @@ public:
}
pk_ = pk;
table_info_stack_.push(info.value());
processed_tables_.insert(info->get().name());
entity_query_data_ = { info.value().get().name() };
try {
access::process(*this, info.value().get().prototype());
@ -175,33 +175,24 @@ public:
}
template<class ContainerType>
void on_has_many(const char * id, ContainerType &, const char *join_column, const utils::foreign_attributes &attr) {
void on_has_many(ContainerType &, const char *join_column, const utils::foreign_attributes &attr)
{
if (attr.fetch() == utils::fetch_type::EAGER) {
const auto info = schema_.info<typename ContainerType::value_type::value_type>();
if (!info) {
throw query_builder_exception{query_build_error::UnknownType};
}
auto curr = table_info_stack_.top().get().name();
auto next = info.value().get().name();
if (processed_tables_.count(next) > 0) {
return;
}
table_info_stack_.push(info.value());
processed_tables_.insert(next);
typename ContainerType::value_type::value_type obj;
access::process(*this , obj);
matador::access::process(*this , obj);
table_info_stack_.pop();
auto pk = info->get().definition().primary_key();
auto pk = info->prototype.primary_key();
if (!pk) {
throw query_builder_exception{query_build_error::MissingPrimaryKey};
}
append_join(
sql::column{std::make_shared<sql::table>(table_info_stack_.top().get().name()), table_info_stack_.top().get().definition().primary_key()->name()},
sql::column{std::make_shared<sql::table>(info->get().name()), join_column}
);
append_join({table_info_stack_.top().get().name(), table_info_stack_.top().get().definition().primary_key()->name()}, {info->name, join_column});
}
}
@ -220,19 +211,13 @@ public:
matador::access::process(*this , obj);
table_info_stack_.pop();
auto pk = info->get().definition().primary_key();
auto pk = info->prototype.primary_key();
if (!pk) {
throw query_builder_exception{query_build_error::MissingPrimaryKey};
}
append_join(
sql::column{std::make_shared<sql::table>(table_info_stack_.top().get().name()), table_info_stack_.top().get().definition().primary_key()->name()},
sql::column{std::make_shared<sql::table>(id), join_column}
);
append_join(
sql::column{std::make_shared<sql::table>(id), inverse_join_column},
sql::column{std::make_shared<sql::table>(info->get().name()), pk->name()}
);
append_join(sql::column{table_info_stack_.top().get().name(), table_info_stack_.top().get().definition().primary_key()->name()}, {id, join_column});
append_join({id, inverse_join_column}, {info->name, pk->name()});
}
template<class ContainerType>
@ -250,21 +235,15 @@ public:
matador::access::process(*this , obj);
table_info_stack_.pop();
auto pk = info->get().definition().primary_key();
auto pk = info->prototype.primary_key();
if (!pk) {
throw query_builder_exception{query_build_error::MissingPrimaryKey};
}
const auto join_columns = join_column_collector_.collect<typename ContainerType::value_type::value_type>();
append_join(
sql::column{std::make_shared<sql::table>(table_info_stack_.top().get().name()), table_info_stack_.top().get().definition().primary_key()->name()},
sql::column{std::make_shared<sql::table>(id), join_columns.inverse_join_column}
);
append_join(
sql::column{std::make_shared<sql::table>(id), join_columns.join_column},
sql::column{std::make_shared<sql::table>(info->get().name()), pk->name()}
);
append_join({table_info_stack_.top().get().name(), table_info_stack_.top().get().definition().primary_key()->name()}, {id, join_columns.inverse_join_column});
append_join({id, join_columns.join_column}, {info->name, pk->name()});
}
private:
@ -277,7 +256,6 @@ private:
private:
utils::value pk_;
std::stack<std::reference_wrapper<const object::basic_object_info>> table_info_stack_;
std::unordered_set<std::string> processed_tables_;
const object::schema &schema_;
entity_query_data entity_query_data_;
int column_index{0};
@ -292,25 +270,16 @@ void session_query_builder::on_foreign_object(const char *id, Pointer &, const u
if (!info) {
throw query_builder_exception{query_build_error::UnknownType};
}
auto curr = table_info_stack_.top().get().name();
auto next = info.value().get().name();
if (processed_tables_.count(next) > 0) {
return;
}
processed_tables_.insert(next);
table_info_stack_.push(info.value());
typename Pointer::value_type obj;
access::process(*this, obj);
matador::access::process(*this, obj);
table_info_stack_.pop();
auto pk = info->get().definition().primary_key();
if (!pk) {
throw query_builder_exception{query_build_error::MissingPrimaryKey};
}
append_join(
sql::column{std::make_shared<sql::table>(table_info_stack_.top().get().name()), id},
sql::column{std::make_shared<sql::table>(info->get().name()), pk->name()}
);
append_join(sql::column{table_info_stack_.top().get().name(), id}, sql::column{info->get().name(), pk->name()});
} else {
push(id);
}

View File

@ -87,7 +87,7 @@ public:
}
}
template<class ContainerType>
void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr)
void on_has_many(ContainerType &, const char *, const utils::foreign_attributes &attr)
{
if (attr.fetch() == utils::fetch_type::LAZY || force_lazy_) {
return;

View File

@ -78,22 +78,22 @@ void belongs_to(Operator &op, const char *id, Type &value) {
}
template<class Operator, class Type, template<class ...> class ContainerType>
void has_many(Operator &op, const char *id, ContainerType<Type> &c, const char *join_column, const utils::foreign_attributes &attr) {
void has_many(Operator &op, const char *id, container<Type, ContainerType> &c, const char *join_column, const utils::foreign_attributes &attr) {
op.on_has_many(id, c, join_column, attr);
}
template<class Operator, class Type, template<class ...> class ContainerType>
void has_many(Operator &op, const char *id, ContainerType<Type> &c, const char *join_column) {
void has_many(Operator &op, const char *id, container<Type, ContainerType> &c, const char *join_column) {
op.on_has_many(id, c, join_column);
}
template<class Operator, class Type, template<class ...> class ContainerType>
void has_many(Operator &op, const char *id, ContainerType<Type> &c, const utils::foreign_attributes &attr) {
void has_many(Operator &op, const char *id, container<Type, ContainerType> &c, const utils::foreign_attributes &attr) {
op.on_has_many(id, c, attr);
}
template<class Operator, class Type, template<class ...> class ContainerType>
void has_many(Operator &op, const char *id, ContainerType<Type> &c) {
void has_many(Operator &op, const char *id, container<Type, ContainerType> &c) {
op.on_has_many(id, c);
}

View File

@ -3,6 +3,7 @@
#include "matador/utils/convert.hpp"
#include <cstdbool>
#include <cstdint>
#include <string>

View File

@ -1,13 +1,13 @@
#include "matador/object/object_definition.hpp"
namespace matador::object {
object_definition::object_definition(const std::initializer_list<attribute_definition> columns)
object_definition::object_definition(std::initializer_list<object::attribute_definition> columns)
: columns_(columns)
{
init();
}
object_definition::object_definition(const std::vector<attribute_definition> &columns)
object_definition::object_definition(const std::vector<object::attribute_definition> &columns)
: columns_(columns)
{
init();
@ -42,7 +42,7 @@ bool object_definition::has_primary_key() const
return pk_index_ > -1;
}
std::optional<attribute_definition> object_definition::primary_key() const
std::optional<object::attribute_definition> object_definition::primary_key() const
{
if (!has_primary_key()) {
return std::nullopt;

View File

@ -36,15 +36,7 @@ std::string schema::name() const {
}
utils::result<std::pair<std::string, std::string>, utils::error> schema::reference( const std::type_index& type_index ) const {
const auto result = find_node(type_index);
if (!result) {
return utils::failure(result.err());
}
if (!result->get()->basic_info().definition().has_primary_key()) {
return utils::failure(make_error( error_code::Failure, "Primary key not found" ));
}
return utils::ok(std::make_pair(result->get()->name(), result->get()->basic_info().definition().primary_key()->name()));
return utils::ok(std::pair<std::string, std::string>{});
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,

View File

@ -2,8 +2,6 @@
#include "matador/sql/backend_provider.hpp"
#include "matador/query/query.hpp"
#include <stdexcept>
namespace matador::orm {

View File

@ -23,9 +23,9 @@ target_include_directories(CoreTests
${CMAKE_SOURCE_DIR}/test/models}
)
#if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# target_compile_options(CoreTests PRIVATE -coverage)
# target_link_options(CoreTests PRIVATE -coverage)
#endif ()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(CoreTests PRIVATE -coverage)
target_link_options(CoreTests PRIVATE -coverage)
endif ()
add_test(NAME CoreTests COMMAND CoreTests)

View File

@ -19,10 +19,11 @@ struct author {
std::string date_of_birth;
unsigned short year_of_birth{};
bool distinguished{false};
std::vector<object::object_ptr<book>> books;
std::vector<matador::object::object_ptr<book>> books;
template<typename Operator>
void process(Operator &op) {
void process(Operator &op)
{
namespace field = matador::access;
field::primary_key(op, "id", id);
field::attribute(op, "first_name", first_name, 63);
@ -30,7 +31,7 @@ struct author {
field::attribute(op, "date_of_birth", date_of_birth, 31);
field::attribute(op, "year_of_birth", year_of_birth);
field::attribute(op, "distinguished", distinguished);
field::has_many(op, "books", books, "author_id", utils::fetch_type::EAGER);
// field::has_many(op, books, "author_id", utils::fetch_type::LAZY);
}
};

View File

@ -21,7 +21,7 @@ struct flight
: id(id), airplane(plane), pilot_name(std::move(name)) {}
unsigned int id{};
object::object_ptr<airplane> airplane;
object::object_ptr<test::airplane> airplane;
std::string pilot_name;
template<class Operator>
@ -29,7 +29,7 @@ struct flight
namespace field = matador::access;
using namespace matador::utils;
field::primary_key(op, "id", id);
field::has_one(op, "airplane_id", airplane, {utils::cascade_type::ALL, utils::fetch_type::EAGER});
// field::has_one(op, "airplane_id", airplane, {utils::cascade_type::ALL, utils::fetch_type::EAGER});
field::attribute(op, "pilot_name", pilot_name, 255);
}
};

View File

@ -16,8 +16,8 @@ namespace matador::test {
struct product {
std::string product_name;
object::object_ptr<supplier> supplier;
object::object_ptr<category> category;
object::object_ptr<test::supplier> supplier;
object::object_ptr<test::category> category;
std::string quantity_per_unit;
unsigned int unit_price;
unsigned int units_in_stock;

View File

@ -16,14 +16,14 @@ struct ingredient
{
unsigned int id{};
std::string name;
std::vector<object::object_ptr<recipe>> recipes;
std::vector<matador::object::object_ptr<recipe>> recipes;
template<class Operator>
void process(Operator &op) {
namespace field = matador::access;
field::primary_key(op, "id", id);
field::attribute(op, "name", name, 255);
field::has_many_to_many(op, "recipe_ingredients", recipes, "ingredient_id", "recipe_id", utils::fetch_type::EAGER);
// field::has_many_to_many(op, "recipe_ingredients", recipes, "ingredient_id", "recipe_id", utils::fetch_type::EAGER);
}
};
@ -31,14 +31,14 @@ struct recipe
{
unsigned int id{};
std::string name;
std::vector<object::object_ptr<ingredient>> ingredients;
std::vector<matador::object::object_ptr<ingredient>> ingredients;
template<class Operator>
void process(Operator &op) {
namespace field = matador::access;
field::primary_key(op, "id", id);
field::attribute(op, "name", name, 255);
field::has_many_to_many(op, "recipe_ingredients", ingredients, utils::fetch_type::LAZY);
// field::has_many_to_many(op, "recipe_ingredients", ingredients, utils::fetch_type::LAZY);
}
};

View File

@ -17,7 +17,7 @@ struct course;
struct student {
unsigned int id{};
std::string name;
std::vector<object::object_ptr<course>> courses;
std::vector<matador::object::object_ptr<course>> courses;
student() = default;
explicit student(unsigned int id, std::string name)
@ -29,7 +29,7 @@ struct student {
namespace field = matador::access;
field::primary_key(op, "id", id);
field::attribute(op, "name", name, 255);
field::has_many_to_many(op, "student_courses", courses, "student_id", "course_id", utils::fetch_type::LAZY);
// field::has_many_to_many(op, "student_courses", courses, "student_id", "course_id", utils::fetch_type::LAZY);
}
};
@ -37,7 +37,7 @@ struct student {
struct course {
unsigned int id{};
std::string title;
std::vector<object::object_ptr<student>> students;
std::vector<matador::object::object_ptr<student>> students;
course() = default;
explicit course(unsigned int id, std::string title)
@ -49,7 +49,7 @@ struct course {
namespace field = matador::access;
field::primary_key(op, "id", id);
field::attribute(op, "title", title, 255);
field::has_many_to_many(op, "student_courses", students, utils::fetch_type::EAGER);
// field::has_many_to_many(op, "student_courses", students, utils::fetch_type::EAGER);
}
};

View File

@ -29,7 +29,7 @@ add_executable(OrmTests
target_link_libraries(OrmTests matador-orm matador-core Catch2::Catch2WithMain)
#target_compile_options(OrmTests PRIVATE -coverage)
#target_link_options(OrmTests PRIVATE -coverage)
target_compile_options(OrmTests PRIVATE -coverage)
target_link_options(OrmTests PRIVATE -coverage)
add_test(NAME OrmTests COMMAND OrmTests)

View File

@ -1,15 +1,11 @@
#include <catch2/catch_test_macros.hpp>
#include "matador/sql/backend_provider.hpp"
#include "matador/sql/connection.hpp"
#include "matador/query/query.hpp"
#include "matador/orm/session_query_builder.hpp"
#include "../backend/test_connection.hpp"
#include "../backend/test_backend_service.hpp"
#include "../../models/airplane.hpp"
#include "../../models/author.hpp"
#include "../../models/book.hpp"
@ -21,7 +17,6 @@
using namespace matador::object;
using namespace matador::orm;
using namespace matador::sql;
using namespace matador::test;
TEST_CASE("Create sql query data for entity with eager has one", "[query][entity][builder]") {
using namespace matador::test;
@ -69,7 +64,6 @@ TEST_CASE("Create sql query data for entity with eager has one", "[query][entity
TEST_CASE("Create sql query data for entity with eager belongs to", "[query][entity][builder]") {
using namespace matador::test;
backend_provider::instance().register_backend("noop", std::make_unique<orm::test_backend_service>());
connection db("noop://noop.db");
schema scm("noop");
auto result = scm.attach<author>("authors")