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,12 +51,7 @@ private:
std::string join_column_; std::string join_column_;
}; };
struct insert_step {
class insert_query_builder {
public:
using step_query_t = std::variant<executable_query, fetchable_query>;
struct insert_step {
sql::query_context ctx; sql::query_context ctx;
utils::result<sql::statement, utils::error> acquire_and_bind(sql::statement_cache &cache) const; utils::result<sql::statement, utils::error> acquire_and_bind(sql::statement_cache &cache) const;
@ -68,21 +63,27 @@ public:
// Identity post-insert // Identity post-insert
std::function<void(const sql::record &)> apply_returning{}; std::function<void(const sql::record &)> apply_returning{};
std::function<void(sql::statement &)> bind_object{}; std::function<void(sql::statement &)> bind_object{};
}; };
template<class ObjectType>
class insert_query_builder {
public: public:
explicit insert_query_builder(const basic_schema &schema, const std::unordered_map<std::type_index, query_contexts> &contexts_by_type); 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}
{}
template<class EntityType> utils::result<std::vector<insert_step>, query_build_error> build(const object::object_ptr<ObjectType> &ptr) {
utils::result<std::vector<insert_step>, query_build_error> build(const object::object_ptr<EntityType> &ptr) { if (const auto it = schema_.find(typeid(ObjectType)); it == schema_.end()) {
if (const auto it = schema_.find(typeid(EntityType)); it == schema_.end()) {
return utils::failure(query_build_error::UnknownType); return utils::failure(query_build_error::UnknownType);
} }
steps_.clear(); steps_.clear();
visited_.clear(); visited_.clear();
ptr_ = ptr;
build_for(ptr); build_for(ptr);
ptr_.reset();
// relation inserts must run after all entity inserts were collected // relation inserts must run after all entity inserts were collected
for (auto &s : relation_steps_) { for (auto &s : relation_steps_) {
@ -95,7 +96,7 @@ public:
template < class PrimaryKeyType > template < class PrimaryKeyType >
static void on_primary_key(const char * /*id*/, PrimaryKeyType &, const utils::primary_key_attribute& /*attr*/) {} 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> template<typename Type>
static void on_attribute(const char * /*id*/, Type &, const utils::field_attributes &/*attr*/) {} static void on_attribute(const char * /*id*/, Type &, const utils::field_attributes &/*attr*/) {}
@ -109,13 +110,16 @@ public:
on_foreign_object(obj, attr); on_foreign_object(obj, attr);
} }
template<class CollectionType> 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)) { if (!utils::is_cascade_type_set(attr.cascade(), utils::cascade_type::Insert)) {
return; 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); 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 basic_schema &schema_;
const std::unordered_map<std::type_index, query_contexts> &contexts_by_type_; 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> steps_;
std::vector<insert_step> relation_steps_; std::vector<insert_step> relation_steps_;
std::unordered_set<std::pair<std::type_index, const void *>, visit_key_hash> visited_; 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" #include "matador/sql/statement_cache.hpp"
namespace matador::query { 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) utils::result<sql::statement, utils::error> insert_step::acquire_and_bind(sql::statement_cache &cache) const {
: 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 {
auto result = cache.acquire(ctx); auto result = cache.acquire(ctx);
if (!result.is_ok()) { if (!result.is_ok()) {
return utils::failure(result.err()); 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)); return utils::ok(std::move(*result));
} }
void insert_query_builder::on_revision(const char* /*id*/, uint64_t&) {}
} // namespace matador::query } // namespace matador::query