#ifndef SESSION_INSERT_BUILDER_HPP #define SESSION_INSERT_BUILDER_HPP #include "matador/query/condition.hpp" #include "matador/query/query_intermediates.hpp" #include "matador/object/schema.hpp" namespace matador::orm { struct entity_insert_data { sql::table table; std::vector columns; std::vector values; }; enum class insert_build_error : std::uint8_t { Ok = 0, UnknownType, MissingPrimaryKey, UnexpectedError }; class insert_builder_exception final : public std::exception { public: explicit insert_builder_exception(const insert_build_error error) : error_(error) {} [[nodiscard]] insert_build_error error() const { return error_; } private: const insert_build_error error_; }; class session_insert_builder final { public: explicit session_insert_builder(const object::schema &scm) : schema_(scm) {} template utils::result, insert_build_error> build(const EntityType &obj) { auto info = schema_.info(); if (!info) { return utils::failure(insert_build_error::UnknownType); } table_info_stack_.push({info.value()}); entity_insert_data_ = {{sql::table{info.value().get().name()}}}; // processed_tables_.insert({info->get().name(), entity_insert_data_.root_table}); try { access::process(*this, obj); return {utils::ok(std::move(entity_insert_data_))}; } catch (const insert_builder_exception &ex) { return {utils::failure(ex.error())}; } catch (...) { return {utils::failure(insert_build_error::UnexpectedError)}; } } template < class V > void on_primary_key(const char *id, V &x, std::enable_if_t && !std::is_same_v>* = nullptr) { push(id, x); } void on_primary_key(const char *id, std::string &, size_t); void on_revision(const char *id, unsigned long long &/*rev*/); template void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes) { } template void on_belongs_to(const char *id, Pointer &obj, const utils::foreign_attributes &attr) { } template void on_has_one(const char *id, Pointer &obj, const utils::foreign_attributes &attr) { } template void on_has_many(const char * /*id*/, ContainerType &, const char *join_column, const utils::foreign_attributes &attr) { } template 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) { } template void on_has_many_to_many(const char *id, ContainerType &/*cont*/, const utils::foreign_attributes &attr) { } private: [[nodiscard]] bool is_root_entity() const; void push(const std::string &column_name, const utils::database_type &value); private: struct table_info { std::reference_wrapper info; }; std::stack table_info_stack_; std::unordered_map> processed_tables_; const object::schema &schema_; std::vector entity_insert_data_; }; } #endif //SESSION_INSERT_BUILDER_HPP