diff --git a/backends/postgres/test/CMakeLists.txt b/backends/postgres/test/CMakeLists.txt index e45efed..9afaa56 100644 --- a/backends/postgres/test/CMakeLists.txt +++ b/backends/postgres/test/CMakeLists.txt @@ -2,7 +2,8 @@ CPMAddPackage("gh:catchorg/Catch2@3.7.1") list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) -set(POSTGRES_CONNECTION_STRING "postgres://test:test123!@127.0.0.1:5432/matador") +set(POSTGRES_CONNECTION_STRING "postgres://news:news@127.0.0.1:15432/matador") +#set(POSTGRES_CONNECTION_STRING "postgres://test:test123!@127.0.0.1:15432/matador") configure_file(Connection.hpp.in ${PROJECT_BINARY_DIR}/backends/postgres/test/connection.hpp @ONLY IMMEDIATE) diff --git a/demo/work.cpp b/demo/work.cpp index 6ac2560..3808d72 100644 --- a/demo/work.cpp +++ b/demo/work.cpp @@ -70,35 +70,35 @@ using namespace work::models; // payload.is_polymorphic_type(); int main() { - object::schema schema("Administration"); + const object::schema schema("Administration"); - auto result = schema.attach("collection_centers") - .and_then([&schema] { return schema.attach("user_directories"); }) - .and_then([&schema] { return schema.attach("ldap_group_schema_settings"); }) - .and_then([&schema] { return schema.attach("ldap_import_settings"); }) - .and_then([&schema] { return schema.attach("ldap_user_schema_settings"); }) - .and_then([&schema] { return schema.attach("internal_user_directories"); }) - .and_then([&schema] { return schema.attach("ldap_user_directories"); } ) - .and_then([&schema] { return schema.attach("login_histories"); }) - .and_then([&schema] { return schema.attach("scenarios"); }) - .and_then([&schema] { return schema.attach("users"); }) - .and_then([&schema] { return schema.attach("user_sessions"); }) - .and_then([&schema] { return schema.attach("jobs"); }) - .and_then([&schema] { return schema.attach("payloads"); }) - .and_then([&schema] { return schema.attach("id_list_payloads"); }) - .and_then([&schema] { return schema.attach("id_payloads"); }) - .and_then([&schema] { return schema.attach("tasks"); }); + sql::connection_pool pool("postgres://news:news@127.0.0.1:15432/matador", 4); + + orm::session ses(pool); + + auto result = ses.attach("collection_centers"); + // .and_then([&ses] { return ses.attach("user_directories"); }) + // .and_then([&ses] { return ses.attach("ldap_group_schema_settings"); }) + // .and_then([&ses] { return ses.attach("ldap_import_settings"); }) + // .and_then([&ses] { return ses.attach("ldap_user_schema_settings"); }) + // .and_then([&ses] { return ses.attach("internal_user_directories"); }) + // .and_then([&ses] { return ses.attach("ldap_user_directories"); } ) + // .and_then([&ses] { return ses.attach("login_histories"); }) + // .and_then([&ses] { return ses.attach("scenarios"); }) + // .and_then([&ses] { return ses.attach("users"); }) + // .and_then([&ses] { return ses.attach("user_sessions"); }) + // .and_then([&ses] { return ses.attach("jobs"); }) + // .and_then([&ses] { return ses.attach("payloads"); }) + // .and_then([&ses] { return ses.attach("id_list_payloads"); }) + // .and_then([&ses] { return ses.attach("id_payloads"); }) + // .and_then([&ses] { return ses.attach("tasks"); }) + // .and_then([&ses] { return ses.create_schema(); }); if (!result) { std::cout << "error: " << result.err().message() << std::endl; return 0; } - sql::connection_pool pool("postgres://test:test123!@127.0.0.1:15432/postgres", 4); - - orm::session ses(pool); - - result = ses.create_schema(); schema.dump(std::cout); // const std::string dns{"sqlite://demo.db"}; // sql::connection c(dns); diff --git a/include/matador/object/attribute_definition_generator.hpp b/include/matador/object/attribute_definition_generator.hpp index c6481e6..ca3ad96 100644 --- a/include/matador/object/attribute_definition_generator.hpp +++ b/include/matador/object/attribute_definition_generator.hpp @@ -97,7 +97,6 @@ public: columns_.push_back(fk_column_generator_.generate(id, temp_val, *result)); } else { columns_.push_back(fk_column_generator_.generate(id, *x, *result)); - } } } diff --git a/include/matador/object/schema.hpp b/include/matador/object/schema.hpp index e3b6116..1efe156 100644 --- a/include/matador/object/schema.hpp +++ b/include/matador/object/schema.hpp @@ -121,6 +121,9 @@ private: static void link_relation_endpoints(const endpoint_ptr &endpoint, const endpoint_ptr &other_endpoint); + template + void ensure_type_is_known(); + private: std::shared_ptr node_; schema &schema_; @@ -143,7 +146,7 @@ public: template [[nodiscard]] utils::result attach(const std::string &name, const std::string &parent = "") { // if (has_node(name)) { - // return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + name + "' already exists")); + // return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + name + "' already exists")); // } auto node = schema_node::make_node(*this, name); relation_completer::complete(node); @@ -241,10 +244,14 @@ private: const std::type_index &type_index); [[nodiscard]] utils::result find_node(const std::string &name) const; [[nodiscard]] utils::result find_node(const std::type_index &type_index) const; + template + [[nodiscard]] utils::result find_node() const { + return find_node(std::type_index(typeid(Type))); + } [[nodiscard]] bool has_node(const std::string &name) const; [[nodiscard]] bool has_node(const std::type_index &index) const; - [[nodiscard]] bool has_node(const std::type_index &index, const std::string &name) const; + [[nodiscard]] bool has_node(const node_ptr& node) const; static void insert_node(const node_ptr &parent, const node_ptr &child); void remove_node(const node_ptr &node); @@ -266,13 +273,15 @@ template void relation_completer::on_has_many(const char *id, CollectionType &, const char *join_column, const utils::foreign_attributes &, - std::enable_if_t::value> * - /*unused*/) { + std::enable_if_t::value> * /*unused*/) { + // Shortcut to value type of object_ptr::value_type in collection using value_type = typename CollectionType::value_type::value_type; // Check if the object_ptr type is already inserted in the schema (by id) if (auto result = schema_.find_node(id); !result) { // Type was not found. + // Ensure value_type is known to the schema. Name will be added later + ensure_type_is_known(); // Create and attach the relation node. const std::type_index ti = typeid(many_to_many_relation); if (const auto endpoint = node_->info().find_relation_endpoint(ti); endpoint == node_->info().endpoint_end()) { @@ -479,11 +488,20 @@ void relation_completer::register_relation_endpoints(const endpoint_ptr &e } template -void relation_completer< - Type>::link_relation_endpoints(const endpoint_ptr &endpoint, const endpoint_ptr &other_endpoint) { +void relation_completer::link_relation_endpoints(const endpoint_ptr &endpoint, const endpoint_ptr &other_endpoint) { endpoint->link_foreign_endpoint(other_endpoint); other_endpoint->link_foreign_endpoint(endpoint); } + +template +template +void relation_completer::ensure_type_is_known() { + if (auto result = schema_.find_node(); result) { + return; + } + auto result = schema_.attach_node(schema_node::make_node(schema_, ""), ""); + relation_completer::complete(result.value()); +} } #endif //SCHEMA_HPP diff --git a/include/matador/orm/session.hpp b/include/matador/orm/session.hpp index 4a82a7a..4d2e898 100644 --- a/include/matador/orm/session.hpp +++ b/include/matador/orm/session.hpp @@ -27,6 +27,8 @@ public: template [[nodiscard]] utils::result attach(const std::string &table_name) const; + template + [[nodiscard]] utils::result attach(const std::string &table_name) const; utils::result create_schema() const; @@ -137,6 +139,11 @@ template return schema_->attach(table_name); } +template +utils::result session::attach( const std::string& table_name ) const { + return schema_->attach(table_name); +} + template utils::result, utils::error> session::insert(Type *obj) { diff --git a/source/core/object/schema.cpp b/source/core/object/schema.cpp index 6f0df05..bf342be 100644 --- a/source/core/object/schema.cpp +++ b/source/core/object/schema.cpp @@ -89,7 +89,7 @@ void schema::dump(std::ostream &os) const { utils::result schema::attach_node(const std::shared_ptr &node, const std::string &parent) { - if (has_node(node->type_index(), node->name())) { + if (has_node(node)) { return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + node->name() + "' already exists.")); } @@ -108,7 +108,7 @@ utils::result schema::attach_node(const std::sha insert_node(parent_node, node); // Todo: check return value - nodes_by_name_.insert({node->name(), node})/*.first*/; + nodes_by_name_.insert({node->name(), node}); nodes_by_type_.insert({node->type_index(), node}); return utils::ok(node); @@ -116,7 +116,7 @@ utils::result schema::attach_node(const std::sha utils::result schema::attach_node(const std::shared_ptr &node, const std::type_index &type_index) { - if (has_node(node->type_index(), node->name())) { + if (has_node(node)) { return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + node->name() + "' already exists.")); } auto result = find_node(type_index); @@ -202,7 +202,7 @@ bool schema::has_node(const std::type_index &index) const { return nodes_by_type_.count(index) > 0; } -bool schema::has_node(const std::type_index &index, const std::string &name) const { - return nodes_by_name_.count(name) > 0 || nodes_by_type_.count(index) > 0; +bool schema::has_node(const node_ptr& node) const { + return nodes_by_name_.count(node->name()) > 0 || nodes_by_type_.count(node->type_index()) > 0; } } // namespace matador::object diff --git a/source/core/utils/error.cpp b/source/core/utils/error.cpp index 8dfbddf..baf4c7b 100644 --- a/source/core/utils/error.cpp +++ b/source/core/utils/error.cpp @@ -6,7 +6,7 @@ namespace matador::utils { std::string error::message() const { - return ec_.message(); + return error_message_; } std::string error::category() const {