Use a transaction around the DELETE + INSERT of the after_connection_commands
Otherwise we can imagine that two clients changing this value at the same time would mix things up. ref #3275
This commit is contained in:
@@ -106,6 +106,8 @@ void Database::set_after_connection_commands(const Database::IrcServerOptions& s
|
|||||||
const auto id = server_options.col<Id>();
|
const auto id = server_options.col<Id>();
|
||||||
if (id == Id::unset_value)
|
if (id == Id::unset_value)
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
|
Transaction transaction;
|
||||||
auto query = Database::after_connection_commands.del();
|
auto query = Database::after_connection_commands.del();
|
||||||
query.where() << ForeignKey{} << "=" << id;
|
query.where() << ForeignKey{} << "=" << id;
|
||||||
query.execute(*Database::db);
|
query.execute(*Database::db);
|
||||||
@@ -330,4 +332,23 @@ std::string Database::gen_uuid()
|
|||||||
return uuid_str;
|
return uuid_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Transaction::Transaction()
|
||||||
|
{
|
||||||
|
const auto result = Database::raw_exec("BEGIN");
|
||||||
|
if (std::get<bool>(result) == false)
|
||||||
|
log_error("Failed to create SQL transaction: ", std::get<std::string>(result));
|
||||||
|
else
|
||||||
|
this->success = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Transaction::~Transaction()
|
||||||
|
{
|
||||||
|
if (this->success)
|
||||||
|
{
|
||||||
|
const auto result = Database::raw_exec("END");
|
||||||
|
if (std::get<bool>(result) == false)
|
||||||
|
log_error("Failed to end SQL transaction: ", std::get<std::string>(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -203,11 +203,20 @@ class Database
|
|||||||
|
|
||||||
static auto raw_exec(const std::string& query)
|
static auto raw_exec(const std::string& query)
|
||||||
{
|
{
|
||||||
Database::db->raw_exec(query);
|
return Database::db->raw_exec(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string gen_uuid();
|
static std::string gen_uuid();
|
||||||
static std::map<CacheKey, EncodingIn::real_type> encoding_in_cache;
|
static std::map<CacheKey, EncodingIn::real_type> encoding_in_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Transaction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Transaction();
|
||||||
|
~Transaction();
|
||||||
|
bool success{false};
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* USE_DATABASE */
|
#endif /* USE_DATABASE */
|
||||||
|
|||||||
Reference in New Issue
Block a user