diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ef29be9d551ebaec233b7fc8a1e4f8255822a302..8027befbc7deb93168a888f7c3354685eb661f81 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -130,8 +130,6 @@ test: script: - *env - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY - - time docker load < /image-cache/caosdb-${CAOSDB_TAG}.tar || time docker load < /image-cache/caosdb-dev.tar || true - - docker pull $CI_REGISTRY/caosdb/src/caosdb-deploy:$CAOSDB_TAG || CAOSDB_TAG=dev - F_BRANCH=${F_BRANCH:-$CI_COMMIT_REF_NAME} - echo "F_BRANCH = $F_BRANCH" @@ -149,6 +147,8 @@ test: fi - echo "CAOSDB_TAG = $CAOSDB_TAG" + - time docker load < /image-cache/caosdb-${CAOSDB_TAG}.tar || time docker load < /image-cache/caosdb-dev.tar || true + - docker pull $CI_REGISTRY/caosdb/src/caosdb-deploy:$CAOSDB_TAG || CAOSDB_TAG=dev - docker load < /image-cache/${CPPINTTEST_IMAGE_CACHE} || true - docker pull $CPPINTTEST_REGISTRY_IMAGE - docker load < /image-cache/mariadb.tar || true diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0053aaadbf0e0124c1c30fabb7e6955d1f9b3a39..4c740017f3628d32fce456b9ec7dfd54670704ee 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,6 +30,7 @@ set(test_cases test_ccaosdb test_issues test_user + test_select ) add_compile_definitions(BUILD_ACM) diff --git a/test/test_list_properties.cpp b/test/test_list_properties.cpp index 472f792105ae1a5add023ef8ad3a2b3409780e64..b60c58fadff358b878108ca72edbb67b1af3f26e 100644 --- a/test/test_list_properties.cpp +++ b/test/test_list_properties.cpp @@ -221,4 +221,28 @@ TEST_F(test_list_properties, insert_list_of_bool) { EXPECT_FALSE(value.GetAsVector().at(1).GetAsBool()); } +TEST_F(test_list_properties, insert_list_non_list_datatype) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto insertion_prop(connection->CreateTransaction()); + + Entity abstract_list_property; + abstract_list_property.SetRole(Role::PROPERTY); + abstract_list_property.SetName("TestProp"); + abstract_list_property.SetDataType(AtomicDataType::TEXT); + abstract_list_property.SetValue(std::vector<std::string>{"item1", "item2", "item3"}); + + insertion_prop->InsertEntity(&abstract_list_property); + std::cout << "response " << insertion_prop->ResponseToString(); + insertion_prop->ExecuteAsynchronously(); + insertion_prop->WaitForIt(); + EXPECT_TRUE(insertion_prop->GetStatus().IsTerminated()); + EXPECT_TRUE(insertion_prop->GetStatus().IsError()); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("FIND ENTITY TestProp"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultSet().size(), 0); +} + } // namespace caosdb::entity diff --git a/test/test_select.cpp b/test/test_select.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f8809540a33d8ff753dda8b56892edc38ed4745f --- /dev/null +++ b/test/test_select.cpp @@ -0,0 +1,676 @@ +/* + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2022 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2022 Timm Fitschen <t.fitschen@indiscale.com> + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ +#include "caosdb/connection.h" // for Connection, ConnectionManager +#include "caosdb/data_type.h" // for AtomicDataType +#include "caosdb/entity.h" // for Entity, Property, Role, Parent +#include "caosdb/result_set.h" // for Entity, ResultSet, ResultSet::ite... +#include "caosdb/result_table.h" // for ResultTable::HeaderIterator, Resu... +#include "caosdb/transaction.h" // for Transaction, ResultTable +#include "caosdb/value.h" // for Value +#include <gtest/gtest-message.h> // for Message +#include <gtest/gtest-spi.h> // for EXPECT_NONFATAL_FA... +#include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestFactoryImpl +#include <gtest/gtest_pred_impl.h> // for Test, TestInfo, EXPECT_EQ, TEST +#include <iostream> // for operator<<, basic_ostream::operat... +#include <memory> // for allocator, unique_ptr, __shared_p... +#include <string> // for string + +namespace caosdb::transaction { +using caosdb::entity::AtomicDataType; +using caosdb::entity::DataType; +using caosdb::entity::Entity; +using caosdb::entity::Parent; +using caosdb::entity::Property; +using caosdb::entity::Role; +using caosdb::entity::Value; + +class test_select : public ::testing::Test { +public: + static void InsertEntity(Entity *entity) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto insert_transaction(connection->CreateTransaction()); + insert_transaction->InsertEntity(entity); + insert_transaction->Execute(); + } + + static void DeleteEntities() { + // delete all entities + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("FIND Entity"); + query_transaction->Execute(); + if (query_transaction->GetResultSet().size() > 0) { + auto delete_transaction(connection->CreateTransaction()); + for (const Entity &entity : query_transaction->GetResultSet()) { + delete_transaction->DeleteById(entity.GetId()); + } + delete_transaction->Execute(); + } + } + + static auto CreateTestProp(const std::string &name, AtomicDataType data_type, bool isList = false) + -> Entity { + Entity entity; + entity.SetRole(Role::PROPERTY); + entity.SetName(name); + entity.SetDescription("Prop Description " + name); + entity.SetDataType(data_type, isList); + return entity; + } + + static auto CreateTestRT() -> Entity { + Entity entity; + entity.SetRole(Role::RECORD_TYPE); + entity.SetDescription("RT Description"); + entity.SetName("TestRT"); + return entity; + } + + static auto CreateTestProp(const std::string &name, const std::string &data_type, + bool isList = false) -> Entity { + Entity entity; + entity.SetRole(Role::PROPERTY); + entity.SetName(name); + entity.SetDescription("Prop Description " + name); + entity.SetDataType(data_type, isList); + return entity; + } + + static auto CreateRecord(const std::string &property_name, const Value &value) -> Entity { + Entity entity; + entity.SetRole(Role::RECORD); + Parent parent; + parent.SetName("TestRT"); + entity.AppendParent(parent); + Property property; + property.SetName(property_name); + property.SetValue(value); + entity.AppendProperty(property); + + Property dummyProperty; + dummyProperty.SetName("TestProp2"); + dummyProperty.SetValue("dummy value"); + entity.AppendProperty(dummyProperty); + + return entity; + } + +protected: + // Fixture methods ////////////////////////////////////////////////////////// + + void SetUp() override { + DeleteEntities(); + + // Test Entities + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto insert_transaction(connection->CreateTransaction()); + // 1. Two RecordTypes + auto rt = CreateTestRT(); + auto rt2 = CreateTestRT(); + rt2.SetName("TestRT2"); + insert_transaction->InsertEntity(&rt); + insert_transaction->InsertEntity(&rt2); + + // 2. Six Scalar Properties + auto p = CreateTestProp("TestProp", AtomicDataType::TEXT); + insert_transaction->InsertEntity(&p); + p = CreateTestProp("TestProp2", AtomicDataType::TEXT); + insert_transaction->InsertEntity(&p); + p = CreateTestProp("TestProp3", AtomicDataType::TEXT); + insert_transaction->InsertEntity(&p); + p = CreateTestProp("TestPropDouble", AtomicDataType::DOUBLE); + p.SetUnit("m"); + insert_transaction->InsertEntity(&p); + p = CreateTestProp("TestPropInt", AtomicDataType::INTEGER); + p.SetUnit("m"); + insert_transaction->InsertEntity(&p); + p = CreateTestProp("TestPropBool", AtomicDataType::BOOLEAN); + insert_transaction->InsertEntity(&p); + + // 3. List Properties + p = CreateTestProp("TestListTextProp", AtomicDataType::TEXT, true); + insert_transaction->InsertEntity(&p); + p = CreateTestProp("TestListReferenceProp", "TestRT2", true); + insert_transaction->InsertEntity(&p); + + // 4. A Record which can be references by others + auto reference_entity = test_select::CreateRecord("TestProp3", Value("val3")); + Property property; + property.SetName("TestPropDouble"); + property.SetUnit("km"); + property.SetValue(231.012); + reference_entity.AppendProperty(property); + + reference_entity.RemoveParent(0); + Parent parent; + parent.SetName("TestRT2"); + reference_entity.AppendParent(parent); + insert_transaction->InsertEntity(&reference_entity); + + insert_transaction->Execute(); + } + + void TearDown() override { DeleteEntities(); } +}; + +/* + * Test select query on empty database. + */ +TEST_F(test_select, test_select_empty) { + test_select::DeleteEntities(); + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT name FROM RecordType TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "name"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 0); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("name").GetAsString(), "bla"); // should never be executed + } +} + +/* + * Test select name query on record type. + */ +TEST_F(test_select, test_select_name) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT name FROM RecordType TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "name"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("name").GetAsString(), "TestRT"); + } +} + +/* + * Test select description query on record type. + */ +TEST_F(test_select, test_select_property_description) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestPropDouble.description FROM Record TestRT2"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestPropDouble.description"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestPropDouble.description").GetAsString(), + "Prop Description TestPropDouble"); + } +} + +/* + * Test select description query on record type. + */ +TEST_F(test_select, test_select_description) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT description FROM RecordType TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "description"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("description").GetAsString(), "RT Description"); + } +} + +/* + * Test select TestProp query on record. + */ +TEST_F(test_select, test_select_testprop) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto entity = test_select::CreateRecord("TestProp", Value("val1")); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestProp FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestProp"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestProp").GetAsString(), "val1"); + } +} + +/* + * Test select double value query on record. + */ +TEST_F(test_select, test_select_double) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto entity = test_select::CreateRecord("TestPropDouble", Value(2.123)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestPropDouble FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestPropDouble"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_TRUE(row.GetValue("TestPropDouble").IsDouble()); + EXPECT_EQ(row.GetValue("TestPropDouble").GetAsDouble(), 2.123); + } +} + +/* + * Test select double value query on record. + */ +TEST_F(test_select, test_select_value) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto entity = test_select::CreateRecord("TestPropDouble", Value(2.123)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestPropDouble.value FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestPropDouble.value"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_TRUE(row.GetValue("TestPropDouble.value").IsDouble()); + EXPECT_EQ(row.GetValue("TestPropDouble.value").GetAsDouble(), 2.123); + } +} + +/* + * Test select unit value query on record. + */ +TEST_F(test_select, test_select_unit) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT unit FROM PROPERTY TestPropDouble"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "unit"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("unit").GetAsString(), "m"); + } +} + +/* + * Test select unit value query on record. + */ +TEST_F(test_select, test_select_property_unit) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto entity = test_select::CreateRecord("TestPropDouble", Value(2.123)); + test_select::InsertEntity(&entity); + + auto check(connection->CreateTransaction()); + check->Query("FIND Record TestRT"); + check->Execute(); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestPropDouble.unit FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestPropDouble.unit"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + + // Fails due to https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/264 + EXPECT_NONFATAL_FAILURE({ EXPECT_EQ(row.GetValue("TestPropDouble.unit").GetAsString(), "m"); }, + "TestPropDouble.unit"); + } +} + +/* + * Test select int value query on record. + */ +TEST_F(test_select, test_select_int) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto entity = test_select::CreateRecord("TestPropInt", Value(1234)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestPropInt FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestPropInt"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_TRUE(row.GetValue("TestPropInt").IsInt64()); + EXPECT_EQ(row.GetValue("TestPropInt").GetAsInt64(), 1234); + } +} + +/* Test select boolean value query on record. */ +TEST_F(test_select, test_select_boolean) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto entity = test_select::CreateRecord("TestPropBool", Value(true)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestPropBool FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestPropBool"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_TRUE(row.GetValue("TestPropBool").IsBool()); + EXPECT_EQ(row.GetValue("TestPropBool").GetAsBool(), true); + } +} + +/* + * Test select the referenced id. + */ +TEST_F(test_select, test_select_reference) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto get_id_of_ref_rec(connection->CreateTransaction()); + get_id_of_ref_rec->Query("SELECT id FROM RECORD TestRT2"); + get_id_of_ref_rec->Execute(); + auto id = (*get_id_of_ref_rec->GetResultTable().GetRows().begin()).GetValue("id").GetAsString(); + + auto entity = test_select::CreateRecord("TestRT2", Value(id)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestRT2 FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestRT2"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestRT2").GetAsString(), id); + } +} + +/* + * Test select the referenced id. + */ +TEST_F(test_select, test_select_reference_value) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto get_id_of_ref_rec(connection->CreateTransaction()); + get_id_of_ref_rec->Query("SELECT id, version FROM RECORD TestRT2"); + get_id_of_ref_rec->Execute(); + auto id = (*get_id_of_ref_rec->GetResultTable().GetRows().begin()).GetValue("id").GetAsString(); + auto version = + (*get_id_of_ref_rec->GetResultTable().GetRows().begin()).GetValue("version").GetAsString(); + + auto entity = test_select::CreateRecord("TestRT2", Value(id)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestRT2.value FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestRT2.value"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestRT2.value").GetAsString(), id + "@" + version); + } +} + +/* + * Test select the referenced entity's property. + */ +TEST_F(test_select, test_select_reference_entitys_property) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto get_id_of_ref_rec(connection->CreateTransaction()); + get_id_of_ref_rec->Query("SELECT id FROM RECORD TestRT2"); + get_id_of_ref_rec->Execute(); + auto id = (*get_id_of_ref_rec->GetResultTable().GetRows().begin()).GetValue("id").GetAsString(); + + auto entity = test_select::CreateRecord("TestRT2", Value(id)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestRT2.TestProp3 FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestRT2.TestProp3"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestRT2.TestProp3").GetAsString(), "val3"); + } +} + +/* + * Test select the referenced entity's property's unit. + */ +TEST_F(test_select, test_select_reference_entitys_propertys_unit) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto get_id_of_ref_rec(connection->CreateTransaction()); + get_id_of_ref_rec->Query("SELECT id FROM RECORD TestRT2"); + get_id_of_ref_rec->Execute(); + auto id = (*get_id_of_ref_rec->GetResultTable().GetRows().begin()).GetValue("id").GetAsString(); + + auto entity = test_select::CreateRecord("TestRT2", Value(id)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestRT2.TestPropDouble.unit FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestRT2.TestPropDouble.unit"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestRT2.TestPropDouble.unit").GetAsString(), "km"); + } +} + +/* + * Test select the referenced entity's property's description. + */ +TEST_F(test_select, test_select_reference_entitys_propertys_description) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto get_id_of_ref_rec(connection->CreateTransaction()); + get_id_of_ref_rec->Query("SELECT id FROM RECORD TestRT2"); + get_id_of_ref_rec->Execute(); + auto id = (*get_id_of_ref_rec->GetResultTable().GetRows().begin()).GetValue("id").GetAsString(); + + auto entity = test_select::CreateRecord("TestRT2", Value(id)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestRT2.TestProp3.description FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestRT2.TestProp3.description"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestRT2.TestProp3.description").GetAsString(), + "Prop Description TestProp3"); + } +} + +/* + * Test select the referenced entity's property's name. + */ +TEST_F(test_select, test_select_reference_entitys_propertys_name) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto get_id_of_ref_rec(connection->CreateTransaction()); + get_id_of_ref_rec->Query("SELECT id FROM RECORD TestRT2"); + get_id_of_ref_rec->Execute(); + auto id = (*get_id_of_ref_rec->GetResultTable().GetRows().begin()).GetValue("id").GetAsString(); + + auto entity = test_select::CreateRecord("TestRT2", Value(id)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestRT2.TestProp3.name FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestRT2.TestProp3.name"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestRT2.TestProp3.name").GetAsString(), "TestProp3"); + } +} + +/* + * Test select the referenced entity's property's id. + */ +TEST_F(test_select, test_select_reference_entitys_propertys_id) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + auto get_id_of_ref_rec(connection->CreateTransaction()); + get_id_of_ref_rec->Query("SELECT id FROM RECORD TestRT2"); + get_id_of_ref_rec->Execute(); + auto id = (*get_id_of_ref_rec->GetResultTable().GetRows().begin()).GetValue("id").GetAsString(); + + auto get_id_of_prop(connection->CreateTransaction()); + get_id_of_prop->Query("SELECT id FROM PROPERTY TestProp3"); + get_id_of_prop->Execute(); + auto pid = (*get_id_of_prop->GetResultTable().GetRows().begin()).GetValue("id").GetAsString(); + + auto entity = test_select::CreateRecord("TestRT2", Value(id)); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestRT2.TestProp3.id FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestRT2.TestProp3.id"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestRT2.TestProp3.id").GetAsString(), pid); + } +} + +/* + * Test select a list (TEXT). + */ +TEST_F(test_select, test_select_list_of_text) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto entity = test_select::CreateRecord("TestRT2", Value()); + Property listp; + listp.SetName("TestListTextProp"); + listp.SetValue(std::vector<std::string>{"item1", "item2", "item3"}); + entity.AppendProperty(listp); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestListTextProp FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestListTextProp"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestListTextProp").GetAsVector().at(0).GetAsString(), "item1"); + EXPECT_EQ(row.GetValue("TestListTextProp").GetAsVector().at(1).GetAsString(), "item2"); + EXPECT_EQ(row.GetValue("TestListTextProp").GetAsVector().at(2).GetAsString(), "item3"); + } +} + +/* + * Test select a list (REFERENCE). + */ +TEST_F(test_select, test_select_list_of_reference) { + const auto &connection = caosdb::connection::ConnectionManager::GetDefaultConnection(); + + auto get_id_of_ref_rec(connection->CreateTransaction()); + get_id_of_ref_rec->Query("SELECT id FROM RECORD TestRT2"); + get_id_of_ref_rec->Execute(); + auto id = (*get_id_of_ref_rec->GetResultTable().GetRows().begin()).GetValue("id").GetAsString(); + + auto entity = test_select::CreateRecord("TestRT2", Value()); + Property listp; + listp.SetName("TestListReferenceProp"); + listp.SetValue(std::vector<std::string>{id, id, id}); + entity.AppendProperty(listp); + test_select::InsertEntity(&entity); + + auto query_transaction(connection->CreateTransaction()); + query_transaction->Query("SELECT TestListReferenceProp FROM Record TestRT"); + query_transaction->Execute(); + EXPECT_EQ(query_transaction->GetResultTable().GetHeader().size(), 1); + for (const auto &column : query_transaction->GetResultTable().GetHeader()) { + EXPECT_EQ(column.GetName(), "TestListReferenceProp"); + } + + EXPECT_EQ(query_transaction->GetResultTable().size(), 1); + for (const auto &row : query_transaction->GetResultTable().GetRows()) { + EXPECT_EQ(row.GetValue("TestListReferenceProp").GetAsVector().at(0).GetAsString(), id); + EXPECT_EQ(row.GetValue("TestListReferenceProp").GetAsVector().at(1).GetAsString(), id); + EXPECT_EQ(row.GetValue("TestListReferenceProp").GetAsVector().at(2).GetAsString(), id); + } +} + +} // namespace caosdb::transaction