session and insert query builder progress

This commit is contained in:
2026-04-16 16:53:06 +02:00
parent 0a0e3752ea
commit d734d647ed
7 changed files with 110 additions and 88 deletions
+1
View File
@@ -13,6 +13,7 @@ enum class error_code : uint8_t {
NoPrimaryKey,
FailedToBuildQuery,
FailedToFindObject,
FailedToInsertObject,
Failed
};
+24 -50
View File
@@ -14,6 +14,7 @@
#include "matador/sql/connection.hpp"
#include "matador/sql/connection_pool.hpp"
#include "matador/sql/executor.hpp"
#include "matador/sql/record.hpp"
#include "matador/sql/resolver_service.hpp"
#include "matador/sql/statement.hpp"
#include "matador/sql/statement_cache.hpp"
@@ -105,40 +106,35 @@ utils::result<object::object_ptr<Type>, utils::error> session::insert(object::ob
}
// Build dependency-ordered insert steps (deps first, root last)
query::insert_query_builder iqb(schema_, contexts_by_type_);
query::insert_query_builder<Type> iqb(schema_, contexts_by_type_);
auto steps = iqb.build(obj);
if (!steps.is_ok()) {
return utils::failure(make_error(error_code::FailedToBuildQuery, "Failed to build insert dependency queries."));
}
// Execute all steps; for Identity steps read RETURNING and write pk back into the object
for (auto &step : *steps) {
// if (step.pk_is_unset && step.set_pk) {
// if (step.pk_generator == utils::generator_type::Manual) {
// if (step.pk_is_unset()) {
// return utils::failure(make_error(error_code::NoPrimaryKey, "Manual primary key is required but unset."));
// }
// } else if (step.pk_generator == utils::generator_type::Sequence) {
// if (step.pk_is_unset()) {
// // hard-coded naming as you specified earlier
// // <table_name>_seq (table name known in schema meta; if you prefer, store it in step too)
// // For now, we derive from the schema type used for the root insert: simplistic but works if table name == entity name.
// const std::string seq_name = it->second.name() + "_seq";
//
// auto id_res = query::select().nextval(seq_name).fetch_value<std::uint64_t>(*this);
// if (!id_res.is_ok() || !id_res.value().has_value()) {
// return utils::failure(make_error(error_code::FailedToBuildQuery, "Failed to obtain next sequence value."));
// }
// step.set_pk(*id_res.value());
// }
// } else if (step.pk_generator == utils::generator_type::Table) {
// if (step.pk_is_unset()) {
// // TODO: implement table id generation; same idea as above:
// // UPDATE <table>_tbl_seq ... RETURNING ...
// return utils::failure(make_error(error_code::Failed, "Table primary key generator not implemented yet."));
// }
// }
// }
for (query::insert_step &step : *steps) {
auto stmt = cache_.acquire(step.ctx);
if (!stmt.is_ok()) {
return utils::failure(stmt.err());
}
if (step.pk_generator == utils::generator_type::Identity) {
// insert and read RETURNING
auto record = stmt->fetch_one();
if (!record.is_ok()) {
return utils::failure(record.err());
}
if (!record.value().has_value()) {
return utils::failure(make_error(error_code::FailedToFindObject, "Failed to insert object and retrieve identity."));
}
step.apply_returning(*record.value());
} else if (step.pk_generator == utils::generator_type::Sequence || step.pk_generator == utils::generator_type::Table) {
auto result = it->second.pk_generator().next_id(*this);
if (!result.is_ok()) {
return utils::failure(result.err());
}
step.apply_primary_key(utils::identifier{*result});
}
auto result = step.acquire_and_bind(cache_);
if (!result.is_ok()) {
@@ -148,28 +144,6 @@ utils::result<object::object_ptr<Type>, utils::error> session::insert(object::ob
if (const auto exec_result = result->execute(); !exec_result.is_ok()) {
return utils::failure(exec_result.err());
}
// --- Execute step ---
// if (std::holds_alternative<query::executable_query>(step.query)) {
// const auto &q = std::get<query::executable_query>(step.query);
// const auto exec_res = q.execute(*this);
// if (!exec_res.is_ok()) {
// return utils::failure(exec_res.err());
// }
// continue;
// }
//
// const auto &q = std::get<query::fetchable_query>(step.query);
// auto rec_res = q.fetch_one(*this);
// if (!rec_res.is_ok()) {
// return utils::failure(rec_res.err());
// }
// if (!rec_res.value().has_value()) {
// return utils::failure(make_error(error_code::FailedToFindObject, "INSERT ... RETURNING did not return a row."));
// }
// if (step.apply_returning) {
// step.apply_returning(*rec_res.value());
// }
}
obj.change_state(object::object_state::Persistent);