diff --git a/backends/postgres/test/CMakeLists.txt b/backends/postgres/test/CMakeLists.txt index 8d52bc1..abb4857 100644 --- a/backends/postgres/test/CMakeLists.txt +++ b/backends/postgres/test/CMakeLists.txt @@ -10,9 +10,6 @@ configure_file(Connection.hpp.in ${PROJECT_BINARY_DIR}/backends/postgres/test/co message(STATUS "postgresql connection string: ${POSTGRES_CONNECTION_STRING}") set(TEST_SOURCES - ../../../test/models/coordinate.hpp - ../../../test/models/location.hpp - ../../../test/models/types.hpp ../../../test/backends/ColorEnumTraits.cpp ../../../test/backends/ColorEnumTraits.hpp ../../../test/backends/ConnectionTest.cpp @@ -25,23 +22,30 @@ set(TEST_SOURCES ../../../test/backends/SchemaFixture.cpp ../../../test/backends/SchemaFixture.hpp ../../../test/backends/SchemaTest.cpp + ../../../test/backends/SequenceFixture.cpp + ../../../test/backends/SequenceFixture.hpp + ../../../test/backends/SequenceTest.cpp ../../../test/backends/SessionFixture.cpp ../../../test/backends/SessionFixture.hpp + ../../../test/backends/SessionInsertBelongsTo.cpp + ../../../test/backends/SessionInsertHasMany.cpp + ../../../test/backends/SessionInsertHasManyToManyTest.cpp + ../../../test/backends/SessionInsertHasOne.cpp ../../../test/backends/SessionTest.cpp ../../../test/backends/StatementCacheTest.cpp ../../../test/backends/StatementTest.cpp - ../../../test/backends/TypeTraitsTest.cpp - ../../../test/utils/record_printer.hpp - ../../../test/utils/record_printer.cpp - ../../../test/models/model_metas.hpp - ../../../test/backends/SequenceFixture.hpp - ../../../test/backends/SequenceFixture.cpp - ../../../test/backends/SequenceTest.cpp - ../../../test/backends/TableSequenceFixture.hpp ../../../test/backends/TableSequenceFixture.cpp + ../../../test/backends/TableSequenceFixture.hpp ../../../test/backends/TableSequenceTest.cpp - ../../../test/backends/SessionInsertHasMany.cpp - ../../../test/backends/SessionInsertHasManyToManyTest.cpp + ../../../test/backends/TypeTraitsTest.cpp + ../../../test/models/author.hpp + ../../../test/models/coordinate.hpp + ../../../test/models/location.hpp + ../../../test/models/model_metas.hpp + ../../../test/models/types.hpp + ../../../test/models/user.hpp + ../../../test/utils/record_printer.cpp + ../../../test/utils/record_printer.hpp ) set(LIBRARY_TEST_TARGET PostgresTests) diff --git a/include/matador/utils/access.hpp b/include/matador/utils/access.hpp index 7b85907..c4403dd 100644 --- a/include/matador/utils/access.hpp +++ b/include/matador/utils/access.hpp @@ -1,5 +1,5 @@ -#ifndef OOS_ACCESS_HPP -#define OOS_ACCESS_HPP +#ifndef MATADOR_ACCESS_HPP +#define MATADOR_ACCESS_HPP #include "matador/utils/primary_key_attribute.hpp" #include "matador/utils/field_attributes.hpp" @@ -7,17 +7,7 @@ #include -namespace matador { - -enum class cascade_type; - -namespace utils { -class field_attributes; -class foreign_attributes; -class primary_key_attribute; -} - -namespace access { +namespace matador::access { template void process(Operator &op, Type &object) { object.process(op); @@ -92,6 +82,5 @@ void has_many_to_many(Operator &op, const char *id, ContainerType &c, const util op.on_has_many_to_many(id, c, attr); } } -} -#endif //OOS_ACCESS_HPP +#endif //MATADOR_ACCESS_HPP diff --git a/test/backends/SessionInsertBelongsTo.cpp b/test/backends/SessionInsertBelongsTo.cpp new file mode 100644 index 0000000..577d641 --- /dev/null +++ b/test/backends/SessionInsertBelongsTo.cpp @@ -0,0 +1,80 @@ +#include "catch2/catch_test_macros.hpp" + +#include "SessionFixture.hpp" + +#include "connection.hpp" + +#include "matador/query/session.hpp" + +#include "models/author.hpp" + +using namespace matador::test; +using namespace matador::query; +using namespace matador::object; + +TEST_CASE_METHOD(SessionFixture, "Test insert object with belongs to relation with identity", "[session][insert][belongs_to][identity]") { + const auto result = schema.attach("books") + .and_then( [this] { return schema.attach("authors"); } ) + .and_then([this] { return schema.create(db); } ); + REQUIRE(result.is_ok()); + + session ses({bus, connection::dns, 4}, schema); + + auto s_king = make_object("Steven King"); + + const auto carrie = make_object("Carrie", s_king, 1974); + + REQUIRE(carrie.is_transient()); + REQUIRE(ses.insert(carrie).is_ok()); + REQUIRE(carrie.is_persistent()); + + auto found_author = ses.find(s_king->id); + REQUIRE(found_author); + REQUIRE(found_author.value()->name == "Steven King"); + REQUIRE(found_author.value()->books.size() == 1); +} + +TEST_CASE_METHOD(SessionFixture, "Test insert object with belongs to relation with table sequence", "[session][insert][belongs_to][table_sequence]") { + const auto result = schema.attach("books") + .and_then( [this] { return schema.attach("authors"); } ) + .and_then([this] { return schema.create(db); } ); + REQUIRE(result.is_ok()); + + session ses({bus, connection::dns, 4}, schema); + + auto s_king = make_object("Steven King"); + + const auto carrie = make_object("Carrie", s_king, 1974); + + REQUIRE(carrie.is_transient()); + REQUIRE(ses.insert(carrie).is_ok()); + REQUIRE(carrie.is_persistent()); + + auto found_author = ses.find(s_king->id); + REQUIRE(found_author); + REQUIRE(found_author.value()->name == "Steven King"); + REQUIRE(found_author.value()->books.size() == 1); +} + +TEST_CASE_METHOD(SessionFixture, "Test insert object with belongs to relation with sequence", "[session][insert][belongs_to][sequence]") { + const auto result = schema.attach("books") + .and_then( [this] { return schema.attach("authors"); } ) + .and_then([this] { return schema.create(db); } ); + REQUIRE(result.is_ok()); + + session ses({bus, connection::dns, 4}, schema); + + auto s_king = make_object("Steven King"); + + const auto carrie = make_object("Carrie", s_king, 1974); + + REQUIRE(carrie.is_transient()); + REQUIRE(ses.insert(carrie).is_ok()); + REQUIRE(carrie.is_persistent()); + + auto found_author = ses.find(s_king->id); + REQUIRE(found_author); + REQUIRE(found_author.value()->name == "Steven King"); + REQUIRE(found_author.value()->books.size() == 1); +} + diff --git a/test/backends/SessionInsertHasMany.cpp b/test/backends/SessionInsertHasMany.cpp index 8ec8915..1ed52f8 100644 --- a/test/backends/SessionInsertHasMany.cpp +++ b/test/backends/SessionInsertHasMany.cpp @@ -15,56 +15,6 @@ using namespace matador::object; using namespace matador::test; namespace matador::test { -template -struct book_pk_generator; - -template -struct author_pk_generator { - unsigned int id{}; - std::string name; - collection>> books; - - author_pk_generator() = default; - explicit author_pk_generator(std::string name) - : name(std::move(name)) {} - - template - void process(Operator &op) { - namespace field = matador::access; - field::primary_key(op, "id", id, PkAttribute); - field::attribute(op, "name", name, VarChar63); - field::has_many(op, "books", books, "author_id", utils::CascadeAllFetchLazy); - } -}; - -template -struct book_pk_generator { - unsigned int id{}; - std::string title; - object_ptr> book_author; - unsigned short published_in{}; - - book_pk_generator() = default; - book_pk_generator(std::string title, object_ptr> author, const unsigned short published_in) - : title(std::move(title)), book_author(std::move(author)), published_in(published_in) {} - - template - void process(Operator &op) { - namespace field = matador::access; - field::primary_key(op, "id", id, PkAttribute); - field::attribute(op, "title", title, VarChar511); - field::belongs_to(op, "author_id", book_author, utils::CascadeAllFetchEager); - field::attribute(op, "published_in", published_in); - } -}; - -using author_identity = author_pk_generator; -using author_sequence = author_pk_generator; -using author_table = author_pk_generator; -using book_identity = book_pk_generator; -using book_sequence = book_pk_generator; -using book_table = book_pk_generator; - template struct colorlist_pk_generator { unsigned int id{}; @@ -88,7 +38,6 @@ struct colorlist_pk_generator { using colorlist_identity = colorlist_pk_generator; using colorlist_sequence = colorlist_pk_generator; using colorlist_table = colorlist_pk_generator; - } template diff --git a/test/backends/SessionInsertHasManyToManyTest.cpp b/test/backends/SessionInsertHasManyToManyTest.cpp index 61d4f49..9af5e75 100644 --- a/test/backends/SessionInsertHasManyToManyTest.cpp +++ b/test/backends/SessionInsertHasManyToManyTest.cpp @@ -30,6 +30,10 @@ struct ingredient_pk_generator { : name(std::move(name)) { } + ingredient_pk_generator(std::string name, std::vector>> recps) + : name(std::move(name)) + , recipes(std::move(recps)){} + template void process(Operator &op) { namespace field = matador::access; @@ -51,8 +55,7 @@ struct recipe_pk_generator { } recipe_pk_generator(std::string name, std::vector>> ings) : name(std::move(name)) - , ingredients(std::move(ings)){ - } + , ingredients(std::move(ings)){} template void process(Operator &op) { @@ -218,3 +221,43 @@ TEST_CASE_METHOD(SessionFixture, "Test insert object with has many to many relat REQUIRE(ing_result.is_ok()); REQUIRE(ing_result.value()->recipes.size() == 2); } + +TEST_CASE_METHOD(SessionFixture, "Test insert object with has many to many relation sequence reverse", "[session][insert][sequence][has_many_to_many][reverse]") { + auto result = schema.attach("recipes") + .and_then( [this] { return schema.attach("ingredients"); } ) + .and_then([this] { return schema.create(db); } ); + + query::session ses({bus, connection::dns, 4}, schema); + + std::vector recipes { + make_object("Apple Pie"), + make_object("Strawberry Cake"), + make_object("Pineapple Pie") + }; + + std::vector ingredients { + make_object("Apple", std::vector{recipes[0], recipes[2]}), + make_object("Strawberry", std::vector{recipes[2]}), + make_object("Pineapple", std::vector{recipes[2]}), + make_object("Sugar", std::vector{recipes[0]}), + make_object("Flour", std::vector{recipes[0]}), + make_object("Butter", std::vector{recipes[1]}), + make_object("Beans", std::vector{recipes[1]}) + }; + + for (auto &i: ingredients) { + REQUIRE(i.is_transient()); + auto res = ses.insert(i); + REQUIRE(res.is_ok()); + REQUIRE(res->is_persistent()); + } + + auto recipe_result = ses.find(1); + REQUIRE(recipe_result.is_ok()); + REQUIRE(recipe_result->is_persistent()); + REQUIRE(recipe_result.value()->recipes.size() == 2); + + const auto ing_result = ses.find(recipes[0]->id); + REQUIRE(ing_result.is_ok()); + REQUIRE(ing_result.value()->ingredients.size() == 3); +} diff --git a/test/backends/SessionInsertHasOne.cpp b/test/backends/SessionInsertHasOne.cpp new file mode 100644 index 0000000..7f870a4 --- /dev/null +++ b/test/backends/SessionInsertHasOne.cpp @@ -0,0 +1,22 @@ +#include "catch2/catch_test_macros.hpp" + +#include "SessionFixture.hpp" + +#include "connection.hpp" + +#include "matador/query/session.hpp" + +#include "models/user.hpp" + +using namespace matador::test; +using namespace matador::query; +using namespace matador::object; + +TEST_CASE_METHOD(SessionFixture, "Test insert object with has_one relation", "[session][insert][has_one]") { + session sess{conn}; + user_pk_generator u; + u.name = "John Doe"; + sess.persist(u); + + REQUIRE(u.id > 0); +} \ No newline at end of file diff --git a/test/models/author.hpp b/test/models/author.hpp index e4ee05f..eb372c5 100644 --- a/test/models/author.hpp +++ b/test/models/author.hpp @@ -41,6 +41,57 @@ struct author { field::has_many(op, "books", books, "author_id", utils::CascadeAllFetchLazy); } }; + +template +struct book_pk_generator; + +template +struct author_pk_generator { + unsigned int id{}; + std::string name; + object::collection>> books; + + author_pk_generator() = default; + explicit author_pk_generator(std::string name) + : name(std::move(name)) {} + + template + void process(Operator &op) { + namespace field = matador::access; + field::primary_key(op, "id", id, PkAttribute); + field::attribute(op, "name", name, VarChar63); + field::has_many(op, "books", books, "author_id", utils::CascadeAllFetchLazy); + } +}; + +template +struct book_pk_generator { + unsigned int id{}; + std::string title; + object::object_ptr> book_author; + unsigned short published_in{}; + + book_pk_generator() = default; + book_pk_generator(std::string title, object::object_ptr> author, const unsigned short published_in) + : title(std::move(title)), book_author(std::move(author)), published_in(published_in) {} + + template + void process(Operator &op) { + namespace field = matador::access; + field::primary_key(op, "id", id, PkAttribute); + field::attribute(op, "title", title, VarChar511); + field::belongs_to(op, "author_id", book_author, utils::CascadeAllFetchEager); + field::attribute(op, "published_in", published_in); + } +}; + +using author_identity = author_pk_generator; +using author_sequence = author_pk_generator; +using author_table = author_pk_generator; +using book_identity = book_pk_generator; +using book_sequence = book_pk_generator; +using book_table = book_pk_generator; + } #endif //QUERY_AUTHOR_HPP diff --git a/test/models/user.hpp b/test/models/user.hpp new file mode 100644 index 0000000..b42d061 --- /dev/null +++ b/test/models/user.hpp @@ -0,0 +1,56 @@ +#ifndef MATADOR_USER_HPP +#define MATADOR_USER_HPP + +#include "matador/utils/access.hpp" + +#include "matador/object/object_ptr.hpp" + +#include + +namespace matador::test { +template +struct user_session_pk_generator; + +template +struct user_pk_generator { + unsigned int id{}; + std::string name; + object::object_ptr> session; + + template + void process(Operator &op) { + namespace field = matador::access; + using namespace matador::utils; + field::primary_key(op, "id", id); + field::attribute(op, "name", name, UniqueVarChar255); + field::has_one(op, "session", session, CascadeAllFetchLazy); + } +}; + +template +struct user_session_pk_generator { + unsigned int id{}; + std::string session_token; + object::object_ptr> user_; + + template + void process(Operator &op) { + namespace field = matador::access; + using namespace matador::utils; + field::primary_key(op, "id", id); + field::attribute(op, "session_token", session_token, VarChar255); + field::belongs_to(op, "user_id", user_, CascadeAllFetchLazy); + } +}; + +using user = user_pk_generator; +using user_identity = user_pk_generator; +using user_sequence = user_pk_generator; +using user_table = user_pk_generator; +using user_session = user_session_pk_generator; +using user_session_identity = user_session_pk_generator; +using user_session_sequence = user_session_pk_generator; +using user_session_table = user_session_pk_generator; +} + +#endif //MATADOR_USER_HPP