|
- #include <cppcore/misc/indent.h>
-
- #include <cpphibernate/types.h>
- #include <cpphibernate/misc/print_container.h>
- #include <cpphibernate/driver/mariadb/classes/schema/schema.h>
-
- using namespace ::cpphibernate;
- using namespace ::cpphibernate::mariadb;
-
- /* schema_t */
-
- std::ostream& schema_t::print(std::ostream& os) const
- {
- using namespace ::cppcore;
-
- os << indent << '{'
- << incindent
- << indent << "\"schema_name\": \"" << name << "\","
- << indent << "\"tables\": " << make_print_container(tables, true, [](auto& s, auto& table) {
- table->print(s);
- })
- << decindent
- << indent << '}';
-
- return os;
- }
-
- void schema_t::init()
- {
- /* build lookup tables */
- for (auto& t : tables)
- {
- assert(static_cast<bool>(t));
- _table_lookup.emplace(t->dataset_id, t.get());
-
- for (auto& f : t->fields)
- {
- assert(static_cast<bool>(f));
- _field_lookup.emplace(f->id, f.get());
- }
- }
-
- /* update table referencs */
- for (auto& t : tables)
- {
- assert(static_cast<bool>(t));
- auto& table = const_cast<table_t&>(*t);
-
- /* get base table */
- auto it = _table_lookup.find(table.base_dataset_id);
- table.base_table = (it != _table_lookup.end()
- ? it->second
- : nullptr);
-
- /* dereived tables */
- for (auto& id : table.derived_dataset_ids)
- {
- it = _table_lookup.find(id);
- if (it == _table_lookup.end())
- throw exception(std::string("unable to find derived table for dataset id ") + std::to_string(id));
- table.derived_tables.emplace_back(it->second);
- }
-
- /* update fields */
- for (auto& f : table.fields)
- {
- assert(static_cast<bool>(f));
- auto& field = const_cast<field_t&>(*f);
-
- /* referenced_table */
- it = _table_lookup.find(field.real_value_id);
- auto * referenced_table = (it != _table_lookup.end()
- ? const_cast<table_t*>(it->second)
- : nullptr);
- field.referenced_table = referenced_table;
-
- /* primary key field */
- if (field.attributes.count(attribute_t::primary_key))
- {
- if (static_cast<bool>(table.primary_key_field))
- throw exception(std::string("Table '") + table.name + "' can not have more then one primary key!");
- table.primary_key_field = &field;
- }
-
- /* foreign table field */
- else if (static_cast<bool>(referenced_table))
- {
- table.foreign_table_fields.emplace_back(&field);
- if (field.value_is_container)
- {
- referenced_table->is_used_in_container = true;
- }
- }
-
- /* normal data field */
- else
- {
- table.data_fields.emplace_back(&field);
- }
- }
- if (!static_cast<bool>(table.primary_key_field))
- throw exception(std::string("Table '") + table.name + "' does not have a primary key!");
- }
-
- /* update foreign fields (one, many, key) */
- for (auto& t : tables)
- {
- assert(static_cast<bool>(t));
- auto& table = const_cast<table_t&>(*t);
-
- for (auto& f : table.foreign_table_fields)
- {
- assert(static_cast<bool>(f));
- assert(static_cast<bool>(f->referenced_table));
-
- auto& field = *f;
- auto& referenced_table = const_cast<table_t&>(*field.referenced_table);
-
- if (field.value_is_container)
- {
- table.foreign_table_many_fields.emplace_back(&field);
- referenced_table.foreign_key_fields.emplace_back(&field);
- }
- else
- {
- table.foreign_table_one_fields.emplace_back(&field);
- if (referenced_table.is_used_in_container)
- {
- referenced_table.foreign_key_fields.push_back(&field);
- }
- }
- }
- }
- }
-
- const table_t& schema_t::table(size_t dataset_id) const
- {
- auto it = _table_lookup.find(dataset_id);
- if (it == _table_lookup.end())
- throw exception(std::string("unable to find table for dataset with id ") + std::to_string(dataset_id));
- assert(static_cast<bool>(it->second));
- return *it->second;
- }
-
- const field_t& schema_t::field(size_t field_id) const
- {
- auto it = _field_lookup.find(field_id);
- if (it == _field_lookup.end())
- throw exception(std::string("unable to find field for dataset with id ") + std::to_string(field_id));
- assert(static_cast<bool>(it->second));
- return *it->second;
- }
|