relation_completer progress
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user