reference column progress

This commit is contained in:
2025-02-09 20:49:00 +01:00
parent a4d6f68ee2
commit 504e111491
11 changed files with 269 additions and 188 deletions
+56 -83
View File
@@ -4,173 +4,146 @@
#include <utility>
namespace matador::object {
attribute_definition::attribute_definition(const char *name)
: name_(name)
, attributes_(utils::null_attributes)
{}
, attributes_(utils::null_attributes) {
}
attribute_definition::attribute_definition(std::string name)
: name_(std::move(name))
, attributes_(utils::null_attributes)
{}
, attributes_(utils::null_attributes) {
}
attribute_definition::attribute_definition(std::string name, const utils::basic_type type, const utils::field_attributes& attr, const null_option null_opt, const size_t index)
attribute_definition::attribute_definition(std::string name, const utils::basic_type type,
const utils::field_attributes &attr, const null_option null_opt,
const size_t index)
: name_(std::move(name))
, index_(index)
, attributes_(attr)
, null_option_(null_opt)
, value_(type, attr.size())
{}
, index_(index)
, attributes_(attr)
, null_option_(null_opt)
, value_(type, attr.size()) {
}
attribute_definition::attribute_definition(std::string name,
const utils::basic_type type,
const size_t index,
std::string ref_table,
std::string ref_column,
const utils::field_attributes& attr, const null_option null_opt)
const utils::basic_type type,
const size_t index,
const std::shared_ptr<attribute_definition> &ref_column,
const utils::field_attributes &attr, const null_option null_opt)
: name_(std::move(name))
, index_(index)
, attributes_(attr)
, null_option_(null_opt)
, value_(type, attr.size())
, ref_table_(std::move(ref_table))
, ref_column_(std::move(ref_column))
{}
, index_(index)
, attributes_(attr)
, null_option_(null_opt)
, value_(type, attr.size())
, reference_column_(ref_column) {
}
const std::string &attribute_definition::name() const
{
const std::string &attribute_definition::name() const {
return name_;
}
std::string attribute_definition::full_name() const
{
std::string attribute_definition::full_name() const {
return table_ + "." + name_;
}
std::string attribute_definition::table_name() const
{
std::string attribute_definition::table_name() const {
return table_;
}
int attribute_definition::index() const
{
int attribute_definition::index() const {
return index_;
}
const utils::field_attributes &attribute_definition::attributes() const
{
const utils::field_attributes &attribute_definition::attributes() const {
return attributes_;
}
bool attribute_definition::is_nullable() const
{
bool attribute_definition::is_nullable() const {
return null_option_ == null_option::NULLABLE;
}
utils::basic_type attribute_definition::type() const
{
utils::basic_type attribute_definition::type() const {
return value_.type();
}
const std::string &attribute_definition::ref_table() const
{
return ref_table_;
std::shared_ptr<attribute_definition> attribute_definition::reference_column() const {
return reference_column_;
}
const std::string &attribute_definition::ref_column() const
{
return ref_column_;
bool attribute_definition::is_foreign_reference() const {
return reference_column_ != nullptr;
}
bool attribute_definition::is_foreign_reference() const
{
return !ref_column_.empty() && !ref_table_.empty();
}
bool attribute_definition::is_integer() const
{
bool attribute_definition::is_integer() const {
return value_.is_integer();
}
bool attribute_definition::is_floating_point() const
{
bool attribute_definition::is_floating_point() const {
return value_.is_floating_point();
}
bool attribute_definition::is_bool() const
{
bool attribute_definition::is_bool() const {
return value_.is_bool();
}
bool attribute_definition::is_string() const
{
bool attribute_definition::is_string() const {
return value_.is_string();
}
bool attribute_definition::is_varchar() const
{
bool attribute_definition::is_varchar() const {
return value_.is_varchar();
}
bool attribute_definition::is_date() const
{
bool attribute_definition::is_date() const {
return value_.is_date();
}
bool attribute_definition::is_time() const
{
bool attribute_definition::is_time() const {
return value_.is_time();
}
bool attribute_definition::is_blob() const
{
bool attribute_definition::is_blob() const {
return value_.is_blob();
}
bool attribute_definition::is_null() const
{
bool attribute_definition::is_null() const {
return value_.is_null();
}
void attribute_definition::type(utils::basic_type /*type*/)
{
void attribute_definition::type(utils::basic_type /*type*/) {
// type_ = type;
// utils::initialize_by_utils::basic_type(type, value_);
// utils::initialize_by_utils::basic_type(type, value_);
}
std::string attribute_definition::str() const
{
std::string attribute_definition::str() const {
return value_.str();
}
std::ostream& operator<<(std::ostream &out, const attribute_definition &col)
{
std::ostream &operator<<(std::ostream &out, const attribute_definition &col) {
out << col.str();
return out;
}
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr, null_option null_opt)
{
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr,
null_option null_opt) {
return {name, type, attr, null_opt};
}
template<>
attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt)
{
attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr,
null_option null_opt) {
return make_column(name, utils::data_type_traits<std::string>::type(attr.size()), attr, null_opt);
}
template<>
attribute_definition make_pk_column<std::string>(const std::string &name, size_t size)
{
attribute_definition make_pk_column<std::string>(const std::string &name, size_t size) {
return make_column<std::string>(name, {size, utils::constraints::FOREIGN_KEY});
}
template<>
[[maybe_unused]] attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table,
const std::string &ref_column)
{
return {name, utils::data_type_traits<std::string>::type(size), 0, ref_table, ref_column, {size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL};
[[maybe_unused]] attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::shared_ptr<attribute_definition> &ref_column) {
return {
name, utils::data_type_traits<std::string>::type(size), 0, ref_column,
{size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL
};
}
}
@@ -18,7 +18,7 @@ void attribute_definition_generator::on_revision(const char *id, uint64_t &rev)
on_attribute(id, rev);
}
std::pair<std::string, std::string> attribute_definition_generator::determine_foreign_ref(const std::type_index &ti)
std::shared_ptr<attribute_definition> attribute_definition_generator::determine_foreign_ref(const std::type_index &ti)
{
return repo_.reference(ti).value();
}
+14 -6
View File
@@ -5,22 +5,30 @@
#include <algorithm>
namespace matador::object {
basic_object_info::basic_object_info(schema_node &node, const std::type_index type_index, object_definition &&definition)
basic_object_info::basic_object_info(schema_node &node,
const std::type_index type_index,
object_definition &&definition,
std::shared_ptr<attribute_definition> &&reference_column)
: node_(node)
, type_index_(type_index)
, definition_(std::move(definition)) {}
, definition_(std::move(definition))
, reference_column_(std::move(reference_column)) {
}
std::type_index basic_object_info::type_index() const {
return type_index_;
return type_index_;
}
std::string basic_object_info::name() const {
return node_.name();
return node_.name();
}
const object_definition& basic_object_info::definition() const {
const object_definition &basic_object_info::definition() const {
return definition_;
}
std::shared_ptr<attribute_definition> basic_object_info::reference_column() const {
return reference_column_;
}
} // namespace matador::object
+28 -19
View File
@@ -1,14 +1,13 @@
#include "matador/object/schema.hpp"
namespace matador::object {
utils::error make_error(const error_code ec, const std::string& msg) {
utils::error make_error(const error_code ec, const std::string &msg) {
return utils::error(ec, msg);
}
schema::schema( const std::string& name)
: name_(name)
, root_(std::shared_ptr<schema_node>(new schema_node(*this))) {
schema::schema(const std::string &name)
: name_(name)
, root_(std::shared_ptr<schema_node>(new schema_node(*this))) {
root_->first_child_ = std::shared_ptr<schema_node>(new schema_node(*this));
root_->last_child_ = std::shared_ptr<schema_node>(new schema_node(*this));
root_->first_child_->next_sibling_ = root_->last_child_;
@@ -35,16 +34,18 @@ std::string schema::name() const {
return name_;
}
utils::result<std::pair<std::string, std::string>, utils::error> schema::reference( const std::type_index& type_index ) const {
const auto result = find_node(type_index);
if (!result) {
return utils::failure(result.err());
}
if (!result->get()->basic_info().definition().has_primary_key()) {
return utils::failure(make_error( error_code::Failure, "Primary key not found" ));
}
utils::result<std::shared_ptr<attribute_definition>, utils::error> schema::reference(const std::type_index &type_index) const {
const auto result = find_node(type_index);
if (!result) {
return utils::failure(result.err());
}
return utils::ok(std::make_pair(result->get()->name(), result->get()->basic_info().definition().primary_key()->name()));
const auto &node = *result;
if (!node->basic_info().definition().has_primary_key()) {
return utils::failure(make_error(error_code::Failure, "Primary key not found"));
}
return utils::ok(std::make_pair(node->name(), node->basic_info().definition().primary_key()->name()));
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
@@ -72,8 +73,8 @@ utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(co
return utils::ok(node);
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node( const std::shared_ptr<schema_node>& node,
const std::type_index& type_index ) {
utils::result<std::shared_ptr<schema_node>, utils::error> schema::attach_node(const std::shared_ptr<schema_node> &node,
const std::type_index &type_index) {
if (has_node(node->type_index(), node->name())) {
return utils::failure(make_error(error_code::NodeAlreadyExists, "Node '" + node->name() + "' already exists."));
}
@@ -100,10 +101,11 @@ utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node(cons
return utils::ok(i->second);
}
utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node( const std::type_index& type_index ) const {
utils::result<std::shared_ptr<schema_node>, utils::error> schema::find_node(const std::type_index &type_index) const {
const auto i = type_index_node_map_.find(type_index);
if (i == type_index_node_map_.end()) {
return utils::failure(make_error(error_code::NodeNotFound, "Couldn't find node by type '" + std::string(type_index.name()) + "'"));
return utils::failure(make_error(error_code::NodeNotFound,
"Couldn't find node by type '" + std::string(type_index.name()) + "'"));
}
return utils::ok(i->second);
}
@@ -124,8 +126,15 @@ void schema::push_back_child(const node_ptr &parent, const node_ptr &child) {
// child->depth = depth + 1;
}
bool schema::has_node(const std::string &name) const {
return node_map_.count(name) > 0;
}
bool schema::has_node(const std::type_index &index) const {
return type_index_node_map_.count(index) > 0;
}
bool schema::has_node(const std::type_index &index, const std::string &name) const {
return node_map_.count(name) > 0 || type_index_node_map_.count(index) > 0;
}
} // namespace matador::object
+45 -32
View File
@@ -3,11 +3,25 @@
#include "matador/object/schema_node.hpp"
namespace matador::object {
schema_node::schema_node(object::schema &tree)
schema_node::schema_node(schema &tree)
: schema_(tree)
, info_(std::make_unique<null_info>(*this, object_definition{}))
{}
, info_(std::make_unique<null_info>(*this, object_definition{})) {
}
schema_node::schema_node(schema &tree, std::string name, std::unique_ptr<basic_object_info> &&info)
: schema_(tree)
, info_(std::move(info))
// , info_(std::make_unique<object_info<Type>>(*this, object_definition(attribute_definition_generator::generate<Type>(schema_))))
, 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)) {
first_child_->next_sibling_ = last_child_;
last_child_->previous_sibling_ = first_child_;
}
std::shared_ptr<schema_node> schema_node::make_node(schema &tree, const std::string &name, std::unique_ptr<basic_object_info> &&info) {
return std::shared_ptr<schema_node>(new schema_node(tree, name, std::move(info)));
}
std::string schema_node::name() const {
return name_;
@@ -17,41 +31,40 @@ std::type_index schema_node::type_index() const {
return info_->type_index();
}
const basic_object_info& schema_node::basic_info() const {
const basic_object_info &schema_node::basic_info() const {
return *info_;
}
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 (first_child_ && first_child_->next_sibling_ != last_child_) {
return first_child_->next_sibling_;
}
// if there is no child, we check for sibling
// if there is a sibling, this is our next iterator to return
// if not, we go back to the parent
auto *node = this;
while (node->parent_ && node->next_sibling_ == node->parent_->last_child_) {
node = node->parent_.get();
}
return node->parent_ ? node->next_sibling_ : node->last_child_;
// if we have a child, child is the next iterator to return
// (if we don't do iterate over the siblings)
if (first_child_ && first_child_->next_sibling_ != last_child_) {
return first_child_->next_sibling_;
}
// if there is no child, we check for sibling
// if there is a sibling, this is our next iterator to return
// if not, we go back to the parent
auto *node = this;
while (node->parent_ && node->next_sibling_ == node->parent_->last_child_) {
node = node->parent_.get();
}
return node->parent_ ? node->next_sibling_ : node->last_child_;
}
schema_node::node_ptr schema_node::prev() const {
// if 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
if (previous_sibling_ && previous_sibling_->previous_sibling_) {
auto node = previous_sibling_;
while (node->last_child_ && node->first_child_->next_sibling_ != node->last_child_) {
node = node->last_child_->previous_sibling_;
}
return node;
// if 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
if (previous_sibling_ && previous_sibling_->previous_sibling_) {
auto node = previous_sibling_;
while (node->last_child_ && node->first_child_->next_sibling_ != node->last_child_) {
node = node->last_child_->previous_sibling_;
}
// if there is no previous sibling, our next iterator
// is the parent of the node
return parent_->parent_ ? parent_ : parent_->first_child_->next_sibling_;
return node;
}
// if there is no previous sibling, our next iterator
// is the parent of the node
return parent_->parent_ ? parent_ : parent_->first_child_->next_sibling_;
}
}