Compare commits

..

No commits in common. "5a7ab5d4d0555b1c0d86deb6cdf96414ab093535" and "e46de87355e47986406f65feffdb85f5dd972869" have entirely different histories.

6 changed files with 29 additions and 149 deletions

View File

@ -25,47 +25,24 @@
using namespace matador; using namespace matador;
using namespace work::models; 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() { int main() {
object::schema schema("Administration"); object::schema schema("Administration");
auto result = schema.attach<admin::CollectionCenter>("collection_center") auto result = schema.attach<admin::CollectionCenter>("collection_center")
.and_then([&schema] { return schema.attach<admin::InternalUserDirectory>("internal_user_directories"); }) .and_then([&schema] { return schema.attach<admin::InternalUserDirectory>("internal_user_directory"); })
.and_then([&schema] { return schema.attach<admin::LdapGroupSchemaSettings>("ldap_group_schema_settings"); }) .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::LdapImportSettings>("ldap_import_settings"); })
.and_then([&schema] { return schema.attach<admin::LdapUserDirectory>("ldap_user_directories"); } ) .and_then([&schema] { return schema.attach<admin::LdapUserDirectory>("ldap_user_directory"); } )
.and_then([&schema] { return schema.attach<admin::LdapUserSchemaSettings>("ldap_user_schema_settings"); }) .and_then([&schema] { return schema.attach<admin::LdapUserSchemaSettings>("ldap_user_schema_settings"); })
.and_then([&schema] { return schema.attach<admin::LoginHistory>("login_histories"); }) .and_then([&schema] { return schema.attach<admin::LoginHistory>("login_history"); })
.and_then([&schema] { return schema.attach<admin::Scenario>("scenarios"); }) .and_then([&schema] { return schema.attach<admin::Scenario>("scenario"); })
.and_then([&schema] { return schema.attach<admin::User>("users"); }) .and_then([&schema] { return schema.attach<admin::User>("user"); })
.and_then([&schema] { return schema.attach<admin::UserDirectory>("user_directories"); }) .and_then([&schema] { return schema.attach<admin::UserDirectory>("user_directory"); })
.and_then([&schema] { return schema.attach<admin::UserSession>("user_sessions"); }) .and_then([&schema] { return schema.attach<admin::UserSession>("user_session"); })
.and_then([&schema] { return schema.attach<jobs::Job>("jobs"); }) .and_then([&schema] { return schema.attach<jobs::Job>("jobs"); })
.and_then([&schema] { return schema.attach<jobs::Payload>("payloads"); }) .and_then([&schema] { return schema.attach<jobs::Payload>("id_payloads"); })
.and_then([&schema] { return schema.attach<jobs::Payload, jobs::IdPayload>("id_list_payloads"); }) .and_then([&schema] { return schema.attach<jobs::IdPayload>("id_list_payloads"); })
.and_then([&schema] { return schema.attach<jobs::Payload, jobs::IdListPayload>("id_payloads"); }) .and_then([&schema] { return schema.attach<jobs::IdListPayload>("payloads"); })
.and_then([&schema] { return schema.attach<jobs::Task>("tasks"); }); .and_then([&schema] { return schema.attach<jobs::Task>("tasks"); });
if (!result.is_ok()) { if (!result.is_ok()) {

View File

@ -26,31 +26,27 @@ public:
[[nodiscard]] const object_definition& definition() const; [[nodiscard]] const object_definition& definition() const;
[[nodiscard]] std::shared_ptr<attribute_definition> reference_column() 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 register_relation_endpoint(const std::type_index &type, const relation_endpoint &endpoint);
void unregister_relation_endpoint(const std::type_index &type); void unregister_relation_endpoint(const std::type_index &type);
[[nodiscard]] const_endpoint_iterator find_relation_endpoint(const std::type_index &type) const; const_endpoint_iterator find_relation_endpoint(const std::type_index &type) const;
endpoint_iterator find_relation_endpoint(const std::type_index &type); endpoint_iterator find_relation_endpoint(const std::type_index &type);
[[nodiscard]] const_endpoint_iterator find_relation_endpoint(const std::string &field) const; const_endpoint_iterator find_relation_endpoint(const std::string &field) const;
endpoint_iterator find_relation_endpoint(const std::string &field); endpoint_iterator find_relation_endpoint(const std::string &field);
endpoint_iterator endpoint_begin(); endpoint_iterator endpoint_begin();
[[nodiscard]] const_endpoint_iterator endpoint_begin() const; const_endpoint_iterator endpoint_begin() const;
endpoint_iterator endpoint_end(); endpoint_iterator endpoint_end();
[[nodiscard]] const_endpoint_iterator endpoint_end() const; const_endpoint_iterator endpoint_end() const;
[[nodiscard]] std::size_t endpoints_size() const; std::size_t endpoints_size() const;
[[nodiscard]] bool endpoints_empty() const; bool endpoints_empty() const;
protected: 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, 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, 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: protected:
std::shared_ptr<schema_node> node_; /**< prototype node of the represented object type */ std::shared_ptr<schema_node> node_; /**< prototype node of the represented object type */

View File

@ -1,7 +1,6 @@
#ifndef SCHEMA_HPP #ifndef SCHEMA_HPP
#define SCHEMA_HPP #define SCHEMA_HPP
#include "matador/object/many_to_many_relation.hpp"
#include "matador/object/primary_key_resolver.hpp" #include "matador/object/primary_key_resolver.hpp"
#include "matador/object/error_code.hpp" #include "matador/object/error_code.hpp"
#include "matador/object/schema_node.hpp" #include "matador/object/schema_node.hpp"
@ -21,38 +20,6 @@ utils::error make_error(error_code ec, const std::string& msg);
class schema; 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> template<typename Type>
class relation_completer final { class relation_completer final {
public: public:
@ -66,15 +33,15 @@ public:
} }
template < class PrimaryKeyType > template < class PrimaryKeyType >
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) {} 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*/) {} void on_primary_key(const char * /*id*/, std::string &/*pk*/, size_t /*size*/) {}
static void on_revision(const char * /*id*/, uint64_t &/*rev*/) {} void on_revision(const char * /*id*/, uint64_t &/*rev*/) {}
template<typename AttributeType> template<typename AttributeType>
static void on_attribute(const char * /*id*/, AttributeType &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {} void on_attribute(const char * /*id*/, AttributeType &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template<typename AttributeType> template<typename AttributeType>
static void on_attribute(const char * /*id*/, std::optional<AttributeType> &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {} void on_attribute(const char * /*id*/, std::optional<AttributeType> &/*val*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template<class ForeignPointerType> template<class ForeignPointerType>
void on_belongs_to(const char * /*id*/, ForeignPointerType &/*obj*/, const utils::foreign_attributes &/*attr*/) { void on_belongs_to(const char * /*id*/, ForeignPointerType &/*obj*/, const utils::foreign_attributes &/*attr*/) {
@ -86,13 +53,11 @@ public:
} }
template<class CollectionType> 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> template<class CollectionType>
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); 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*/) {}
template<class ContainerType> template<class ContainerType>
void on_has_many_to_many(const char *id, ContainerType &collection, const utils::foreign_attributes &attr); void on_has_many_to_many(const char * /*id*/, ContainerType &/*col*/, const utils::foreign_attributes &/*attr*/) {}
private: private:
template<class ForeignPointerType> template<class ForeignPointerType>
@ -144,9 +109,9 @@ public:
return utils::ok<void>(); return utils::ok<void>();
} }
template <typename Type, typename SuperType> template <typename Type, typename ParentType>
[[nodiscard]] utils::result<void, utils::error> attach(const std::string name) { [[nodiscard]] utils::result<void, utils::error> attach(const std::string name) {
const auto ti = std::type_index(typeid(SuperType)); const auto ti = std::type_index(typeid(ParentType));
auto result = find_node(ti); auto result = find_node(ti);
if (!result) { if (!result) {
return utils::failure(make_error(error_code::NodeNotFound, "Parent node '" + std::string(ti.name()) + "' not found")); return utils::failure(make_error(error_code::NodeNotFound, "Parent node '" + std::string(ti.name()) + "' not found"));
@ -243,36 +208,6 @@ private:
t_type_index_node_map expected_node_map_; 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<typename Type>
template<class ForeignPointerType> template<class ForeignPointerType>
void relation_completer<Type>::on_foreign_key() { void relation_completer<Type>::on_foreign_key() {

View File

@ -33,19 +33,6 @@ public:
return node; 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); static std::shared_ptr<schema_node> make_null_node(schema& tree);
schema_node(const schema_node& other) = delete; schema_node(const schema_node& other) = delete;

View File

@ -30,7 +30,7 @@ public:
* *
* @tparam F Type of join function * @tparam F Type of join function
* @param size Number of threads * @param size Number of threads
* @param join_func Join-function. * @param join_func Join function.
*/ */
template<typename F> template<typename F>
leader_follower_thread_pool(const std::size_t size, F join_func) leader_follower_thread_pool(const std::size_t size, F join_func)
@ -55,7 +55,7 @@ public:
void promote_new_leader(); void promote_new_leader();
/** /**
* Returns the number of threads. * Returns number of threads.
* *
* @return Number of threads. * @return Number of threads.
*/ */
@ -85,7 +85,7 @@ public:
/** /**
* Returns true if the thread pool is running. * Returns true if the thread pool is running.
* *
* @return True if the thread pool is running. * @return True if thread pool is running.
*/ */
[[nodiscard]] bool is_running() const; [[nodiscard]] bool is_running() const;

View File

@ -27,13 +27,6 @@ basic_object_info::basic_object_info(std::shared_ptr<schema_node> node,
, pk_column_(std::move(pk_column)) { , 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 { std::type_index basic_object_info::type_index() const {
return type_index_; return type_index_;
} }
@ -50,14 +43,6 @@ std::shared_ptr<attribute_definition> basic_object_info::reference_column() cons
return pk_column_; 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) { void basic_object_info::register_relation_endpoint(const std::type_index &type, const relation_endpoint &endpoint) {
relation_endpoints_.insert(std::make_pair(type, endpoint)); relation_endpoints_.insert(std::make_pair(type, endpoint));
} }