added test for table sequence
This commit is contained in:
parent
6423bd505b
commit
6b2db17f58
|
|
@ -37,6 +37,9 @@ set(TEST_SOURCES
|
||||||
../../../test/backends/SequenceFixture.hpp
|
../../../test/backends/SequenceFixture.hpp
|
||||||
../../../test/backends/SequenceFixture.cpp
|
../../../test/backends/SequenceFixture.cpp
|
||||||
../../../test/backends/SequenceTest.cpp
|
../../../test/backends/SequenceTest.cpp
|
||||||
|
../../../test/backends/TableSequenceFixture.hpp
|
||||||
|
../../../test/backends/TableSequenceFixture.cpp
|
||||||
|
../../../test/backends/TableSequenceTest.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBRARY_TEST_TARGET PostgresTests)
|
set(LIBRARY_TEST_TARGET PostgresTests)
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ struct LoginHistory : core::Model {
|
||||||
template<typename Operator>
|
template<typename Operator>
|
||||||
void process( Operator& op ) {
|
void process( Operator& op ) {
|
||||||
namespace field = matador::access;
|
namespace field = matador::access;
|
||||||
|
field::process_base<Model>( op, *this );
|
||||||
field::process( op, *matador::base_class<Model>( this ) );
|
field::process( op, *matador::base_class<Model>( this ) );
|
||||||
field::belongs_to( op, "client", client, matador::utils::CascadeAllFetchLazy );
|
field::belongs_to( op, "client", client, matador::utils::CascadeAllFetchLazy );
|
||||||
field::belongs_to( op, "scenario", scenario, matador::utils::CascadeAllFetchLazy );
|
field::belongs_to( op, "scenario", scenario, matador::utils::CascadeAllFetchLazy );
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
namespace matador::query {
|
namespace matador::query {
|
||||||
|
|
||||||
class table;
|
class table;
|
||||||
|
class column_expression;
|
||||||
|
|
||||||
// ReSharper disable CppNonExplicitConvertingConstructor
|
// ReSharper disable CppNonExplicitConvertingConstructor
|
||||||
class table_column {
|
class table_column {
|
||||||
|
|
@ -35,6 +36,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
table_column(const std::shared_ptr<abstract_column_expression>& expression) noexcept;
|
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& operator=(const table_column& other);
|
||||||
table_column(const table_column& other) = default;
|
table_column(const table_column& other) = default;
|
||||||
table_column(table_column&& other) noexcept = default;
|
table_column(table_column&& other) noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,20 @@ void process(Operator &op, const Type &object) {
|
||||||
process(op, const_cast<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 >
|
template< class Operator, class Type >
|
||||||
void primary_key(Operator &op, const char *id, Type &value, const utils::primary_key_attribute &attr) {
|
void primary_key(Operator &op, const char *id, Type &value, const utils::primary_key_attribute &attr) {
|
||||||
op.on_primary_key(id, value, attr);
|
op.on_primary_key(id, value, attr);
|
||||||
|
|
|
||||||
|
|
@ -8,33 +8,31 @@ namespace matador {
|
||||||
/**
|
/**
|
||||||
* @brief Safely casts a given derived class to its base class
|
* @brief Safely casts a given derived class to its base class
|
||||||
*
|
*
|
||||||
* @tparam B The base class type
|
* @tparam Base The base class type
|
||||||
* @tparam D The class type of the derived class
|
* @tparam Derived The class type of the derived class
|
||||||
* @param derived The derived object
|
* @param derived The derived object
|
||||||
* @return The cast object
|
* @return The cast object
|
||||||
*/
|
*/
|
||||||
template < class B, class D>
|
template < class Base, class Derived>
|
||||||
const B* base_class(const D *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_same_v<B, D>, "class B must not be of same type as class D");
|
static_assert(std::is_base_of_v<Base, Derived>, "class Base must be base of class Derived");
|
||||||
static_assert(std::is_base_of_v<B, D>, "class B must be base of class D");
|
return static_cast<const Base*>(derived);
|
||||||
return static_cast<const B*>(derived);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Safely casts a given derived class to its base class
|
* @brief Safely casts a given derived class to its base class
|
||||||
*
|
*
|
||||||
* @tparam B The base class type
|
* @tparam Base The base class type
|
||||||
* @tparam D The class type of the derived class
|
* @tparam Derived The class type of the derived class
|
||||||
* @param derived The derived object
|
* @param derived The derived object
|
||||||
* @return The cast object
|
* @return The cast object
|
||||||
*/
|
*/
|
||||||
template < class B, class D>
|
template < class Base, class Derived>
|
||||||
B* base_class(D *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_same_v<B, D>, "class B must not be of same type as class D");
|
static_assert(std::is_base_of_v<Base, Derived>, "class Base must be base of class Derived");
|
||||||
static_assert(std::is_base_of_v<B, D>, "class B must be base of class D");
|
return static_cast<Base*>(derived);
|
||||||
return static_cast<B*>(derived);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ void prepare_column(sql::query_context& ctx, const sql::dialect& d, const table_
|
||||||
attribute_string_writer writer(d, {});
|
attribute_string_writer writer(d, {});
|
||||||
expression_evaluator v(d, ctx);
|
expression_evaluator v(d, ctx);
|
||||||
col.expression()->accept(v);
|
col.expression()->accept(v);
|
||||||
|
ctx.sql += v.result();
|
||||||
|
|
||||||
if (col.has_alias()) {
|
if (col.has_alias()) {
|
||||||
ctx.sql.append(" ").append(d.as()).append(" ").append(col.alias());
|
ctx.sql.append(" ").append(d.as()).append(" ").append(col.alias());
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "matador/query/expression/column_expression.hpp"
|
||||||
|
|
||||||
namespace matador::query {
|
namespace matador::query {
|
||||||
|
|
||||||
table_column operator ""_col(const char *name, const size_t len) {
|
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::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(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) {
|
table_column & table_column::operator=(const table_column &other) {
|
||||||
if (this == &other) {
|
if (this == &other) {
|
||||||
return *this;
|
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 {
|
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 {
|
const std::string& table_column::name() const {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
#ifndef MATADOR_SEQUENCE_FIXTURE_HPP
|
#ifndef MATADOR_SEQUENCE_FIXTURE_HPP
|
||||||
#define MATADOR_SEQUENCE_FIXTURE_HPP
|
#define MATADOR_SEQUENCE_FIXTURE_HPP
|
||||||
|
|
||||||
#include "matador/query/schema.hpp"
|
|
||||||
|
|
||||||
#include "matador/sql/connection.hpp"
|
#include "matador/sql/connection.hpp"
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
@ -10,18 +8,18 @@
|
||||||
namespace matador::test {
|
namespace matador::test {
|
||||||
class SequenceFixture {
|
class SequenceFixture {
|
||||||
public:
|
public:
|
||||||
SequenceFixture();
|
SequenceFixture();
|
||||||
~SequenceFixture();
|
~SequenceFixture();
|
||||||
|
|
||||||
void check_sequence_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;
|
void check_sequence_not_exists(const std::string &sequence_name) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
sql::connection db;
|
sql::connection db;
|
||||||
std::stack <std::string> sequences_to_drop;
|
std::stack <std::string> sequences_to_drop;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void drop_sequence_if_exists(const std::string &sequence_name) const;
|
void drop_sequence_if_exists(const std::string &sequence_name) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue