added a lock mechanism to statement_proxy
This commit is contained in:
parent
6e2baad3ef
commit
31964e55c1
|
|
@ -21,6 +21,7 @@ enum class error_code : uint8_t {
|
||||||
RESET_FAILED,
|
RESET_FAILED,
|
||||||
OPEN_ERROR,
|
OPEN_ERROR,
|
||||||
CLOSE_ERROR,
|
CLOSE_ERROR,
|
||||||
|
STATEMENT_LOCKED,
|
||||||
FAILURE
|
FAILURE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
#include "matador/sql/error_code.hpp"
|
#include "matador/sql/error_code.hpp"
|
||||||
#include "matador/sql/connection_pool.hpp"
|
#include "matador/sql/connection_pool.hpp"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
class statement_cache_proxy final : public statement_proxy {
|
class statement_cache_proxy final : public statement_proxy {
|
||||||
|
|
@ -11,11 +13,49 @@ public:
|
||||||
: statement_proxy(std::move(stmt)) {}
|
: statement_proxy(std::move(stmt)) {}
|
||||||
|
|
||||||
utils::result<size_t, utils::error> execute(interface::parameter_binder& bindings) override {
|
utils::result<size_t, utils::error> execute(interface::parameter_binder& bindings) override {
|
||||||
|
if (!try_lock()) {
|
||||||
|
return utils::failure(utils::error{
|
||||||
|
error_code::STATEMENT_LOCKED,
|
||||||
|
"Failed to execute statement because it is already in use"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto guard = statement_guard(*this);
|
||||||
return statement_->execute(bindings);
|
return statement_->execute(bindings);
|
||||||
}
|
}
|
||||||
utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch(interface::parameter_binder& bindings) override {
|
utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch(interface::parameter_binder& bindings) override {
|
||||||
|
if (!try_lock()) {
|
||||||
|
return utils::failure(utils::error{
|
||||||
|
error_code::STATEMENT_LOCKED,
|
||||||
|
"Failed to execute statement because it is already in use"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto guard = statement_guard(*this);
|
||||||
return statement_->fetch(bindings);
|
return statement_->fetch(bindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
[[nodiscard]] bool try_lock() {
|
||||||
|
bool expected = false;
|
||||||
|
return locked_.compare_exchange_strong(expected, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock() {
|
||||||
|
locked_.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct statement_guard {
|
||||||
|
explicit statement_guard(statement_cache_proxy &statement_proxy)
|
||||||
|
: proxy(statement_proxy) {}
|
||||||
|
~statement_guard() { proxy.unlock(); }
|
||||||
|
|
||||||
|
statement_cache_proxy &proxy;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic_bool locked_{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#include "test_result_reader.hpp"
|
#include "test_result_reader.hpp"
|
||||||
|
|
||||||
#include "matador/sql/query_context.hpp"
|
#include "matador/sql/query_context.hpp"
|
||||||
#include "matador/sql/record.hpp"
|
|
||||||
|
|
||||||
#include "matador/sql/internal/query_result_impl.hpp"
|
#include "matador/sql/internal/query_result_impl.hpp"
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue