insert_query_builder progress

This commit is contained in:
Sascha Kühl 2026-04-16 07:00:37 +02:00
parent a0326632ab
commit 0a0e3752ea
2 changed files with 31 additions and 32 deletions

View File

@ -51,38 +51,39 @@ private:
std::string join_column_;
};
struct insert_step {
sql::query_context ctx;
utils::result<sql::statement, utils::error> acquire_and_bind(sql::statement_cache &cache) const;
// Session uses these to handle manual/sequence/table pre-insert PKs
utils::generator_type pk_generator{utils::generator_type::Manual};
utils::primary_key_accessor pk_accessor;
// Identity post-insert
std::function<void(const sql::record &)> apply_returning{};
std::function<void(sql::statement &)> bind_object{};
};
template<class ObjectType>
class insert_query_builder {
public:
using step_query_t = std::variant<executable_query, fetchable_query>;
explicit insert_query_builder(const basic_schema &schema, const std::unordered_map<std::type_index, query_contexts> &contexts_by_type)
: schema_(schema)
, contexts_by_type_{contexts_by_type}
{}
struct insert_step {
sql::query_context ctx;
utils::result<sql::statement, utils::error> acquire_and_bind(sql::statement_cache &cache) const;
// Session uses these to handle manual/sequence/table pre-insert PKs
utils::generator_type pk_generator{utils::generator_type::Manual};
utils::primary_key_accessor pk_accessor;
// Identity post-insert
std::function<void(const sql::record &)> apply_returning{};
std::function<void(sql::statement &)> bind_object{};
};
public:
explicit insert_query_builder(const basic_schema &schema, const std::unordered_map<std::type_index, query_contexts> &contexts_by_type);
template<class EntityType>
utils::result<std::vector<insert_step>, query_build_error> build(const object::object_ptr<EntityType> &ptr) {
if (const auto it = schema_.find(typeid(EntityType)); it == schema_.end()) {
utils::result<std::vector<insert_step>, query_build_error> build(const object::object_ptr<ObjectType> &ptr) {
if (const auto it = schema_.find(typeid(ObjectType)); it == schema_.end()) {
return utils::failure(query_build_error::UnknownType);
}
steps_.clear();
visited_.clear();
ptr_ = ptr;
build_for(ptr);
ptr_.reset();
// relation inserts must run after all entity inserts were collected
for (auto &s : relation_steps_) {
@ -95,7 +96,7 @@ public:
template < class PrimaryKeyType >
static void on_primary_key(const char * /*id*/, PrimaryKeyType &, const utils::primary_key_attribute& /*attr*/) {}
static void on_revision(const char *id, uint64_t &/*rev*/);
static void on_revision(const char * /*id*/, uint64_t &/*rev*/) {}
template<typename Type>
static void on_attribute(const char * /*id*/, Type &, const utils::field_attributes &/*attr*/) {}
@ -109,13 +110,16 @@ public:
on_foreign_object(obj, attr);
}
template<class CollectionType>
void on_has_many(const char * /*id*/, CollectionType &con, const char *, const utils::foreign_attributes &attr, std::enable_if_t<object::is_object_ptr<typename CollectionType::value_type>::value> * = nullptr) {
void on_has_many(const char * /*id*/, CollectionType &objects, const char *join_column, const utils::foreign_attributes &attr, std::enable_if_t<object::is_object_ptr<typename CollectionType::value_type>::value> * = nullptr) {
if (!utils::is_cascade_type_set(attr.cascade(), utils::cascade_type::Insert)) {
return;
}
for (auto &obj : con) {
has_many_linker<typename CollectionType::value_type> linker(ptr_, join_column);
for (auto &obj : objects) {
obj.is_persistent() ? build_for(obj) : on_foreign_object(obj, attr);
access::process(linker, obj);
}
}
@ -250,6 +254,8 @@ private:
const basic_schema &schema_;
const std::unordered_map<std::type_index, query_contexts> &contexts_by_type_;
object::object_ptr<ObjectType> ptr_;
std::vector<insert_step> steps_;
std::vector<insert_step> relation_steps_;
std::unordered_set<std::pair<std::type_index, const void *>, visit_key_hash> visited_;

View File

@ -3,12 +3,7 @@
#include "matador/sql/statement_cache.hpp"
namespace matador::query {
insert_query_builder::insert_query_builder(const basic_schema& schema, const std::unordered_map<std::type_index, query_contexts> &contexts_by_type)
: schema_(schema)
, contexts_by_type_{contexts_by_type}
{}
utils::result<sql::statement, utils::error> insert_query_builder::insert_step::acquire_and_bind(sql::statement_cache &cache) const {
utils::result<sql::statement, utils::error> insert_step::acquire_and_bind(sql::statement_cache &cache) const {
auto result = cache.acquire(ctx);
if (!result.is_ok()) {
return utils::failure(result.err());
@ -18,6 +13,4 @@ utils::result<sql::statement, utils::error> insert_query_builder::insert_step::a
return utils::ok(std::move(*result));
}
void insert_query_builder::on_revision(const char* /*id*/, uint64_t&) {}
} // namespace matador::query