relation_completer progress
This commit is contained in:
parent
3add45dfdf
commit
5a7ab5d4d0
|
|
@ -25,24 +25,47 @@
|
|||
using namespace matador;
|
||||
using namespace work::models;
|
||||
|
||||
// Proposal for polymorphic classes:
|
||||
// object_ptr::as<Type> does the following checks;
|
||||
//
|
||||
// 1. The requested type has super class
|
||||
// 2. Super class has discriminator column defined
|
||||
// 3. Super class has discriminator value defined
|
||||
// 4. Discriminator value is mapped to the requested type
|
||||
//
|
||||
// If all checks succeed, the requested is fetched from
|
||||
// the database.
|
||||
// schema.attach<jobs::Payload>("payloads", make_polymorph("type"));
|
||||
// schema.attach<jobs::Payload, jobs::IdPayload>("id_list_payloads", make_polymorph_type("IdPayload"));
|
||||
// schema.attach<jobs::Payload, jobs::IdListPayload>("id_payloads"make_polymorph_type("IdListPayload"));
|
||||
// object::object_ptr<jobs::Payload> payload;
|
||||
// auto result = payload.as<jobs::IdPayload>();
|
||||
// if (result.is_ok()) {
|
||||
// const auto& is_payload = result.value();
|
||||
// // Use requested type
|
||||
// id_payload->id = 1;
|
||||
// }
|
||||
// payload.is_polymorphic();
|
||||
// payload.is_polymorphic_type<jobs::IdPayload>();
|
||||
|
||||
int main() {
|
||||
object::schema schema("Administration");
|
||||
|
||||
auto result = schema.attach<admin::CollectionCenter>("collection_center")
|
||||
.and_then([&schema] { return schema.attach<admin::InternalUserDirectory>("internal_user_directory"); })
|
||||
.and_then([&schema] { return schema.attach<admin::InternalUserDirectory>("internal_user_directories"); })
|
||||
.and_then([&schema] { return schema.attach<admin::LdapGroupSchemaSettings>("ldap_group_schema_settings"); })
|
||||
.and_then([&schema] { return schema.attach<admin::LdapImportSettings>("ldap_import_settings"); })
|
||||
.and_then([&schema] { return schema.attach<admin::LdapUserDirectory>("ldap_user_directory"); } )
|
||||
.and_then([&schema] { return schema.attach<admin::LdapUserDirectory>("ldap_user_directories"); } )
|
||||
.and_then([&schema] { return schema.attach<admin::LdapUserSchemaSettings>("ldap_user_schema_settings"); })
|
||||
.and_then([&schema] { return schema.attach<admin::LoginHistory>("login_history"); })
|
||||
.and_then([&schema] { return schema.attach<admin::Scenario>("scenario"); })
|
||||
.and_then([&schema] { return schema.attach<admin::User>("user"); })
|
||||
.and_then([&schema] { return schema.attach<admin::UserDirectory>("user_directory"); })
|
||||
.and_then([&schema] { return schema.attach<admin::UserSession>("user_session"); })
|
||||
.and_then([&schema] { return schema.attach<admin::LoginHistory>("login_histories"); })
|
||||
.and_then([&schema] { return schema.attach<admin::Scenario>("scenarios"); })
|
||||
.and_then([&schema] { return schema.attach<admin::User>("users"); })
|
||||
.and_then([&schema] { return schema.attach<admin::UserDirectory>("user_directories"); })
|
||||
.and_then([&schema] { return schema.attach<admin::UserSession>("user_sessions"); })
|
||||
.and_then([&schema] { return schema.attach<jobs::Job>("jobs"); })
|
||||
.and_then([&schema] { return schema.attach<jobs::Payload>("id_payloads"); })
|
||||
.and_then([&schema] { return schema.attach<jobs::IdPayload>("id_list_payloads"); })
|
||||
.and_then([&schema] { return schema.attach<jobs::IdListPayload>("payloads"); })
|
||||
.and_then([&schema] { return schema.attach<jobs::Payload>("payloads"); })
|
||||
.and_then([&schema] { return schema.attach<jobs::Payload, jobs::IdPayload>("id_list_payloads"); })
|
||||
.and_then([&schema] { return schema.attach<jobs::Payload, jobs::IdListPayload>("id_payloads"); })
|
||||
.and_then([&schema] { return schema.attach<jobs::Task>("tasks"); });
|
||||
|
||||
if (!result.is_ok()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,13 @@ basic_object_info::basic_object_info(std::shared_ptr<schema_node> node,
|
|||
, pk_column_(std::move(pk_column)) {
|
||||
}
|
||||
|
||||
basic_object_info::basic_object_info(std::shared_ptr<schema_node> node,
|
||||
const std::type_index type_index,
|
||||
object_definition &&definition)
|
||||
: node_(std::move(node))
|
||||
, type_index_(type_index)
|
||||
, definition_(std::move(definition)) {}
|
||||
|
||||
std::type_index basic_object_info::type_index() const {
|
||||
return type_index_;
|
||||
}
|
||||
|
|
@ -43,6 +50,14 @@ std::shared_ptr<attribute_definition> basic_object_info::reference_column() cons
|
|||
return pk_column_;
|
||||
}
|
||||
|
||||
bool basic_object_info::has_primary_key() const {
|
||||
return identifier_.has_value();
|
||||
}
|
||||
|
||||
const utils::identifier& basic_object_info::primary_key() const {
|
||||
return identifier_.value();
|
||||
}
|
||||
|
||||
void basic_object_info::register_relation_endpoint(const std::type_index &type, const relation_endpoint &endpoint) {
|
||||
relation_endpoints_.insert(std::make_pair(type, endpoint));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue