From 5af0a8040c33d07dacf78343eb9ed0a03437a65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 18 Mar 2018 02:50:33 +0100 Subject: 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 --- src/database/database.cpp | 21 +++++++++++++++++++++ src/database/database.hpp | 11 ++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/database/database.cpp b/src/database/database.cpp index 812d27c..b1525d5 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -106,6 +106,8 @@ void Database::set_after_connection_commands(const Database::IrcServerOptions& s const auto id = server_options.col(); if (id == Id::unset_value) return ; + + Transaction transaction; auto query = Database::after_connection_commands.del(); query.where() << ForeignKey{} << "=" << id; query.execute(*Database::db); @@ -330,4 +332,23 @@ std::string Database::gen_uuid() return uuid_str; } +Transaction::Transaction() +{ + const auto result = Database::raw_exec("BEGIN"); + if (std::get(result) == false) + log_error("Failed to create SQL transaction: ", std::get(result)); + else + this->success = true; + +} + +Transaction::~Transaction() +{ + if (this->success) + { + const auto result = Database::raw_exec("END"); + if (std::get(result) == false) + log_error("Failed to end SQL transaction: ", std::get(result)); + } +} #endif diff --git a/src/database/database.hpp b/src/database/database.hpp index 0e88be8..5dde447 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -203,11 +203,20 @@ class Database static auto raw_exec(const std::string& query) { - Database::db->raw_exec(query); + return Database::db->raw_exec(query); } private: static std::string gen_uuid(); static std::map encoding_in_cache; }; + +class Transaction +{ +public: + Transaction(); + ~Transaction(); + bool success{false}; +}; + #endif /* USE_DATABASE */ -- cgit v1.2.3