attaching schema nodes progress

This commit is contained in:
Sascha Kühl 2025-07-14 15:57:14 +02:00
parent 1b2847696d
commit 0d93b9b1ed
19 changed files with 182 additions and 91 deletions

View File

@ -70,9 +70,13 @@ using namespace work::models;
// payload.is_polymorphic_type<jobs::IdPayload>(); // payload.is_polymorphic_type<jobs::IdPayload>();
int main() { int main() {
logger::default_min_log_level(logger::log_level::LVL_DEBUG);
logger::add_log_sink(logger::create_stdout_sink());
const object::schema schema("Administration"); const object::schema schema("Administration");
sql::connection_pool<sql::connection> pool("postgres://test:test123!@127.0.0.1:5432/matador", 4); sql::connection_pool<sql::connection> pool("postgres://news:news@127.0.0.1:15432/matador", 4);
// sql::connection_pool<sql::connection> pool("postgres://test:test123!@127.0.0.1:5432/matador", 4);
orm::session ses(pool); orm::session ses(pool);
@ -92,14 +96,20 @@ int main() {
.and_then([&ses] { return ses.attach<jobs::IdPayload, jobs::Payload>("id_list_payloads"); }) .and_then([&ses] { return ses.attach<jobs::IdPayload, jobs::Payload>("id_list_payloads"); })
.and_then([&ses] { return ses.attach<jobs::IdListPayload, jobs::Payload>("id_payloads"); }) .and_then([&ses] { return ses.attach<jobs::IdListPayload, jobs::Payload>("id_payloads"); })
.and_then([&ses] { return ses.attach<jobs::Task>("tasks"); }) .and_then([&ses] { return ses.attach<jobs::Task>("tasks"); })
.and_then([&ses] { return ses.create_schema(); }); ;
// ses.dump_schema(std::cout);
if (!result) { if (!result) {
std::cout << "error: " << result.err().message() << std::endl; std::cout << "error: " << result.err().message() << std::endl;
return 0; return 0;
} }
ses.dump_schema(std::cout); result = ses.create_schema();
if (!result) {
std::cout << "error: " << result.err() << std::endl;
return 0;
}
// const std::string dns{"sqlite://demo.db"}; // const std::string dns{"sqlite://demo.db"};
// sql::connection c(dns); // sql::connection c(dns);
// //
@ -110,7 +120,6 @@ int main() {
// return 0; // return 0;
// } // }
return 0; return 0;
} }

View File

@ -25,6 +25,7 @@ public:
attribute_definition(attribute_definition&&) noexcept = default; attribute_definition(attribute_definition&&) noexcept = default;
attribute_definition& operator=(attribute_definition&&) noexcept = default; attribute_definition& operator=(attribute_definition&&) noexcept = default;
attribute_definition() = default;
template<typename Type> template<typename Type>
explicit attribute_definition(std::string name, std::string table_name, const utils::field_attributes& attr) explicit attribute_definition(std::string name, std::string table_name, const utils::field_attributes& attr)
: attribute_definition(std::move(name), std::move(table_name), utils::data_type_traits<Type>::type(attr.size()), attr) : attribute_definition(std::move(name), std::move(table_name), utils::data_type_traits<Type>::type(attr.size()), attr)
@ -61,8 +62,10 @@ public:
void name(const std::string& n); void name(const std::string& n);
[[nodiscard]] std::string full_name() const; [[nodiscard]] std::string full_name() const;
[[nodiscard]] std::string table_name() const; [[nodiscard]] std::string table_name() const;
void table_name(const std::string& tn);
[[nodiscard]] int index() const; [[nodiscard]] int index() const;
[[nodiscard]] const utils::field_attributes& attributes() const; [[nodiscard]] const utils::field_attributes& attributes() const;
[[nodiscard]] utils::field_attributes& attributes();
[[nodiscard]] bool is_nullable() const; [[nodiscard]] bool is_nullable() const;
[[nodiscard]] utils::basic_type type() const; [[nodiscard]] utils::basic_type type() const;
[[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const; [[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const;
@ -141,7 +144,7 @@ private:
* @param type * @param type
* @param attr Length of the column name * @param attr Length of the column name
* @param null_opt * @param null_opt
* @return A column object with given name * @return A column object with a given name
*/ */
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL); attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL);

View File

@ -1,13 +1,13 @@
#ifndef QUERY_COLUMN_DEFINITION_GENERATOR_HPP #ifndef QUERY_COLUMN_DEFINITION_GENERATOR_HPP
#define QUERY_COLUMN_DEFINITION_GENERATOR_HPP #define QUERY_COLUMN_DEFINITION_GENERATOR_HPP
#include "attribute_definition.hpp" #include "matador/object/attribute_definition.hpp"
#include "matador/utils/access.hpp" #include "matador/utils/access.hpp"
#include "matador/utils/data_type_traits.hpp" #include "matador/utils/data_type_traits.hpp"
#include "matador/utils/error.hpp" #include "matador/utils/error.hpp"
#include "matador/utils/field_attributes.hpp" #include "matador/utils/field_attributes.hpp"
#include "matador/utils/foreign_attributes.hpp"
#include <memory> #include <memory>
#include <typeindex> #include <typeindex>
@ -54,13 +54,13 @@ private:
class attribute_definition_generator final { class attribute_definition_generator final {
private: private:
attribute_definition_generator(std::vector<attribute_definition> &columns, const schema &repo); attribute_definition_generator(std::vector<attribute_definition> &columns, schema &repo);
public: public:
~attribute_definition_generator() = default; ~attribute_definition_generator() = default;
template < class Type > template < class Type >
static std::vector<attribute_definition> generate(const schema &repo) static std::vector<attribute_definition> generate(schema &repo)
{ {
std::vector<attribute_definition> columns; std::vector<attribute_definition> columns;
attribute_definition_generator gen(columns, repo); attribute_definition_generator gen(columns, repo);
@ -69,6 +69,14 @@ public:
return columns; return columns;
} }
template < class Type >
static std::vector<attribute_definition> generate(const Type& obj, schema &repo) {
std::vector<attribute_definition> columns;
attribute_definition_generator gen(columns, repo);
access::process(gen, obj);
return columns;
}
template < class V > template < class V >
void on_primary_key(const char *, V &x, std::enable_if_t<std::is_integral_v<V> && !std::is_same_v<bool, V>>* = nullptr); void on_primary_key(const char *, V &x, std::enable_if_t<std::is_integral_v<V> && !std::is_same_v<bool, V>>* = nullptr);
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);
@ -91,13 +99,19 @@ public:
template <class Pointer> template <class Pointer>
void on_foreign_key(const char *id, Pointer &x) { void on_foreign_key(const char *id, Pointer &x) {
if (const auto result = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)))) { std::shared_ptr<attribute_definition> ref_column;
std::type_index ti = typeid(typename Pointer::value_type);
if (const auto result = determine_foreign_ref(std::type_index(ti))) {
ref_column = *result;
} else {
ref_column = std::make_shared<attribute_definition>();
insert_missing_reference_column(ti, ref_column);
}
if (x.empty()) { if (x.empty()) {
typename Pointer::value_type temp_val; typename Pointer::value_type temp_val;
columns_.push_back(fk_column_generator_.generate(id, temp_val, *result)); columns_.push_back(fk_column_generator_.generate(id, temp_val, ref_column));
} else { } else {
columns_.push_back(fk_column_generator_.generate(id, *x, *result)); columns_.push_back(fk_column_generator_.generate(id, *x, ref_column));
}
} }
} }
template<class ContainerType> template<class ContainerType>
@ -109,11 +123,12 @@ public:
private: private:
[[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> determine_foreign_ref(const std::type_index &ti) const; [[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> determine_foreign_ref(const std::type_index &ti) const;
void insert_missing_reference_column(const std::type_index &ti, std::shared_ptr<attribute_definition> ref_column) const;
private: private:
size_t index_ = 0; size_t index_ = 0;
std::vector<attribute_definition> &columns_; std::vector<attribute_definition> &columns_;
const schema &repo_; schema &repo_;
fk_attribute_generator fk_column_generator_; fk_attribute_generator fk_column_generator_;
}; };

View File

@ -49,13 +49,12 @@ public:
[[nodiscard]] bool endpoints_empty() const; [[nodiscard]] 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, const 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, const std::shared_ptr<attribute_definition> &pk_column);
basic_object_info(std::shared_ptr<schema_node> node, std::type_index type_index, object_definition &&definition); 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 */
std::type_index type_index_; /**< type index of the represented object type */
object_definition definition_; object_definition definition_;
std::optional<utils::identifier> identifier_; std::optional<utils::identifier> identifier_;
std::shared_ptr<attribute_definition> pk_column_; std::shared_ptr<attribute_definition> pk_column_;

View File

@ -13,23 +13,23 @@ public:
using create_func = std::function<std::unique_ptr<Type>()>; using create_func = std::function<std::unique_ptr<Type>()>;
object_info(const std::shared_ptr<schema_node>& node, object_info(const std::shared_ptr<schema_node>& node,
std::shared_ptr<attribute_definition> &&ref_column) const std::shared_ptr<attribute_definition> &ref_column)
: basic_object_info(node, typeid(Type), {}, std::move(ref_column), {}) : basic_object_info(node, typeid(Type), {}, ref_column, {})
, creator_([]{return std::make_unique<Type>(); }){ , creator_([]{return std::make_unique<Type>(); }){
} }
object_info(const std::shared_ptr<schema_node>& node, object_info(const std::shared_ptr<schema_node>& node,
utils::identifier &&pk, utils::identifier &&pk,
std::shared_ptr<attribute_definition> &&ref_column, const std::shared_ptr<attribute_definition> &ref_column,
object_definition &&definition) object_definition &&definition)
: basic_object_info(node, typeid(Type), std::move(pk), std::move(ref_column), std::move(definition)) : basic_object_info(node, typeid(Type), std::move(pk), ref_column, std::move(definition))
, creator_([]{return std::make_unique<Type>(); }){ , creator_([]{return std::make_unique<Type>(); }){
} }
object_info(const std::shared_ptr<schema_node>& node, object_info(const std::shared_ptr<schema_node>& node,
utils::identifier &&pk, utils::identifier &&pk,
std::shared_ptr<attribute_definition> &&ref_column, const std::shared_ptr<attribute_definition> &ref_column,
object_definition &&definition, object_definition &&definition,
create_func&& creator) create_func&& creator)
: basic_object_info(node, typeid(Type), std::move(pk), std::move(ref_column), std::move(definition)) : basic_object_info(node, typeid(Type), std::move(pk), ref_column, std::move(definition))
, creator_(std::move(creator)){ , creator_(std::move(creator)){
} }
object_info(const std::shared_ptr<schema_node>& node, object_info(const std::shared_ptr<schema_node>& node,

View File

@ -129,17 +129,16 @@ void relation_completer<Type>::on_has_many(const char *id, CollectionType &,
if (const auto endpoint = nodes_.top()->info().find_relation_endpoint(typeid(relation_value_type)); endpoint == nodes_.top()->info().endpoint_end()) { if (const auto endpoint = nodes_.top()->info().find_relation_endpoint(typeid(relation_value_type)); endpoint == nodes_.top()->info().endpoint_end()) {
// Endpoint was not found // Endpoint was not found
log_.debug("node '%s' has has many foreign keys '%s' mapped by '%s'", nodes_.top()->name().c_str(), id, join_column); log_.debug("node '%s' has has many foreign keys '%s' mapped by '%s'", nodes_.top()->name().c_str(), id, join_column);
const auto node = schema_node::make_relation_node<relation_value_type>( result = schema_node::make_relation_node<relation_value_type>(
schema_.schema(), id, [join_column] { schema_.schema(), id, [join_column] {
return std::make_unique<relation_value_type>(join_column, "id"); return std::make_unique<relation_value_type>("id", join_column);
}); });
result = schema_.attach_node(node);
if (!result) { if (!result) {
// Todo: throw internal error // Todo: throw internal error
return; return;
} }
const auto local_endpoint = std::make_shared<relation_endpoint>(id, relation_type::HAS_MANY, nodes_.top()); const auto local_endpoint = std::make_shared<relation_endpoint>(id, relation_type::HAS_MANY, nodes_.top());
const auto foreign_endpoint = std::make_shared<relation_endpoint>(join_column, relation_type::BELONGS_TO, node); const auto foreign_endpoint = std::make_shared<relation_endpoint>(join_column, relation_type::BELONGS_TO, result.value());
nodes_.top()->info_->register_relation_endpoint(typeid(value_type), local_endpoint); nodes_.top()->info_->register_relation_endpoint(typeid(value_type), local_endpoint);
foreign_endpoint->node_->info_->register_relation_endpoint(nodes_.top()->type_index(), foreign_endpoint); foreign_endpoint->node_->info_->register_relation_endpoint(nodes_.top()->type_index(), foreign_endpoint);
link_relation_endpoints(local_endpoint, foreign_endpoint); link_relation_endpoints(local_endpoint, foreign_endpoint);
@ -171,18 +170,17 @@ void relation_completer<Type>::on_has_many(const char *id, CollectionType &, con
using value_type = typename CollectionType::value_type; using value_type = typename CollectionType::value_type;
using relation_value_type = many_to_relation<Type, value_type>; using relation_value_type = many_to_relation<Type, value_type>;
const auto node = schema_node::make_relation_node<relation_value_type>( const auto result = schema_node::make_relation_node<relation_value_type>(
schema_.schema(), id, [join_column] { schema_.schema(), id, [join_column] {
return std::make_unique<relation_value_type>(join_column, "value"); return std::make_unique<relation_value_type>(join_column, "value");
}); });
const auto result = schema_.attach_node(node);
if (!result) { if (!result) {
// Todo: throw internal exception // Todo: throw internal exception
} }
const auto local_endpoint = std::make_shared<relation_endpoint>(id, relation_type::HAS_MANY, nodes_.top()); const auto local_endpoint = std::make_shared<relation_endpoint>(id, relation_type::HAS_MANY, nodes_.top());
const auto foreign_endpoint = std::make_shared<relation_endpoint>(join_column, relation_type::BELONGS_TO, node); const auto foreign_endpoint = std::make_shared<relation_endpoint>(join_column, relation_type::BELONGS_TO, result.value());
nodes_.top()->info_->register_relation_endpoint(typeid(value_type), local_endpoint); nodes_.top()->info_->register_relation_endpoint(typeid(value_type), local_endpoint);
foreign_endpoint->node_->info_->register_relation_endpoint(nodes_.top()->type_index(), foreign_endpoint); foreign_endpoint->node_->info_->register_relation_endpoint(nodes_.top()->type_index(), foreign_endpoint);
link_relation_endpoints(local_endpoint, foreign_endpoint); link_relation_endpoints(local_endpoint, foreign_endpoint);
@ -210,13 +208,18 @@ void relation_completer<Type>::on_has_many_to_many(const char *id,
} }
link_relation_endpoints(local_endpoint, it->second); link_relation_endpoints(local_endpoint, it->second);
} else { } else {
// Relation not not found. // Relation not found.
auto creator = [join_column, inverse_join_column] { auto creator = [join_column, inverse_join_column] {
return std::make_unique<relation_value_type>(join_column, inverse_join_column); return std::make_unique<relation_value_type>(join_column, inverse_join_column);
}; };
auto node = schema_node::make_relation_node<relation_value_type>(schema_.schema(), id, std::move(creator)); result = schema_node::make_relation_node<relation_value_type>(schema_.schema(), id, std::move(creator));
if (!result) {
// Todo: throw internal error
return;
}
auto& node = result.value();
auto local_endpoint = std::make_shared<relation_endpoint>(id, relation_type::HAS_MANY, nodes_.top()); auto local_endpoint = std::make_shared<relation_endpoint>(id, relation_type::HAS_MANY, nodes_.top());
auto join_endpoint = std::make_shared<relation_endpoint>(join_column, relation_type::BELONGS_TO, node); auto join_endpoint = std::make_shared<relation_endpoint>(join_column, relation_type::BELONGS_TO, node);
auto inverse_join_endpoint = std::make_shared<relation_endpoint>(inverse_join_column, relation_type::BELONGS_TO, auto inverse_join_endpoint = std::make_shared<relation_endpoint>(inverse_join_column, relation_type::BELONGS_TO,
@ -226,11 +229,6 @@ void relation_completer<Type>::on_has_many_to_many(const char *id,
link_relation_endpoints(local_endpoint, join_endpoint); link_relation_endpoints(local_endpoint, join_endpoint);
node->info_->register_relation_endpoint(typeid(typename CollectionType::value_type::value_type), node->info_->register_relation_endpoint(typeid(typename CollectionType::value_type::value_type),
inverse_join_endpoint); inverse_join_endpoint);
result = schema_.attach_node(node);
if (!result) {
// Todo: throw internal error
return;
}
} }
} }

View File

@ -40,11 +40,11 @@ public:
[[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, const std::string &parent = "") { [[nodiscard]] utils::result<void, utils::error> attach(const std::string &name, const std::string &parent = "") {
if (const auto it = nodes_by_type_.find(typeid(Type)); it == nodes_by_type_.end() ) { if (const auto it = nodes_by_type_.find(typeid(Type)); it == nodes_by_type_.end() ) {
auto node = schema_node::make_node<Type>(*this, name); auto node = schema_node::make_node<Type>(*this, name);
foreign_node_completer::complete<Type>(node);
relation_completer<Type>::complete(node);
if (auto result = attach_node(node, parent); !result) { if (auto result = attach_node(node, parent); !result) {
return utils::failure(result.err()); return utils::failure(result.err());
} }
foreign_node_completer::complete<Type>(node);
relation_completer<Type>::complete(node);
} else if (!has_node(name)) { } else if (!has_node(name)) {
it->second->update_name(name); it->second->update_name(name);
nodes_by_name_[name] = it->second; nodes_by_name_[name] = it->second;
@ -142,7 +142,7 @@ public:
return utils::ok(basic_object_info_ref{result.value()->info()}); return utils::ok(basic_object_info_ref{result.value()->info()});
} }
[[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> reference( [[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> reference_column(
const std::type_index &type_index) const; const std::type_index &type_index) const;
void dump(std::ostream &os) const; void dump(std::ostream &os) const;
@ -169,7 +169,8 @@ private:
private: private:
friend class internal::shadow_schema; friend class internal::shadow_schema;
friend class foreign_node_completer; friend class schema_node;
friend class attribute_definition_generator;
std::string name_; std::string name_;
std::shared_ptr<schema_node> root_; std::shared_ptr<schema_node> root_;
@ -177,6 +178,8 @@ private:
t_node_map nodes_by_name_; t_node_map nodes_by_name_;
t_type_index_node_map nodes_by_type_; t_type_index_node_map nodes_by_type_;
logger::logger log_; logger::logger log_;
std::unordered_map<std::type_index, std::shared_ptr<attribute_definition> > missing_references_;
}; };
} }

View File

@ -18,14 +18,15 @@ public:
template < typename Type > template < typename Type >
static std::shared_ptr<schema_node> make_node(object::schema& tree, const std::string& name) { static std::shared_ptr<schema_node> make_node(object::schema& tree, const std::string& name) {
auto node = std::shared_ptr<schema_node>(new schema_node(tree, name)); auto node = std::shared_ptr<schema_node>(new schema_node(tree, name, typeid(Type)));
primary_key_resolver resolver; primary_key_resolver resolver;
auto pk_info = resolver.resolve<Type>(); auto pk_info = resolver.resolve<Type>();
auto ref_column = determine_reference_column(typeid(Type), name, pk_info, tree);
auto info = std::make_unique<object_info<Type>>( auto info = std::make_unique<object_info<Type>>(
node, node,
std::move(pk_info.pk), std::move(pk_info.pk),
std::make_shared<attribute_definition>(pk_info.pk_column_name, name, pk_info.type, utils::constraints::FOREIGN_KEY), ref_column,
object_definition{attribute_definition_generator::generate<Type>(tree)}, object_definition{attribute_definition_generator::generate<Type>(tree)},
[]{ return std::make_unique<Type>(); } []{ return std::make_unique<Type>(); }
); );
@ -35,17 +36,21 @@ public:
} }
template < typename Type, typename CreatorFunc > template < typename Type, typename CreatorFunc >
static std::shared_ptr<schema_node> make_relation_node(object::schema& tree, const std::string& name, CreatorFunc &&creator) { static utils::result<node_ptr, utils::error> make_relation_node(object::schema& tree, const std::string& name, CreatorFunc &&creator) {
auto node = std::shared_ptr<schema_node>(new schema_node(tree, name)); const auto result = make_and_attach_node(tree, name, typeid(Type));
if (!result) {
return result;
}
auto obj = creator();
auto info = std::make_unique<object_info<Type>>( auto info = std::make_unique<object_info<Type>>(
node, result.value(),
object_definition{attribute_definition_generator::generate<Type>(tree)}, object_definition{attribute_definition_generator::generate(*obj, tree)},
std::move(creator) std::move(creator)
); );
node->info_ = std::move(info); result.value()->info_ = std::move(info);
return node; return result;
} }
static std::shared_ptr<schema_node> make_null_node(schema& tree); static std::shared_ptr<schema_node> make_null_node(schema& tree);
@ -77,10 +82,17 @@ public:
private: private:
explicit schema_node(object::schema& tree); explicit schema_node(object::schema& tree);
schema_node(object::schema& tree, std::string name); schema_node(object::schema& tree, const std::type_index& ti);
schema_node(object::schema& tree, std::string name, const std::type_index& ti);
void unlink(); void unlink();
static utils::result<node_ptr, utils::error> make_and_attach_node(object::schema& tree, const std::string& name, const std::type_index& ti);
static std::shared_ptr<attribute_definition> determine_reference_column(const std::type_index& ti,
const std::string& name,
const primary_key_info& pk_info,
object::schema& tree);
private: private:
friend class schema; friend class schema;
template<typename Type> template<typename Type>
@ -89,6 +101,7 @@ private:
friend class const_schema_node_iterator; friend class const_schema_node_iterator;
object::schema &schema_; object::schema &schema_;
std::type_index type_index_;
std::unique_ptr<basic_object_info> info_; std::unique_ptr<basic_object_info> info_;
std::shared_ptr<schema_node> parent_; std::shared_ptr<schema_node> parent_;

View File

@ -11,9 +11,9 @@ class const_schema_node_iterator {
public: public:
using iterator_category = std::bidirectional_iterator_tag; using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
using value_type = schema_node; using value_type = std::shared_ptr<schema_node>;
using pointer = value_type*; using pointer = schema_node*;
using reference = value_type&; using reference = value_type;
/** /**
* Creates an empty iterator * Creates an empty iterator
@ -28,7 +28,7 @@ public:
* *
* @param node The schema node of the object * @param node The schema node of the object
*/ */
explicit const_schema_node_iterator(std::shared_ptr<value_type> node); explicit const_schema_node_iterator(const value_type& node);
/** /**
* Copy from a given const_object_view_iterator. * Copy from a given const_object_view_iterator.
@ -109,7 +109,7 @@ public:
* *
* @return The iterators underlying node. * @return The iterators underlying node.
*/ */
const reference operator*() const; reference operator*() const;
/** /**
* Returns the pointer to the node. * Returns the pointer to the node.
@ -123,7 +123,7 @@ private:
void decrement(); void decrement();
private: private:
std::shared_ptr<value_type> node_; value_type node_;
}; };
} }

View File

@ -50,7 +50,7 @@ public:
friend bool operator<(const error &lhs, const error &rhs); friend bool operator<(const error &lhs, const error &rhs);
friend bool operator<(const error &lhs, const std::error_code &rhs); friend bool operator<(const error &lhs, const std::error_code &rhs);
// friend std::ostream& operator<<(std::ostream &out, const error &err); friend std::ostream& operator<<(std::ostream &out, const error &err);
[[nodiscard]] std::string message() const; [[nodiscard]] std::string message() const;
[[nodiscard]] std::string category() const; [[nodiscard]] std::string category() const;

View File

@ -77,6 +77,10 @@ std::string attribute_definition::table_name() const {
return table_; return table_;
} }
void attribute_definition::table_name( const std::string& tn ) {
table_= tn;
}
int attribute_definition::index() const { int attribute_definition::index() const {
return index_; return index_;
} }
@ -85,6 +89,10 @@ const utils::field_attributes &attribute_definition::attributes() const {
return attributes_; return attributes_;
} }
utils::field_attributes& attribute_definition::attributes() {
return attributes_;
}
bool attribute_definition::is_nullable() const { bool attribute_definition::is_nullable() const {
return null_option_ == null_option::NULLABLE; return null_option_ == null_option::NULLABLE;
} }

View File

@ -3,7 +3,7 @@
namespace matador::object { namespace matador::object {
attribute_definition_generator::attribute_definition_generator(std::vector<object::attribute_definition> &columns, const schema &repo) attribute_definition_generator::attribute_definition_generator(std::vector<object::attribute_definition> &columns, schema &repo)
: columns_(columns) : columns_(columns)
, repo_(repo) , repo_(repo)
{} {}
@ -19,7 +19,11 @@ void attribute_definition_generator::on_revision(const char *id, uint64_t &rev)
} }
utils::result<std::shared_ptr<attribute_definition>, utils::error> attribute_definition_generator::determine_foreign_ref(const std::type_index &ti) const { utils::result<std::shared_ptr<attribute_definition>, utils::error> attribute_definition_generator::determine_foreign_ref(const std::type_index &ti) const {
return repo_.reference(ti); return repo_.reference_column(ti);
}
void attribute_definition_generator::insert_missing_reference_column(const std::type_index& ti, std::shared_ptr<attribute_definition> ref_column) const {
repo_.missing_references_.insert({ti, ref_column});
} }
void fk_attribute_generator::on_primary_key(const char *, std::string &, const size_t size) void fk_attribute_generator::on_primary_key(const char *, std::string &, const size_t size)

View File

@ -8,34 +8,31 @@ namespace matador::object {
basic_object_info::basic_object_info(std::shared_ptr<schema_node> node, basic_object_info::basic_object_info(std::shared_ptr<schema_node> node,
const std::type_index type_index, const std::type_index type_index,
utils::identifier &&pk, utils::identifier &&pk,
std::shared_ptr<attribute_definition> &&pk_column, const std::shared_ptr<attribute_definition> &pk_column,
object_definition &&definition) object_definition &&definition)
: node_(std::move(node)) : node_(std::move(node))
, type_index_(type_index)
, definition_(std::move(definition)) , definition_(std::move(definition))
, identifier_(std::move(pk)) , identifier_(std::move(pk))
, pk_column_(std::move(pk_column)) { , pk_column_(pk_column) {
} }
basic_object_info::basic_object_info(std::shared_ptr<schema_node> node, basic_object_info::basic_object_info(std::shared_ptr<schema_node> node,
const std::type_index type_index, const std::type_index type_index,
utils::identifier &&pk, utils::identifier &&pk,
std::shared_ptr<attribute_definition> &&pk_column) const std::shared_ptr<attribute_definition> &pk_column)
: node_(std::move(node)) : node_(std::move(node))
, type_index_(type_index)
, identifier_(std::move(pk)) , identifier_(std::move(pk))
, pk_column_(std::move(pk_column)) { , pk_column_(pk_column) {
} }
basic_object_info::basic_object_info(std::shared_ptr<schema_node> node, basic_object_info::basic_object_info(std::shared_ptr<schema_node> node,
const std::type_index type_index, const std::type_index type_index,
object_definition &&definition) object_definition &&definition)
: node_(std::move(node)) : node_(std::move(node))
, type_index_(type_index)
, definition_(std::move(definition)) {} , 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 node_->type_index();
} }
std::string basic_object_info::name() const { std::string basic_object_info::name() const {

View File

@ -53,7 +53,7 @@ bool schema::contains( const std::type_index& index ) const {
return nodes_by_type_.count(index) > 0; return nodes_by_type_.count(index) > 0;
} }
utils::result<std::shared_ptr<attribute_definition>, utils::error> schema::reference(const std::type_index &type_index) const { utils::result<std::shared_ptr<attribute_definition>, utils::error> schema::reference_column(const std::type_index &type_index) const {
const auto result = find_node(type_index); const auto result = find_node(type_index);
if (result) { if (result) {
return utils::ok((*result)->info().reference_column()); return utils::ok((*result)->info().reference_column());
@ -64,8 +64,8 @@ utils::result<std::shared_ptr<attribute_definition>, utils::error> schema::refer
void schema::dump(std::ostream &os) const { void schema::dump(std::ostream &os) const {
for (const auto &node : *this) { for (const auto &node : *this) {
os << "node [" << node.name() << "] (" << node.type_index().name() << ")\n"; os << "node [" << node->name() << "] (" << node->type_index().name() << ")\n";
for (auto it = node.info().endpoint_begin(); it != node.info().endpoint_end(); ++it) { for (auto it = node->info().endpoint_begin(); it != node->info().endpoint_end(); ++it) {
os << " " << /*node.name() << "::" <<*/ it->second->field_name() << " (" << it->second->type_name() << ")"; os << " " << /*node.name() << "::" <<*/ it->second->field_name() << " (" << it->second->type_name() << ")";
if (it->second->foreign_endpoint()) { if (it->second->foreign_endpoint()) {
os << " <---> " << it->second->foreign_endpoint()->node().name() << "::" << it->second->foreign_endpoint()->field_name() << " (" << it->second->foreign_endpoint()->type_name() << ")\n"; os << " <---> " << it->second->foreign_endpoint()->node().name() << "::" << it->second->foreign_endpoint()->field_name() << " (" << it->second->foreign_endpoint()->type_name() << ")\n";

View File

@ -1,14 +1,22 @@
#include <utility> #include <utility>
#include "matador/object/schema.hpp"
#include "matador/object/schema_node.hpp" #include "matador/object/schema_node.hpp"
namespace matador::object { namespace matador::object {
schema_node::schema_node(object::schema &tree) schema_node::schema_node(object::schema &tree)
: schema_(tree) { : schema_(tree)
, type_index_(typeid(detail::null_type)){
} }
schema_node::schema_node(object::schema &tree, std::string name) schema_node::schema_node(object::schema &tree, const std::type_index& ti)
: schema_(tree) : schema_(tree)
, type_index_(ti) {
}
schema_node::schema_node(object::schema &tree, std::string name, const std::type_index& ti)
: schema_(tree)
, type_index_(ti)
, first_child_(std::shared_ptr<schema_node>(new schema_node(tree))) , first_child_(std::shared_ptr<schema_node>(new schema_node(tree)))
, last_child_(std::shared_ptr<schema_node>(new schema_node(tree))) , last_child_(std::shared_ptr<schema_node>(new schema_node(tree)))
, name_(std::move(name)) { , name_(std::move(name)) {
@ -28,7 +36,7 @@ std::string schema_node::name() const {
} }
std::type_index schema_node::type_index() const { std::type_index schema_node::type_index() const {
return info_->type_index(); return type_index_;
} }
const basic_object_info &schema_node::info() const { const basic_object_info &schema_node::info() const {
@ -37,7 +45,7 @@ const basic_object_info &schema_node::info() const {
void schema_node::update_name(const std::string& name) { void schema_node::update_name(const std::string& name) {
name_ = name; name_ = name;
info_->reference_column()->name(name); info_->reference_column()->table_name(name);
} }
const object::schema& schema_node::schema() const { const object::schema& schema_node::schema() const {
@ -50,7 +58,7 @@ bool schema_node::has_children() const {
schema_node::node_ptr schema_node::next() const { schema_node::node_ptr schema_node::next() const {
// if we have a child, child is the next iterator to return // if we have a child, child is the next iterator to return
// (if we don't do iterate over the siblings) // (if we don't iterate over the siblings)
if (first_child_ && first_child_->next_sibling_ != last_child_) { if (first_child_ && first_child_->next_sibling_ != last_child_) {
return first_child_->next_sibling_; return first_child_->next_sibling_;
} }
@ -65,7 +73,7 @@ schema_node::node_ptr schema_node::next() const {
} }
schema_node::node_ptr schema_node::prev() const { schema_node::node_ptr schema_node::prev() const {
// if node has a previous sibling, we set it // if the node has a previous sibling, we set it
// as our next iterator. then we check if there // as our next iterator. then we check if there
// are last children. if so, we set the last-last // are last children. if so, we set the last-last
// child as our iterator // child as our iterator
@ -87,4 +95,30 @@ void schema_node::unlink() {
next_sibling_.reset(); next_sibling_.reset();
previous_sibling_.reset(); previous_sibling_.reset();
} }
utils::result<schema_node::node_ptr, utils::error> schema_node::make_and_attach_node(object::schema& tree, const std::string& name, const std::type_index& ti) {
const auto node = std::shared_ptr<schema_node>(new schema_node(tree, name, ti));
return tree.attach_node(node, "");
}
std::shared_ptr<attribute_definition> schema_node::determine_reference_column(const std::type_index& ti, const std::string& name, const primary_key_info& pk_info, object::schema& tree) {
const auto it = tree.missing_references_.find(ti);
if (it == tree.missing_references_.end()) {
return std::make_shared<attribute_definition>(pk_info.pk_column_name, name, pk_info.type, utils::constraints::FOREIGN_KEY);
}
auto ref_column = it->second;
tree.missing_references_.erase(it);
ref_column->name(pk_info.pk_column_name);
ref_column->table_name(name);
ref_column->type(pk_info.type);
ref_column->attributes() = utils::constraints::FOREIGN_KEY;
if (name.empty()) {
tree.missing_references_.insert({ti, ref_column});
}
return ref_column;
}
} }

View File

@ -4,8 +4,8 @@
namespace matador::object { namespace matador::object {
const_schema_node_iterator::const_schema_node_iterator(std::shared_ptr<value_type> node) const_schema_node_iterator::const_schema_node_iterator(const value_type& node)
: node_(std::move(node)) : node_(node)
{} {}
bool const_schema_node_iterator::operator==(const const_schema_node_iterator &i) const bool const_schema_node_iterator::operator==(const const_schema_node_iterator &i) const
@ -25,7 +25,7 @@ const_schema_node_iterator& const_schema_node_iterator::operator++()
} }
const_schema_node_iterator const_schema_node_iterator::operator++( int ) { const_schema_node_iterator const_schema_node_iterator::operator++( int ) {
const std::shared_ptr<value_type> tmp = node_; const value_type tmp = node_;
increment(); increment();
return const_schema_node_iterator(tmp); return const_schema_node_iterator(tmp);
} }
@ -38,7 +38,7 @@ const_schema_node_iterator& const_schema_node_iterator::operator--()
const_schema_node_iterator const_schema_node_iterator::operator--(int) const_schema_node_iterator const_schema_node_iterator::operator--(int)
{ {
const std::shared_ptr<value_type> tmp = node_; const value_type tmp = node_;
decrement(); decrement();
return const_schema_node_iterator(tmp); return const_schema_node_iterator(tmp);
} }
@ -50,7 +50,7 @@ const_schema_node_iterator::pointer const_schema_node_iterator::operator->() con
const_schema_node_iterator::reference const_schema_node_iterator::operator*() const const_schema_node_iterator::reference const_schema_node_iterator::operator*() const
{ {
return *node_; return node_;
} }
const_schema_node_iterator::pointer const_schema_node_iterator::get() const const_schema_node_iterator::pointer const_schema_node_iterator::get() const

View File

@ -81,9 +81,12 @@ bool operator<(const error &lhs, const std::error_code &rhs) {
return lhs.ec_ < rhs; return lhs.ec_ < rhs;
} }
// std::ostream & operator<<(std::ostream &out, const error &err) { std::ostream & operator<<(std::ostream &out, const error &err) {
// out << err.ec_ << " " << err.ec_.message(); out << err.ec_ << " " << err.ec_.message() << "\n";
// return out; for (const auto & [key, value] : err.error_infos_) {
// } out << " " << key << ": " << value << "\n";
}
return out;
}
} }

View File

@ -18,10 +18,15 @@ session::session(sql::connection_pool<sql::connection> &pool)
, schema_(std::make_unique<object::schema>(dialect_.default_schema_name())){} , schema_(std::make_unique<object::schema>(dialect_.default_schema_name())){}
utils::result<void, utils::error> session::create_schema() const { utils::result<void, utils::error> session::create_schema() const {
std::vector<std::shared_ptr<object::schema_node>> relations_nodes;
auto c = pool_.acquire(); auto c = pool_.acquire();
for (const auto &t : *schema_) { for (const auto &node : *schema_) {
// if (!node->info().has_primary_key()) {
// relations_nodes.push_back(node);
// continue;
// }
auto result = query::query::create() auto result = query::query::create()
.table(t.name(), t.info().definition().columns()) .table(node->name(), node->info().definition().columns())
.execute(*c); .execute(*c);
if ( !result ) { if ( !result ) {
return utils::failure(result.err()); return utils::failure(result.err());

View File

@ -276,7 +276,7 @@ void query_compiler::visit(internal::query_create_table_part &create_table_part)
for (const auto &[column, reference_column]: context.foreign_contexts) { for (const auto &[column, reference_column]: context.foreign_contexts) {
result += ", CONSTRAINT FK_" + create_table_part.table().name; result += ", CONSTRAINT FK_" + create_table_part.table().name;
result += "_" + column; result += "_" + column;
result += " FOREIGN KEY (" + column + ")"; result += " FOREIGN KEY (" + dialect_->prepare_identifier_string(column) + ")";
result += " REFERENCES " + reference_column->table_name() + "(" + reference_column->name() + ")"; result += " REFERENCES " + reference_column->table_name() + "(" + reference_column->name() + ")";
} }