moved parameter_binder from member to parameter to bind, execute and fetch methods

This commit is contained in:
sascha 2025-07-30 21:00:40 +02:00
parent ebd8bccfb3
commit 6e2baad3ef
18 changed files with 169 additions and 168 deletions

View File

@ -1,14 +1,13 @@
#ifndef QUERY_POSTGRES_PARAMETER_BINDER_H
#define QUERY_POSTGRES_PARAMETER_BINDER_H
#include "matador/utils/attribute_writer.hpp"
#include "matador/sql/interface/parameter_binder.hpp"
#include <vector>
namespace matador::backends::postgres {
class postgres_parameter_binder final : public utils::attribute_writer
{
class postgres_parameter_binder final : public sql::interface::parameter_binder {
public:
struct bind_data {
explicit bind_data(size_t size);

View File

@ -2,8 +2,7 @@
#define QUERY_POSTGRES_STATEMENT_HPP
#include "matador/sql/interface/statement_impl.hpp"
#include "postgres_parameter_binder.h"
#include "matador/sql/interface/parameter_binder.hpp"
#include <libpq-fe.h>
@ -14,18 +13,17 @@ class postgres_statement final : public sql::statement_impl
public:
postgres_statement(PGconn *db, std::string name, const sql::query_context &query);
utils::result<size_t, utils::error> execute() override;
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetch() override;
utils::result<size_t, utils::error> execute(const sql::interface::parameter_binder& bindings) override;
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetch(const sql::interface::parameter_binder& bindings) override;
void reset() override;
protected:
utils::attribute_writer& binder() override;
[[nodiscard]] std::unique_ptr<utils::attribute_writer> create_binder() const override;
private:
PGconn *db_{nullptr};
std::string name_;
postgres_parameter_binder binder_;
};
}

View File

@ -53,7 +53,7 @@ postgres_parameter_binder::bind_data::bind_data(const size_t size)
, formats(size)
{}
postgres_parameter_binder::postgres_parameter_binder(size_t size)
postgres_parameter_binder::postgres_parameter_binder(const size_t size)
: bind_data_(size)
{}

View File

@ -1,5 +1,6 @@
#include "postgres_statement.hpp"
#include "postgres_error.hpp"
#include "postgres_parameter_binder.h"
#include "postgres_result_reader.hpp"
namespace matador::backends::postgres {
@ -8,17 +9,19 @@ postgres_statement::postgres_statement(PGconn *db, std::string name, const sql::
: statement_impl(query)
, db_(db)
, name_(std::move(name))
, binder_(query_.bind_vars.size())
{}
utils::result<size_t, utils::error> postgres_statement::execute()
{
utils::result<size_t, utils::error> postgres_statement::execute(const sql::interface::parameter_binder& bindings) {
const auto* postgres_bindings = dynamic_cast<const postgres_parameter_binder*>(&bindings);
if (!postgres_bindings) {
return utils::failure(utils::error(sql::error_code::EXECUTE_FAILED, "Failed to cast bindings to postgres bindings"));
}
PGresult *res = PQexecPrepared(db_,
name_.c_str(),
static_cast<int>(binder_.params().values.size()),
binder_.params().values.data(),
binder_.params().lengths.data(),
binder_.params().formats.data(),
static_cast<int>(postgres_bindings->params().values.size()),
postgres_bindings->params().values.data(),
postgres_bindings->params().lengths.data(),
postgres_bindings->params().formats.data(),
0);
if (is_result_error(res)) {
@ -30,17 +33,20 @@ utils::result<size_t, utils::error> postgres_statement::execute()
return utils::ok(static_cast<size_t>(0));
}
return utils::ok(static_cast<size_t>(std::stoul(tuples)));
return utils::ok((std::stoul(tuples)));
}
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_statement::fetch()
{
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_statement::fetch(const sql::interface::parameter_binder& bindings) {
const auto* postgres_bindings = dynamic_cast<const postgres_parameter_binder*>(&bindings);
if (!postgres_bindings) {
return utils::failure(utils::error(sql::error_code::EXECUTE_FAILED, "Failed to cast bindings to postgres bindings"));
}
PGresult *res = PQexecPrepared(db_,
name_.c_str(),
static_cast<int>(binder_.params().values.size()),
binder_.params().values.data(),
binder_.params().lengths.data(),
binder_.params().formats.data(),
static_cast<int>(postgres_bindings->params().values.size()),
postgres_bindings->params().values.data(),
postgres_bindings->params().lengths.data(),
postgres_bindings->params().formats.data(),
0);
if (is_result_error(res)) {
@ -52,9 +58,7 @@ utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_st
void postgres_statement::reset() {}
utils::attribute_writer& postgres_statement::binder()
{
return binder_;
std::unique_ptr<utils::attribute_writer> postgres_statement::create_binder() const {
return std::make_unique<postgres_parameter_binder>(query_.bind_vars.size());
}
}
}

View File

@ -1,37 +1,11 @@
#ifndef QUERY_PARAMETER_BINDER_HPP
#define QUERY_PARAMETER_BINDER_HPP
#include "matador/utils/types.hpp"
#include <string>
#include <cstring>
#include "matador/utils/attribute_writer.hpp"
namespace matador::sql::interface {
class parameter_binder
{
public:
virtual ~parameter_binder() = default;
virtual void bind(size_t pos, int8_t) = 0;
virtual void bind(size_t pos, int16_t) = 0;
virtual void bind(size_t pos, int32_t) = 0;
virtual void bind(size_t pos, int64_t) = 0;
virtual void bind(size_t pos, uint8_t) = 0;
virtual void bind(size_t pos, uint16_t) = 0;
virtual void bind(size_t pos, uint32_t) = 0;
virtual void bind(size_t pos, uint64_t) = 0;
virtual void bind(size_t pos, bool) = 0;
virtual void bind(size_t pos, float) = 0;
virtual void bind(size_t pos, double) = 0;
virtual void bind(size_t pos, const char *) = 0;
virtual void bind(size_t pos, const char *, size_t size) = 0;
virtual void bind(size_t pos, const std::string&) = 0;
virtual void bind(size_t pos, const std::string &x, size_t size) = 0;
virtual void bind(size_t pos, const utils::blob &) = 0;
// virtual void bind(size_t pos, const matador::time&) = 0;
// virtual void bind(size_t pos, const matador::date&) = 0;
};
using parameter_binder = utils::attribute_writer;
}

View File

@ -3,6 +3,7 @@
#include "matador/sql/query_context.hpp"
#include "matador/sql/internal/query_result_impl.hpp"
#include "matador/sql/interface/parameter_binder.hpp"
#include "matador/sql/object_parameter_binder.hpp"
#include "matador/utils/data_type_traits.hpp"
@ -21,24 +22,23 @@ protected:
public:
virtual ~statement_impl() = default;
virtual utils::result<size_t, utils::error> execute() = 0;
virtual utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch() = 0;
virtual utils::result<size_t, utils::error> execute(const interface::parameter_binder& bindings) = 0;
virtual utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch(const interface::parameter_binder& bindings) = 0;
template < class Type >
void bind_object(Type &obj)
{
void bind_object(Type &obj, const interface::parameter_binder& bindings) {
object_parameter_binder object_binder_;
object_binder_.reset(start_index());
object_binder_.bind(obj, binder());
object_binder_.bind(obj, bindings);
}
template < class Type >
void bind(const size_t pos, Type &val) {
utils::data_type_traits<Type>::bind_value(binder(), adjust_index(pos), val);
void bind(const size_t pos, Type &val, const interface::parameter_binder& bindings) {
utils::data_type_traits<Type>::bind_value(bindings, adjust_index(pos), val);
}
void bind(size_t pos, const char *value, size_t size);
void bind(size_t pos, std::string &val, size_t size);
void bind(size_t pos, const char *value, size_t size, interface::parameter_binder& bindings) const;
void bind(size_t pos, std::string &val, size_t size, interface::parameter_binder& bindings) const;
virtual void reset() = 0;
@ -46,12 +46,13 @@ public:
[[nodiscard]] bool is_valid_host_var(const std::string &host_var, size_t pos) const;
protected:
virtual utils::attribute_writer& binder() = 0;
[[nodiscard]] virtual size_t start_index() const;
[[nodiscard]] virtual size_t adjust_index(size_t index) const;
[[nodiscard]] virtual std::unique_ptr<utils::attribute_writer> create_binder() const = 0;
protected:
friend class statement;
friend class statement_proxy;
query_context query_;
};

View File

@ -2,6 +2,7 @@
#define STATEMENT_PROXY_HPP
#include "matador/sql/interface/statement_impl.hpp"
#include "matador/sql/interface/parameter_binder.hpp"
namespace matador::sql {
class statement_proxy {
@ -11,22 +12,24 @@ protected:
public:
virtual ~statement_proxy() = default;
virtual utils::result<size_t, utils::error> execute() = 0;
virtual utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch() = 0;
virtual utils::result<size_t, utils::error> execute(interface::parameter_binder& bindings) = 0;
virtual utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch(interface::parameter_binder& bindings) = 0;
template<class Type>
void bind(const Type &obj) {
statement_->bind_object(obj);
void bind(const Type &obj, const interface::parameter_binder& bindings) {
statement_->bind_object(obj, bindings);
}
template<typename Type>
void bind(size_t pos, Type &value) {
statement_->bind(pos, value);
void bind(size_t pos, Type &value, const interface::parameter_binder& bindings) {
statement_->bind(pos, value, bindings);
}
void bind(size_t pos, const char *value, size_t size) const;
void bind(size_t pos, std::string &val, size_t size) const;
void bind(size_t pos, const char *value, size_t size, interface::parameter_binder& bindings) const;
void bind(size_t pos, std::string &val, size_t size, interface::parameter_binder& bindings) const;
void reset() const;
[[nodiscard]] std::unique_ptr<utils::attribute_writer> create_binder() const;
protected:
std::unique_ptr<statement_impl> statement_;
};

View File

@ -9,8 +9,6 @@
#include "matador/utils/foreign_attributes.hpp"
#include "matador/utils/primary_key_attribute.hpp"
#include <string>
namespace matador::sql {
namespace detail {
@ -61,8 +59,7 @@ private:
}
class object_parameter_binder
{
class object_parameter_binder {
public:
template<class Type>
void bind(Type &obj, utils::attribute_writer &binder) {

View File

@ -5,6 +5,7 @@
#include "matador/sql/query_result.hpp"
#include "matador/sql/interface/statement_proxy.hpp"
#include "matador/sql/interface/parameter_binder.hpp"
#include "matador/utils/error.hpp"
#include "matador/utils/result.hpp"
@ -38,10 +39,7 @@ public:
*
* @param x The statement to move from
*/
statement(statement &&x) noexcept
: statement_proxy_(std::move(x.statement_proxy_))
, logger_(std::move(x.logger_)) {
}
statement(statement &&x) noexcept;
/**
* Assignment move constructor for statement
@ -49,14 +47,10 @@ public:
* @param x The statement to move from
* @return Reference to this
*/
statement &operator=(statement &&x) noexcept {
statement_proxy_ = std::move(x.statement_proxy_);
logger_ = std::move(x.logger_);
return *this;
}
statement &operator=(statement &&x) noexcept;
statement(const statement &x) = default;
statement &operator=(const statement &x) = default;
statement(const statement &x);
statement &operator=(const statement &x);
statement &bind(size_t pos, const char *value);
statement &bind(size_t pos, std::string &val, size_t size);
@ -134,24 +128,25 @@ private:
private:
std::shared_ptr<statement_proxy> statement_proxy_;
std::unique_ptr<utils::attribute_writer> bindings_;
std::shared_ptr<abstract_sql_logger> logger_;
};
template<typename Type>
statement &statement::bind(size_t pos, Type &value) {
statement_proxy_->bind(pos, value);
statement_proxy_->bind(pos, value, *bindings_);
return *this;
}
template<class Type>
statement &statement::bind(const Type &obj) {
statement_proxy_->bind(obj);
statement_proxy_->bind(obj, bindings_);
return *this;
}
template<class Type>
utils::result<query_result<Type>, utils::error> statement::fetch() {
return statement_proxy_->fetch().and_then([](std::unique_ptr<query_result_impl> &&value) {
return statement_proxy_->fetch(*bindings_).and_then([](std::unique_ptr<query_result_impl> &&value) {
return utils::ok(query_result<Type>(std::forward<decltype(value)>(value)));
});
// if (!result.is_ok()) {
@ -162,7 +157,7 @@ utils::result<query_result<Type>, utils::error> statement::fetch() {
template<class Type>
utils::result<std::unique_ptr<Type>, utils::error> statement::fetch_one() {
auto result = statement_proxy_->fetch();
auto result = statement_proxy_->fetch(*bindings_);
if (!result.is_ok()) {
return utils::failure(result.err());
}

View File

@ -19,11 +19,11 @@ 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<size_t, utils::error> execute(interface::parameter_binder& bindings) override {
return statement_->execute(bindings);
}
utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch() override {
return statement_->fetch();
utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch(interface::parameter_binder& bindings) override {
return statement_->fetch(bindings);
}
};

View File

@ -6,35 +6,29 @@ statement_impl::statement_impl(query_context query)
: query_(std::move(query))
{}
void statement_impl::bind(const size_t pos, const char *value, const size_t size)
{
utils::data_type_traits<const char*>::bind_value(binder(), adjust_index(pos), value, size);
void statement_impl::bind(const size_t pos, const char *value, const size_t size, interface::parameter_binder& bindings) const {
utils::data_type_traits<const char*>::bind_value(bindings, adjust_index(pos), value, size);
}
void statement_impl::bind(const size_t pos, std::string &val, const size_t size)
{
utils::data_type_traits<std::string>::bind_value(binder(), adjust_index(pos), val, size);
void statement_impl::bind(const size_t pos, std::string &val, const size_t size, interface::parameter_binder& bindings) const {
utils::data_type_traits<std::string>::bind_value(bindings, adjust_index(pos), val, size);
}
const std::vector<std::string> &statement_impl::bind_vars() const
{
const std::vector<std::string> &statement_impl::bind_vars() const {
return query_.bind_vars;
}
bool statement_impl::is_valid_host_var(const std::string &host_var, const size_t pos) const
{
bool statement_impl::is_valid_host_var(const std::string &host_var, const size_t pos) const {
const auto host_var_at_pos = bind_vars().at(pos);
return host_var_at_pos == host_var;
}
size_t statement_impl::start_index() const
{
size_t statement_impl::start_index() const {
return 0;
}
size_t statement_impl::adjust_index( size_t index ) const
{
size_t statement_impl::adjust_index(const size_t index) const {
return index;
}

View File

@ -4,14 +4,18 @@ namespace matador::sql {
statement_proxy::statement_proxy(std::unique_ptr<statement_impl>&& stmt)
: statement_(std::move(stmt)){}
void statement_proxy::bind(const size_t pos, const char* value, const size_t size) const {
statement_->bind(pos, value, size);
void statement_proxy::bind(const size_t pos, const char* value, const size_t size, interface::parameter_binder& bindings) const {
statement_->bind(pos, value, size, bindings);
}
void statement_proxy::bind(const size_t pos, std::string& val, const size_t size) const {
statement_->bind(pos, val, size);
void statement_proxy::bind(const size_t pos, std::string& val, const size_t size, interface::parameter_binder& bindings) const {
statement_->bind(pos, val, size, bindings);
}
void statement_proxy::reset() const {
statement_->reset();
}
std::unique_ptr<utils::attribute_writer> statement_proxy::create_binder() const {
return statement_->create_binder();
}
}

View File

@ -11,20 +11,47 @@ statement::statement(const std::shared_ptr<statement_proxy>& proxy, logger_ptr
: statement_proxy_(proxy)
, logger_(std::move(logger)){}
statement &statement::bind(const size_t pos, const char *value) {
statement_proxy_->bind(pos, value, strlen(value));
statement::statement(statement&& x) noexcept
: statement_proxy_(std::move(x.statement_proxy_))
, bindings_(std::move(x.bindings_))
, logger_(std::move(x.logger_)) {
}
statement& statement::operator=(statement&& x) noexcept {
statement_proxy_ = std::move(x.statement_proxy_);
bindings_ = std::move(x.bindings_);
logger_ = std::move(x.logger_);
return *this;
}
statement &statement::bind(const size_t pos, std::string &val, const size_t size)
{
statement_proxy_->bind(pos, val, size);
statement::statement(const statement& x)
: statement_proxy_(x.statement_proxy_)
, bindings_(x.statement_proxy_->create_binder())
, logger_(x.logger_) {
}
statement& statement::operator=(const statement& x) {
if (&x == this) {
return *this;
}
statement_proxy_ = x.statement_proxy_;
bindings_ = x.statement_proxy_->create_binder();
logger_ = x.logger_;
return *this;
}
statement &statement::bind(const size_t pos, const char *value) {
statement_proxy_->bind(pos, value, strlen(value), *bindings_);
return *this;
}
statement &statement::bind(const size_t pos, std::string &val, const size_t size) {
statement_proxy_->bind(pos, val, size, *bindings_);
return *this;
}
utils::result<size_t, utils::error> statement::execute() const {
// logger_.info(statement_->query_.sql);
return statement_proxy_->execute();
return statement_proxy_->execute(*bindings_);
}
//bool is_unknown(const std::vector<object::column_definition> &columns) {
@ -39,7 +66,7 @@ utils::result<query_result<record>, utils::error> statement::fetch() const {
// }
auto result = statement_proxy_->fetch();
auto result = statement_proxy_->fetch(*bindings_);
if (!result.is_ok()) {
return utils::failure(result.err());
}
@ -49,7 +76,7 @@ utils::result<query_result<record>, utils::error> statement::fetch() const {
utils::result<std::optional<record>, utils::error> statement::fetch_one() const {
// logger_.info(statement_->query_.sql);
auto result = statement_proxy_->fetch();
auto result = statement_proxy_->fetch(*bindings_);
if (!result.is_ok()) {
return utils::failure(result.err());
}

View File

@ -10,11 +10,11 @@ public:
explicit statement_cache_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<size_t, utils::error> execute(interface::parameter_binder& bindings) override {
return statement_->execute(bindings);
}
utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch() override {
return statement_->fetch();
utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch(interface::parameter_binder& bindings) override {
return statement_->fetch(bindings);
}
};
@ -43,8 +43,8 @@ utils::result<statement, utils::error> statement_cache::acquire(const query_cont
// If cache max size reached ensure space
if (cache_map_.size() >= max_size_) {
const size_t& lru_key = usage_list_.back();
cache_map_.erase(lru_key);
const auto& key_to_remove = usage_list_.back();
cache_map_.erase(key_to_remove);
usage_list_.pop_back();
}

View File

@ -1,4 +1,5 @@
#include "test_connection.hpp"
#include "test_statement.hpp"
#include "test_result_reader.hpp"
#include "matador/sql/query_context.hpp"
@ -17,25 +18,21 @@ namespace matador::test::orm {
test_connection::test_connection(const sql::connection_info &info)
: connection_impl(info) {}
utils::result<void, utils::error> test_connection::open()
{
utils::result<void, utils::error> test_connection::open() {
is_open_ = true;
return utils::ok<void>();
}
utils::result<void, utils::error> test_connection::close()
{
utils::result<void, utils::error> test_connection::close() {
is_open_ = false;
return utils::ok<void>();
}
utils::result<bool, utils::error> test_connection::is_open() const
{
utils::result<bool, utils::error> test_connection::is_open() const {
return utils::ok(is_open_);
}
utils::result<bool, utils::error> test_connection::is_valid() const
{
utils::result<bool, utils::error> test_connection::is_valid() const {
return is_open();
}
@ -47,33 +44,28 @@ utils::result<utils::version, utils::error> test_connection::server_version() co
return utils::ok(utils::version{3, 2, 1});
}
utils::result<size_t, utils::error> test_connection::execute(const std::string &/*stmt*/)
{
utils::result<size_t, utils::error> test_connection::execute(const std::string &/*stmt*/) {
return utils::ok(static_cast<size_t>(4));
}
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> test_connection::fetch(const sql::query_context &context)
{
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> test_connection::fetch(const sql::query_context &context) {
return utils::ok(std::make_unique<sql::query_result_impl>(std::make_unique<test_result_reader>(), context.prototype, context.prototype.size()));
}
utils::result<std::unique_ptr<sql::statement_impl>, utils::error> test_connection::prepare(const sql::query_context &/*context*/)
{
return utils::ok(std::unique_ptr<sql::statement_impl>{});
utils::result<std::unique_ptr<sql::statement_impl>, utils::error> test_connection::prepare(const sql::query_context &context) {
std::unique_ptr<sql::statement_impl> s(std::make_unique<test_statement>(context));
return utils::ok(std::move(s));
}
utils::result<std::vector<object::attribute_definition>, utils::error> test_connection::describe(const std::string &/*table*/)
{
utils::result<std::vector<object::attribute_definition>, utils::error> test_connection::describe(const std::string &/*table*/) {
return utils::ok(std::vector<object::attribute_definition>{});
}
utils::result<bool, utils::error> test_connection::exists(const std::string &/*schema_name*/, const std::string &/*table_name*/)
{
utils::result<bool, utils::error> test_connection::exists(const std::string &/*schema_name*/, const std::string &/*table_name*/) {
return utils::ok(false);
}
std::string test_connection::to_escaped_string(const utils::blob& value) const
{
std::string test_connection::to_escaped_string(const utils::blob& value) const {
return utils::to_string(value);
}

View File

@ -1,22 +1,22 @@
#include "test_statement.hpp"
#include "test_result_reader.hpp"
#include "test_parameter_binder.hpp"
namespace matador::test::orm {
test_statement::test_statement(const sql::query_context &query)
: statement_impl(query) {}
utils::result<size_t, utils::error> test_statement::execute() {
utils::result<size_t, utils::error> test_statement::execute(const sql::interface::parameter_binder &/*bindings*/) {
return utils::ok(static_cast<size_t>(8));
}
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> test_statement::fetch() {
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> test_statement::fetch(const sql::interface::parameter_binder &/*bindings*/) {
return utils::ok(std::make_unique<sql::query_result_impl>(std::make_unique<test_result_reader>(), query_.prototype, query_.prototype.size()));
}
void test_statement::reset() {}
utils::attribute_writer &test_statement::binder() {
return binder_;
std::unique_ptr<utils::attribute_writer> test_statement::create_binder() const {
return std::make_unique<test_parameter_binder>();
}
} // namespace matador::test::orm

View File

@ -1,8 +1,6 @@
#ifndef TEST_STATEMENT_HPP
#define TEST_STATEMENT_HPP
#include "test_parameter_binder.hpp"
#include "matador/sql/interface/statement_impl.hpp"
namespace matador::test::orm {
@ -10,15 +8,12 @@ namespace matador::test::orm {
class test_statement final : public sql::statement_impl {
public:
explicit test_statement(const sql::query_context &query);
utils::result<size_t, utils::error> execute() override;
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetch() override;
utils::result<size_t, utils::error> execute(const sql::interface::parameter_binder &bindings) override;
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetch(const sql::interface::parameter_binder &bindings) override;
void reset() override;
protected:
utils::attribute_writer &binder() override;
private:
test_parameter_binder binder_;
[[nodiscard]] std::unique_ptr<utils::attribute_writer> create_binder() const override;
};
}

View File

@ -17,12 +17,12 @@ TEST_CASE("Test statement cache", "[statement][cache]") {
backend_provider::instance().register_backend("noop", std::make_unique<orm::test_backend_service>());
connection_pool pool("noop://noop.db", 4);
statement_cache cache(pool, 4);
statement_cache cache(pool, 2);
query_context ctx;
ctx.sql = "SELECT * FROM person";
REQUIRE(cache.capacity() == 4);
REQUIRE(cache.capacity() == 2);
REQUIRE(cache.empty());
auto result = cache.acquire(ctx);
@ -30,7 +30,25 @@ TEST_CASE("Test statement cache", "[statement][cache]") {
REQUIRE(cache.size() == 1);
REQUIRE(!cache.empty());
REQUIRE(cache.capacity() == 4);
REQUIRE(cache.capacity() == 2);
const auto stmt = result.value();
ctx.sql = "SELECT title FROM book";
result = cache.acquire(ctx);
REQUIRE(result);
REQUIRE(cache.size() == 2);
REQUIRE(!cache.empty());
REQUIRE(cache.capacity() == 2);
ctx.sql = "SELECT name FROM author";
result = cache.acquire(ctx);
REQUIRE(result);
REQUIRE(cache.size() == 2);
REQUIRE(!cache.empty());
REQUIRE(cache.capacity() == 2);
}