replaced pk_is_unset, pk_setter and pk_value_extractor with pk_accessor
This commit is contained in:
parent
1806e2670c
commit
57246d8742
|
|
@ -6,81 +6,9 @@
|
|||
#include "matador/query/query.hpp"
|
||||
#include "matador/query/query_builder_exception.hpp"
|
||||
|
||||
#include "matador/utils/primary_key_accessor.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
struct pk_setter {
|
||||
const std::string &name;
|
||||
std::uint64_t value;
|
||||
|
||||
template<class V>
|
||||
void on_primary_key(const char *id, V &pk, const utils::primary_key_attribute &/*attr*/) {
|
||||
if (id != nullptr && name == id) {
|
||||
pk = static_cast<V>(value);
|
||||
}
|
||||
}
|
||||
static void on_revision(const char * /*id*/, uint64_t & /*rev*/) {}
|
||||
template<typename T>
|
||||
static void on_attribute(const char * /*id*/, T &, const utils::field_attributes &/*attr*/) {}
|
||||
template<class P>
|
||||
static void on_belongs_to(const char * /*id*/, P &, const utils::foreign_attributes & ) {}
|
||||
template<class P>
|
||||
static void on_has_one(const char * /*id*/, P &, const utils::foreign_attributes & ) {}
|
||||
template<class C>
|
||||
static void on_has_many(const char * /*id*/, C &, const char * /*join_column*/, const utils::foreign_attributes & ) {}
|
||||
template<class C>
|
||||
static void on_has_many_to_many(const char * /*id*/, C &, const char * /*join_column*/, const char * /*inverse_join_column*/, const utils::foreign_attributes & ) {}
|
||||
template<class C>
|
||||
static void on_has_many_to_many(const char * /*id*/, C &, const utils::foreign_attributes & ) {}
|
||||
};
|
||||
|
||||
struct pk_unset_checker {
|
||||
const std::string &name;
|
||||
bool unset{true};
|
||||
|
||||
template<class V>
|
||||
void on_primary_key(const char *id, V &pk, const utils::primary_key_attribute &/*attr*/) {
|
||||
if (id != nullptr && name == id) {
|
||||
// Your convention: 0 means unset for integer PKs
|
||||
unset = (static_cast<std::uint64_t>(pk) == 0ULL);
|
||||
}
|
||||
}
|
||||
static void on_revision(const char * /*id*/, uint64_t & /*rev*/) {}
|
||||
template<typename T>
|
||||
static void on_attribute(const char * /*id*/, T &, const utils::field_attributes &/*attr*/) {}
|
||||
template<class P>
|
||||
static void on_belongs_to(const char * /*id*/, P &, const utils::foreign_attributes & ) {}
|
||||
template<class P>
|
||||
static void on_has_one(const char * /*id*/, P &, const utils::foreign_attributes & ) {}
|
||||
template<class C>
|
||||
static void on_has_many(const char * /*id*/, C &, const char * /*join_column*/, const utils::foreign_attributes & ) {}
|
||||
template<class C>
|
||||
static void on_has_many_to_many(const char * /*id*/, C &, const char * /*join_column*/, const char * /*inverse_join_column*/, const utils::foreign_attributes & ) {}
|
||||
template<class C>
|
||||
static void on_has_many_to_many(const char * /*id*/, C &, const utils::foreign_attributes & ) {}
|
||||
};
|
||||
|
||||
struct pk_value_extractor {
|
||||
std::uint64_t value{0};
|
||||
|
||||
template<class V>
|
||||
void on_primary_key(const char * /*id*/, V &pk, const utils::primary_key_attribute &/*attr*/) {
|
||||
value = static_cast<std::uint64_t>(pk);
|
||||
}
|
||||
static void on_revision(const char * /*id*/, uint64_t & /*rev*/) {}
|
||||
template<typename T>
|
||||
static void on_attribute(const char * /*id*/, T &, const utils::field_attributes &/*attr*/) {}
|
||||
template<class P>
|
||||
static void on_belongs_to(const char * /*id*/, P &, const utils::foreign_attributes & ) {}
|
||||
template<class P>
|
||||
static void on_has_one(const char * /*id*/, P &, const utils::foreign_attributes & ) {}
|
||||
template<class C>
|
||||
static void on_has_many(const char * /*id*/, C &, const char * /*join_column*/, const utils::foreign_attributes & ) {}
|
||||
template<class C>
|
||||
static void on_has_many_to_many(const char * /*id*/, C &, const char * /*join_column*/, const char * /*inverse_join_column*/, const utils::foreign_attributes & ) {}
|
||||
template<class C>
|
||||
static void on_has_many_to_many(const char * /*id*/, C &, const utils::foreign_attributes & ) {}
|
||||
};
|
||||
|
||||
class insert_query_builder {
|
||||
public:
|
||||
using step_query_t = std::variant<executable_query, fetchable_query>;
|
||||
|
|
@ -90,10 +18,7 @@ public:
|
|||
|
||||
// Session uses these to handle manual/sequence/table pre-insert PKs
|
||||
utils::generator_type pk_generator{utils::generator_type::Manual};
|
||||
std::string pk_name;
|
||||
|
||||
std::function<bool()> pk_is_unset{};
|
||||
std::function<void(std::uint64_t)> set_pk{};
|
||||
utils::primary_key_accessor pk_accessor;
|
||||
|
||||
// Identity post-insert
|
||||
std::function<void(const sql::record &)> apply_returning{};
|
||||
|
|
@ -180,19 +105,18 @@ public:
|
|||
}
|
||||
|
||||
// Extract FK value from the foreign object
|
||||
pk_value_extractor fk{};
|
||||
access::process(fk, *obj);
|
||||
if (fk.value == 0ULL) {
|
||||
insert_step rel_step{};
|
||||
const auto pk = rel_step.pk_accessor.get(obj);
|
||||
if (pk.is_valid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Build INSERT into relation table with the 2 FK columns
|
||||
insert_step rel_step{};
|
||||
rel_step.query = executable_query{
|
||||
insert()
|
||||
.into(relation_table, {table_column{&relation_table, join_column}, table_column{&relation_table, inverse_join_column}})
|
||||
.values({utils::database_type{current_entity_pk_}, utils::database_type{fk.value}})
|
||||
};
|
||||
// rel_step.query = executable_query{
|
||||
// insert()
|
||||
// .into(relation_table, {table_column{&relation_table, join_column}, table_column{&relation_table, inverse_join_column}})
|
||||
// .values({utils::database_type{current_entity_pk_}, utils::database_type{fk.value}})
|
||||
// };
|
||||
relation_steps_.push_back(std::move(rel_step));
|
||||
}
|
||||
}
|
||||
|
|
@ -238,29 +162,18 @@ private:
|
|||
const auto &info = it->second.node().info();
|
||||
insert_step step{};
|
||||
if (info.has_primary_key()) {
|
||||
step.pk_name = info.primary_key_attribute()->name();
|
||||
step.pk_generator = it->second.pk_generator().type();
|
||||
|
||||
step.pk_is_unset = [ptr, name = step.pk_name]() {
|
||||
pk_unset_checker chk{name};
|
||||
access::process(chk, *ptr);
|
||||
return chk.unset;
|
||||
};
|
||||
|
||||
step.set_pk = [ptr, name = step.pk_name](std::uint64_t v) {
|
||||
pk_setter setter{name, v};
|
||||
access::process(setter, *ptr);
|
||||
};
|
||||
}
|
||||
|
||||
if (info.has_primary_key() && step.pk_generator == utils::generator_type::Identity) {
|
||||
const table_column pk_col(&it->second.table(), step.pk_name);
|
||||
const auto pk_name = info.primary_key_attribute()->name();
|
||||
const table_column pk_col(&it->second.table(), pk_name);
|
||||
step.query = fetchable_query{insert().into(it->second.table()).values(*ptr).returning(pk_col)};
|
||||
step.apply_returning = [ptr, pk_name = step.pk_name](const sql::record &rec) {
|
||||
if (auto v = rec.at<std::uint64_t>(pk_name); v.has_value()) {
|
||||
pk_setter setter{pk_name, *v};
|
||||
access::process(setter, *ptr);
|
||||
}
|
||||
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);
|
||||
};
|
||||
} else {
|
||||
step.query = executable_query{insert().into(it->second.table()).values(*ptr)};
|
||||
|
|
@ -289,6 +202,7 @@ private:
|
|||
std::vector<insert_step> relation_steps_;
|
||||
std::unordered_set<std::pair<std::type_index, const void *>, visit_key_hash> visited_;
|
||||
|
||||
|
||||
std::uint64_t current_entity_pk_{0};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue