added test for table sequence

This commit is contained in:
sascha 2026-03-19 11:52:34 +01:00
parent 6423bd505b
commit 6b2db17f58
11 changed files with 137 additions and 26 deletions

View File

@ -37,6 +37,9 @@ set(TEST_SOURCES
../../../test/backends/SequenceFixture.hpp
../../../test/backends/SequenceFixture.cpp
../../../test/backends/SequenceTest.cpp
../../../test/backends/TableSequenceFixture.hpp
../../../test/backends/TableSequenceFixture.cpp
../../../test/backends/TableSequenceTest.cpp
)
set(LIBRARY_TEST_TARGET PostgresTests)

View File

@ -52,6 +52,7 @@ struct LoginHistory : core::Model {
template<typename Operator>
void process( Operator& op ) {
namespace field = matador::access;
field::process_base<Model>( op, *this );
field::process( op, *matador::base_class<Model>( this ) );
field::belongs_to( op, "client", client, matador::utils::CascadeAllFetchLazy );
field::belongs_to( op, "scenario", scenario, matador::utils::CascadeAllFetchLazy );

View File

@ -13,6 +13,7 @@
namespace matador::query {
class table;
class column_expression;
// ReSharper disable CppNonExplicitConvertingConstructor
class table_column {
@ -35,6 +36,7 @@ public:
table_column(const std::shared_ptr<abstract_column_expression>& expression) noexcept;
table_column(column_expression&& expression) noexcept;
table_column& operator=(const table_column& other);
table_column(const table_column& other) = default;
table_column(table_column&& other) noexcept = default;

View File

@ -25,6 +25,20 @@ void process(Operator &op, const Type &object) {
process(op, const_cast<Type &>(object));
}
template<class Base, class Derived, class Operator>
void process_base(Operator &op, const Derived &object) {
static_assert(!std::is_same_v<Base, Derived>, "class Base must not be of same type as class Derived");
static_assert(std::is_base_of_v<Base, Derived>, "class Base must be base of class Derived");
process(op, static_cast<const Base&>(object));
}
template<class Base, class Derived, class Operator>
void process_base(Operator &op, Derived &object) {
static_assert(!std::is_same_v<Base, Derived>, "class Base must not be of same type as class Derived");
static_assert(std::is_base_of_v<Base, Derived>, "class Base must be base of class Derived");
process(op, static_cast<Base&>(object));
}
template< class Operator, class Type >
void primary_key(Operator &op, const char *id, Type &value, const utils::primary_key_attribute &attr) {
op.on_primary_key(id, value, attr);

View File

@ -8,33 +8,31 @@ namespace matador {
/**
* @brief Safely casts a given derived class to its base class
*
* @tparam B The base class type
* @tparam D The class type of the derived class
* @tparam Base The base class type
* @tparam Derived The class type of the derived class
* @param derived The derived object
* @return The cast object
*/
template < class B, class D>
const B* base_class(const D *derived)
{
static_assert(!std::is_same_v<B, D>, "class B must not be of same type as class D");
static_assert(std::is_base_of_v<B, D>, "class B must be base of class D");
return static_cast<const B*>(derived);
template < class Base, class Derived>
const Base* base_class(const Derived *derived) {
static_assert(!std::is_same_v<Base, Derived>, "class Base must not be of same type as class Derived");
static_assert(std::is_base_of_v<Base, Derived>, "class Base must be base of class Derived");
return static_cast<const Base*>(derived);
}
/**
* @brief Safely casts a given derived class to its base class
*
* @tparam B The base class type
* @tparam D The class type of the derived class
* @tparam Base The base class type
* @tparam Derived The class type of the derived class
* @param derived The derived object
* @return The cast object
*/
template < class B, class D>
B* base_class(D *derived)
{
static_assert(!std::is_same_v<B, D>, "class B must not be of same type as class D");
static_assert(std::is_base_of_v<B, D>, "class B must be base of class D");
return static_cast<B*>(derived);
template < class Base, class Derived>
Base* base_class(Derived *derived) {
static_assert(!std::is_same_v<Base, Derived>, "class Base must not be of same type as class Derived");
static_assert(std::is_base_of_v<Base, Derived>, "class Base must be base of class Derived");
return static_cast<Base*>(derived);
}
}

View File

@ -15,6 +15,7 @@ void prepare_column(sql::query_context& ctx, const sql::dialect& d, const table_
attribute_string_writer writer(d, {});
expression_evaluator v(d, ctx);
col.expression()->accept(v);
ctx.sql += v.result();
if (col.has_alias()) {
ctx.sql.append(" ").append(d.as()).append(" ").append(col.alias());

View File

@ -5,6 +5,8 @@
#include <stdexcept>
#include <utility>
#include "matador/query/expression/column_expression.hpp"
namespace matador::query {
table_column operator ""_col(const char *name, const size_t len) {
@ -67,6 +69,10 @@ table_column::table_column(const class table* tab,
table_column::table_column(const std::shared_ptr<abstract_column_expression>& expression) noexcept
: table_column(nullptr, "", "", utils::basic_type::Unknown, {}, sql::sql_function_t::None, expression) {}
table_column::table_column(column_expression&& expression) noexcept
: table_column(std::shared_ptr(expression.release())) {
}
table_column & table_column::operator=(const table_column &other) {
if (this == &other) {
return *this;
@ -95,7 +101,7 @@ bool table_column::equals(const table_column &x) const {
}
table_column table_column::as(const std::string& alias) const {
return {table_, column_name_, alias, type_, attributes_, function_};
return {table_, column_name_, alias, type_, attributes_, function_, expression_};
}
const std::string& table_column::name() const {

View File

@ -1,8 +1,6 @@
#ifndef MATADOR_SEQUENCE_FIXTURE_HPP
#define MATADOR_SEQUENCE_FIXTURE_HPP
#include "matador/query/schema.hpp"
#include "matador/sql/connection.hpp"
#include <stack>
@ -10,18 +8,18 @@
namespace matador::test {
class SequenceFixture {
public:
SequenceFixture();
~SequenceFixture();
SequenceFixture();
~SequenceFixture();
void check_sequence_exists(const std::string &sequence_name) const;
void check_sequence_not_exists(const std::string &sequence_name) const;
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 <std::string> sequences_to_drop;
sql::connection db;
std::stack <std::string> sequences_to_drop;
private:
void drop_sequence_if_exists(const std::string &sequence_name) const;
void drop_sequence_if_exists(const std::string &sequence_name) const;
};
}

View File

@ -0,0 +1,30 @@
#include "TableSequenceFixture.hpp"
#include "matador/query/query.hpp"
#include "matador/query/builder.hpp"
#include "connection.hpp"
#include "catch2/catch_test_macros.hpp"
namespace matador::test {
TableSequenceFixture::TableSequenceFixture()
: db(connection::dns) {
REQUIRE(db.open());
REQUIRE(query::query::create()
.table(sequence_table_name)
.columns({
query::column("name", utils::basic_type::Varchar, 255),
query::column("next_id", utils::basic_type::Int64)
})
.execute(db));
}
TableSequenceFixture::~TableSequenceFixture() {
REQUIRE(query::query::drop()
.table(sequence_table_name)
.execute(db));
REQUIRE(db.close());
}
}

View File

@ -0,0 +1,18 @@
#ifndef MATADOR_TABLE_SEQUENCE_FIXTURE_HPP
#define MATADOR_TABLE_SEQUENCE_FIXTURE_HPP
#include "matador/sql/connection.hpp"
namespace matador::test {
class TableSequenceFixture {
public:
TableSequenceFixture();
~TableSequenceFixture();
protected:
sql::connection db;
std::string sequence_table_name{"test_seq_table"};
};
}
#endif //MATADOR_TABLE_SEQUENCE_FIXTURE_HPP

View File

@ -0,0 +1,40 @@
#include "catch2/catch_test_macros.hpp"
#include "matador/query/criteria.hpp"
#include "matador/query/expression/expression_operators.hpp"
#include "matador/query/query.hpp"
#include "matador/query/table_column.hpp"
#include "TableSequenceFixture.hpp"
using namespace matador::query;
using namespace matador::test;
TEST_CASE_METHOD(TableSequenceFixture, "test create and drop table sequence", "[table_sequence][create][drop]") {
const auto next_id_col = "next_id"_col;
auto result = query::query::insert()
.into(sequence_table_name, { "name", next_id_col})
.values({ "test_seq", 1 })
.execute(db);
REQUIRE(result);
REQUIRE(result->affected_rows == 1);
table_column exp(next_id_col - 1);
auto id_result = query::query::update(sequence_table_name)
.set(next_id_col, next_id_col + 1)
.where("name"_col == "test_seq")
.returning((next_id_col - 1).as("id"))
.fetch_value<int64_t>(db);
REQUIRE(id_result);
REQUIRE(id_result->has_value());
REQUIRE(id_result->value() == 1);
id_result = query::query::select({next_id_col})
.from(sequence_table_name)
.where("name"_col == "test_seq")
.fetch_value<int64_t>(db);
REQUIRE(id_result);
REQUIRE(id_result->has_value());
REQUIRE(id_result->value() == 2);
}