#include "matador/object/repository.hpp" #include "matador/logger/log_manager.hpp" #include "author.hpp" #include "book.hpp" #include "recipe.hpp" #include /* * node author * * relation_endpoints * 1. - field_name "books" * - type "has_many" * - node * - foreign endpoint (1) "author" * * node book * 2. - field_name "author_id" * - type "belongs_to" * - node * - foreign endpoint (2) "books" * * Attach process: * * attach * - relation completer detects "has_many" * - has_many doesn't find (not yet attached) * - create endpoint (1) without foreign endpoint * - create node many_to_many_relation("author_id", "id") * - 3. create endpoint * - field name "author_id" * - type "belongs_to" * - node > * - foreign endpoint (1) "author * - set foreign endpoint of (1) to endpoint (3) * - register endpoint in authors node by type book * - attach (internal) node> * * attach * - relation completer detects "belongs_to" * - belongs_to finds * - try to find relation endpoint of type book in authors node * - if endpoint was found * - validate node in endpoint * - if node is of type many_to_many_relation * - detach node of endpoint * - update node in endpoint to * - else * - create endpoint (1) * - create endpoint (2) * - set foreign endpoint of (1) to endpoint (2) * - set foreign endpoint of (2) to endpoint (1) * - check relation endpoints... */ namespace demo { struct names { unsigned int id{}; std::vector names_list; template void process(Operator &op) { namespace field = matador::access; field::primary_key( op, "id", id ); field::has_many(op, "name_list", names_list, "names_id", matador::utils::fetch_type::EAGER); } }; struct user; struct profile { unsigned int id{}; std::string first_name; std::string last_name; matador::object::object_ptr user; template void process(Operator &op) { namespace field = matador::access; field::primary_key( op, "id", id ); field::attribute( op, "first_name", first_name, 255 ); field::attribute( op, "last_name", last_name, 255 ); field::belongs_to( op, "user_id", user, matador::utils::default_foreign_attributes ); } }; struct user { unsigned int id{}; std::string username; matador::object::object_ptr profile; template void process(Operator &op) { namespace field = matador::access; field::primary_key( op, "id", id ); field::attribute( op, "username", username, 255 ); field::has_one(op, "profile_id", profile, matador::utils::default_foreign_attributes ); } }; struct person { unsigned int id{}; std::string name; template void process(Operator &op) { namespace field = matador::access; field::primary_key( op, "id", id ); field::attribute( op, "name", name, 255 ); } }; struct person_repo { unsigned int id{}; matador::object::collection> person_list; template void process(Operator &op) { namespace field = matador::access; field::primary_key( op, "id", id ); field::has_many( op, "person_list", person_list, "person_id", matador::utils::default_foreign_attributes ); } }; } using namespace demo; using namespace matador; int main() { // logger::default_min_log_level(logger::log_level::LVL_DEBUG); // logger::add_log_sink(logger::create_stdout_sink()); { // has_many with builtin-type object::repository repo; auto result = repo.attach("names"); repo.dump(std::cout); } { // has_many with foreign without belongs_to object::repository repo; auto result = repo.attach("person_repo") .and_then([&repo] { return repo.attach("persons"); }); repo.dump(std::cout); } { // has_many with foreign without belongs_to object::repository repo; auto result = repo.attach("persons") .and_then([&repo] { return repo.attach("person_repo"); }); repo.dump(std::cout); } { // has_many to belongs_to object::repository repo; auto result = repo.attach("authors") .and_then([&repo] { return repo.attach("books"); }); repo.dump(std::cout); } { // belongs_to to has_many object::repository repo; auto result = repo.attach("books") .and_then([&repo] { return repo.attach("authors"); }); repo.dump(std::cout); } { // has_many_to_many (with join columns first) object::repository repo; auto result = repo.attach("ingredients") .and_then([&repo] { return repo.attach("recipes"); }); repo.dump(std::cout); } { // has_many_to_many (with join columns last) object::repository repo; auto result = repo.attach("recipes") .and_then([&repo] { return repo.attach("ingredients"); }); repo.dump(std::cout); } { // belongs_to to has_one object::repository repo; auto result = repo.attach("profiles") .and_then([&repo] { return repo.attach("users"); }); repo.dump(std::cout); } { // has_one to belongs_to object::repository repo; auto result = repo.attach("users") .and_then([&repo] { return repo.attach("profiles"); }); repo.dump(std::cout); } }