diff --git a/backends/postgres/include/postgres_parameter_binder.h b/backends/postgres/include/postgres_parameter_binder.h index 2903a01..32c102d 100644 --- a/backends/postgres/include/postgres_parameter_binder.h +++ b/backends/postgres/include/postgres_parameter_binder.h @@ -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 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); diff --git a/backends/postgres/include/postgres_statement.hpp b/backends/postgres/include/postgres_statement.hpp index ae906aa..12ecc80 100644 --- a/backends/postgres/include/postgres_statement.hpp +++ b/backends/postgres/include/postgres_statement.hpp @@ -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 @@ -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 execute() override; - utils::result, utils::error> fetch() override; + utils::result execute(const sql::interface::parameter_binder& bindings) override; + utils::result, utils::error> fetch(const sql::interface::parameter_binder& bindings) override; void reset() override; + protected: - utils::attribute_writer& binder() override; + [[nodiscard]] std::unique_ptr create_binder() const override; private: PGconn *db_{nullptr}; std::string name_; - - postgres_parameter_binder binder_; }; } diff --git a/backends/postgres/src/postgres_parameter_binder.cpp b/backends/postgres/src/postgres_parameter_binder.cpp index 35f215d..561f258 100644 --- a/backends/postgres/src/postgres_parameter_binder.cpp +++ b/backends/postgres/src/postgres_parameter_binder.cpp @@ -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) {} diff --git a/backends/postgres/src/postgres_statement.cpp b/backends/postgres/src/postgres_statement.cpp index 45739e2..267a7e6 100644 --- a/backends/postgres/src/postgres_statement.cpp +++ b/backends/postgres/src/postgres_statement.cpp @@ -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 postgres_statement::execute() -{ +utils::result postgres_statement::execute(const sql::interface::parameter_binder& bindings) { + const auto* postgres_bindings = dynamic_cast(&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(binder_.params().values.size()), - binder_.params().values.data(), - binder_.params().lengths.data(), - binder_.params().formats.data(), + static_cast(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 postgres_statement::execute() return utils::ok(static_cast(0)); } - return utils::ok(static_cast(std::stoul(tuples))); + return utils::ok((std::stoul(tuples))); } -utils::result, utils::error> postgres_statement::fetch() -{ +utils::result, utils::error> postgres_statement::fetch(const sql::interface::parameter_binder& bindings) { + const auto* postgres_bindings = dynamic_cast(&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(binder_.params().values.size()), - binder_.params().values.data(), - binder_.params().lengths.data(), - binder_.params().formats.data(), + static_cast(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, utils::error> postgres_st void postgres_statement::reset() {} -utils::attribute_writer& postgres_statement::binder() -{ - return binder_; +std::unique_ptr postgres_statement::create_binder() const { + return std::make_unique(query_.bind_vars.size()); +} } - -} \ No newline at end of file diff --git a/include/matador/sql/interface/parameter_binder.hpp b/include/matador/sql/interface/parameter_binder.hpp index a23f324..a5f554e 100644 --- a/include/matador/sql/interface/parameter_binder.hpp +++ b/include/matador/sql/interface/parameter_binder.hpp @@ -1,37 +1,11 @@ #ifndef QUERY_PARAMETER_BINDER_HPP #define QUERY_PARAMETER_BINDER_HPP -#include "matador/utils/types.hpp" - -#include -#include +#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; } diff --git a/include/matador/sql/interface/statement_impl.hpp b/include/matador/sql/interface/statement_impl.hpp index 5d168b3..fdc3d30 100644 --- a/include/matador/sql/interface/statement_impl.hpp +++ b/include/matador/sql/interface/statement_impl.hpp @@ -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 execute() = 0; - virtual utils::result, utils::error> fetch() = 0; + virtual utils::result execute(const interface::parameter_binder& bindings) = 0; + virtual utils::result, 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::bind_value(binder(), adjust_index(pos), val); + void bind(const size_t pos, Type &val, const interface::parameter_binder& bindings) { + utils::data_type_traits::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 create_binder() const = 0; protected: friend class statement; + friend class statement_proxy; query_context query_; }; diff --git a/include/matador/sql/interface/statement_proxy.hpp b/include/matador/sql/interface/statement_proxy.hpp index 6ae5533..b4ac207 100644 --- a/include/matador/sql/interface/statement_proxy.hpp +++ b/include/matador/sql/interface/statement_proxy.hpp @@ -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 execute() = 0; - virtual utils::result, utils::error> fetch() = 0; + virtual utils::result execute(interface::parameter_binder& bindings) = 0; + virtual utils::result, utils::error> fetch(interface::parameter_binder& bindings) = 0; template - 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 - 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 create_binder() const; + protected: std::unique_ptr statement_; }; diff --git a/include/matador/sql/object_parameter_binder.hpp b/include/matador/sql/object_parameter_binder.hpp index 47ea03c..3989bc2 100644 --- a/include/matador/sql/object_parameter_binder.hpp +++ b/include/matador/sql/object_parameter_binder.hpp @@ -9,8 +9,6 @@ #include "matador/utils/foreign_attributes.hpp" #include "matador/utils/primary_key_attribute.hpp" -#include - namespace matador::sql { namespace detail { @@ -61,8 +59,7 @@ private: } -class object_parameter_binder -{ +class object_parameter_binder { public: template void bind(Type &obj, utils::attribute_writer &binder) { diff --git a/include/matador/sql/statement.hpp b/include/matador/sql/statement.hpp index 1584a07..1148c01 100644 --- a/include/matador/sql/statement.hpp +++ b/include/matador/sql/statement.hpp @@ -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_; + std::unique_ptr bindings_; std::shared_ptr logger_; }; template statement &statement::bind(size_t pos, Type &value) { - statement_proxy_->bind(pos, value); + statement_proxy_->bind(pos, value, *bindings_); return *this; } template statement &statement::bind(const Type &obj) { - statement_proxy_->bind(obj); + statement_proxy_->bind(obj, bindings_); return *this; } template utils::result, utils::error> statement::fetch() { - return statement_proxy_->fetch().and_then([](std::unique_ptr &&value) { + return statement_proxy_->fetch(*bindings_).and_then([](std::unique_ptr &&value) { return utils::ok(query_result(std::forward(value))); }); // if (!result.is_ok()) { @@ -162,7 +157,7 @@ utils::result, utils::error> statement::fetch() { template utils::result, 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()); } diff --git a/source/orm/sql/connection.cpp b/source/orm/sql/connection.cpp index 5f0f179..16be520 100644 --- a/source/orm/sql/connection.cpp +++ b/source/orm/sql/connection.cpp @@ -19,11 +19,11 @@ public: explicit connection_statement_proxy(std::unique_ptr&& stmt) : statement_proxy(std::move(stmt)) {} - utils::result execute() override { - return statement_->execute(); + utils::result execute(interface::parameter_binder& bindings) override { + return statement_->execute(bindings); } - utils::result, utils::error> fetch() override { - return statement_->fetch(); + utils::result, utils::error> fetch(interface::parameter_binder& bindings) override { + return statement_->fetch(bindings); } }; diff --git a/source/orm/sql/interface/statement_impl.cpp b/source/orm/sql/interface/statement_impl.cpp index 6319144..6cd9c20 100644 --- a/source/orm/sql/interface/statement_impl.cpp +++ b/source/orm/sql/interface/statement_impl.cpp @@ -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::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::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::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::bind_value(bindings, adjust_index(pos), val, size); } -const std::vector &statement_impl::bind_vars() const -{ +const std::vector &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; } diff --git a/source/orm/sql/interface/statement_proxy.cpp b/source/orm/sql/interface/statement_proxy.cpp index 4d65d68..0c5654e 100644 --- a/source/orm/sql/interface/statement_proxy.cpp +++ b/source/orm/sql/interface/statement_proxy.cpp @@ -4,14 +4,18 @@ namespace matador::sql { statement_proxy::statement_proxy(std::unique_ptr&& 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 statement_proxy::create_binder() const { + return statement_->create_binder(); +} } diff --git a/source/orm/sql/statement.cpp b/source/orm/sql/statement.cpp index 4c12722..b9b8b15 100644 --- a/source/orm/sql/statement.cpp +++ b/source/orm/sql/statement.cpp @@ -11,20 +11,47 @@ statement::statement(const std::shared_ptr& 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 statement::execute() const { // logger_.info(statement_->query_.sql); - return statement_proxy_->execute(); + return statement_proxy_->execute(*bindings_); } //bool is_unknown(const std::vector &columns) { @@ -39,7 +66,7 @@ utils::result, 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, utils::error> statement::fetch() const { utils::result, 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()); } diff --git a/source/orm/sql/statement_cache.cpp b/source/orm/sql/statement_cache.cpp index 71af0fb..894d872 100644 --- a/source/orm/sql/statement_cache.cpp +++ b/source/orm/sql/statement_cache.cpp @@ -10,11 +10,11 @@ public: explicit statement_cache_proxy(std::unique_ptr&& stmt) : statement_proxy(std::move(stmt)) {} - utils::result execute() override { - return statement_->execute(); + utils::result execute(interface::parameter_binder& bindings) override { + return statement_->execute(bindings); } - utils::result, utils::error> fetch() override { - return statement_->fetch(); + utils::result, utils::error> fetch(interface::parameter_binder& bindings) override { + return statement_->fetch(bindings); } }; @@ -43,8 +43,8 @@ utils::result 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(); } diff --git a/test/orm/backend/test_connection.cpp b/test/orm/backend/test_connection.cpp index bfd4068..aa3070d 100644 --- a/test/orm/backend/test_connection.cpp +++ b/test/orm/backend/test_connection.cpp @@ -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 test_connection::open() -{ +utils::result test_connection::open() { is_open_ = true; return utils::ok(); } -utils::result test_connection::close() -{ +utils::result test_connection::close() { is_open_ = false; return utils::ok(); } -utils::result test_connection::is_open() const -{ +utils::result test_connection::is_open() const { return utils::ok(is_open_); } -utils::result test_connection::is_valid() const -{ +utils::result test_connection::is_valid() const { return is_open(); } @@ -47,33 +44,28 @@ utils::result test_connection::server_version() co return utils::ok(utils::version{3, 2, 1}); } -utils::result test_connection::execute(const std::string &/*stmt*/) -{ +utils::result test_connection::execute(const std::string &/*stmt*/) { return utils::ok(static_cast(4)); } -utils::result, utils::error> test_connection::fetch(const sql::query_context &context) -{ +utils::result, utils::error> test_connection::fetch(const sql::query_context &context) { return utils::ok(std::make_unique(std::make_unique(), context.prototype, context.prototype.size())); } -utils::result, utils::error> test_connection::prepare(const sql::query_context &/*context*/) -{ - return utils::ok(std::unique_ptr{}); +utils::result, utils::error> test_connection::prepare(const sql::query_context &context) { + std::unique_ptr s(std::make_unique(context)); + return utils::ok(std::move(s)); } -utils::result, utils::error> test_connection::describe(const std::string &/*table*/) -{ +utils::result, utils::error> test_connection::describe(const std::string &/*table*/) { return utils::ok(std::vector{}); } -utils::result test_connection::exists(const std::string &/*schema_name*/, const std::string &/*table_name*/) -{ +utils::result 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); } diff --git a/test/orm/backend/test_statement.cpp b/test/orm/backend/test_statement.cpp index 47fac0d..d13f4d3 100644 --- a/test/orm/backend/test_statement.cpp +++ b/test/orm/backend/test_statement.cpp @@ -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 test_statement::execute() { +utils::result test_statement::execute(const sql::interface::parameter_binder &/*bindings*/) { return utils::ok(static_cast(8)); } -utils::result, utils::error> test_statement::fetch() { +utils::result, utils::error> test_statement::fetch(const sql::interface::parameter_binder &/*bindings*/) { return utils::ok(std::make_unique(std::make_unique(), query_.prototype, query_.prototype.size())); } void test_statement::reset() {} - -utils::attribute_writer &test_statement::binder() { - return binder_; +std::unique_ptr test_statement::create_binder() const { + return std::make_unique(); } } // namespace matador::test::orm diff --git a/test/orm/backend/test_statement.hpp b/test/orm/backend/test_statement.hpp index ef93cc4..c892e18 100644 --- a/test/orm/backend/test_statement.hpp +++ b/test/orm/backend/test_statement.hpp @@ -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 execute() override; - utils::result, utils::error> fetch() override; + utils::result execute(const sql::interface::parameter_binder &bindings) override; + utils::result, 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 create_binder() const override; }; } diff --git a/test/orm/sql/StatementCacheTest.cpp b/test/orm/sql/StatementCacheTest.cpp index f469251..1470791 100644 --- a/test/orm/sql/StatementCacheTest.cpp +++ b/test/orm/sql/StatementCacheTest.cpp @@ -17,12 +17,12 @@ TEST_CASE("Test statement cache", "[statement][cache]") { backend_provider::instance().register_backend("noop", std::make_unique()); 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); } \ No newline at end of file