implemented the first version of statement_cache

This commit is contained in:
2025-07-30 10:34:33 +02:00
parent f90a670fb3
commit ebd8bccfb3
31 changed files with 575 additions and 278 deletions
+53 -25
View File
@@ -13,6 +13,21 @@
namespace matador::sql {
namespace internal {
class connection_statement_proxy final : public statement_proxy {
public:
explicit connection_statement_proxy(std::unique_ptr<statement_impl>&& stmt)
: statement_proxy(std::move(stmt)) {}
utils::result<size_t, utils::error> execute() override {
return statement_->execute();
}
utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch() override {
return statement_->fetch();
}
};
}
connection::connection(connection_info info, const std::shared_ptr<abstract_sql_logger> &sql_logger)
: connection_info_(std::move(info))
, logger_(sql_logger)
@@ -57,8 +72,10 @@ connection & connection::operator=(connection &&x) noexcept {
return *this;
}
connection::~connection()
{
connection::~connection() {
if (!connection_) {
return;
}
if (connection_->is_open()) {
connection_->close();
}
@@ -66,8 +83,7 @@ connection::~connection()
connection_ = nullptr;
}
utils::result<void, utils::error> connection::open() const
{
utils::result<void, utils::error> connection::open() const {
const auto res = is_open();
if (res.is_error()) {
return utils::failure(res.err());
@@ -79,8 +95,7 @@ utils::result<void, utils::error> connection::open() const
return utils::ok<void>();
}
utils::result<void, utils::error> connection::close() const
{
utils::result<void, utils::error> connection::close() const {
logger_->on_close();
return connection_->close();
}
@@ -185,27 +200,17 @@ utils::result<size_t, utils::error> connection::execute(const query_context& ctx
return execute(ctx.sql);
}
utils::result<statement, utils::error> connection::prepare(const query_context &ctx) const
{
if (ctx.command != sql_command::SQL_CREATE_TABLE && (ctx.prototype.empty() || has_unknown_columns(ctx.prototype))) {
if (const auto result = describe(ctx.table.name); result.is_ok()) {
for (auto &col: ctx.prototype) {
const auto rit = std::find_if(std::begin(*result), std::end(*result),
[&col](const auto &value) {
return value.name() == col.name();
});
if (col.type() == utils::basic_type::type_null && rit != result->end()) {
const_cast<object::attribute_definition&>(col).type(rit->type());
}
}
}
utils::result<statement, utils::error> connection::prepare(const query_context &ctx) {
auto result = perform_prepare(ctx);
if (!result) {
return utils::failure(result.err());
}
if (auto result = connection_->prepare(ctx); result.is_ok()) {
return utils::ok(statement(result.release()));
}
return utils::ok(statement(std::unique_ptr<statement_impl>{}));
return utils::ok(statement(
std::make_shared<internal::connection_statement_proxy>(result.release()),
logger_)
);
}
std::string connection::str( const query_context& ctx ) const
@@ -218,4 +223,27 @@ const class dialect &connection::dialect() const
return connection_->dialect();
}
utils::result<std::unique_ptr<statement_impl>, utils::error> connection::perform_prepare(const query_context& ctx) const {
if (ctx.command != sql_command::SQL_CREATE_TABLE && (ctx.prototype.empty() || has_unknown_columns(ctx.prototype))) {
if (const auto result = describe(ctx.table.name); result.is_ok()) {
for (auto &col: ctx.prototype) {
const auto rit = std::find_if(
std::begin(*result),
std::end(*result),
[&col](const auto &value) { return value.name() == col.name(); }
);
if (col.type() == utils::basic_type::type_null && rit != result->end()) {
const_cast<object::attribute_definition&>(col).type(rit->type());
}
}
}
}
auto result = connection_->prepare(ctx);
if (!result) {
return utils::failure(result.err());
}
return utils::ok(result.release());
}
}