Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

114 linhas
5.2 KiB

  1. #include <cpphibernate/misc/print_container.h>
  2. #include <cpphibernate/driver/mariadb/classes/tables/table.h>
  3. #include <cppcore/misc/indent.h>
  4. #include <cpphibernate/types.inl>
  5. #include <cpphibernate/driver/mariadb/context/data_context.inl>
  6. using namespace ::cpphibernate;
  7. using namespace ::cpphibernate::mariadb;
  8. /* table_t */
  9. table_t::~table_t()
  10. { }
  11. std::ostream& table_t::print(std::ostream& os) const
  12. {
  13. using namespace ::cppcore;
  14. os << indent << '{'
  15. << incindent
  16. << indent << "\"id\": " << id << ","
  17. << indent << "\"dataset_id\": " << dataset_id << ","
  18. << indent << "\"base_dataset_id\": " << base_dataset_id << ","
  19. << indent << "\"derived_dataset_ids\": " << make_print_container(derived_dataset_ids, false) << ","
  20. << indent << "\"name\": \"" << name << "\","
  21. << indent << "\"base_table\": " << (base_table ? std::string("\"") + base_table->name + "\"" : "null") << ","
  22. << indent << "\"derived_tables\":" << make_print_container(derived_tables, true, [](auto& s, auto& ptr){
  23. s << indent << '"' << ptr->name << '"';
  24. }) << ","
  25. << indent << "\"primary_key_field\": " << (primary_key_field ? std::string("\"") + primary_key_field->name + "\"" : "null") << ","
  26. << indent << "\"foreign_key_fields\": " << make_print_container(foreign_key_fields, true, [](auto& s, auto& ptr){
  27. s << indent << '"' << ptr->name << '.' << ptr->name << '"';
  28. }) << ","
  29. << indent << "\"foreign_table_fields\": " << make_print_container(foreign_table_fields, true, [](auto& s, auto& ptr){
  30. s << indent << '"' << ptr->name << '"';
  31. }) << ","
  32. << indent << "\"foreign_table_one_fields\": " << make_print_container(foreign_table_one_fields, true, [](auto& s, auto& ptr){
  33. s << indent << '"' << ptr->name << '"';
  34. }) << ","
  35. << indent << "\"foreign_table_many_fields\": " << make_print_container(foreign_table_many_fields, true, [](auto& s, auto& ptr){
  36. s << indent << '"' << ptr->name << '"';
  37. }) << ","
  38. << indent << "\"data_fields\": " << make_print_container(data_fields, true, [](auto& s, auto& ptr){
  39. s << indent << '"' << ptr->name << '"';
  40. }) << ","
  41. << indent << "\"fields\":" << make_print_container(fields, true, [](auto& s, auto& field) {
  42. field->print(s);
  43. })
  44. << decindent
  45. << indent << '}';
  46. return os;
  47. }
  48. std::string table_t::get_primary_key(const data_context& context) const
  49. {
  50. assert(primary_key_field);
  51. if ( primary_key_field->is_default(context)
  52. && base_table)
  53. {
  54. auto key = get_key_from_base(context);
  55. primary_key_field->set(context, key);
  56. return key;
  57. }
  58. else
  59. {
  60. return *primary_key_field->get(context);
  61. }
  62. }
  63. std::string table_t::get_key_from_base(const data_context& context) const
  64. {
  65. if (!base_table)
  66. {
  67. throw exception(std::string("table has no base table: ") + name);
  68. }
  69. auto& statement = get_statement_key_from_base();
  70. auto base_key = base_table->get_primary_key(context);
  71. statement.set(0, base_key);
  72. auto result = context.connection.execute_stored(statement);
  73. if (!result)
  74. throw exception("unable to fetch key from database: unable to execute query!");
  75. auto row = result->next();
  76. if (!row)
  77. throw exception("unable to fetch key from database: result set is empty!");
  78. return row->at(0).get<std::string>();
  79. }
  80. ::cppmariadb::statement& table_t::get_statement_key_from_base() const
  81. {
  82. if (!_statement_key_from_base)
  83. {
  84. if (!base_table)
  85. throw exception(std::string("table has no base table: ") + name);
  86. assert(primary_key_field);
  87. assert(base_table);
  88. assert(base_table->primary_key_field);
  89. auto& key_info = *primary_key_field;
  90. auto& base_key = *base_table->primary_key_field;
  91. std::ostringstream os;
  92. os << "SELECT `"
  93. << key_info.name
  94. << "` FROM `"
  95. << key_info.table.name
  96. << "` WHERE `"
  97. << base_key.table.name
  98. << "_id`=?\?";
  99. _statement_key_from_base.reset(new ::cppmariadb::statement(os.str()));
  100. }
  101. return *_statement_key_from_base;
  102. }