diff --git a/conanfile.txt b/conanfile.txt index 69500336708fd7cea1378704312df7a688ff1205..b8287f5d4aff42c2858068b7996a717e85daaba6 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,5 +1,5 @@ [requires] -caosdb/0.0.18 +caosdb/0.0.19 gtest/1.11.0 [generators] diff --git a/test/test_transaction.cpp b/test/test_transaction.cpp index 70624decb063804732a1709476d9bdbae2390c8b..be3c775d6987a9903ea02186dd7c5d5ae5e8cb01 100644 --- a/test/test_transaction.cpp +++ b/test/test_transaction.cpp @@ -37,6 +37,7 @@ #include <gtest/gtest-message.h> // for Message #include <gtest/gtest-test-part.h> // for TestPartResult #include <gtest/gtest_pred_impl.h> // for AssertionResult +#include <initializer_list> // for initializer_list #include <iostream> // for operator<<, endl #include <limits> // for numeric_limits #include <memory> // for unique_ptr, allocator @@ -723,7 +724,7 @@ auto test_numeric_values_impl(AtomicDataType a_type) -> void { prop.SetValue(static_cast<S>(value)); props_orig.push_back(prop); auto i_stat = insert_transaction->InsertEntity(&prop); - EXPECT_EQ(i_stat, StatusCode::READY); + EXPECT_EQ(i_stat, StatusCode::GO_ON); insert_transaction->ExecuteAsynchronously(); auto t_stat = insert_transaction->WaitForIt(); EXPECT_TRUE(t_stat.IsTerminated()); @@ -787,7 +788,7 @@ TEST_F(test_transaction, test_integer_out_of_range) { prop.SetValue(value); auto i_stat = insert_transaction->InsertEntity(&prop); - EXPECT_EQ(i_stat, StatusCode::READY); + EXPECT_EQ(i_stat, StatusCode::GO_ON); insert_transaction->ExecuteAsynchronously(); auto t_stat = insert_transaction->WaitForIt(); @@ -802,22 +803,164 @@ TEST_F(test_transaction, test_integer_out_of_range) { } } -// /* -// * test miscellaneous queries -// */ -// TEST_F(test_transaction, test_queries_misc) { -// const auto &connection = -// caosdb::connection::ConnectionManager::GetDefaultConnection(); - -// // query empty database -// auto query_transaction(connection->CreateTransaction()); -// query_transaction->Query("FIND Property \"Prop *\""); -// query_transaction->ExecuteAsynchronously(); -// auto t_stat = query_transaction->WaitForIt(); -// std::cout << "status: " << t_stat.GetCode() << " // " -// << t_stat.GetDescription() << std::endl; -// EXPECT_TRUE(t_stat.GetCode() >= 0); -// } +/* + * Insert three record types in a single transaction. + */ +TEST_F(test_transaction, test_multi_insert_transactions) { + const auto &connection = + caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto insert_transaction(connection->CreateTransaction()); + + for (std::string name : {"RT1", "RT2", "RT3"}) { + Entity entity; + entity.SetRole(Role::RECORD_TYPE); + entity.SetName(name); + auto stat = insert_transaction->InsertEntity(&entity); + EXPECT_EQ(stat, StatusCode::GO_ON); + } + insert_transaction->Execute(); + auto insert_status = insert_transaction->GetStatus(); + + ASSERT_TRUE(insert_status.IsTerminated()); + ASSERT_FALSE(insert_status.IsError()); + + // test end results + auto retrieve_transaction(connection->CreateTransaction()); + for (const Entity &entity : insert_transaction->GetResultSet()) { + retrieve_transaction->RetrieveById(entity.GetId()); + } + retrieve_transaction->Execute(); + + auto retrieve_status = retrieve_transaction->GetStatus(); + ASSERT_TRUE(retrieve_status.IsTerminated()); + ASSERT_FALSE(retrieve_status.IsError()); +} + +/* + * Update three record types in a single transaction. + */ +TEST_F(test_transaction, test_multi_update_transactions) { + const auto &connection = + caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto insert_transaction(connection->CreateTransaction()); + + for (std::string name : {"RT1", "RT2", "RT3"}) { + Entity entity; + entity.SetRole(Role::RECORD_TYPE); + entity.SetName(name); + insert_transaction->InsertEntity(&entity); + } + insert_transaction->Execute(); + + auto retrieve_transaction(connection->CreateTransaction()); + for (const Entity &entity : insert_transaction->GetResultSet()) { + retrieve_transaction->RetrieveById(entity.GetId()); + } + retrieve_transaction->Execute(); + + auto update_transaction(connection->CreateTransaction()); + for (Entity entity : retrieve_transaction->GetResultSet()) { + ASSERT_EQ(entity.GetDescription(), ""); + entity.SetDescription("NewDescription"); + ASSERT_EQ(update_transaction->UpdateEntity(&entity), StatusCode::GO_ON); + } + update_transaction->Execute(); + + auto update_status = update_transaction->GetStatus(); + + ASSERT_TRUE(update_status.IsTerminated()); + ASSERT_FALSE(update_status.IsError()); + + // test end results + auto final_retrieve_transaction(connection->CreateTransaction()); + for (const Entity &entity : update_transaction->GetResultSet()) { + final_retrieve_transaction->RetrieveById(entity.GetId()); + } + final_retrieve_transaction->Execute(); + + auto final_retrieve_status = final_retrieve_transaction->GetStatus(); + ASSERT_TRUE(final_retrieve_status.IsTerminated()); + ASSERT_FALSE(final_retrieve_status.IsError()); + + for (const Entity &entity : final_retrieve_transaction->GetResultSet()) { + ASSERT_EQ(entity.GetDescription(), "NewDescription"); + } +} + +/* + * + * Setup: Insert A, B, while A references B + * + * Complex transaction: Insert C, update A (remove reference to B, add reference + * to C), delete B. + */ +TEST_F(test_transaction, test_multi_write_transactions) { + const auto &connection = + caosdb::connection::ConnectionManager::GetDefaultConnection(); + + Entity entity_a; + Entity entity_b; + Entity entity_c; + Property reference_b; + Property reference_c; + + // SETUP + entity_a.SetRole(Role::RECORD_TYPE); + entity_a.SetName("RTA"); + entity_b.SetRole(Role::RECORD_TYPE); + entity_b.SetName("RTB"); + reference_b.SetName("RTB"); + entity_a.AppendProperty(reference_b); + + auto insert_transaction(connection->CreateTransaction()); + insert_transaction->InsertEntity(&entity_a); + insert_transaction->InsertEntity(&entity_b); + insert_transaction->ExecuteAsynchronously(); + insert_transaction->WaitForIt(); + ASSERT_TRUE(insert_transaction->GetStatus().IsTerminated()); + ASSERT_FALSE(insert_transaction->GetStatus().IsError()); + auto entity_a_id = + insert_transaction->GetResultSet().at(0).GetId(); // entity_a + auto entity_b_id = + insert_transaction->GetResultSet().at(1).GetId(); // entity_b + + auto retrieve_transaction(connection->CreateTransaction()); + retrieve_transaction->RetrieveById(entity_a_id); + + retrieve_transaction->Execute(); + + // COMPLEX TRANSACTION + entity_c.SetRole(Role::RECORD_TYPE); + entity_c.SetName("RTC"); + reference_c.SetName("RTC"); + + Entity entity_a_update(retrieve_transaction->GetResultSet().at(0)); + entity_a_update.RemoveProperty(0); + entity_a_update.AppendProperty(reference_c); + + auto complex_transaction(connection->CreateTransaction()); + ASSERT_EQ(complex_transaction->InsertEntity(&entity_c), StatusCode::GO_ON); + ASSERT_EQ(complex_transaction->DeleteById(entity_b_id), StatusCode::GO_ON); + ASSERT_EQ(complex_transaction->UpdateEntity(&entity_a_update), + StatusCode::GO_ON); + complex_transaction->ExecuteAsynchronously(); + complex_transaction->WaitForIt(); + + EXPECT_TRUE(complex_transaction->GetStatus().IsTerminated()); + EXPECT_FALSE(complex_transaction->GetStatus().IsError()); + + // test end results + retrieve_transaction = connection->CreateTransaction(); + ASSERT_EQ(retrieve_transaction->RetrieveById(entity_a_update.GetId()), + StatusCode::GO_ON); + retrieve_transaction->ExecuteAsynchronously(); + retrieve_transaction->WaitForIt(); + + const auto &final_entity = retrieve_transaction->GetResultSet().at(0); + EXPECT_EQ("RTC", final_entity.GetProperties().at(0).GetName()); +} /* * insert three recordtypes and the submit multiple queries in different @@ -1151,4 +1294,27 @@ TEST_F(test_transaction, test_full_workflow) { EXPECT_EQ(retr_transaction->GetResultSet().size(), 1); } +TEST_F(test_transaction, test_delete_string_id) { + const auto &connection = + caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto transaction(connection->CreateTransaction()); + + transaction->DeleteById("20"); + transaction->DeleteById("string"); + transaction->DeleteById("21"); + + transaction->ExecuteAsynchronously(); + transaction->WaitForIt(); + + EXPECT_TRUE(transaction->GetStatus().IsTerminated()); + EXPECT_TRUE(transaction->GetStatus().IsError()); + const auto &results = transaction->GetResultSet(); + EXPECT_FALSE(results.at(0).HasErrors()); + EXPECT_TRUE(results.at(1).HasErrors()); + EXPECT_EQ(results.at(1).GetErrors().size(), 1); + EXPECT_EQ(results.at(1).GetErrors().at(0).GetDescription(), + "Entity does not exist."); + EXPECT_FALSE(results.at(2).HasErrors()); +} + } // namespace caosdb::transaction