From 626eae1ac8c14fca96b4dda812f127ab9b1f2aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20K=C3=BChl?= Date: Thu, 26 Feb 2026 07:31:35 +0100 Subject: [PATCH] added more pk generator types --- backends/postgres/test/CMakeLists.txt | 4 ++-- include/matador/orm/session.hpp | 2 +- .../matador/query/abstract_pk_generator.hpp | 9 ++++++++ include/matador/query/basic_schema.hpp | 16 ++++++++------ include/matador/query/database.hpp | 20 +++++++++++++++++ .../matador/query/insert_query_builder.hpp | 4 ++-- include/matador/query/manual_pk_generator.hpp | 13 +++++++++++ include/matador/query/schema.hpp | 11 ---------- include/matador/query/table_pk_generator.hpp | 16 ++++++++++++++ .../matador/utils/primary_key_attribute.hpp | 2 +- .../utils/primary_key_generator_type.hpp | 2 +- source/orm/CMakeLists.txt | 6 +++++ source/orm/query/abstract_pk_generator.cpp | 10 +++++++++ source/orm/query/basic_schema.cpp | 8 +++---- source/orm/query/manual_pk_generator.cpp | 13 +++++++++++ source/orm/query/sequence_pk_generator.cpp | 5 +++-- source/orm/query/table_pk_generator.cpp | 22 +++++++++++++++++++ 17 files changed, 132 insertions(+), 31 deletions(-) create mode 100644 include/matador/query/database.hpp create mode 100644 include/matador/query/manual_pk_generator.hpp create mode 100644 include/matador/query/table_pk_generator.hpp create mode 100644 source/orm/query/abstract_pk_generator.cpp create mode 100644 source/orm/query/manual_pk_generator.cpp create mode 100644 source/orm/query/table_pk_generator.cpp diff --git a/backends/postgres/test/CMakeLists.txt b/backends/postgres/test/CMakeLists.txt index ad29d5c..b3bdd32 100644 --- a/backends/postgres/test/CMakeLists.txt +++ b/backends/postgres/test/CMakeLists.txt @@ -2,8 +2,8 @@ CPMAddPackage("gh:catchorg/Catch2@3.7.1") list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/extras) -set(POSTGRES_CONNECTION_STRING "postgres://test:test123!@127.0.0.1:15442/matador") -#set(POSTGRES_CONNECTION_STRING "postgres://test:test123!@127.0.0.1:5432/matador") +#set(POSTGRES_CONNECTION_STRING "postgres://test:test123!@127.0.0.1:15442/matador") +set(POSTGRES_CONNECTION_STRING "postgres://test:test123!@127.0.0.1:5432/matador") configure_file(Connection.hpp.in ${PROJECT_BINARY_DIR}/backends/postgres/test/connection.hpp @ONLY IMMEDIATE) diff --git a/include/matador/orm/session.hpp b/include/matador/orm/session.hpp index 7461c17..9a8d782 100644 --- a/include/matador/orm/session.hpp +++ b/include/matador/orm/session.hpp @@ -112,7 +112,7 @@ utils::result, utils::error> session::insert(object::ob // Execute all steps; for Identity steps read RETURNING and write pk back into the object for (auto &step : *steps) { if (step.pk_is_unset && step.set_pk) { - if (step.pk_generator == utils::generator_type::Manually) { + if (step.pk_generator == utils::generator_type::Manual) { if (step.pk_is_unset()) { return utils::failure(make_error(error_code::NoPrimaryKey, "Manual primary key is required but unset.")); } diff --git a/include/matador/query/abstract_pk_generator.hpp b/include/matador/query/abstract_pk_generator.hpp index 1f9fd29..6c6943b 100644 --- a/include/matador/query/abstract_pk_generator.hpp +++ b/include/matador/query/abstract_pk_generator.hpp @@ -3,6 +3,7 @@ #include "matador/utils/error.hpp" #include "matador/utils/result.hpp" +#include "matador/utils/primary_key_generator_type.hpp" #include @@ -14,6 +15,14 @@ class abstract_pk_generator { public: virtual ~abstract_pk_generator() = default; virtual utils::result next_id(const sql::executor& exec) = 0; + + [[nodiscard]] utils::generator_type type() const; + +protected: + explicit abstract_pk_generator(utils::generator_type type); + +private: + utils::generator_type generator_type_{}; }; } #endif //MATADOR_ABSTRACT_PK_GENERATOR_HPP \ No newline at end of file diff --git a/include/matador/query/basic_schema.hpp b/include/matador/query/basic_schema.hpp index 2173413..5a01f87 100644 --- a/include/matador/query/basic_schema.hpp +++ b/include/matador/query/basic_schema.hpp @@ -1,31 +1,33 @@ #ifndef MATADOR_BASIC_SCHEMA_HPP #define MATADOR_BASIC_SCHEMA_HPP -#include -#include -#include - #include "matador/object/repository.hpp" +#include "matador/query/abstract_pk_generator.hpp" #include "matador/query/table.hpp" #include "matador/sql/internal/collection_resolver_producer.hpp" #include "matador/sql/internal/object_resolver_producer.hpp" #include "matador/sql/producer_resolver_factory.hpp" +#include +#include +#include + namespace matador::query { class schema_node final { public: - schema_node(class table tab, utils::generator_type generator_type, const object::repository_node& node); + schema_node(class table tab, std::unique_ptr &&pk_generator, const object::repository_node& node); [[nodiscard]] const std::string& name() const; [[nodiscard]] const class table& table() const; - [[nodiscard]] utils::generator_type generator_type() const; + [[nodiscard]] abstract_pk_generator& pk_generator() const; [[nodiscard]] const object::repository_node& node() const; private: class table table_; utils::generator_type generator_type_{}; + std::unique_ptr pk_generator_; const object::repository_node& node_; }; @@ -33,7 +35,7 @@ class primary_key_generator_finder final { public: template< typename Type > utils::generator_type find(const object::object_info& info) { - generator_type_ = utils::generator_type::Manually; + generator_type_ = utils::generator_type::Manual; access::process(*this, info.prototype()); diff --git a/include/matador/query/database.hpp b/include/matador/query/database.hpp new file mode 100644 index 0000000..58ddb85 --- /dev/null +++ b/include/matador/query/database.hpp @@ -0,0 +1,20 @@ +#ifndef MATADOR_DATABASE_HPP +#define MATADOR_DATABASE_HPP + +#include "matador/query/schema.hpp" +#include "matador/utils/result.hpp" +#include "matador/utils/error.hpp" + +namespace matador::query { +class database final { +public: + utils::result add(const std::string &name, const schema &schema); + utils::result remove(const std::string &name); + + [[nodiscard]] utils::result get(const std::string &name); + +private: + std::unordered_map schema_map_; +}; +} +#endif //MATADOR_DATABASE_HPP \ No newline at end of file diff --git a/include/matador/query/insert_query_builder.hpp b/include/matador/query/insert_query_builder.hpp index e01f89f..cba6056 100644 --- a/include/matador/query/insert_query_builder.hpp +++ b/include/matador/query/insert_query_builder.hpp @@ -89,7 +89,7 @@ public: step_query_t query; // Session uses these to handle manual/sequence/table pre-insert PKs - utils::generator_type pk_generator{utils::generator_type::Manually}; + utils::generator_type pk_generator{utils::generator_type::Manual}; std::string pk_name; std::function pk_is_unset{}; @@ -228,7 +228,7 @@ private: insert_step step{}; if (info.has_primary_key()) { step.pk_name = info.primary_key_attribute()->name(); - step.pk_generator = it->second.generator_type(); + step.pk_generator = it->second.pk_generator().type(); step.pk_is_unset = [ptr, name = step.pk_name]() { pk_unset_checker chk{name}; diff --git a/include/matador/query/manual_pk_generator.hpp b/include/matador/query/manual_pk_generator.hpp new file mode 100644 index 0000000..df36240 --- /dev/null +++ b/include/matador/query/manual_pk_generator.hpp @@ -0,0 +1,13 @@ +#ifndef MATADOR_MANUAL_PK_GENERATOR_HPP +#define MATADOR_MANUAL_PK_GENERATOR_HPP + +#include "matador/query/abstract_pk_generator.hpp" + +namespace matador::query { +class manual_pk_generator : public abstract_pk_generator { +public: + manual_pk_generator(); + [[nodiscard]] utils::result next_id(const sql::executor& exec) override; +}; +} +#endif //MATADOR_MANUAL_PK_GENERATOR_HPP \ No newline at end of file diff --git a/include/matador/query/schema.hpp b/include/matador/query/schema.hpp index e2cad6c..1bcc1a7 100644 --- a/include/matador/query/schema.hpp +++ b/include/matador/query/schema.hpp @@ -183,17 +183,6 @@ class schema; using schema_ref = std::reference_wrapper; -class schema_repository final { -public: - utils::result add(const std::string &name, const schema &schema); - utils::result remove(const std::string &name); - - [[nodiscard]] utils::result get(const std::string &name); - -private: - std::unordered_map schema_map_; -}; - template class schema_observer final : public object::observer { public: diff --git a/include/matador/query/table_pk_generator.hpp b/include/matador/query/table_pk_generator.hpp new file mode 100644 index 0000000..2a0d1be --- /dev/null +++ b/include/matador/query/table_pk_generator.hpp @@ -0,0 +1,16 @@ +#ifndef MATADOR_TABLE_PK_GENERATOR_HPP +#define MATADOR_TABLE_PK_GENERATOR_HPP + +#include "matador/query/abstract_pk_generator.hpp" + +namespace matador::query { +class table_pk_generator : public abstract_pk_generator { +public: + table_pk_generator(const std::string& table_name, const std::string& sequence_name); + [[nodiscard]] utils::result next_id(const sql::executor& exec) override; + +private: + std::string table_name; +}; +} +#endif //MATADOR_TABLE_PK_GENERATOR_HPP \ No newline at end of file diff --git a/include/matador/utils/primary_key_attribute.hpp b/include/matador/utils/primary_key_attribute.hpp index b7fa6ba..42f5154 100644 --- a/include/matador/utils/primary_key_attribute.hpp +++ b/include/matador/utils/primary_key_attribute.hpp @@ -44,7 +44,7 @@ public: [[nodiscard]] generator_type generator() const; private: size_t size_ = 0; - generator_type generator_ = generator_type::Manually; + generator_type generator_ = generator_type::Manual; }; const primary_key_attribute default_pk_attributes {}; diff --git a/include/matador/utils/primary_key_generator_type.hpp b/include/matador/utils/primary_key_generator_type.hpp index 5f668dd..b815115 100644 --- a/include/matador/utils/primary_key_generator_type.hpp +++ b/include/matador/utils/primary_key_generator_type.hpp @@ -3,7 +3,7 @@ namespace matador::utils { enum class generator_type { - Manually, /**< User sets the primary key value manually. */ + Manual, /**< User sets the primary key value manually. */ Auto, /**< Matador chooses the best generator type depending on the underlying dbms. */ Identity, /**< DBMS automatically generates the primary key value. */ Sequence, /**< DBMS automatically generates the primary key value by using a sequence table. */ diff --git a/source/orm/CMakeLists.txt b/source/orm/CMakeLists.txt index 25e9159..8a886a8 100644 --- a/source/orm/CMakeLists.txt +++ b/source/orm/CMakeLists.txt @@ -192,6 +192,12 @@ add_library(matador-orm STATIC sql/resolver_service.cpp sql/statement.cpp sql/statement_cache.cpp + ../../include/matador/query/database.hpp + query/abstract_pk_generator.cpp + ../../include/matador/query/manual_pk_generator.hpp + query/manual_pk_generator.cpp + ../../include/matador/query/table_pk_generator.hpp + query/table_pk_generator.cpp ) target_include_directories(matador-orm diff --git a/source/orm/query/abstract_pk_generator.cpp b/source/orm/query/abstract_pk_generator.cpp new file mode 100644 index 0000000..d7367f8 --- /dev/null +++ b/source/orm/query/abstract_pk_generator.cpp @@ -0,0 +1,10 @@ +#include "matador/query/abstract_pk_generator.hpp" + +namespace matador::query { +abstract_pk_generator::abstract_pk_generator(const utils::generator_type type) +: generator_type_{type} {} + +utils::generator_type abstract_pk_generator::type() const { + return generator_type_; +} +} diff --git a/source/orm/query/basic_schema.cpp b/source/orm/query/basic_schema.cpp index 108e373..8166a0b 100644 --- a/source/orm/query/basic_schema.cpp +++ b/source/orm/query/basic_schema.cpp @@ -3,9 +3,9 @@ #include "matador/sql/executor.hpp" namespace matador::query { -schema_node::schema_node(class table tab, utils::generator_type generator_type, const object::repository_node& node) +schema_node::schema_node(class table tab, std::unique_ptr &&pk_generator, const object::repository_node& node) : table_(std::move(tab)) -, generator_type_(generator_type) +, pk_generator_(std::move(pk_generator)) , node_(std::move(node)) { } @@ -17,8 +17,8 @@ const table &schema_node::table() const { return table_; } -utils::generator_type schema_node::generator_type() const { - return generator_type_; +abstract_pk_generator& schema_node::pk_generator() const { + return *pk_generator_; } const object::repository_node& schema_node::node() const { diff --git a/source/orm/query/manual_pk_generator.cpp b/source/orm/query/manual_pk_generator.cpp new file mode 100644 index 0000000..520b049 --- /dev/null +++ b/source/orm/query/manual_pk_generator.cpp @@ -0,0 +1,13 @@ +#include "matador/query/manual_pk_generator.hpp" + +#include "matador/sql/error_code.hpp" + +namespace matador::query { +manual_pk_generator::manual_pk_generator() +: abstract_pk_generator(utils::generator_type::Manual){ +} + +utils::result manual_pk_generator::next_id(const sql::executor &/*exec*/) { + return utils::failure(utils::error(sql::error_code::FAILURE, "Manual PK generator not implemented")); +} +} diff --git a/source/orm/query/sequence_pk_generator.cpp b/source/orm/query/sequence_pk_generator.cpp index 7f529eb..949e356 100644 --- a/source/orm/query/sequence_pk_generator.cpp +++ b/source/orm/query/sequence_pk_generator.cpp @@ -5,11 +5,12 @@ namespace matador::query { sequence_pk_generator::sequence_pk_generator(const std::string& sequence_name) -: query_(query::select().nextval(sequence_name)) { +: abstract_pk_generator(utils::generator_type::Sequence) +, query_(query::select().nextval(sequence_name)) { } utils::result sequence_pk_generator::next_id(const sql::executor& exec) { - return query_.fetch_value(exec).and_then([](std::optional id) -> utils::result { + return query_.fetch_value(exec).and_then([](const std::optional id) -> utils::result { if (!id) { return utils::failure(utils::error(sql::error_code::RETRIEVE_DATA_FAILED, "Sequence returned no value")); } diff --git a/source/orm/query/table_pk_generator.cpp b/source/orm/query/table_pk_generator.cpp new file mode 100644 index 0000000..1ad1578 --- /dev/null +++ b/source/orm/query/table_pk_generator.cpp @@ -0,0 +1,22 @@ +#include "matador/query/table_pk_generator.hpp" +#include "matador/query/query.hpp" + +namespace matador::query { +table_pk_generator::table_pk_generator(const std::string& table_name, const std::string &sequence_name) +: abstract_pk_generator(utils::generator_type::Table) { + + // query::update(table_name) + // .set("next_id", "next_id + 1") + // .where("name", "=", table_name) + // .returning("next_id - 1 AS id"); + /* + *UPDATE id_table + SET next_id = next_id + 1 + WHERE name = 'users' + RETURNING next_id - 1 AS id; + */ +} + +utils::result table_pk_generator::next_id(const sql::executor &exec) { +} +}