relation_completer progress

This commit is contained in:
Sascha Kühl
2025-06-30 16:01:21 +02:00
parent 3add45dfdf
commit 5a7ab5d4d0
5 changed files with 146 additions and 26 deletions
+10 -6
View File
@@ -26,27 +26,31 @@ public:
[[nodiscard]] const object_definition& definition() const;
[[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const;
bool has_primary_key() const;
[[nodiscard]] const utils::identifier& primary_key() const;
void register_relation_endpoint(const std::type_index &type, const relation_endpoint &endpoint);
void unregister_relation_endpoint(const std::type_index &type);
const_endpoint_iterator find_relation_endpoint(const std::type_index &type) const;
[[nodiscard]] const_endpoint_iterator find_relation_endpoint(const std::type_index &type) const;
endpoint_iterator find_relation_endpoint(const std::type_index &type);
const_endpoint_iterator find_relation_endpoint(const std::string &field) const;
[[nodiscard]] const_endpoint_iterator find_relation_endpoint(const std::string &field) const;
endpoint_iterator find_relation_endpoint(const std::string &field);
endpoint_iterator endpoint_begin();
const_endpoint_iterator endpoint_begin() const;
[[nodiscard]] const_endpoint_iterator endpoint_begin() const;
endpoint_iterator endpoint_end();
const_endpoint_iterator endpoint_end() const;
[[nodiscard]] const_endpoint_iterator endpoint_end() const;
std::size_t endpoints_size() const;
bool endpoints_empty() const;
[[nodiscard]] std::size_t endpoints_size() const;
[[nodiscard]] bool endpoints_empty() const;
protected:
basic_object_info(std::shared_ptr<schema_node> node, std::type_index type_index, utils::identifier &&pk, std::shared_ptr<attribute_definition> &&pk_column, object_definition &&definition);
basic_object_info(std::shared_ptr<schema_node> node, std::type_index type_index, utils::identifier &&pk, std::shared_ptr<attribute_definition> &&pk_column);
basic_object_info(std::shared_ptr<schema_node> node, std::type_index type_index, object_definition &&definition);
protected:
std::shared_ptr<schema_node> node_; /**< prototype node of the represented object type */
+75 -10
View File
@@ -1,6 +1,7 @@
#ifndef SCHEMA_HPP
#define SCHEMA_HPP
#include "matador/object/many_to_many_relation.hpp"
#include "matador/object/primary_key_resolver.hpp"
#include "matador/object/error_code.hpp"
#include "matador/object/schema_node.hpp"
@@ -20,6 +21,38 @@ utils::error make_error(error_code ec, const std::string& msg);
class schema;
/*
* 1. has_many (MM)
* no belongs to
* relation table is needed
* - element type is a foreign table (FT),
* then relation table must look like follows:
* relation_table<MM, FT>
* where MM and FT must be defined as belongs to
* - element type if a builtin type BT (i.e. string, int, etc.),
* then the relation table must look like follows:
* relation_table<MM, BT>
* where MM as belongs to and BT as given type
*
* 2. has_many_to_many (MM1, MM2)
* relation_table is needed
* relation_table<MM1, MM2>
* where MM1 and MM2 must be defined as belongs to
*
* 3. hans_many (MM) <-> belongs_to (BT)
* belongs_to has foreign key to the has_many side
* no relation table needed
*
* 4. has_one to belongs_to
* no relation table is needed
*
* 5. has_many (MM) <-> has_one (HO)
* invalid relation -> error
*
* 6. has_one
* no has_many or belongs_to
* invalid relation -> error
*/
template<typename Type>
class relation_completer final {
public:
@@ -33,15 +66,15 @@ public:
}
template < class PrimaryKeyType >
void on_primary_key(const char * /*id*/, PrimaryKeyType &/*pk*/, std::enable_if_t<std::is_integral_v<PrimaryKeyType> && !std::is_same_v<bool, PrimaryKeyType>>* = nullptr) {}
void on_primary_key(const char * /*id*/, std::string &/*pk*/, size_t /*size*/) {}
void on_revision(const char * /*id*/, uint64_t &/*rev*/) {}
static void on_primary_key(const char * /*id*/, PrimaryKeyType &/*pk*/, std::enable_if_t<std::is_integral_v<PrimaryKeyType> && !std::is_same_v<bool, PrimaryKeyType>>* = nullptr) {}
static void on_primary_key(const char * /*id*/, std::string &/*pk*/, size_t /*size*/) {}
static void on_revision(const char * /*id*/, uint64_t &/*rev*/) {}
template<typename AttributeType>
void on_attribute(const char * /*id*/, AttributeType &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
static void on_attribute(const char * /*id*/, AttributeType &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template<typename AttributeType>
void on_attribute(const char * /*id*/, std::optional<AttributeType> &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
static void on_attribute(const char * /*id*/, std::optional<AttributeType> &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template<class ForeignPointerType>
void on_belongs_to(const char * /*id*/, ForeignPointerType &/*obj*/, const utils::foreign_attributes &/*attr*/) {
@@ -53,11 +86,13 @@ public:
}
template<class CollectionType>
void on_has_many(const char * /*id*/, CollectionType &, const char *, const utils::foreign_attributes &/*attr*/) {}
void on_has_many(const char * /*id*/, CollectionType &, const char *, const utils::foreign_attributes &/*attr*/);
template<class CollectionType>
void on_has_many_to_many(const char * /*id*/, CollectionType &/*col*/, const char * /*join_column*/, const char * /*inverse_join_column*/, const utils::foreign_attributes &/*attr*/) {}
void on_has_many_to_many(const char *id, CollectionType &collection, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &attr);
template<class ContainerType>
void on_has_many_to_many(const char * /*id*/, ContainerType &/*col*/, const utils::foreign_attributes &/*attr*/) {}
void on_has_many_to_many(const char *id, ContainerType &collection, const utils::foreign_attributes &attr);
private:
template<class ForeignPointerType>
@@ -109,9 +144,9 @@ public:
return utils::ok<void>();
}
template <typename Type, typename ParentType>
template <typename Type, typename SuperType>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string name) {
const auto ti = std::type_index(typeid(ParentType));
const auto ti = std::type_index(typeid(SuperType));
auto result = find_node(ti);
if (!result) {
return utils::failure(make_error(error_code::NodeNotFound, "Parent node '" + std::string(ti.name()) + "' not found"));
@@ -208,6 +243,36 @@ private:
t_type_index_node_map expected_node_map_;
};
template<typename Type>
template<class CollectionType>
void relation_completer<Type>::on_has_many( const char*, CollectionType&, const char*, const utils::foreign_attributes& ) {
}
template<typename Type>
template<class CollectionType>
void relation_completer<Type>::on_has_many_to_many( const char *id, CollectionType &/*collection*/, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &attr) {
auto result = schema_.find_node(id);
if (result) {
} else {
//
using relation_type = many_to_many_relation<typename CollectionType::value_type, Type>;
auto creator = [join_column, inverse_join_column] {
return new many_to_many_relation<typename CollectionType::value_type, Type>(join_column, inverse_join_column);
};
auto node = schema_node::make_relation_node<relation_type>(schema_, id);
schema_.attach_node(node, typeid(relation_type));
}
}
template<typename Type>
template<class ContainerType>
void relation_completer<Type>::on_has_many_to_many( const char *id, ContainerType &collection, const utils::foreign_attributes &attr ) {
}
template<typename Type>
template<class ForeignPointerType>
void relation_completer<Type>::on_foreign_key() {
+13
View File
@@ -33,6 +33,19 @@ public:
return node;
}
template < typename Type >
static std::shared_ptr<schema_node> make_relation_node(schema& tree, const std::string& name) {
auto node = std::shared_ptr<schema_node>(new schema_node(tree, name));
auto info = std::make_unique<object_info<Type>>(
node,
object_definition{attribute_definition_generator::generate<Type>(tree)}
);
node->info_ = std::move(info);
return node;
}
static std::shared_ptr<schema_node> make_null_node(schema& tree);
schema_node(const schema_node& other) = delete;