You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

153 rivejä
4.8 KiB

  1. #include <cppcore/misc/indent.h>
  2. #include <cpphibernate/types.h>
  3. #include <cpphibernate/misc/print_container.h>
  4. #include <cpphibernate/driver/mariadb/classes/schema/schema.h>
  5. using namespace ::cpphibernate;
  6. using namespace ::cpphibernate::mariadb;
  7. /* schema_t */
  8. std::ostream& schema_t::print(std::ostream& os) const
  9. {
  10. using namespace ::cppcore;
  11. os << indent << '{'
  12. << incindent
  13. << indent << "\"schema_name\": \"" << name << "\","
  14. << indent << "\"tables\": " << make_print_container(tables, true, [](auto& s, auto& table) {
  15. table->print(s);
  16. })
  17. << decindent
  18. << indent << '}';
  19. return os;
  20. }
  21. void schema_t::init()
  22. {
  23. /* build lookup tables */
  24. for (auto& t : tables)
  25. {
  26. assert(static_cast<bool>(t));
  27. _table_lookup.emplace(t->dataset_id, t.get());
  28. for (auto& f : t->fields)
  29. {
  30. assert(static_cast<bool>(f));
  31. _field_lookup.emplace(f->id, f.get());
  32. }
  33. }
  34. /* update table referencs */
  35. for (auto& t : tables)
  36. {
  37. assert(static_cast<bool>(t));
  38. auto& table = const_cast<table_t&>(*t);
  39. /* get base table */
  40. auto it = _table_lookup.find(table.base_dataset_id);
  41. table.base_table = (it != _table_lookup.end()
  42. ? it->second
  43. : nullptr);
  44. /* dereived tables */
  45. for (auto& id : table.derived_dataset_ids)
  46. {
  47. it = _table_lookup.find(id);
  48. if (it == _table_lookup.end())
  49. throw exception(std::string("unable to find derived table for dataset id ") + std::to_string(id));
  50. table.derived_tables.emplace_back(it->second);
  51. }
  52. /* update fields */
  53. for (auto& f : table.fields)
  54. {
  55. assert(static_cast<bool>(f));
  56. auto& field = const_cast<field_t&>(*f);
  57. /* referenced_table */
  58. it = _table_lookup.find(field.real_value_id);
  59. auto * referenced_table = (it != _table_lookup.end()
  60. ? const_cast<table_t*>(it->second)
  61. : nullptr);
  62. field.referenced_table = referenced_table;
  63. /* primary key field */
  64. if (field.attributes.count(attribute_t::primary_key))
  65. {
  66. if (static_cast<bool>(table.primary_key_field))
  67. throw exception(std::string("Table '") + table.name + "' can not have more then one primary key!");
  68. table.primary_key_field = &field;
  69. }
  70. /* foreign table field */
  71. else if (static_cast<bool>(referenced_table))
  72. {
  73. table.foreign_table_fields.emplace_back(&field);
  74. if (field.value_is_container)
  75. {
  76. referenced_table->is_used_in_container = true;
  77. }
  78. }
  79. /* normal data field */
  80. else
  81. {
  82. table.data_fields.emplace_back(&field);
  83. }
  84. }
  85. if (!static_cast<bool>(table.primary_key_field))
  86. throw exception(std::string("Table '") + table.name + "' does not have a primary key!");
  87. }
  88. /* update foreign fields (one, many, key) */
  89. for (auto& t : tables)
  90. {
  91. assert(static_cast<bool>(t));
  92. auto& table = const_cast<table_t&>(*t);
  93. for (auto& f : table.foreign_table_fields)
  94. {
  95. assert(static_cast<bool>(f));
  96. assert(static_cast<bool>(f->referenced_table));
  97. auto& field = *f;
  98. auto& referenced_table = const_cast<table_t&>(*field.referenced_table);
  99. if (field.value_is_container)
  100. {
  101. table.foreign_table_many_fields.emplace_back(&field);
  102. referenced_table.foreign_key_fields.emplace_back(&field);
  103. }
  104. else
  105. {
  106. table.foreign_table_one_fields.emplace_back(&field);
  107. if (referenced_table.is_used_in_container)
  108. {
  109. referenced_table.foreign_key_fields.push_back(&field);
  110. }
  111. }
  112. }
  113. }
  114. }
  115. const table_t& schema_t::table(size_t dataset_id) const
  116. {
  117. auto it = _table_lookup.find(dataset_id);
  118. if (it == _table_lookup.end())
  119. throw exception(std::string("unable to find table for dataset with id ") + std::to_string(dataset_id));
  120. assert(static_cast<bool>(it->second));
  121. return *it->second;
  122. }
  123. const field_t& schema_t::field(size_t field_id) const
  124. {
  125. auto it = _field_lookup.find(field_id);
  126. if (it == _field_lookup.end())
  127. throw exception(std::string("unable to find field for dataset with id ") + std::to_string(field_id));
  128. assert(static_cast<bool>(it->second));
  129. return *it->second;
  130. }