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.
 
 
 

126 lines
3.9 KiB

  1. #include <cpphibernate/driver/mariadb/classes/fields/field.h>
  2. #include <cpphibernate/driver/mariadb/classes/tables/table.h>
  3. #include <cpphibernate/driver/mariadb/context/create_update_context.inl>
  4. using namespace ::cpphibernate;
  5. using namespace ::cpphibernate::mariadb;
  6. static std::string build_foreign_one_delete_query(const field_t& field, bool key_known);
  7. void field_t::foreign_one_delete(
  8. const create_update_context& context,
  9. const std::string& primary_key,
  10. const value_t& foreign_key) const
  11. {
  12. /* get statement */
  13. auto& statement = foreign_key.has_value()
  14. ? get_statement_foreign_one_delete_key_known()
  15. : get_statement_foreign_one_delete_key_unknown();
  16. /* update statement values */
  17. statement.set(0, primary_key);
  18. if (foreign_key.has_value())
  19. statement.set(1, *foreign_key);
  20. /* execute query */
  21. auto& connection = context.connection;
  22. cpphibernate_log_debug("execute DELETE old foreign one query: " << std::endl << statement.query(connection) << std::endl);
  23. connection.execute(statement);
  24. /* cleanup tables */
  25. assert(referenced_table);
  26. table_t::table_set processed;
  27. referenced_table->cleanup(context, processed, true, true);
  28. }
  29. ::cppmariadb::statement& field_t::get_statement_foreign_one_delete_key_known() const
  30. {
  31. if (!_statement_foreign_one_delete_key_known)
  32. {
  33. auto query = build_foreign_one_delete_query(*this, true);
  34. _statement_foreign_one_delete_key_known.reset(new ::cppmariadb::statement(std::move(query)));
  35. }
  36. return *_statement_foreign_one_delete_key_known;
  37. }
  38. cppmariadb::statement& field_t::get_statement_foreign_one_delete_key_unknown() const
  39. {
  40. if (!_statement_foreign_one_delete_key_unknown)
  41. {
  42. auto query = build_foreign_one_delete_query(*this, false);
  43. _statement_foreign_one_delete_key_unknown.reset(new ::cppmariadb::statement(std::move(query)));
  44. }
  45. return *_statement_foreign_one_delete_key_unknown;
  46. }
  47. std::string build_foreign_one_delete_query(const field_t& field, bool key_known)
  48. {
  49. assert(field.table.primary_key_field);
  50. assert(field.referenced_table);
  51. assert(field.referenced_table->primary_key_field);
  52. if (key_known)
  53. {
  54. auto& ref_table = *field.referenced_table;
  55. auto& key_info = *field.table.primary_key_field;
  56. auto& ref_key_info = *ref_table.primary_key_field;
  57. std::ostringstream os;
  58. os << "WHERE `"
  59. << ref_key_info.name
  60. << "` IN (SELECT `"
  61. << ref_key_info.table.name
  62. << "_id_"
  63. << field.name
  64. << "` FROM `"
  65. << key_info.table.name
  66. << "` WHERE `"
  67. << key_info.name
  68. << "`="
  69. << key_info.convert_to_open
  70. << "?\?"
  71. << key_info.convert_to_close
  72. << " AND `"
  73. << ref_key_info.table.name
  74. << "_id_"
  75. << field.name
  76. << "`!="
  77. << ref_key_info.convert_to_open
  78. << "?\?"
  79. << ref_key_info.convert_to_close
  80. << ")";
  81. auto where = os.str();
  82. auto query = ref_table.build_delete_query(&where);
  83. return query;
  84. }
  85. else
  86. {
  87. auto& ref_table = *field.referenced_table;
  88. auto& key_info = *field.table.primary_key_field;
  89. auto& ref_key_info = *ref_table.primary_key_field;
  90. std::ostringstream os;
  91. os << "WHERE `"
  92. << ref_key_info.name
  93. << "` IN (SELECT `"
  94. << ref_key_info.table.name
  95. << "_id_"
  96. << field.name
  97. << "` FROM `"
  98. << key_info.table.name
  99. << "` WHERE `"
  100. << key_info.name
  101. << "`="
  102. << key_info.convert_to_open
  103. << "?\?"
  104. << key_info.convert_to_close
  105. << ")";
  106. auto where = os.str();
  107. auto query = ref_table.build_delete_query(&where);
  108. return query;
  109. }
  110. }