From 86c9e6b1cd04620690963ecf9c25c9e45592fb4e Mon Sep 17 00:00:00 2001 From: sascha Date: Fri, 13 Mar 2026 16:18:41 +0100 Subject: [PATCH] sequence tests progress --- .../postgres/include/postgres_connection.hpp | 2 + backends/postgres/src/postgres_connection.cpp | 4 ++ backends/postgres/test/CMakeLists.txt | 2 + include/matador/query/basic_schema.hpp | 1 - .../matador/query/insert_query_builder.hpp | 12 ++--- include/matador/sql/connection.hpp | 3 ++ .../matador/sql/interface/connection_impl.hpp | 2 + source/orm/sql/connection.cpp | 4 ++ test/backends/QueryFixture.cpp | 1 + test/backends/SequenceFixture.cpp | 35 ++++++++++++++ test/backends/SequenceFixture.hpp | 30 ++++++++++++ test/orm/backend/test_connection.cpp | 5 ++ test/orm/backend/test_connection.hpp | 1 + todo.md | 48 +++++++++---------- 14 files changed, 117 insertions(+), 33 deletions(-) create mode 100644 test/backends/SequenceFixture.cpp create mode 100644 test/backends/SequenceFixture.hpp diff --git a/backends/postgres/include/postgres_connection.hpp b/backends/postgres/include/postgres_connection.hpp index 0691271..52d9a6c 100644 --- a/backends/postgres/include/postgres_connection.hpp +++ b/backends/postgres/include/postgres_connection.hpp @@ -38,6 +38,8 @@ public: utils::result, utils::error> describe(const std::string& table) override; utils::result exists(const std::string &schema_name, const std::string &table_name) override; + utils::result sequence_exists(const std::string &schema_name, const std::string &sequence_name) override; + [[nodiscard]] std::string to_escaped_string( const utils::blob_type_t& value ) const override; private: diff --git a/backends/postgres/src/postgres_connection.cpp b/backends/postgres/src/postgres_connection.cpp index c6169d3..6427374 100644 --- a/backends/postgres/src/postgres_connection.cpp +++ b/backends/postgres/src/postgres_connection.cpp @@ -298,6 +298,10 @@ utils::result postgres_connection::exists(const std::string return utils::ok(*result == 1); } +utils::result postgres_connection::sequence_exists(const std::string& schema_name, const std::string& sequence_name) { + return utils::ok(false); +} + std::string postgres_connection::to_escaped_string(const utils::blob_type_t &value) const { size_t escapedDataLength; unsigned char *escapedData = PQescapeByteaConn(conn_, value.data(), value.size(), &escapedDataLength); diff --git a/backends/postgres/test/CMakeLists.txt b/backends/postgres/test/CMakeLists.txt index b3bdd32..4ce3e93 100644 --- a/backends/postgres/test/CMakeLists.txt +++ b/backends/postgres/test/CMakeLists.txt @@ -34,6 +34,8 @@ set(TEST_SOURCES ../../../test/utils/record_printer.hpp ../../../test/utils/record_printer.cpp ../../../test/models/model_metas.hpp + ../../../test/backends/SequenceFixture.hpp + ../../../test/backends/SequenceFixture.cpp ) set(LIBRARY_TEST_TARGET PostgresTests) diff --git a/include/matador/query/basic_schema.hpp b/include/matador/query/basic_schema.hpp index 5a01f87..7dd8665 100644 --- a/include/matador/query/basic_schema.hpp +++ b/include/matador/query/basic_schema.hpp @@ -26,7 +26,6 @@ public: private: class table table_; - utils::generator_type generator_type_{}; std::unique_ptr pk_generator_; const object::repository_node& node_; }; diff --git a/include/matador/query/insert_query_builder.hpp b/include/matador/query/insert_query_builder.hpp index f83ec34..a1a08f8 100644 --- a/include/matador/query/insert_query_builder.hpp +++ b/include/matador/query/insert_query_builder.hpp @@ -141,7 +141,7 @@ public: template static void on_has_many(const char * /*id*/, Collection &/*con*/, const char * /*join_column*/, const utils::foreign_attributes & ) {} template - void on_has_many_to_many(const char *id, Collection &con, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes & ) { + void on_has_many_to_many(const char *id, Collection &container, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes & ) { if (id == nullptr || join_column == nullptr || inverse_join_column == nullptr) { return; } @@ -151,13 +151,13 @@ public: return; } - const auto rel_it = schema_.find(std::string{id}); - if (rel_it == schema_.end()) { + const auto it = schema_.find(std::string{id}); + if (it == schema_.end()) { throw query_builder_exception(query_build_error::UnknownType); } - const table &rel_table = rel_it->second.table(); + const table &relation_table = it->second.table(); - for (auto &obj : con) { + for (auto &obj : container) { if (!obj) { continue; } @@ -179,7 +179,7 @@ public: insert_step rel_step{}; rel_step.query = executable_query{ query::query::insert() - .into(rel_table, {table_column{&rel_table, join_column}, table_column{&rel_table, inverse_join_column}}) + .into(relation_table, {table_column{&relation_table, join_column}, table_column{&relation_table, inverse_join_column}}) .values({utils::database_type{current_entity_pk_}, utils::database_type{fk.value}}) }; relation_steps_.push_back(std::move(rel_step)); diff --git a/include/matador/sql/connection.hpp b/include/matador/sql/connection.hpp index 76c46e5..623eac4 100644 --- a/include/matador/sql/connection.hpp +++ b/include/matador/sql/connection.hpp @@ -135,6 +135,9 @@ public: [[nodiscard]] utils::result exists(const std::string &schema_name, const std::string &table_name) const; [[nodiscard]] utils::result exists(const std::string &table_name) const; + + [[nodiscard]] utils::result sequence_exists(const std::string &sequence_name) const; + [[nodiscard]] utils::result, utils::error> fetch(const query_context &ctx) const override; [[nodiscard]] utils::result execute(const query_context &ctx) const override; [[nodiscard]] utils::result prepare(const query_context &ctx) override; diff --git a/include/matador/sql/interface/connection_impl.hpp b/include/matador/sql/interface/connection_impl.hpp index 1346b0b..57ad095 100644 --- a/include/matador/sql/interface/connection_impl.hpp +++ b/include/matador/sql/interface/connection_impl.hpp @@ -42,6 +42,8 @@ public: virtual utils::result, utils::error> describe(const std::string &table) = 0; virtual utils::result exists(const std::string &schema_name, const std::string &table_name) = 0; + virtual utils::result sequence_exists(const std::string &schema_name, const std::string &sequence_name) = 0; + [[nodiscard]] const class dialect &dialect() const; [[nodiscard]] virtual std::string to_escaped_string(const utils::blob_type_t &value) const = 0; diff --git a/source/orm/sql/connection.cpp b/source/orm/sql/connection.cpp index 3cadfcd..cd8b510 100644 --- a/source/orm/sql/connection.cpp +++ b/source/orm/sql/connection.cpp @@ -163,6 +163,10 @@ utils::result connection::exists(const std::string &table_na return connection_->exists(dialect().default_schema_name(), table_name); } +utils::result connection::sequence_exists(const std::string& sequence_name) const { + return connection_->sequence_exists(sequence_name); +} + bool has_unknown_columns(const std::vector &columns) { return std::any_of(std::begin(columns), std::end(columns), [](const auto &col) { return col.type() == utils::basic_type::Null; diff --git a/test/backends/QueryFixture.cpp b/test/backends/QueryFixture.cpp index 56ded79..58d8770 100644 --- a/test/backends/QueryFixture.cpp +++ b/test/backends/QueryFixture.cpp @@ -47,5 +47,6 @@ void QueryFixture::drop_table_if_exists(const std::string &table_name) const { } return utils::ok(true); }); + REQUIRE(result); } } diff --git a/test/backends/SequenceFixture.cpp b/test/backends/SequenceFixture.cpp new file mode 100644 index 0000000..ee7636d --- /dev/null +++ b/test/backends/SequenceFixture.cpp @@ -0,0 +1,35 @@ +#include "SequenceFixture.hpp" + +#include "matador/query/query.hpp" + +#include "matador/sql/dialect.hpp" + +#include "connection.hpp" + +#include "catch2/catch_test_macros.hpp" + +namespace matador::test { +SequenceFixture::SequenceFixture() +: db(connection::dns) +, repo(db.dialect().default_schema_name()) { + REQUIRE(db.open()); +} + +SequenceFixture::~SequenceFixture() { + while (!sequences_to_drop.empty()) { + drop_sequence_if_exists(sequences_to_drop.top()); + sequences_to_drop.pop(); + } + REQUIRE(repo.drop(db)); + REQUIRE(db.close()); +} + +void SequenceFixture::check_sequence_exists(const std::string& sequence_name) const { +} + +void SequenceFixture::check_sequence_not_exists(const std::string& sequence_name) const { +} + +void SequenceFixture::drop_sequence_if_exists(const std::string& sequence_name) const { +} +} diff --git a/test/backends/SequenceFixture.hpp b/test/backends/SequenceFixture.hpp new file mode 100644 index 0000000..4a698d0 --- /dev/null +++ b/test/backends/SequenceFixture.hpp @@ -0,0 +1,30 @@ +#ifndef MATADOR_SEQUENCE_FIXTURE_HPP +#define MATADOR_SEQUENCE_FIXTURE_HPP + + +#include "matador/query/schema.hpp" + +#include "matador/sql/connection.hpp" + +#include + +namespace matador::test { +class SequenceFixture { +public: + SequenceFixture(); + ~SequenceFixture(); + + void check_sequence_exists(const std::string &sequence_name) const; + void check_sequence_not_exists(const std::string &sequence_name) const; + +protected: + sql::connection db; + std::stack sequences_to_drop; + query::schema repo; + +private: + void drop_sequence_if_exists(const std::string &sequence_name) const; +}; +} + +#endif //MATADOR_SEQUENCE_FIXTURE_HPP \ No newline at end of file diff --git a/test/orm/backend/test_connection.cpp b/test/orm/backend/test_connection.cpp index 49eb048..7d3b776 100644 --- a/test/orm/backend/test_connection.cpp +++ b/test/orm/backend/test_connection.cpp @@ -70,6 +70,11 @@ utils::result test_connection::exists(const std::string &/*s return utils::ok(false); } +utils::result test_connection::sequence_exists(const std::string& /*schema_name*/, + const std::string& /*sequence_name*/) { + return utils::ok(false); +} + std::string test_connection::to_escaped_string(const utils::blob_type_t &value) const { return utils::to_string(value); } diff --git a/test/orm/backend/test_connection.hpp b/test/orm/backend/test_connection.hpp index ef95731..7443ec5 100644 --- a/test/orm/backend/test_connection.hpp +++ b/test/orm/backend/test_connection.hpp @@ -22,6 +22,7 @@ public: utils::result, utils::error> prepare(const sql::query_context &context) override; utils::result, utils::error> describe(const std::string &table) override; utils::result exists(const std::string &schema_name, const std::string &table_name) override; + utils::result sequence_exists(const std::string &schema_name, const std::string &sequence_name) override; [[nodiscard]] std::string to_escaped_string( const utils::blob_type_t& value ) const override; diff --git a/todo.md b/todo.md index 1eedf22..015c5cf 100644 --- a/todo.md +++ b/todo.md @@ -1,5 +1,27 @@ # Todo +Order of next steps: +1. Finish pk generator + - classes + - detection on schema attach + - tests +2. PK accessor class + - extract from `insert_query_builder` class + - get(), set(), is_null/valid/set() + - detection on schema attach + - tests +3. Add owner-awareness to the collection class + - add owner field + - bind owner on session insert + - tests +4. Finish `insert_query_builder` + - collect all inserts for entities with relations + - tests +5. Finish `session::insert` method + - use `insert_query_builder` + - correct handling of pk generator + - tests + - move `prepare_*` methods from `dialect` to `query_compiler` - add `insert_query_builder` and `update_update_builder` (returning multiple statements) - finish fetch eager many-to-many relations @@ -18,32 +40,6 @@ 7. Extend `session::insert` logic to use pk generator 8. Add generator to `schema_node` or `table` class when attaching type -```cpp -struct abstract_pk_generator { - virtual ~abstract_pk_generator() = default; - virtual int64_t next_id() = 0; - virtual std::vector next_ids(int count) = 0; -}; - -struct sequence_pk_generator : abstract_pk_generator { - explicit sequence_pk_generator(const std::string& sequence_name) - : query_(query::query::select().nextval(sequence_name)) {} - int64_t next_id(sql::executor& exec) override { - return query_.fetch_value(exec); - } - std::vector next_ids(int count) override; -private: - query::fetchable_query query_; -}; - -struct table_pk_generator : abstract_pk_generator { - explicit table_pk_generator(const std::string& table_name); - int64_t next_id() override; - std::vector next_ids(int count) override; -private: - std::string table_name_; -}; -``` __Proposal for polymorphic classes:__