insert query builder insert step refactoring progress
This commit is contained in:
parent
95cd363097
commit
e6adffc264
|
|
@ -11,6 +11,7 @@
|
||||||
#include "matador/query/query_contexts.hpp"
|
#include "matador/query/query_contexts.hpp"
|
||||||
#include "matador/query/query_builder_exception.hpp"
|
#include "matador/query/query_builder_exception.hpp"
|
||||||
|
|
||||||
|
#include "matador/sql/execute_result.hpp"
|
||||||
#include "matador/sql/statement.hpp"
|
#include "matador/sql/statement.hpp"
|
||||||
|
|
||||||
#include "matador/utils/primary_key_accessor.hpp"
|
#include "matador/utils/primary_key_accessor.hpp"
|
||||||
|
|
@ -86,9 +87,9 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ObjectType>
|
template <typename ObjectType>
|
||||||
class insert_step_sequence : public insert_step2 {
|
class insert_step_pk_generated : public insert_step2 {
|
||||||
public:
|
public:
|
||||||
insert_step_sequence(sql::query_context ctx, const object::object_ptr<ObjectType>& ptr, abstract_pk_generator& pk_generator)
|
insert_step_pk_generated(sql::query_context ctx, const object::object_ptr<ObjectType>& ptr, abstract_pk_generator& pk_generator)
|
||||||
: insert_step2(std::move(ctx))
|
: insert_step2(std::move(ctx))
|
||||||
, ptr_(ptr)
|
, ptr_(ptr)
|
||||||
, pk_generator_(pk_generator){}
|
, pk_generator_(pk_generator){}
|
||||||
|
|
@ -120,40 +121,88 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ObjectType>
|
template <typename ObjectType>
|
||||||
class insert_step_identity : public insert_step2 {
|
class insert_step_pk_identity : public insert_step2 {
|
||||||
public:
|
public:
|
||||||
insert_step_identity(sql::query_context ctx, const object::object_ptr<ObjectType>& ptr)
|
insert_step_pk_identity(sql::query_context ctx, const object::object_ptr<ObjectType>& ptr, const std::string &pk_column_name)
|
||||||
: insert_step2(std::move(ctx))
|
: insert_step2(std::move(ctx))
|
||||||
, ptr_(ptr) {}
|
, ptr_(ptr)
|
||||||
|
, pk_column_name_(pk_column_name){}
|
||||||
|
|
||||||
utils::result<void, utils::error> prepare(sql::executor& conn) const override {
|
utils::result<void, utils::error> prepare(sql::executor&) const override {
|
||||||
return utils::ok<void>();
|
return utils::ok<void>();
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::result<void, utils::error> insert(sql::statement& stmt) const override {
|
utils::result<void, utils::error> insert(sql::statement& stmt) const override {
|
||||||
stmt.bind(*ptr_);
|
stmt.bind(*ptr_);
|
||||||
|
|
||||||
auto record = stmt.fetch_one();
|
auto result = stmt.fetch_one();
|
||||||
if (!record.is_ok()) {
|
if (!result.is_ok()) {
|
||||||
return utils::failure(record.err());
|
return utils::failure(result.err());
|
||||||
}
|
}
|
||||||
if (!record.value().has_value()) {
|
if (!result.value().has_value()) {
|
||||||
return utils::failure(utils::error(error_code::FailedToFindObject, "Failed to insert object and retrieve identity."));
|
return utils::failure(utils::error(error_code::FailedToFindObject, "Failed to insert object and retrieve identity."));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto pk_name = info.primary_key_attribute()->name();
|
auto rec = result->value();
|
||||||
const table_column pk_col(&it->second.table(), pk_name);
|
const auto& f = rec.at(pk_column_name_);
|
||||||
step.apply_returning = [ptr, &step, pk_name = pk_name](const sql::record &rec) {
|
utils::identifier id;
|
||||||
const auto& f = rec.at(pk_name);
|
if (auto res = id.assign(f.value()); !res.is_ok()) {
|
||||||
utils::identifier id;
|
return utils::failure(res.err());
|
||||||
id.assign(f.value());
|
}
|
||||||
step.pk_accessor.set(*ptr, id);
|
pk_accessor_.set(*ptr_, id);
|
||||||
};
|
|
||||||
|
|
||||||
ptr_.change_state(object::object_state::Persistent);
|
ptr_.change_state(object::object_state::Persistent);
|
||||||
return utils::ok<void>();
|
return utils::ok<void>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
object::object_ptr<ObjectType> ptr_;
|
||||||
|
std::string pk_column_name_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ObjectType>
|
||||||
|
class insert_step_pk_manual : public insert_step2 {
|
||||||
|
public:
|
||||||
|
insert_step_pk_manual(sql::query_context ctx, const object::object_ptr<ObjectType>& ptr)
|
||||||
|
: insert_step2(std::move(ctx))
|
||||||
|
, ptr_(ptr) {}
|
||||||
|
|
||||||
|
utils::result<void, utils::error> prepare(sql::executor &) const override {
|
||||||
|
return utils::ok<void>();
|
||||||
|
}
|
||||||
|
utils::result<void, utils::error> insert(sql::statement &stmt) const override {
|
||||||
|
stmt.bind(*ptr_);
|
||||||
|
if (const auto exec_result = stmt.execute(); !exec_result.is_ok()) {
|
||||||
|
return utils::failure(exec_result.err());
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr_.change_state(object::object_state::Persistent);
|
||||||
|
return utils::ok<void>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
object::object_ptr<ObjectType> ptr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ObjectType>
|
||||||
|
class insert_step_relation : public insert_step2 {
|
||||||
|
public:
|
||||||
|
insert_step_relation(sql::query_context ctx, const object::object_ptr<ObjectType>& ptr)
|
||||||
|
: insert_step2(std::move(ctx))
|
||||||
|
, ptr_(ptr) {}
|
||||||
|
|
||||||
|
utils::result<void, utils::error> prepare(sql::executor &) const override {
|
||||||
|
return utils::ok<void>();
|
||||||
|
}
|
||||||
|
utils::result<void, utils::error> insert(sql::statement &stmt) const override {
|
||||||
|
stmt.bind(*ptr_);
|
||||||
|
if (const auto exec_result = stmt.execute(); !exec_result.is_ok()) {
|
||||||
|
return utils::failure(exec_result.err());
|
||||||
|
}
|
||||||
|
|
||||||
|
return utils::ok<void>();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
object::object_ptr<ObjectType> ptr_;
|
object::object_ptr<ObjectType> ptr_;
|
||||||
};
|
};
|
||||||
|
|
@ -380,14 +429,23 @@ private:
|
||||||
// 2) Build INSERT for this object
|
// 2) Build INSERT for this object
|
||||||
const auto &info = it->second.node().info();
|
const auto &info = it->second.node().info();
|
||||||
insert_step step{};
|
insert_step step{};
|
||||||
if (info.has_primary_key()) {
|
if (!info.has_primary_key() || it->second.pk_generator().type() == utils::generator_type::None) {
|
||||||
step.pk_generator = it->second.pk_generator().type();
|
return utils::failure(utils::error{error_code::MissingPrimaryKey, "Type " + info.name() + " has no primary key"});
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto cit = contexts_by_type_.find(it->second.node().info().type_index());
|
const auto cit = contexts_by_type_.find(it->second.node().info().type_index());
|
||||||
if (cit == contexts_by_type_.end()) {
|
if (cit == contexts_by_type_.end()) {
|
||||||
return utils::failure(utils::error{error_code::UnknownType, "Unknown type"});
|
return utils::failure(utils::error{error_code::UnknownType, "Unknown type"});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (it->second.pk_generator().type() == utils::generator_type::Manual) {
|
||||||
|
steps2_.push_back(std::make_unique<insert_step_pk_manual<EntityType>>(cit->second.insert, ptr));
|
||||||
|
} else if (it->second.pk_generator().type() == utils::generator_type::Identity) {
|
||||||
|
steps2_.push_back(std::make_unique<insert_step_pk_identity<EntityType>>(cit->second.insert, ptr, info.primary_key_attribute()->name()));
|
||||||
|
} else {
|
||||||
|
steps2_.push_back(std::make_unique<insert_step_pk_generated<EntityType>>(cit->second.insert, ptr));
|
||||||
|
}
|
||||||
|
step.pk_generator = it->second.pk_generator().type();
|
||||||
|
|
||||||
step.ctx = cit->second.insert;
|
step.ctx = cit->second.insert;
|
||||||
step.bind_object = [ptr](sql::statement &stmt) {
|
step.bind_object = [ptr](sql::statement &stmt) {
|
||||||
stmt.bind(*ptr);
|
stmt.bind(*ptr);
|
||||||
|
|
@ -432,6 +490,7 @@ private:
|
||||||
|
|
||||||
object::object_ptr<ObjectType> ptr_;
|
object::object_ptr<ObjectType> ptr_;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<insert_step2>> steps2_;
|
||||||
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_;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue