From 9c37e989bab0a7466a3fdeffdcc9824b14a05e28 Mon Sep 17 00:00:00 2001 From: sascha Date: Wed, 6 May 2026 16:18:27 +0200 Subject: [PATCH] insert query builder improvements progress --- .../matador/query/insert_query_builder.hpp | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/include/matador/query/insert_query_builder.hpp b/include/matador/query/insert_query_builder.hpp index acd4ee9..bac26cb 100644 --- a/include/matador/query/insert_query_builder.hpp +++ b/include/matador/query/insert_query_builder.hpp @@ -1,6 +1,8 @@ #ifndef MATADOR_INSERT_QUERY_BUILDER_HPP #define MATADOR_INSERT_QUERY_BUILDER_HPP +#include + #include "matador/object/collection.hpp" #include "matador/query/basic_schema.hpp" @@ -69,6 +71,93 @@ struct insert_step { std::function make_object_persistent{}; }; +class insert_step2 { +public: + explicit insert_step2(sql::query_context ctx) + : ctx_(std::move(ctx)) {} + virtual ~insert_step2() = default; + + virtual utils::result prepare(sql::executor &conn) const = 0; + virtual utils::result insert(sql::statement &stmt) const = 0; + +protected: + utils::primary_key_accessor pk_accessor_; + sql::query_context ctx_; +}; + +template +class insert_step_sequence : public insert_step2 { +public: + insert_step_sequence(sql::query_context ctx, const object::object_ptr& ptr, abstract_pk_generator& pk_generator) + : insert_step2(std::move(ctx)) + , ptr_(ptr) + , pk_generator_(pk_generator){} + + utils::result prepare(sql::executor& conn) const override { + auto result = pk_generator_.next_id(conn); + if (!result.is_ok()) { + return utils::failure(result.err()); + } + pk_accessor_.set(*ptr_, *result); + + return utils::ok(); + } + + utils::result insert(sql::statement& stmt) const override { + stmt.bind(*ptr_); + + if (const auto exec_result = stmt.execute(); !exec_result.is_ok()) { + return utils::failure(exec_result.err()); + } + + ptr_.change_state(object::object_state::Persistent); + return utils::ok(); + } + +private: + object::object_ptr ptr_; + abstract_pk_generator& pk_generator_; +}; + +template +class insert_step_identity : public insert_step2 { +public: + insert_step_identity(sql::query_context ctx, const object::object_ptr& ptr) + : insert_step2(std::move(ctx)) + , ptr_(ptr) {} + + utils::result prepare(sql::executor& conn) const override { + return utils::ok(); + } + + utils::result insert(sql::statement& stmt) const override { + stmt.bind(*ptr_); + + auto record = stmt.fetch_one(); + if (!record.is_ok()) { + return utils::failure(record.err()); + } + if (!record.value().has_value()) { + return utils::failure(utils::error(error_code::FailedToFindObject, "Failed to insert object and retrieve identity.")); + } + + const auto pk_name = info.primary_key_attribute()->name(); + const table_column pk_col(&it->second.table(), pk_name); + step.apply_returning = [ptr, &step, pk_name = pk_name](const sql::record &rec) { + const auto& f = rec.at(pk_name); + utils::identifier id; + id.assign(f.value()); + step.pk_accessor.set(*ptr, id); + }; + + ptr_.change_state(object::object_state::Persistent); + return utils::ok(); + } + +private: + object::object_ptr ptr_; +}; + template class insert_query_builder { public: