attaching schema nodes progress
This commit is contained in:
parent
1b2847696d
commit
0d93b9b1ed
|
|
@ -70,9 +70,13 @@ using namespace work::models;
|
|||
// payload.is_polymorphic_type<jobs::IdPayload>();
|
||||
|
||||
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");
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -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::IdListPayload, jobs::Payload>("id_payloads"); })
|
||||
.and_then([&ses] { return ses.attach<jobs::Task>("tasks"); })
|
||||
.and_then([&ses] { return ses.create_schema(); });
|
||||
;
|
||||
// ses.dump_schema(std::cout);
|
||||
|
||||
if (!result) {
|
||||
std::cout << "error: " << result.err().message() << std::endl;
|
||||
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"};
|
||||
// sql::connection c(dns);
|
||||
//
|
||||
|
|
@ -110,7 +120,6 @@ int main() {
|
|||
// return 0;
|
||||
// }
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public:
|
|||
attribute_definition(attribute_definition&&) noexcept = default;
|
||||
attribute_definition& operator=(attribute_definition&&) noexcept = default;
|
||||
|
||||
attribute_definition() = default;
|
||||
template<typename Type>
|
||||
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)
|
||||
|
|
@ -61,8 +62,10 @@ public:
|
|||
void name(const std::string& n);
|
||||
[[nodiscard]] std::string full_name() const;
|
||||
[[nodiscard]] std::string table_name() const;
|
||||
void table_name(const std::string& tn);
|
||||
[[nodiscard]] int index() const;
|
||||
[[nodiscard]] const utils::field_attributes& attributes() const;
|
||||
[[nodiscard]] utils::field_attributes& attributes();
|
||||
[[nodiscard]] bool is_nullable() const;
|
||||
[[nodiscard]] utils::basic_type type() const;
|
||||
[[nodiscard]] std::shared_ptr<attribute_definition> reference_column() const;
|
||||
|
|
@ -141,7 +144,7 @@ private:
|
|||
* @param type
|
||||
* @param attr Length of the column name
|
||||
* @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);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#ifndef 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/data_type_traits.hpp"
|
||||
#include "matador/utils/error.hpp"
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
#include "matador/utils/foreign_attributes.hpp"
|
||||
|
||||
|
||||
#include <memory>
|
||||
#include <typeindex>
|
||||
|
|
@ -54,13 +54,13 @@ private:
|
|||
|
||||
class attribute_definition_generator final {
|
||||
private:
|
||||
attribute_definition_generator(std::vector<attribute_definition> &columns, const schema &repo);
|
||||
attribute_definition_generator(std::vector<attribute_definition> &columns, schema &repo);
|
||||
|
||||
public:
|
||||
~attribute_definition_generator() = default;
|
||||
|
||||
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;
|
||||
attribute_definition_generator gen(columns, repo);
|
||||
|
|
@ -69,6 +69,14 @@ public:
|
|||
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 >
|
||||
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);
|
||||
|
|
@ -91,13 +99,19 @@ public:
|
|||
|
||||
template <class Pointer>
|
||||
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()) {
|
||||
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 {
|
||||
columns_.push_back(fk_column_generator_.generate(id, *x, *result));
|
||||
}
|
||||
columns_.push_back(fk_column_generator_.generate(id, *x, ref_column));
|
||||
}
|
||||
}
|
||||
template<class ContainerType>
|
||||
|
|
@ -109,11 +123,12 @@ public:
|
|||
|
||||
private:
|
||||
[[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:
|
||||
size_t index_ = 0;
|
||||
std::vector<attribute_definition> &columns_;
|
||||
const schema &repo_;
|
||||
schema &repo_;
|
||||
|
||||
fk_attribute_generator fk_column_generator_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,13 +49,12 @@ public:
|
|||
[[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, 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, 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);
|
||||
|
||||
protected:
|
||||
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_;
|
||||
std::optional<utils::identifier> identifier_;
|
||||
std::shared_ptr<attribute_definition> pk_column_;
|
||||
|
|
|
|||
|
|
@ -13,23 +13,23 @@ public:
|
|||
using create_func = std::function<std::unique_ptr<Type>()>;
|
||||
|
||||
object_info(const std::shared_ptr<schema_node>& node,
|
||||
std::shared_ptr<attribute_definition> &&ref_column)
|
||||
: basic_object_info(node, typeid(Type), {}, std::move(ref_column), {})
|
||||
const std::shared_ptr<attribute_definition> &ref_column)
|
||||
: basic_object_info(node, typeid(Type), {}, ref_column, {})
|
||||
, creator_([]{return std::make_unique<Type>(); }){
|
||||
}
|
||||
object_info(const std::shared_ptr<schema_node>& node,
|
||||
utils::identifier &&pk,
|
||||
std::shared_ptr<attribute_definition> &&ref_column,
|
||||
const std::shared_ptr<attribute_definition> &ref_column,
|
||||
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>(); }){
|
||||
}
|
||||
object_info(const std::shared_ptr<schema_node>& node,
|
||||
utils::identifier &&pk,
|
||||
std::shared_ptr<attribute_definition> &&ref_column,
|
||||
const std::shared_ptr<attribute_definition> &ref_column,
|
||||
object_definition &&definition,
|
||||
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)){
|
||||
}
|
||||
object_info(const std::shared_ptr<schema_node>& node,
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
// 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);
|
||||
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] {
|
||||
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) {
|
||||
// Todo: throw internal error
|
||||
return;
|
||||
}
|
||||
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);
|
||||
foreign_endpoint->node_->info_->register_relation_endpoint(nodes_.top()->type_index(), 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 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] {
|
||||
return std::make_unique<relation_value_type>(join_column, "value");
|
||||
});
|
||||
|
||||
const auto result = schema_.attach_node(node);
|
||||
if (!result) {
|
||||
// Todo: throw internal exception
|
||||
}
|
||||
|
||||
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);
|
||||
foreign_endpoint->node_->info_->register_relation_endpoint(nodes_.top()->type_index(), 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);
|
||||
} else {
|
||||
// Relation not not found.
|
||||
// Relation not found.
|
||||
auto creator = [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 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,
|
||||
|
|
@ -226,11 +229,6 @@ void relation_completer<Type>::on_has_many_to_many(const char *id,
|
|||
link_relation_endpoints(local_endpoint, join_endpoint);
|
||||
node->info_->register_relation_endpoint(typeid(typename CollectionType::value_type::value_type),
|
||||
inverse_join_endpoint);
|
||||
result = schema_.attach_node(node);
|
||||
if (!result) {
|
||||
// Todo: throw internal error
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@ public:
|
|||
[[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() ) {
|
||||
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) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
foreign_node_completer::complete<Type>(node);
|
||||
relation_completer<Type>::complete(node);
|
||||
} else if (!has_node(name)) {
|
||||
it->second->update_name(name);
|
||||
nodes_by_name_[name] = it->second;
|
||||
|
|
@ -142,7 +142,7 @@ public:
|
|||
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;
|
||||
|
||||
void dump(std::ostream &os) const;
|
||||
|
|
@ -169,7 +169,8 @@ private:
|
|||
|
||||
private:
|
||||
friend class internal::shadow_schema;
|
||||
friend class foreign_node_completer;
|
||||
friend class schema_node;
|
||||
friend class attribute_definition_generator;
|
||||
|
||||
std::string name_;
|
||||
std::shared_ptr<schema_node> root_;
|
||||
|
|
@ -177,6 +178,8 @@ private:
|
|||
t_node_map nodes_by_name_;
|
||||
t_type_index_node_map nodes_by_type_;
|
||||
logger::logger log_;
|
||||
|
||||
std::unordered_map<std::type_index, std::shared_ptr<attribute_definition> > missing_references_;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,14 +18,15 @@ public:
|
|||
|
||||
template < typename Type >
|
||||
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;
|
||||
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>>(
|
||||
node,
|
||||
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)},
|
||||
[]{ return std::make_unique<Type>(); }
|
||||
);
|
||||
|
|
@ -35,17 +36,21 @@ public:
|
|||
}
|
||||
|
||||
template < typename Type, typename CreatorFunc >
|
||||
static std::shared_ptr<schema_node> make_relation_node(object::schema& tree, const std::string& name, CreatorFunc &&creator) {
|
||||
auto node = std::shared_ptr<schema_node>(new schema_node(tree, name));
|
||||
static utils::result<node_ptr, utils::error> make_relation_node(object::schema& tree, const std::string& name, CreatorFunc &&creator) {
|
||||
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>>(
|
||||
node,
|
||||
object_definition{attribute_definition_generator::generate<Type>(tree)},
|
||||
result.value(),
|
||||
object_definition{attribute_definition_generator::generate(*obj, tree)},
|
||||
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);
|
||||
|
|
@ -77,10 +82,17 @@ public:
|
|||
|
||||
private:
|
||||
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();
|
||||
|
||||
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:
|
||||
friend class schema;
|
||||
template<typename Type>
|
||||
|
|
@ -89,6 +101,7 @@ private:
|
|||
friend class const_schema_node_iterator;
|
||||
|
||||
object::schema &schema_;
|
||||
std::type_index type_index_;
|
||||
std::unique_ptr<basic_object_info> info_;
|
||||
|
||||
std::shared_ptr<schema_node> parent_;
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ class const_schema_node_iterator {
|
|||
public:
|
||||
using iterator_category = std::bidirectional_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = schema_node;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
using value_type = std::shared_ptr<schema_node>;
|
||||
using pointer = schema_node*;
|
||||
using reference = value_type;
|
||||
|
||||
/**
|
||||
* Creates an empty iterator
|
||||
|
|
@ -28,7 +28,7 @@ public:
|
|||
*
|
||||
* @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.
|
||||
|
|
@ -109,7 +109,7 @@ public:
|
|||
*
|
||||
* @return The iterators underlying node.
|
||||
*/
|
||||
const reference operator*() const;
|
||||
reference operator*() const;
|
||||
|
||||
/**
|
||||
* Returns the pointer to the node.
|
||||
|
|
@ -123,7 +123,7 @@ private:
|
|||
void decrement();
|
||||
|
||||
private:
|
||||
std::shared_ptr<value_type> node_;
|
||||
value_type node_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public:
|
|||
friend bool operator<(const error &lhs, const error &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 category() const;
|
||||
|
|
|
|||
|
|
@ -77,6 +77,10 @@ std::string attribute_definition::table_name() const {
|
|||
return table_;
|
||||
}
|
||||
|
||||
void attribute_definition::table_name( const std::string& tn ) {
|
||||
table_= tn;
|
||||
}
|
||||
|
||||
int attribute_definition::index() const {
|
||||
return index_;
|
||||
}
|
||||
|
|
@ -85,6 +89,10 @@ const utils::field_attributes &attribute_definition::attributes() const {
|
|||
return attributes_;
|
||||
}
|
||||
|
||||
utils::field_attributes& attribute_definition::attributes() {
|
||||
return attributes_;
|
||||
}
|
||||
|
||||
bool attribute_definition::is_nullable() const {
|
||||
return null_option_ == null_option::NULLABLE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
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)
|
||||
, 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 {
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -8,34 +8,31 @@ namespace matador::object {
|
|||
basic_object_info::basic_object_info(std::shared_ptr<schema_node> node,
|
||||
const std::type_index type_index,
|
||||
utils::identifier &&pk,
|
||||
std::shared_ptr<attribute_definition> &&pk_column,
|
||||
const std::shared_ptr<attribute_definition> &pk_column,
|
||||
object_definition &&definition)
|
||||
: node_(std::move(node))
|
||||
, type_index_(type_index)
|
||||
, definition_(std::move(definition))
|
||||
, 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,
|
||||
const std::type_index type_index,
|
||||
utils::identifier &&pk,
|
||||
std::shared_ptr<attribute_definition> &&pk_column)
|
||||
const std::shared_ptr<attribute_definition> &pk_column)
|
||||
: node_(std::move(node))
|
||||
, type_index_(type_index)
|
||||
, 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,
|
||||
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_;
|
||||
return node_->type_index();
|
||||
}
|
||||
|
||||
std::string basic_object_info::name() const {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ bool schema::contains( const std::type_index& index ) const {
|
|||
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);
|
||||
if (result) {
|
||||
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 {
|
||||
for (const auto &node : *this) {
|
||||
os << "node [" << node.name() << "] (" << node.type_index().name() << ")\n";
|
||||
for (auto it = node.info().endpoint_begin(); it != node.info().endpoint_end(); ++it) {
|
||||
os << "node [" << node->name() << "] (" << node->type_index().name() << ")\n";
|
||||
for (auto it = node->info().endpoint_begin(); it != node->info().endpoint_end(); ++it) {
|
||||
os << " " << /*node.name() << "::" <<*/ it->second->field_name() << " (" << it->second->type_name() << ")";
|
||||
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";
|
||||
|
|
|
|||
|
|
@ -1,14 +1,22 @@
|
|||
#include <utility>
|
||||
|
||||
#include "matador/object/schema.hpp"
|
||||
#include "matador/object/schema_node.hpp"
|
||||
|
||||
namespace matador::object {
|
||||
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)
|
||||
, 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)))
|
||||
, last_child_(std::shared_ptr<schema_node>(new schema_node(tree)))
|
||||
, name_(std::move(name)) {
|
||||
|
|
@ -28,7 +36,7 @@ std::string schema_node::name() const {
|
|||
}
|
||||
|
||||
std::type_index schema_node::type_index() const {
|
||||
return info_->type_index();
|
||||
return type_index_;
|
||||
}
|
||||
|
||||
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) {
|
||||
name_ = name;
|
||||
info_->reference_column()->name(name);
|
||||
info_->reference_column()->table_name(name);
|
||||
}
|
||||
|
||||
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 {
|
||||
// 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_) {
|
||||
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 {
|
||||
// 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
|
||||
// are last children. if so, we set the last-last
|
||||
// child as our iterator
|
||||
|
|
@ -87,4 +95,30 @@ void schema_node::unlink() {
|
|||
next_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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
namespace matador::object {
|
||||
|
||||
const_schema_node_iterator::const_schema_node_iterator(std::shared_ptr<value_type> node)
|
||||
: node_(std::move(node))
|
||||
const_schema_node_iterator::const_schema_node_iterator(const value_type& node)
|
||||
: node_(node)
|
||||
{}
|
||||
|
||||
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 std::shared_ptr<value_type> tmp = node_;
|
||||
const value_type tmp = node_;
|
||||
increment();
|
||||
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 std::shared_ptr<value_type> tmp = node_;
|
||||
const value_type tmp = node_;
|
||||
decrement();
|
||||
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
|
||||
{
|
||||
return *node_;
|
||||
return node_;
|
||||
}
|
||||
|
||||
const_schema_node_iterator::pointer const_schema_node_iterator::get() const
|
||||
|
|
|
|||
|
|
@ -81,9 +81,12 @@ bool operator<(const error &lhs, const std::error_code &rhs) {
|
|||
return lhs.ec_ < rhs;
|
||||
}
|
||||
|
||||
// std::ostream & operator<<(std::ostream &out, const error &err) {
|
||||
// out << err.ec_ << " " << err.ec_.message();
|
||||
// return out;
|
||||
// }
|
||||
std::ostream & operator<<(std::ostream &out, const error &err) {
|
||||
out << err.ec_ << " " << err.ec_.message() << "\n";
|
||||
for (const auto & [key, value] : err.error_infos_) {
|
||||
out << " " << key << ": " << value << "\n";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,10 +18,15 @@ session::session(sql::connection_pool<sql::connection> &pool)
|
|||
, schema_(std::make_unique<object::schema>(dialect_.default_schema_name())){}
|
||||
|
||||
utils::result<void, utils::error> session::create_schema() const {
|
||||
std::vector<std::shared_ptr<object::schema_node>> relations_nodes;
|
||||
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()
|
||||
.table(t.name(), t.info().definition().columns())
|
||||
.table(node->name(), node->info().definition().columns())
|
||||
.execute(*c);
|
||||
if ( !result ) {
|
||||
return utils::failure(result.err());
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
result += ", CONSTRAINT FK_" + create_table_part.table().name;
|
||||
result += "_" + column;
|
||||
result += " FOREIGN KEY (" + column + ")";
|
||||
result += " FOREIGN KEY (" + dialect_->prepare_identifier_string(column) + ")";
|
||||
result += " REFERENCES " + reference_column->table_name() + "(" + reference_column->name() + ")";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue