insert_query_builder progress
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "matador/query/criteria.hpp"
|
||||
#include "matador/query/insert_query_builder.hpp"
|
||||
#include "matador/query/query.hpp"
|
||||
#include "matador/query/query_contexts.hpp"
|
||||
#include "matador/query/generator.hpp"
|
||||
#include "matador/query/schema.hpp"
|
||||
|
||||
@@ -89,6 +90,7 @@ private:
|
||||
const query::basic_schema &schema_;
|
||||
mutable std::unordered_map<std::string, std::vector<object::attribute> > prototypes_;
|
||||
std::shared_ptr<sql::resolver_service> resolver_service_;
|
||||
std::unordered_map<std::type_index, query::query_contexts> contexts_by_type_;
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
@@ -103,63 +105,72 @@ 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_);
|
||||
query::insert_query_builder 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."));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // --- 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());
|
||||
// }
|
||||
// }
|
||||
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."));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
auto result = step.acquire_and_bind(cache_);
|
||||
if (!result.is_ok()) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
|
||||
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);
|
||||
return utils::ok(obj);
|
||||
|
||||
Reference in New Issue
Block a user