diff --git a/backends/mysql/test/CMakeLists.txt b/backends/mysql/test/CMakeLists.txt index 378f04a..cb8bcd2 100644 --- a/backends/mysql/test/CMakeLists.txt +++ b/backends/mysql/test/CMakeLists.txt @@ -22,7 +22,9 @@ set(TEST_SOURCES ../../tests/QueryTest.cpp ../../tests/SessionTest.cpp ../../tests/ConnectionTest.cpp - ../../tests/SessionRecordTest.cpp) + ../../tests/SessionRecordTest.cpp + ../../tests/StatementTest.cpp + ../../tests/TypeTraitsTest.cpp) set(LIBRARY_TEST_TARGET mysql_tests) diff --git a/backends/postgres/test/CMakeLists.txt b/backends/postgres/test/CMakeLists.txt index 827c2c0..492ceb6 100644 --- a/backends/postgres/test/CMakeLists.txt +++ b/backends/postgres/test/CMakeLists.txt @@ -22,7 +22,9 @@ set(TEST_SOURCES ../../tests/QueryTest.cpp ../../tests/SessionTest.cpp ../../tests/ConnectionTest.cpp - ../../tests/SessionRecordTest.cpp) + ../../tests/SessionRecordTest.cpp + ../../tests/StatementTest.cpp + ../../tests/TypeTraitsTest.cpp) set(LIBRARY_TEST_TARGET postgres_tests) diff --git a/backends/sqlite/test/CMakeLists.txt b/backends/sqlite/test/CMakeLists.txt index 3c9a999..dacc99a 100644 --- a/backends/sqlite/test/CMakeLists.txt +++ b/backends/sqlite/test/CMakeLists.txt @@ -22,7 +22,9 @@ set(TEST_SOURCES ../../tests/QueryTest.cpp ../../tests/SessionTest.cpp ../../tests/ConnectionTest.cpp - ../../tests/SessionRecordTest.cpp) + ../../tests/SessionRecordTest.cpp + ../../tests/StatementTest.cpp + ../../tests/TypeTraitsTest.cpp) set(LIBRARY_TEST_TARGET sqlite_tests) diff --git a/backends/tests/SessionRecordTest.cpp b/backends/tests/SessionRecordTest.cpp index b0151aa..d4daa96 100644 --- a/backends/tests/SessionRecordTest.cpp +++ b/backends/tests/SessionRecordTest.cpp @@ -1,3 +1,361 @@ -// -// Created by sascha on 28.01.24. -// +#include + +#include "matador/sql/column.hpp" +#include "matador/sql/condition.hpp" +#include "matador/sql/session.hpp" + +#include "connection.hpp" + +#include + +class SessionRecordFixture +{ +public: + SessionRecordFixture() + : pool(matador::test::connection::dns, 4), ses(pool) + {} + ~SessionRecordFixture() { + drop_table_if_exists("flight"); + drop_table_if_exists("airplane"); + drop_table_if_exists("person"); + } + +protected: + matador::sql::connection_pool pool; + matador::sql::session ses; + +private: + void drop_table_if_exists(const std::string &table_name) { + if (ses.table_exists(table_name)) { + ses.drop().table(table_name).execute(); + } + } +}; + +using namespace matador::sql; + +TEST_CASE_METHOD(SessionRecordFixture, " Create and drop table statement", "[session record]") +{ + REQUIRE(!ses.table_exists("person")); + ses.create() + .table("person", { + make_pk_column("id"), + make_column("name", 255), + make_column("age") + }) + .execute(); + + REQUIRE(ses.table_exists("person")); + + ses.drop() + .table("person") + .execute(); + + REQUIRE(!ses.table_exists("person")); +} + +TEST_CASE_METHOD(SessionRecordFixture, " Create and drop table statement with foreign key", "[session record]") +{ + ses.create() + .table("airplane", { + make_pk_column("id"), + make_column("brand", 255), + make_column("model", 255), + }) + .execute(); + + REQUIRE(ses.table_exists("airplane")); + + ses.create() + .table("flight", { + make_pk_column("id"), + make_fk_column("airplane_id", "airplane", "id"), + make_column("pilot_name", 255), + }) + .execute(); + + REQUIRE(ses.table_exists("flight")); + + ses.drop() + .table("flight") + .execute(); + + REQUIRE(!ses.table_exists("flight")); + + ses.drop() + .table("airplane") + .execute(); + + REQUIRE(!ses.table_exists("airplane")); +} + +TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement", "[session record]") +{ + ses.create() + .table("person", { + make_pk_column("id"), + make_column("name", 255), + make_column("age") + }) + .execute(); + + auto res = ses.insert() + .into("person", {"id", "name", "age"}) + .values({7, "george", 45}) + .execute(); + + REQUIRE(res == 1); + + auto result = ses.select({"id", "name", "age"}) + .from("person") + .fetch_all(); + + for (const auto &i: result) { + REQUIRE(i.size() == 3); + REQUIRE(i.at(0).name() == "id"); + // REQUIRE(i.at(0).type() == data_type_t::type_long_long); + REQUIRE(i.at(0).template as() == 7); + REQUIRE(i.at(1).name() == "name"); + // REQUIRE(i.at(1).type() == data_type_t::type_varchar); + REQUIRE(i.at(1).template as() == "george"); + REQUIRE(i.at(2).name() == "age"); + // REQUIRE(i.at(2).type() == matador::sql::data_type_t::type_int); + REQUIRE(i.at(2).template as() == 45); + } + + ses.drop() + .table("person") + .execute(); +} + +TEST_CASE_METHOD(SessionRecordFixture, " Execute insert record statement with foreign key", "[session record]") +{ + ses.create() + .table("airplane", { + make_pk_column("id"), + make_column("brand", 255), + make_column("model", 255), + }) + .execute(); + + ses.create() + .table("flight", { + make_pk_column("id"), + make_fk_column("airplane_id", "airplane", "id"), + make_column("pilot_name", 255), + }) + .execute(); + + auto res = ses.insert().into("airplane", {"id", "brand", "model"}).values({1, "Airbus", "A380"}).execute(); + REQUIRE(res == 1); + + res = ses.insert().into("airplane", {"id", "brand", "model"}).values({2, "Boeing", "707"}).execute(); + REQUIRE(res == 1); + + res = ses.insert().into("airplane", {"id", "brand", "model"}).values({3, "Boeing", "747"}).execute(); + REQUIRE(res == 1); + + auto count = ses.select({count_all()}).from("airplane").fetch_value(); + REQUIRE(count == 3); + + res = ses.insert().into("flight", {"id", "airplane_id", "pilot_name"}).values({4, 1, "George"}).execute(); + REQUIRE(res == 1); + + ses.drop().table("flight").execute(); + ses.drop().table("airplane").execute(); + + REQUIRE(!ses.table_exists("flight")); + REQUIRE(!ses.table_exists("airplane")); +} + +TEST_CASE_METHOD(SessionRecordFixture, " Execute update record statement", "[session record]") +{ + ses.create() + .table("person", { + make_pk_column("id"), + make_column("name", 255), + make_column("age") + }) + .execute(); + + auto res = ses.insert() + .into("person", {"id", "name", "age"}) + .values({7, "george", 45}) + .execute(); + + REQUIRE(res == 1); + + res = ses.update("person") + .set({{"id", 7}, + {"name", "jane"}, + {"age", 35}}) + .where("id"_col == 7) + .execute(); + + REQUIRE(res == 1); + + auto result = ses.select({"id", "name", "age"}) + .from("person") + .fetch_all(); + + for (const auto &i: result) { + REQUIRE(i.size() == 3); + REQUIRE(i.at(0).name() == "id"); + REQUIRE(i.at(0).type() == data_type_t::type_long_long); + REQUIRE(i.at(0).as() == 7); + REQUIRE(i.at(1).name() == "name"); + REQUIRE(i.at(1).type() == data_type_t::type_varchar); + REQUIRE(i.at(1).as() == "jane"); + REQUIRE(i.at(2).name() == "age"); + REQUIRE(i.at(2).type() == matador::sql::data_type_t::type_int); + REQUIRE(i.at(2).as() == 35); + } + + ses.drop().table("person").execute(); +} + +TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement", "[session record]") +{ + ses.create() + .table("person", { + make_pk_column("id"), + make_column("name", 255), + make_column("age") + }) + .execute(); + + auto res = ses.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute(); + REQUIRE(res == 1); + + auto result = ses.select({"id", "name", "age"}) + .from("person") + .fetch_all(); + + std::list expected_names{"george", "jane", "michael", "bob"}; + for (const auto &p: result) { + REQUIRE(p.at(1).str() == expected_names.front()); + expected_names.pop_front(); + } + REQUIRE(expected_names.empty()); + + auto rec = ses.select({"id", "name", "age"}) + .from("person") + .fetch_one(); + REQUIRE(rec.at(1).str() == "george"); + + auto name = ses.select({"name"}) + .from("person") + .fetch_value(); + REQUIRE(name == "george"); + + ses.drop().table("person").execute(); +} + +TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with order by", "[session record]") +{ + ses.create() + .table("person", { + make_pk_column("id"), + make_column("name", 255), + make_column("age") + }) + .execute(); + + auto res = ses.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute(); + REQUIRE(res == 1); + + auto result = ses.select({"id", "name", "age"}) + .from("person") + .order_by("name").asc() + .fetch_all(); + + std::list expected_names{"bob", "george", "jane", "michael"}; + for (const auto &p: result) { + REQUIRE(p.at(1).str() == expected_names.front()); + expected_names.pop_front(); + } + REQUIRE(expected_names.empty()); + + ses.drop().table("person").execute(); +} + +TEST_CASE_METHOD(SessionRecordFixture, " Execute select statement with group by and order by", "[session record]") +{ + ses.create() + .table("person", { + make_pk_column("id"), + make_column("name", 255), + make_column("age") + }) + .execute(); + + auto res = ses.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({3, "michael", 13}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({5, "charlie", 67}).execute(); + REQUIRE(res == 1); + + auto result = ses.select({alias(count("age"), "age_count"), "age"}) + .from("person") + .group_by("age") + .order_by("age_count").desc() + .fetch_all(); + + std::list> expected_values{{2, 45}, + {2, 13}, + {1, 67}}; + for (const auto &r: result) { + REQUIRE(r.at(0).as() == expected_values.front().first); + REQUIRE(r.at(1).as() == expected_values.front().second); + expected_values.pop_front(); + } + + ses.drop().table("person").execute(); +} + +TEST_CASE_METHOD(SessionRecordFixture, " Execute delete statement", "[session record]") +{ + ses.create() + .table("person", { + make_pk_column("id"), + make_column("name", 255), + make_column("age") + }).execute(); + + auto res = ses.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute(); + REQUIRE(res == 1); + res = ses.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute(); + REQUIRE(res == 1); + + auto count = ses.select({count_all()}).from("person").fetch_value(); + REQUIRE(count == 2); + + res = ses.remove() + .from("person") + .where("id"_col == 1) + .execute(); + + REQUIRE(res == 1); + + count = ses.select({count_all()}).from("person").fetch_value(); + REQUIRE(count == 1); + + ses.drop().table("person").execute(); +} diff --git a/test/StatementTest.cpp b/backends/tests/StatementTest.cpp similarity index 50% rename from test/StatementTest.cpp rename to backends/tests/StatementTest.cpp index 6d0515d..628b4ac 100644 --- a/test/StatementTest.cpp +++ b/backends/tests/StatementTest.cpp @@ -1,5 +1,4 @@ #include -#include #include "matador/sql/column.hpp" #include "matador/sql/condition.hpp" @@ -7,56 +6,52 @@ #include "matador/sql/connection_pool.hpp" #include "matador/sql/session.hpp" -#include "Databases.hpp" +#include "connection.hpp" #include "models/airplane.hpp" using namespace matador::sql; using namespace matador::test; -template class StatementTestFixture { public: StatementTestFixture() - : pool_(Type::dns, 4), session_(pool_) + : pool(matador::test::connection::dns, 4), ses(pool) { - session_.create() - .table("airplane") - .execute(); + ses.create().table("airplane").execute(); } ~StatementTestFixture() { - session_.drop().table("airplane").execute(); + drop_table_if_exists("airplane"); } - matador::sql::session &session() - { return session_; } +protected: + matador::sql::connection_pool pool; + matador::sql::session ses; - std::vector> &planes() - { return planes_; } + std::vector> planes{ + make_entity(1, "Airbus", "A380"), + make_entity(2, "Boeing", "707"), + make_entity(3, "Boeing", "747") + }; private: - matador::sql::connection_pool pool_; - matador::sql::session session_; + void drop_table_if_exists(const std::string &table_name) { + if (ses.table_exists(table_name)) { + ses.drop().table(table_name).execute(); + } + } - std::vector> planes_{ - make_entity(1, "Airbus", "A380"), - make_entity(2, "Boeing", "707"), - make_entity(3, "Boeing", "747") - }; }; -TEMPLATE_TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[statement]", Sqlite, Postgres, MySql) +TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement]") { - auto &s = StatementTestFixture::session(); - auto &planes = StatementTestFixture::planes(); - SECTION("Insert with prepared statement and placeholder") { - auto stmt = s.insert() - .template into("airplane") - .template values().prepare(); + auto stmt = ses.insert() + .into("airplane") + .values().prepare(); for (const auto &plane: planes) { auto res = stmt.bind(*plane).execute(); @@ -64,7 +59,7 @@ TEMPLATE_TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[s stmt.reset(); } - auto result = s.template select().from("airplane").template fetch_all(); + auto result = ses.select().from("airplane").fetch_all(); size_t index{0}; for (const auto &i: result) { @@ -76,15 +71,15 @@ TEMPLATE_TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[s SECTION("Select with prepared statement") { for (const auto &plane: planes) { - auto res = s.insert().template into("airplane").values(*plane).execute(); + auto res = ses.insert().into("airplane").values(*plane).execute(); REQUIRE(res == 1); } - auto stmt = s.template select().from("airplane").where("brand"_col == _).prepare(); + auto stmt = ses.select().from("airplane").where("brand"_col == _).prepare(); stmt.bind(0, "Airbus"); - auto result = stmt.template fetch(); + auto result = stmt.fetch(); for (const auto &i: result) { REQUIRE(i.id == planes[0]->id); @@ -96,7 +91,7 @@ TEMPLATE_TEST_CASE_METHOD(StatementTestFixture, "Create prepared statement", "[s stmt.bind(0, "Boeing"); - result = stmt.template fetch(); + result = stmt.fetch(); size_t index{1}; for (const auto &i: result) { diff --git a/test/TypeTraitsTest.cpp b/backends/tests/TypeTraitsTest.cpp similarity index 68% rename from test/TypeTraitsTest.cpp rename to backends/tests/TypeTraitsTest.cpp index de9af92..5ebf633 100644 --- a/test/TypeTraitsTest.cpp +++ b/backends/tests/TypeTraitsTest.cpp @@ -1,44 +1,41 @@ #include -#include -#include "matador/sql/connection_pool.hpp" #include "matador/sql/session.hpp" #include "matador/utils/enum_mapper.hpp" -#include "Databases.hpp" +#include "connection.hpp" #include "models/location.hpp" -using namespace matador::sql; using namespace matador::test; -using namespace matador::sql; -using namespace matador::test; - -template class TypeTraitsTestFixture { public: TypeTraitsTestFixture() - : pool_(Type::dns, 4), session_(pool_) + : pool(matador::test::connection::dns, 4), ses(pool) { - session_.create() + ses.create() .table("location") .execute(); } ~TypeTraitsTestFixture() { - session_.drop().table("location").execute(); + ses.drop().table("location").execute(); } - matador::sql::session &session() - { return session_; } +protected: + matador::sql::connection_pool pool; + matador::sql::session ses; private: - matador::sql::connection_pool pool_; - matador::sql::session session_; + void drop_table_if_exists(const std::string &table_name) { + if (ses.table_exists(table_name)) { + ses.drop().table(table_name).execute(); + } + } }; static const matador::utils::enum_mapper color_enum({ @@ -83,18 +80,15 @@ struct data_type_traits } -TEMPLATE_TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]", Sqlite, Postgres, MySql) +TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]") { - auto &s = TypeTraitsTestFixture::session(); - SECTION("Insert and select with direct execution") { location loc{1, "center", {1, 2, 3}, Color::Black}; - auto res = s.insert().template into("location").values(loc).execute(); + auto res = ses.insert().into("location").values(loc).execute(); REQUIRE(res == 1); - auto result = s.template select().from("location"). - template fetch_all(); + auto result = ses.select().from("location").fetch_all(); for (const auto &l: result) { REQUIRE(l.name == "center"); @@ -104,11 +98,11 @@ TEMPLATE_TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes SECTION("Insert and select with prepared statement") { location loc{1, "center", {1, 2, 3}, Color::Black}; - auto stmt = s.insert().template into("location").template values().prepare(); + auto stmt = ses.insert().into("location").values().prepare(); auto res = stmt.bind(loc).execute(); REQUIRE(res == 1); - auto result = s.template select().from("location"). + auto result = ses.select().from("location"). template fetch_all(); for (const auto &l: result) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dad6695..bfda9e8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,11 +9,9 @@ FetchContent_Declare( FetchContent_MakeAvailable(Catch2) add_executable(tests QueryBuilderTest.cpp - SessionTest.cpp RecordTest.cpp ConnectionPoolTest.cpp BackendProviderTest.cpp - ConnectionTest.cpp models/product.hpp ColumnGeneratorTest.cpp ColumnNameGeneratorTest.cpp @@ -25,13 +23,9 @@ add_executable(tests QueryBuilderTest.cpp models/person.hpp AnyTypeToVisitorTest.cpp ColumnTest.cpp - SessionRecordTest.cpp StatementCacheTest.cpp - StatementTest.cpp models/coordinate.hpp models/location.hpp - TypeTraitsTest.cpp - Databases.hpp models/optional.hpp ConvertTest.cpp DummyConnection.hpp diff --git a/test/ConnectionTest.cpp b/test/ConnectionTest.cpp deleted file mode 100644 index 68deb5c..0000000 --- a/test/ConnectionTest.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include - -#include "matador/sql/connection.hpp" - -#include "Databases.hpp" - -using namespace matador::sql; - -template -class ConnectionTestFixture -{ -public: - ConnectionTestFixture() = default; - ~ConnectionTestFixture() = default; - - std::string dns() { return Type::dns; } -}; - -TEMPLATE_TEST_CASE_METHOD(ConnectionTestFixture, "Create connection", "[connection]", Sqlite, Postgres, MySql) { - - connection c(ConnectionTestFixture::dns()); - REQUIRE(!c.is_open()); - - c.open(); - REQUIRE(c.is_open()); - - c.close(); - REQUIRE(!c.is_open()); -} \ No newline at end of file diff --git a/test/Databases.hpp b/test/Databases.hpp deleted file mode 100644 index 0b3de2d..0000000 --- a/test/Databases.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef QUERY_DATABASES_HPP -#define QUERY_DATABASES_HPP - -struct Postgres -{ - constexpr static const char *dns{"postgres://test:test123@127.0.0.1:15432/test"}; -// constexpr static const char *dns{"postgres://test:test123@127.0.0.1:5432/matador_test"}; -}; - -struct Sqlite -{ - constexpr static const char *dns{"sqlite://sqlite.db"}; -}; - -struct MySql -{ - constexpr static const char *dns{"mysql://test:test123!@127.0.0.1:3306/testdb"}; -// constexpr static const char *dns{"mysql://test:test123!@127.0.0.1:3306/matador_test"}; -}; - -#endif //QUERY_DATABASES_HPP diff --git a/test/SessionRecordTest.cpp b/test/SessionRecordTest.cpp deleted file mode 100644 index 3e4b4d0..0000000 --- a/test/SessionRecordTest.cpp +++ /dev/null @@ -1,378 +0,0 @@ -#include -#include -#include - -#include -#include - -#include "Databases.hpp" - -#include - -using namespace matador::sql; - -template -class SessionRecordTestFixture -{ -public: - SessionRecordTestFixture() - : pool_(Type::dns, 4), session_(pool_) - {} - - matador::sql::session &session() - { return session_; } - -private: - matador::sql::connection_pool pool_; - matador::sql::session session_; -}; - -TEMPLATE_TEST_CASE_METHOD(SessionRecordTestFixture, "Create and drop table statement", "[session record]", Sqlite, Postgres, MySql) -{ - auto &s = SessionRecordTestFixture::session(); - - REQUIRE(!s.table_exists("person")); - s.create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }) - .execute(); - - REQUIRE(s.table_exists("person")); - - s.drop() - .table("person") - .execute(); - - REQUIRE(!s.table_exists("person")); -} - -TEMPLATE_TEST_CASE_METHOD(SessionRecordTestFixture, "Create and drop table statement with foreign key", "[session record]", Sqlite, Postgres, MySql) -{ - auto &s = SessionRecordTestFixture::session(); - - s.create() - .table("airplane", { - make_pk_column("id"), - make_column("brand", 255), - make_column("model", 255), - }) - .execute(); - - REQUIRE(s.table_exists("airplane")); - - s.create() - .table("flight", { - make_pk_column("id"), - make_fk_column("airplane_id", "airplane", "id"), - make_column("pilot_name", 255), - }) - .execute(); - - REQUIRE(s.table_exists("flight")); - - s.drop() - .table("flight") - .execute(); - - REQUIRE(!s.table_exists("flight")); - - s.drop() - .table("airplane") - .execute(); - - REQUIRE(!s.table_exists("airplane")); -} - -TEMPLATE_TEST_CASE_METHOD(SessionRecordTestFixture, "Execute insert record statement", "[session record]", MySql) -{ - auto &s = SessionRecordTestFixture::session(); - - s.create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }) - .execute(); - - auto res = s.insert() - .into("person", {"id", "name", "age"}) - .values({7, "george", 45}) - .execute(); - - REQUIRE(res == 1); - - auto result = s.select({"id", "name", "age"}) - .from("person") - .fetch_all(); - - for (const auto &i: result) { - REQUIRE(i.size() == 3); - REQUIRE(i.at(0).name() == "id"); -// REQUIRE(i.at(0).type() == data_type_t::type_long_long); - REQUIRE(i.at(0).template as() == 7); - REQUIRE(i.at(1).name() == "name"); -// REQUIRE(i.at(1).type() == data_type_t::type_varchar); - REQUIRE(i.at(1).template as() == "george"); - REQUIRE(i.at(2).name() == "age"); -// REQUIRE(i.at(2).type() == matador::sql::data_type_t::type_int); - REQUIRE(i.at(2).template as() == 45); - } - - s.drop() - .table("person") - .execute(); -} - -TEST_CASE("Execute insert record statement with foreign key", "[session record]") -{ - connection_pool pool("sqlite://sqlite.db", 4); - session s(pool); - - s.create() - .table("airplane", { - make_pk_column("id"), - make_column("brand", 255), - make_column("model", 255), - }) - .execute(); - - s.create() - .table("flight", { - make_pk_column("id"), - make_fk_column("airplane_id", "airplane", "id"), - make_column("pilot_name", 255), - }) - .execute(); - - auto res = s.insert().into("airplane", {"id", "brand", "model"}).values({1, "Airbus", "A380"}).execute(); - REQUIRE(res == 1); - - res = s.insert().into("airplane", {"id", "brand", "model"}).values({2, "Boeing", "707"}).execute(); - REQUIRE(res == 1); - - res = s.insert().into("airplane", {"id", "brand", "model"}).values({3, "Boeing", "747"}).execute(); - REQUIRE(res == 1); - - auto count = s.select({count_all()}).from("airplane").fetch_value(); - REQUIRE(count == 3); - - res = s.insert().into("flight", {"id", "airplane_id", "pilot_name"}).values({4, 1, "George"}).execute(); - REQUIRE(res == 1); - - s.drop().table("flight").execute(); - s.drop().table("airplane").execute(); - - REQUIRE(!s.table_exists("flight")); - REQUIRE(!s.table_exists("airplane")); -} - -TEST_CASE("Execute update record statement", "[session record]") -{ - connection_pool pool("sqlite://sqlite.db", 4); - session s(pool); - - s.create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }) - .execute(); - - auto res = s.insert() - .into("person", {"id", "name", "age"}) - .values({7, "george", 45}) - .execute(); - - REQUIRE(res == 1); - - res = s.update("person") - .set({{"id", 7}, - {"name", "jane"}, - {"age", 35}}) - .where("id"_col == 7) - .execute(); - - REQUIRE(res == 1); - - auto result = s.select({"id", "name", "age"}) - .from("person") - .fetch_all(); - - for (const auto &i: result) { - REQUIRE(i.size() == 3); - REQUIRE(i.at(0).name() == "id"); - REQUIRE(i.at(0).type() == data_type_t::type_long_long); - REQUIRE(i.at(0).as() == 7); - REQUIRE(i.at(1).name() == "name"); - REQUIRE(i.at(1).type() == data_type_t::type_varchar); - REQUIRE(i.at(1).as() == "jane"); - REQUIRE(i.at(2).name() == "age"); - REQUIRE(i.at(2).type() == matador::sql::data_type_t::type_int); - REQUIRE(i.at(2).as() == 35); - } - - s.drop().table("person").execute(); -} - -TEST_CASE("Execute select statement", "[session record]") -{ - connection_pool pool("sqlite://sqlite.db", 4); - session s(pool); - - s.create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }) - .execute(); - - auto res = s.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute(); - REQUIRE(res == 1); - - auto result = s.select({"id", "name", "age"}) - .from("person") - .fetch_all(); - - std::list expected_names{"george", "jane", "michael", "bob"}; - for (const auto &p: result) { - REQUIRE(p.at(1).str() == expected_names.front()); - expected_names.pop_front(); - } - REQUIRE(expected_names.empty()); - - auto rec = s.select({"id", "name", "age"}) - .from("person") - .fetch_one(); - REQUIRE(rec.at(1).str() == "george"); - - auto name = s.select({"name"}) - .from("person") - .fetch_value(); - REQUIRE(name == "george"); - - s.drop().table("person").execute(); -} - -TEST_CASE("Execute select statement with order by", "[session record]") -{ - connection_pool pool("sqlite://sqlite.db", 4); - session s(pool); - - s.create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }) - .execute(); - - auto res = s.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({2, "jane", 32}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({3, "michael", 67}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute(); - REQUIRE(res == 1); - - auto result = s.select({"id", "name", "age"}) - .from("person") - .order_by("name").asc() - .fetch_all(); - - std::list expected_names{"bob", "george", "jane", "michael"}; - for (const auto &p: result) { - REQUIRE(p.at(1).str() == expected_names.front()); - expected_names.pop_front(); - } - REQUIRE(expected_names.empty()); - - s.drop().table("person").execute(); -} - -TEST_CASE("Execute select statement with group by and order by", "[session record]") -{ - connection_pool pool("sqlite://sqlite.db", 4); - session s(pool); - - s.create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }) - .execute(); - - auto res = s.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({3, "michael", 13}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({4, "bob", 13}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({5, "charlie", 67}).execute(); - REQUIRE(res == 1); - - auto result = s.select({alias(count("age"), "age_count"), "age"}) - .from("person") - .group_by("age") - .order_by("age_count").desc() - .fetch_all(); - - std::list> expected_values{{2, 45}, - {2, 13}, - {1, 67}}; - for (const auto &r: result) { - REQUIRE(r.at(0).as() == expected_values.front().first); - REQUIRE(r.at(1).as() == expected_values.front().second); - expected_values.pop_front(); - } - - s.drop().table("person").execute(); -} - -TEST_CASE("Execute delete statement", "[session record]") -{ - connection_pool pool("sqlite://sqlite.db", 4); - session s(pool); - - s.create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("age") - }).execute(); - - auto res = s.insert().into("person", {"id", "name", "age"}).values({1, "george", 45}).execute(); - REQUIRE(res == 1); - res = s.insert().into("person", {"id", "name", "age"}).values({2, "jane", 45}).execute(); - REQUIRE(res == 1); - - auto count = s.select({count_all()}).from("person").fetch_value(); - REQUIRE(count == 2); - - res = s.remove() - .from("person") - .where("id"_col == 1) - .execute(); - - REQUIRE(res == 1); - - count = s.select({count_all()}).from("person").fetch_value(); - REQUIRE(count == 1); - - s.drop().table("person").execute(); -} \ No newline at end of file diff --git a/test/SessionTest.cpp b/test/SessionTest.cpp deleted file mode 100644 index 3d23b1c..0000000 --- a/test/SessionTest.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include - -#include -#include -#include - -#include "Databases.hpp" - -#include "models/product.hpp" -#include "models/airplane.hpp" -#include "models/flight.hpp" -#include "models/person.hpp" - -using namespace matador::sql; -using namespace matador::test; - -template -class SessionTestFixture -{ -public: - SessionTestFixture() - : pool_(Type::dns, 4), session_(pool_) - {} - ~SessionTestFixture() = default; - - matador::sql::session &session() - { return session_; } - -private: - matador::sql::connection_pool pool_; - matador::sql::session session_; -}; - -TEMPLATE_TEST_CASE_METHOD(SessionTestFixture, "Create table with foreign key relation", "[session]", Sqlite, Postgres) { - auto &s = SessionTestFixture::session(); - - s.create() - .template table("airplane") - .execute(); - - REQUIRE(s.table_exists("airplane")); - - s.create() - .template table("flight") - .execute(); - - REQUIRE(s.table_exists("flight")); - - s.drop().table("flight").execute(); - s.drop().table("airplane").execute(); - - REQUIRE(!s.table_exists("flight")); - REQUIRE(!s.table_exists("airplane")); -} - -TEMPLATE_TEST_CASE_METHOD(SessionTestFixture, "Execute select statement with where clause", "[session]", Postgres) { - auto &s = SessionTestFixture::session(); - - s.create() - .template table("person") - .execute(); - - person george{7, "george", 45}; - - auto res = s.insert() - .into("person", george) - .execute(); - REQUIRE(res == 1); - - // fetch person as record - auto result_record = s.template select() - .from("person") - .where("id"_col == 7) - .fetch_all(); - - for (const auto& i : result_record) { - REQUIRE(i.size() == 3); - REQUIRE(i.at(0).name() == "id"); - REQUIRE(i.at(0).type() == data_type_t::type_unsigned_long); - REQUIRE(i.at(0).template as() == george.id); - REQUIRE(i.at(1).name() == "name"); - REQUIRE(i.at(1).type() == data_type_t::type_varchar); - REQUIRE(i.at(1).template as() == george.name); - REQUIRE(i.at(2).name() == "age"); - REQUIRE(i.at(2).type() == matador::sql::data_type_t::type_unsigned_int); - REQUIRE(i.at(2).template as() == george.age); - } - - // fetch person as person - auto result_person = s.template select() - .from("person") - .where("id"_col == 7) - .template fetch_all(); - - for (const auto& i : result_person) { - REQUIRE(i.id == 7); - REQUIRE(i.name == "george"); - REQUIRE(i.age == 45); - } - - s.drop().table("person").execute(); -} - -TEMPLATE_TEST_CASE_METHOD(SessionTestFixture, "Execute insert statement", "[session]", Sqlite, Postgres) { - auto &s = SessionTestFixture::session(); - - s.create() - .table("person", { - make_pk_column("id"), - make_column("name", 255), - make_column("color", 63) - }) - .execute(); - - auto res = s.insert() - .into("person", {"id", "name", "color"}) - .values({7, "george", "green"}) - .execute(); - - REQUIRE(res == 1); - - s.drop().table("person").execute(); -} - -TEMPLATE_TEST_CASE_METHOD(SessionTestFixture, "Select statement with foreign key", "[session]", Sqlite, Postgres) { - auto &s = SessionTestFixture::session(); - - s.create() - .template table("airplane") - .execute(); - - s.create() - .template table("flight") - .execute(); - - std::vector> planes { - make_entity(1, "Airbus", "A380"), - make_entity(2, "Boeing", "707"), - make_entity(3, "Boeing", "747") - }; - - for (const auto &plane : planes) { - auto res = s.insert().template into("airplane").values(*plane).execute(); - REQUIRE(res == 1); - } - - auto count = s.select({count_all()}).from("airplane").template fetch_value(); - REQUIRE(count == 3); - - flight f4711{4, planes.at(1), "hans"}; - - auto res = s.insert().template into("flight").values(f4711).execute(); - REQUIRE(res == 1); - - auto f = *s.template select().from("flight").template fetch_all().begin(); - REQUIRE(f.id == 4); - REQUIRE(f.pilot_name == "hans"); - REQUIRE(f.airplane.get() != nullptr); - REQUIRE(f.airplane->id == 2); - - s.drop().table("flight").execute(); - s.drop().table("airplane").execute(); -} \ No newline at end of file diff --git a/test/ValueGeneratorTest.cpp b/test/ValueGeneratorTest.cpp index ffa4ee8..a8e1df6 100644 --- a/test/ValueGeneratorTest.cpp +++ b/test/ValueGeneratorTest.cpp @@ -16,7 +16,7 @@ TEST_CASE("Extract values object", "[value extractor]") { p.quantity_per_unit = "pcs"; p.category = make_entity(); p.category->id = 7; - p.supplier = make_entity();; + p.supplier = make_entity(); p.supplier->id = 13; p.product_name = "candle";