#include #include #include using namespace ::cpphibernate; using namespace ::cpphibernate::mariadb; static std::string build_foreign_one_delete_query(const field_t& field, bool key_known); void field_t::foreign_one_delete( const create_update_context& context, const std::string& primary_key, const value_t& foreign_key) const { /* get statement */ auto& statement = foreign_key.has_value() ? get_statement_foreign_one_delete_key_known() : get_statement_foreign_one_delete_key_unknown(); /* update statement values */ statement.set(0, primary_key); if (foreign_key.has_value()) statement.set(1, *foreign_key); /* execute query */ auto& connection = context.connection; cpphibernate_log_debug("execute DELETE old foreign one query: " << std::endl << statement.query(connection) << std::endl); connection.execute(statement); /* cleanup tables */ assert(referenced_table); table_t::table_set processed; referenced_table->cleanup(context, processed, true, true); } ::cppmariadb::statement& field_t::get_statement_foreign_one_delete_key_known() const { if (!_statement_foreign_one_delete_key_known) { auto query = build_foreign_one_delete_query(*this, true); _statement_foreign_one_delete_key_known.reset(new ::cppmariadb::statement(std::move(query))); } return *_statement_foreign_one_delete_key_known; } cppmariadb::statement& field_t::get_statement_foreign_one_delete_key_unknown() const { if (!_statement_foreign_one_delete_key_unknown) { auto query = build_foreign_one_delete_query(*this, false); _statement_foreign_one_delete_key_unknown.reset(new ::cppmariadb::statement(std::move(query))); } return *_statement_foreign_one_delete_key_unknown; } std::string build_foreign_one_delete_query(const field_t& field, bool key_known) { assert(field.table.primary_key_field); assert(field.referenced_table); assert(field.referenced_table->primary_key_field); if (key_known) { auto& ref_table = *field.referenced_table; auto& key_info = *field.table.primary_key_field; auto& ref_key_info = *ref_table.primary_key_field; std::ostringstream os; os << "WHERE `" << ref_key_info.name << "` IN (SELECT `" << ref_key_info.table.name << "_id_" << field.name << "` FROM `" << key_info.table.name << "` WHERE `" << key_info.name << "`=" << key_info.convert_to_open << "?\?" << key_info.convert_to_close << " AND `" << ref_key_info.table.name << "_id_" << field.name << "`!=" << ref_key_info.convert_to_open << "?\?" << ref_key_info.convert_to_close << ")"; auto where = os.str(); auto query = ref_table.build_delete_query(&where); return query; } else { auto& ref_table = *field.referenced_table; auto& key_info = *field.table.primary_key_field; auto& ref_key_info = *ref_table.primary_key_field; std::ostringstream os; os << "WHERE `" << ref_key_info.name << "` IN (SELECT `" << ref_key_info.table.name << "_id_" << field.name << "` FROM `" << key_info.table.name << "` WHERE `" << key_info.name << "`=" << key_info.convert_to_open << "?\?" << key_info.convert_to_close << ")"; auto where = os.str(); auto query = ref_table.build_delete_query(&where); return query; } }