has many primitive relation progress
This commit is contained in:
parent
1e08996087
commit
a714cd2a53
|
|
@ -46,6 +46,11 @@ public:
|
|||
many_to_relation(std::string local_name, std::string remote_name)
|
||||
: local_name_(std::move(local_name))
|
||||
, type_name_(std::move(remote_name)) {}
|
||||
many_to_relation(std::string local_name, std::string remote_name, const object_ptr<LocalType>& local, const Type& value)
|
||||
: local_name_(std::move(local_name))
|
||||
, type_name_(std::move(remote_name))
|
||||
, local_(local)
|
||||
, value_(value){}
|
||||
|
||||
template<class Operator>
|
||||
void process(Operator &op) {
|
||||
|
|
|
|||
|
|
@ -227,9 +227,11 @@ void relation_completer<Type, Observers...>::on_has_many(const char *id, Collect
|
|||
using value_type = typename CollectionType::value_type;
|
||||
using relation_value_type = many_to_relation<Type, value_type>;
|
||||
|
||||
auto observers = internal::observer_list_copy_creator<Type, relation_value_type, Observers...>::copy_create(observers_);
|
||||
|
||||
auto node = repository_node::make_node<relation_value_type>(repo_, id, [join_column] {
|
||||
return std::make_unique<relation_value_type>(join_column, "value");
|
||||
}, {});
|
||||
}, std::move(observers));
|
||||
const auto result = repo_.attach_node(node.release(), "");
|
||||
if (!result) {
|
||||
// Todo: throw internal exception
|
||||
|
|
|
|||
|
|
@ -104,7 +104,10 @@ public:
|
|||
on_foreign_object(obj, attr);
|
||||
}
|
||||
template<class CollectionType>
|
||||
void on_has_many(const char * /*id*/, object::collection<object::object_ptr<CollectionType>> &objects, const char *join_column, const utils::foreign_attributes &attr) {
|
||||
void on_has_many(const char * /*id*/,
|
||||
object::collection<object::object_ptr<CollectionType>> &objects,
|
||||
const char *join_column,
|
||||
const utils::foreign_attributes &attr) {
|
||||
if (!utils::is_cascade_type_set(attr.cascade(), utils::cascade_type::Insert)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -120,7 +123,35 @@ public:
|
|||
|
||||
}
|
||||
template<class CollectionType>
|
||||
static void on_has_many(const char * /*id*/, object::collection<CollectionType> &/*con*/, const char *, const utils::foreign_attributes &/*attr*/) {}
|
||||
void on_has_many(const char *id,
|
||||
object::collection<CollectionType> &objects,
|
||||
const char *join_column,
|
||||
const utils::foreign_attributes &attr) {
|
||||
if (!utils::is_cascade_type_set(attr.cascade(), utils::cascade_type::Insert)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto it = schema_.find(std::string{id});
|
||||
if (it == schema_.end()) {
|
||||
throw query_builder_exception(error_code::UnknownType, "Unknown type " + std::string{id});
|
||||
}
|
||||
|
||||
using relation_value_type = object::many_to_relation<ObjectType, CollectionType>;
|
||||
if (std::type_index(typeid(relation_value_type)) != it->second.node().info().type_index()) {
|
||||
throw query_builder_exception(error_code::InvalidRelationType, "Invalid relation type");
|
||||
}
|
||||
|
||||
const auto cit = contexts_by_type_.find(it->second.node().info().type_index());
|
||||
if (cit == contexts_by_type_.end()) {
|
||||
throw query_builder_exception(error_code::UnknownType, "Unknown type" + std::string{id});
|
||||
}
|
||||
|
||||
for (auto &obj : objects) {
|
||||
auto rel = object::make_object<relation_value_type>(join_column, "value", ptr_, obj);
|
||||
|
||||
relation_steps_.push_back(std::make_unique<insert_step_relation<relation_value_type>>(cit->second.insert, rel));
|
||||
}
|
||||
}
|
||||
|
||||
template<class ForeignType>
|
||||
void on_has_many_to_many(const char *id, object::collection<object::object_ptr<ForeignType>> &objects, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &attr) {
|
||||
|
|
|
|||
|
|
@ -94,9 +94,7 @@ public:
|
|||
}
|
||||
|
||||
template<class CollectionType>
|
||||
void on_has_many(const char * /*id*/, CollectionType &/*cont*/, const char * /*join_column*/, 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 &/*cont*/, const char * /*join_column*/, const utils::foreign_attributes &/*attr*/, std::enable_if_t<!object::is_object_ptr<typename CollectionType::value_type>::value> * = nullptr) {}
|
||||
|
||||
template<class CollectionType>
|
||||
void on_has_many_to_many(const char *id, CollectionType &, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &/*attr*/) {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ utils::result<query_result<record>, utils::error> statement::fetch() const {
|
|||
}
|
||||
|
||||
utils::result<std::optional<record>, utils::error> statement::fetch_one() const {
|
||||
logger_->on_fetch(statement_proxy_->sql());
|
||||
std::cout << statement_proxy_->sql() << std::endl;
|
||||
auto result = statement_proxy_->fetch(*bindings_);
|
||||
if (!result.is_ok()) {
|
||||
return utils::failure(result.err());
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#include <utility>
|
||||
|
||||
#include "catch2/catch_test_macros.hpp"
|
||||
|
||||
#include "SessionFixture.hpp"
|
||||
|
|
@ -65,6 +67,30 @@ using book_identity = book_pk_generator<utils::Identity>;
|
|||
using book_sequence = book_pk_generator<utils::Sequence>;
|
||||
using book_table = book_pk_generator<utils::Table>;
|
||||
|
||||
template<const utils::primary_key_attribute &PkAttribute>
|
||||
struct colorlist_pk_generator {
|
||||
unsigned int id{};
|
||||
std::string name;
|
||||
collection<std::string> colors;
|
||||
|
||||
colorlist_pk_generator() = default;
|
||||
colorlist_pk_generator(std::string name, const std::vector<std::string>& color_names)
|
||||
: name(std::move(name))
|
||||
, colors(color_names) {}
|
||||
|
||||
template<typename Operator>
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::access;
|
||||
field::primary_key(op, "id", id, PkAttribute);
|
||||
field::attribute(op, "name", name, VarChar511);
|
||||
field::has_many(op, "colors", colors, "colorlist_id", utils::CascadeAllFetchLazy);
|
||||
}
|
||||
};
|
||||
|
||||
using colorlist_identity = colorlist_pk_generator<utils::Identity>;
|
||||
using colorlist_sequence = colorlist_pk_generator<utils::Sequence>;
|
||||
using colorlist_table = colorlist_pk_generator<utils::Table>;
|
||||
|
||||
}
|
||||
|
||||
template<typename AuthorType, typename BookType>
|
||||
|
|
@ -162,4 +188,23 @@ TEST_CASE_METHOD(SessionFixture, "Test insert object with has many relation with
|
|||
auto author = *author_result;
|
||||
REQUIRE(author.is_persistent());
|
||||
REQUIRE(author->books.size() == 5);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(SessionFixture, "Test insert object with has many primitive relation with table sequence", "[session][insert][has_many][primitive][table_sequence]") {
|
||||
const auto result = schema.attach<colorlist_identity>("colorlist")
|
||||
.and_then([this] { return schema.create(db); } );
|
||||
REQUIRE(result.is_ok());
|
||||
|
||||
session ses({bus, connection::dns, 4}, schema);
|
||||
|
||||
const auto c = make_object<colorlist_identity>("rgb", std::vector<std::string>{"red", "green", "blue"});
|
||||
|
||||
auto res = ses.insert(c);
|
||||
REQUIRE(res.is_ok());
|
||||
|
||||
auto colorlist_result = ses.find<colorlist_identity>(c->id);
|
||||
REQUIRE(colorlist_result);
|
||||
auto clist = *colorlist_result;
|
||||
REQUIRE(clist.is_persistent());
|
||||
REQUIRE(clist->colors.size() == 3);
|
||||
}
|
||||
Loading…
Reference in New Issue