diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 02c895db00b140cf0014c89bb3f33988884e6c8d..a54a23c5ad43ef851afeea2e31351a00ec2cadcc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -107,6 +107,7 @@ trigger_inttest: # ... or use main if possible... - if [[ "$CI_COMMIT_REF_NAME" == "main" ]] ; then CPPINT_REF=main ; + F_BRANCH=main ; fi - if echo "$CI_COMMIT_REF_NAME" | grep -c "^v" ; then CPPINT_REF=main ; diff --git a/include/caosdb/configuration.h b/include/caosdb/configuration.h index 4910bee6954097797ccb755142c8a51aff62e641..bb6a1ff598be3df57ae24b21e5844cad6a9c0e71 100644 --- a/include/caosdb/configuration.h +++ b/include/caosdb/configuration.h @@ -237,7 +237,9 @@ private: ConnectionConfigurationHelper connection_configuration_helper; LoggingConfigurationHelper logging_configuration_helper; - inline ConfigurationManager() { InitializeDefaults(); }; + inline ConfigurationManager(){ + // InitializeDefaults(); + }; /** * Initialize this ConfigurationManager with the defaults. diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h index dac3e73d363a161ea69b3610d3bd2301aa94da72..f18a0d904d1be282ec35b4842539850e3f31425b 100644 --- a/include/caosdb/entity.h +++ b/include/caosdb/entity.h @@ -60,6 +60,7 @@ using caosdb::StatusCode; using caosdb::entity::v1alpha1::EntityResponse; using caosdb::entity::v1alpha1::FileTransmissionId; using google::protobuf::RepeatedPtrField; +using ProtoMessage = caosdb::entity::v1alpha1::Message; const std::string logger_name = "caosdb::entity"; @@ -102,13 +103,13 @@ private: */ class Messages { public: - [[nodiscard]] inline auto Size() const -> int { + [[nodiscard]] inline auto size() const -> int { if (wrapped == nullptr) { return 0; } return wrapped->size(); } - [[nodiscard]] inline auto At(int index) const -> const Message { + [[nodiscard]] inline auto at(int index) const -> const Message { if (wrapped == nullptr) { throw std::out_of_range("Number of messages: 0"); } @@ -135,8 +136,7 @@ private: */ class Parent { public: - explicit inline Parent(caosdb::entity::v1alpha1::Parent *wrapped) - : wrapped(wrapped){}; + explicit inline Parent(ProtoParent *wrapped) : wrapped(wrapped){}; Parent(); /** @@ -220,7 +220,7 @@ private: /** * Message which serves as storage backend. */ - mutable caosdb::entity::v1alpha1::Parent *wrapped; + mutable ProtoParent *wrapped; // Messages errors; // Messages warnings; // Messages infos; @@ -238,11 +238,11 @@ public: * * That is also the number of parents the owning entity currently has. */ - [[nodiscard]] inline auto Size() const -> int { return wrapped->size(); } + [[nodiscard]] inline auto size() const -> int { return wrapped->size(); } /** * Return the parent at the given index. */ - [[nodiscard]] inline auto At(int index) const -> const Parent { + [[nodiscard]] inline auto at(int index) const -> const Parent { return Parent(&(wrapped->at(index))); } @@ -257,7 +257,7 @@ private: /** * Append a parent. * - * This increases the Size() by one. + * This increases the size() by one. */ auto Append(const Parent &parent) -> void; /** @@ -275,8 +275,7 @@ private: */ class Property { public: - explicit inline Property(caosdb::entity::v1alpha1::Property *wrapped) - : wrapped(wrapped){}; + explicit inline Property(ProtoProperty *wrapped) : wrapped(wrapped){}; Property(); /** @@ -321,6 +320,10 @@ public: * Set the name of this property. */ auto SetName(const std::string &name) -> void; + /** + * Set the description of this property. + */ + auto SetDescription(const std::string &description) -> void; /** * Set the importance of this property. */ @@ -358,7 +361,7 @@ public: private: static auto CreateProtoProperty() -> ProtoProperty *; - mutable caosdb::entity::v1alpha1::Property *wrapped; + mutable ProtoProperty *wrapped; }; /** @@ -373,11 +376,11 @@ public: * * This is also the number of properties the owningn entity currently has. */ - [[nodiscard]] inline auto Size() const -> int { return wrapped->size(); } + [[nodiscard]] inline auto size() const -> int { return wrapped->size(); } /** * Return the property at the given index. */ - [[nodiscard]] auto At(int index) const -> const Property { + [[nodiscard]] auto at(int index) const -> const Property { return Property(&(wrapped->at(index))); } @@ -392,7 +395,7 @@ private: /** * Append a property * - * This increases the Size() by one. + * This increases the size() by one. */ auto Append(const Property &property) -> void; @@ -479,6 +482,10 @@ public: auto SetRole(const std::string &role) -> void; auto SetName(const std::string &name) -> void; + /** + * Set the description of this entity. + */ + auto SetDescription(const std::string &description) -> void; auto SetValue(const std::string &value) -> void; auto SetUnit(const std::string &unit) -> void; diff --git a/include/caosdb/logging.h b/include/caosdb/logging.h index 2f04ec6087cfec19e1a5fbe87483544bd4e144a6..439eefd41ea0c90f263b095f1033270e3d546e7b 100644 --- a/include/caosdb/logging.h +++ b/include/caosdb/logging.h @@ -38,10 +38,10 @@ namespace caosdb::logging { const std::string logger_name = "caosdb::logging"; -typedef boost::log::sources::severity_channel_logger<int, std::string> +typedef boost::log::sources::severity_channel_logger_mt<int, std::string> boost_logger_class; -BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(logger, boost_logger_class) +BOOST_LOG_GLOBAL_LOGGER(logger, boost_logger_class) /** * This class stores the integer log level. diff --git a/include/caosdb/transaction.h b/include/caosdb/transaction.h index 9073b73752119fc29222589747d2cb65c1c54a74..b25cd41c3412109c887739d095c17a1c6746c1b8 100644 --- a/include/caosdb/transaction.h +++ b/include/caosdb/transaction.h @@ -176,8 +176,7 @@ using caosdb::entity::v1alpha1::MultiTransactionResponse; using caosdb::entity::v1alpha1::RegisterFileUploadRequest; using caosdb::entity::v1alpha1::RegisterFileUploadResponse; using caosdb::transaction::TransactionStatus; -using WrappedResponseCase = - caosdb::entity::v1alpha1::TransactionResponse::WrappedResponseCase; +using TransactionResponseCase = caosdb::entity::v1alpha1::TransactionResponse::TransactionResponseCase; class Transaction; @@ -186,133 +185,62 @@ static const std::string logger_name = "caosdb::transaction"; /** * Abstract base class for the results of a Transaction. */ -template <class T> class ResultSet { +class ResultSet { class iterator; public: virtual ~ResultSet() = default; - [[nodiscard]] virtual auto Size() const noexcept -> int = 0; - [[nodiscard]] virtual auto At(const int index) const -> const T & = 0; + [[nodiscard]] virtual auto size() const noexcept -> int = 0; + [[nodiscard]] virtual auto at(const int index) const -> const Entity & = 0; + [[nodiscard]] virtual auto mutable_at(int index) const -> Entity * = 0; auto begin() const -> iterator; auto end() const -> iterator; private: - class iterator : public std::iterator<std::output_iterator_tag, T> { + class iterator : public std::iterator<std::output_iterator_tag, Entity> { public: - explicit iterator(const ResultSet<T> *result_set, int index = 0); - auto operator*() const -> const T &; + explicit iterator(const ResultSet *result_set, int index = 0); + auto operator*() const -> const Entity &; auto operator++() -> iterator &; auto operator++(int) -> iterator; auto operator!=(const iterator &rhs) const -> bool; private: int current_index = 0; - const ResultSet<T> *result_set; + const ResultSet *result_set; }; }; -template <class T> -ResultSet<T>::iterator::iterator(const ResultSet *result_set_param, int index) - : current_index(index), result_set(result_set_param) {} - -template <class T> auto ResultSet<T>::iterator::operator*() const -> const T & { - return this->result_set->At(current_index); -} - -template <class T> -auto ResultSet<T>::iterator::operator++() -> ResultSet<T>::iterator & { - current_index++; - return *this; -} - -template <class T> -auto ResultSet<T>::iterator::operator++(int) -> ResultSet<T>::iterator { - iterator tmp(*this); - operator++(); - return tmp; -} - -template <class T> -auto ResultSet<T>::iterator::operator!=(const iterator &rhs) const -> bool { - return this->current_index != rhs.current_index; -} - -template <class T> auto ResultSet<T>::begin() const -> ResultSet<T>::iterator { - return ResultSet<T>::iterator(this, 0); -} - -template <class T> auto ResultSet<T>::end() const -> ResultSet<T>::iterator { - return ResultSet<T>::iterator(this, Size()); -} - -template <class T> class AbstractMultiResultSet : public ResultSet<T> { +class AbstractMultiResultSet : public ResultSet { public: virtual ~AbstractMultiResultSet() = default; inline explicit AbstractMultiResultSet( - std::vector<std::unique_ptr<T>> result_set) + std::vector<std::unique_ptr<Entity>> result_set) : items(std::move(result_set)) {} - [[nodiscard]] inline auto Size() const noexcept -> int override { + [[nodiscard]] inline auto size() const noexcept -> int override { return this->items.size(); } - [[nodiscard]] inline auto At(const int index) const -> const T & override { + [[nodiscard]] inline auto at(const int index) const + -> const Entity & override { return *(this->items.at(index)); } + [[nodiscard]] inline auto mutable_at(int index) const -> Entity * override { + return this->items.at(index).get(); + } protected: - std::vector<std::unique_ptr<T>> items; -}; - -/** - * Container of files which have been downloaded during a transaction. - */ -class FilesResultSet : public AbstractMultiResultSet<FileDescriptor> { -public: - ~FilesResultSet() = default; - explicit FilesResultSet( - std::vector<std::unique_ptr<FileDescriptor>> result_set); + std::vector<std::unique_ptr<Entity>> items; }; /** * Container with results of a transaction. - * - * In contrast to UniqueResult, this one can also hold multiple entities or zero - * entities. */ -class MultiResultSet : public AbstractMultiResultSet<Entity> { +class MultiResultSet : public AbstractMultiResultSet { public: ~MultiResultSet() = default; explicit MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set); }; -/** - * Container with the single result of a transaction. - * - * In contrast to MultiResultSet, this one guarantees to hold exactly one - * entity. - */ -class UniqueResult : public ResultSet<Entity> { -public: - ~UniqueResult() = default; - explicit inline UniqueResult(EntityResponse *entityResponse) - : entity(new Entity(entityResponse)){}; - explicit inline UniqueResult(IdResponse *idResponse) - : entity(new Entity(idResponse)){}; - [[nodiscard]] auto GetEntity() const -> const Entity &; - [[nodiscard]] inline auto Size() const noexcept -> int override { return 1; } - [[nodiscard]] inline auto At(const int index) const - -> const Entity & override { - if (index != 0) { - throw std::out_of_range("Index out of range. Length is 1."); - } - return *(this->entity); - } - - friend Transaction; - -private: - std::unique_ptr<Entity> entity; -}; - /** * @brief Create a transaction via `CaosDBConnection.createTransaction()` */ @@ -350,13 +278,6 @@ public: const std::string &local_path) noexcept -> StatusCode; - /** - * Return a ResultSet<FileDescriptor>. - * - * The file result set is empty until the transaction terminates. - */ - auto GetDownloadedFiles() const noexcept -> const FilesResultSet &; - /** * Add an entity id to this transaction for retrieval. * @@ -440,10 +361,8 @@ public: return this->status; } - [[nodiscard]] inline auto GetResultSet() const noexcept - -> const ResultSet<Entity> & { - const ResultSet<Entity> *result_set = this->result_set.get(); - return *result_set; + [[nodiscard]] inline auto GetResultSet() const noexcept -> const ResultSet & { + return *(this->result_set.get()); } /** @@ -503,7 +422,7 @@ private: const FileTransmissionId &file_transmission_id) -> void; bool has_query = false; TransactionType transaction_type = TransactionType::NONE; - mutable std::unique_ptr<ResultSet<Entity>> result_set; + mutable std::unique_ptr<ResultSet> result_set; mutable TransactionStatus status = TransactionStatus::INITIAL(); std::shared_ptr<EntityTransactionService::Stub> entity_service; std::shared_ptr<FileTransmissionService::Stub> file_service; diff --git a/proto b/proto index ab5494165946c032325a2d37dec1d563ffc8a959..af178772ef43ded290168f33852ef3d85583b20a 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit ab5494165946c032325a2d37dec1d563ffc8a959 +Subproject commit af178772ef43ded290168f33852ef3d85583b20a diff --git a/src/caosdb/entity.cpp b/src/caosdb/entity.cpp index ec84d669ee0a93c0b43d468fa0e4081d155b9bfc..d283305dedd408e8dedd8c3a9320803a3696e932 100644 --- a/src/caosdb/entity.cpp +++ b/src/caosdb/entity.cpp @@ -118,6 +118,10 @@ auto Property::SetName(const std::string &name) -> void { this->wrapped->set_name(name); } +auto Property::SetDescription(const std::string &description) -> void { + this->wrapped->set_description(description); +} + auto Property::SetImportance(const std::string &importance) -> void { this->wrapped->set_importance(importance); } @@ -194,6 +198,10 @@ auto Entity::SetName(const std::string &name) -> void { this->wrapped->set_name(name); } +auto Entity::SetDescription(const std::string &description) -> void { + this->wrapped->set_description(description); +} + auto Entity::SetValue(const std::string &value) -> void { this->wrapped->set_value(value); } diff --git a/src/caosdb/logging.cpp b/src/caosdb/logging.cpp index 3be4d38ac9a882f59a0b803c818c276d326ab504..5e6cd4e3577b57ec7491a26ae71982667a096609 100644 --- a/src/caosdb/logging.cpp +++ b/src/caosdb/logging.cpp @@ -44,6 +44,10 @@ namespace caosdb::logging { +BOOST_LOG_GLOBAL_LOGGER_INIT(logger, boost_logger_class) { + boost_logger_class lg; + return lg; +} LoggingConfiguration::LoggingConfiguration(int level) : LevelConfiguration(level) {} diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp index 8122b130fc94078f76a81876fbbcae4e4fc38f58..06fc46af3019eb406db16d6f7e82e415541c8122 100644 --- a/src/caosdb/transaction.cpp +++ b/src/caosdb/transaction.cpp @@ -113,9 +113,9 @@ using caosdb::entity::v1alpha1::FileTransmissionService; using caosdb::entity::v1alpha1::MultiTransactionRequest; using caosdb::entity::v1alpha1::MultiTransactionResponse; using TransactionResponseCase = - caosdb::entity::v1alpha1::TransactionResponse::WrappedResponseCase; -using QueryResponseCase = - caosdb::entity::v1alpha1::RetrieveResponse::WrappedResponseCase; + caosdb::entity::v1alpha1::TransactionResponse::TransactionResponseCase; +using RetrieveResponseCase = + caosdb::entity::v1alpha1::RetrieveResponse::RetrieveResponseCase; using caosdb::utility::get_arena; using grpc::ClientAsyncResponseReader; using ProtoEntity = caosdb::entity::v1alpha1::Entity; @@ -123,14 +123,39 @@ using FileExchange::FileExchangeClient; using google::protobuf::Arena; using grpc::CompletionQueue; -MultiResultSet::MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set) - : AbstractMultiResultSet<Entity>(std::move(result_set)) {} +ResultSet::iterator::iterator(const ResultSet *result_set_param, int index) + : current_index(index), result_set(result_set_param) {} + +auto ResultSet::iterator::operator*() const -> const Entity & { + return this->result_set->at(current_index); +} + +auto ResultSet::iterator::operator++() -> ResultSet::iterator & { + current_index++; + return *this; +} + +auto ResultSet::iterator::operator++(int) -> ResultSet::iterator { + iterator tmp(*this); + operator++(); + return tmp; +} + +auto ResultSet::iterator::operator!=(const iterator &rhs) const -> bool { + return this->current_index != rhs.current_index; +} + +auto ResultSet::begin() const -> ResultSet::iterator { + return ResultSet::iterator(this, 0); +} -[[nodiscard]] auto UniqueResult::GetEntity() const -> const Entity & { - const Entity *result = this->entity.get(); - return *result; +auto ResultSet::end() const -> ResultSet::iterator { + return ResultSet::iterator(this, size()); } +MultiResultSet::MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set) + : AbstractMultiResultSet(std::move(result_set)) {} + Transaction::Transaction( std::shared_ptr<EntityTransactionService::Stub> entity_service, std::shared_ptr<FileTransmissionService::Stub> file_service) @@ -324,7 +349,7 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { if (status.GetCode() == StatusCode::SUCCESS && !download_files.empty()) { // run over all retrieved entities and get the download_id for (auto sub_response : *(response->mutable_responses())) { - if (sub_response.wrapped_response_case() == + if (sub_response.transaction_response_case() == TransactionResponseCase::kRetrieveResponse) { if (sub_response.retrieve_response() .entity_response() @@ -366,112 +391,201 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { } auto Transaction::WaitForIt() const noexcept -> TransactionStatus { - if (this->response->responses_size() == 1) { - auto *responses = this->response->mutable_responses(0); - switch (responses->wrapped_response_case()) { - case WrappedResponseCase::kRetrieveResponse: { - auto *retrieve_response = responses->mutable_retrieve_response(); - switch (retrieve_response->wrapped_response_case()) { - case QueryResponseCase::kEntityResponse: { - auto *entity = retrieve_response->release_entity_response(); - auto id = entity->entity().id(); - if (!entity->errors().empty()) { - this->status = TransactionStatus::TRANSACTION_ERROR( - "The request returned with errors."); - } - - this->result_set = std::make_unique<UniqueResult>(entity); - if (!id.empty() && download_files.count(id) == 1) { - const auto &local_path = download_files.at(id).local_path; - const auto &unique_result_set = - dynamic_cast<const UniqueResult &>(*result_set); - unique_result_set.entity->SetLocalPath(local_path); - } + // if (this->response->responses_size() == 1) { + // auto *responses = this->response->mutable_responses(0); + // switch (responses->wrapped_response_case()) { + // case WrappedResponseCase::kRetrieveResponse: { + // auto *retrieve_response = responses->mutable_retrieve_response(); + // switch (retrieve_response->query_response_case()) { + // case QueryResponseCase::kEntity: { + // auto *entity = retrieve_response->release_entity(); + // if (!entity->errors().empty()) { + // this->status = TransactionStatus::TRANSACTION_ERROR( + //"The request returned with errors."); + //} + // this->result_set = std::make_unique<UniqueResult>(entity); + //} break; + // case QueryResponseCase::kSelectResult: { + //// TODO(tf) Select queries + //} break; + // case QueryResponseCase::kCountResult: { + // this->query_count = retrieve_response->count_result(); + // std::vector<std::unique_ptr<Entity>> entities; + // this->result_set = + // std::make_unique<MultiResultSet>(std::move(entities)); + //} break; + // default: + //// TODO(tf) Error + // break; + //} + //} break; + // case WrappedResponseCase::kUpdateResponse: { + // auto *updatedIdResponse = responses->mutable_update_response(); + // if (!updatedIdResponse->entity_errors().empty()) { + // this->status = TransactionStatus::TRANSACTION_ERROR( + //"The request returned with errors."); + //} + // this->result_set = std::make_unique<UniqueResult>(updatedIdResponse); + //} break; + // case WrappedResponseCase::kInsertResponse: { + // auto *insertedIdResponse = responses->mutable_insert_response(); + // if (!insertedIdResponse->entity_errors().empty()) { + // this->status = TransactionStatus::TRANSACTION_ERROR( + //"The request returned with errors."); + //} + // this->result_set = std::make_unique<UniqueResult>(insertedIdResponse); + //} break; + // default: + //// TODO(tf) Error and Update + // break; + //} + //} else { + bool set_error = false; + auto *responses = this->response->mutable_responses(); + std::vector<std::unique_ptr<Entity>> entities; + for (auto &sub_response : *responses) { + std::unique_ptr<Entity> result; + switch (sub_response.transaction_response_case()) { + + case TransactionResponseCase::kRetrieveResponse: { + auto *retrieve_response = sub_response.mutable_retrieve_response(); + + switch (retrieve_response->retrieve_response_case()) { + case RetrieveResponseCase::kEntityResponse: { + auto *retrieve_entity_response = retrieve_response->release_entity_response(); + result = std::make_unique<Entity>(retrieve_entity_response); } break; - case QueryResponseCase::kSelectResult: { + case RetrieveResponseCase::kSelectResult: { CAOSDB_LOG_ERROR(logger_name) << "Results of a SELECT query cannot be " "processed by this client yet."; // TODO(tf) Select queries } break; - case QueryResponseCase::kCountResult: { + case RetrieveResponseCase::kCountResult: { this->query_count = retrieve_response->count_result(); - std::vector<std::unique_ptr<Entity>> entities; - this->result_set = - std::make_unique<MultiResultSet>(std::move(entities)); } break; + case RetrieveResponseCase::kFindResult: { + for (auto &entity_response : *retrieve_response->mutable_find_result()->mutable_result_set()) { + result = std::make_unique<Entity>(&entity_response); + if (result->HasErrors()) { + set_error = true; + } + entities.push_back(std::move(result)); + } + } break; default: CAOSDB_LOG_FATAL(logger_name) << "Received invalid QueryResponseCase."; break; } - } break; - case WrappedResponseCase::kUpdateResponse: { - auto *updatedIdResponse = responses->mutable_update_response(); - if (!updatedIdResponse->id_response().errors().empty()) { - this->status = TransactionStatus::TRANSACTION_ERROR( - "The request returned with errors."); - } - this->result_set = std::make_unique<UniqueResult>( - updatedIdResponse->release_id_response()); - } break; - case WrappedResponseCase::kInsertResponse: { - auto *insertedIdResponse = responses->mutable_insert_response(); - if (!insertedIdResponse->id_response().errors().empty()) { - this->status = TransactionStatus::TRANSACTION_ERROR( - "The request returned with errors."); - } - this->result_set = std::make_unique<UniqueResult>( - insertedIdResponse->release_id_response()); - } break; - case WrappedResponseCase::kDeleteResponse: { - auto *deletedIdResponse = responses->mutable_delete_response(); - if (!deletedIdResponse->id_response().errors().empty()) { - this->status = TransactionStatus::TRANSACTION_ERROR( - "The request returned with errors."); - } - this->result_set = std::make_unique<UniqueResult>( - deletedIdResponse->release_id_response()); - } break; + //<<<<<<< HEAD + //} break; + // case WrappedResponseCase::kUpdateResponse: { + // auto *updatedIdResponse = responses->mutable_update_response(); + // if (!updatedIdResponse->id_response().errors().empty()) { + // this->status = TransactionStatus::TRANSACTION_ERROR( + //"The request returned with errors."); + //} + // this->result_set = std::make_unique<UniqueResult>( + // updatedIdResponse->release_id_response()); + //} break; + // case WrappedResponseCase::kInsertResponse: { + // auto *insertedIdResponse = responses->mutable_insert_response(); + // if (!insertedIdResponse->id_response().errors().empty()) { + // this->status = TransactionStatus::TRANSACTION_ERROR( + //"The request returned with errors."); + //} + // this->result_set = std::make_unique<UniqueResult>( + // insertedIdResponse->release_id_response()); + //} break; + // case WrappedResponseCase::kDeleteResponse: { + // auto *deletedIdResponse = responses->mutable_delete_response(); + // if (!deletedIdResponse->id_response().errors().empty()) { + // this->status = TransactionStatus::TRANSACTION_ERROR( + //"The request returned with errors."); + //} + // this->result_set = std::make_unique<UniqueResult>( + // deletedIdResponse->release_id_response()); + //} break; + // default: + // CAOSDB_LOG_FATAL(logger_name) << "Received invalid + // WrappedResponseCase."; break; + //} + //} else { + // auto *responses = this->response->mutable_responses(); + // std::vector<std::unique_ptr<Entity>> entities; + // CAOSDB_LOG_DEBUG(logger_name) + //<< "Number of subresponses: " << responses->size(); + // for (auto sub_response : *responses) { + // switch (sub_response.wrapped_response_case()) { + // case TransactionResponseCase::kRetrieveResponse: + // entities.push_back(std::make_unique<Entity>( + // sub_response.mutable_retrieve_response()->release_entity_response())); + // break; + // case TransactionResponseCase::kInsertResponse: + // entities.push_back(std::make_unique<Entity>( + // sub_response.mutable_insert_response()->release_id_response())); + // break; + // case TransactionResponseCase::kDeleteResponse: + // entities.push_back(std::make_unique<Entity>( + // sub_response.mutable_delete_response()->release_id_response())); + // break; + // case TransactionResponseCase::kUpdateResponse: + // entities.push_back(std::make_unique<Entity>( + // sub_response.mutable_update_response()->release_id_response())); + // break; + // default: + // CAOSDB_LOG_FATAL(logger_name) + //<< "Received invalid TransactionResponseCase."; + // break; + //} + //} + // this->result_set = + // std::make_unique<MultiResultSet>(std::move(entities)); + //======= + + break; + } + + case TransactionResponseCase::kInsertResponse: { + auto *inserted_id_response = sub_response.mutable_insert_response()->release_id_response(); + result = std::make_unique<Entity>(inserted_id_response); + break; + } + case TransactionResponseCase::kDeleteResponse: { + auto *deleted_id_response = sub_response.mutable_delete_response()->release_id_response(); + result = std::make_unique<Entity>(deleted_id_response); + break; + } + case TransactionResponseCase::kUpdateResponse: { + auto *updated_id_response = sub_response.mutable_update_response()->release_id_response(); + result = std::make_unique<Entity>(updated_id_response); + break; + } default: - CAOSDB_LOG_FATAL(logger_name) << "Received invalid WrappedResponseCase."; + CAOSDB_LOG_FATAL(logger_name) + << "Received invalid TransactionResponseCase."; break; } - } else { - auto *responses = this->response->mutable_responses(); - std::vector<std::unique_ptr<Entity>> entities; - CAOSDB_LOG_DEBUG(logger_name) - << "Number of subresponses: " << responses->size(); - for (auto sub_response : *responses) { - switch (sub_response.wrapped_response_case()) { - case TransactionResponseCase::kRetrieveResponse: - entities.push_back(std::make_unique<Entity>( - sub_response.mutable_retrieve_response()->release_entity_response())); - break; - case TransactionResponseCase::kInsertResponse: - entities.push_back(std::make_unique<Entity>( - sub_response.mutable_insert_response()->release_id_response())); - break; - case TransactionResponseCase::kDeleteResponse: - entities.push_back(std::make_unique<Entity>( - sub_response.mutable_delete_response()->release_id_response())); - break; - case TransactionResponseCase::kUpdateResponse: - entities.push_back(std::make_unique<Entity>( - sub_response.mutable_update_response()->release_id_response())); - break; - default: - CAOSDB_LOG_FATAL(logger_name) - << "Received invalid TransactionResponseCase."; - break; + if(result != nullptr) { + if (result->HasErrors()) { + set_error = true; } + entities.push_back(std::move(result)); } - for (auto &entity : entities) { - auto id = entity->GetId(); - if (!id.empty() && download_files.count(id) == 1) { - const auto &local_path = download_files.at(id).local_path; - entity->SetLocalPath(local_path); - } + } + + // copy local path of downloaded files into the entities file descriptor + for (auto &entity : entities) { + auto id = entity->GetId(); + if (!id.empty() && download_files.count(id) == 1) { + const auto &local_path = download_files.at(id).local_path; + entity->SetLocalPath(local_path); } - this->result_set = std::make_unique<MultiResultSet>(std::move(entities)); + } + this->result_set = std::make_unique<MultiResultSet>(std::move(entities)); + + if (set_error) { + this->status = TransactionStatus::TRANSACTION_ERROR( + "The request terminated with errors."); } return this->status; diff --git a/test/test_entity.cpp b/test/test_entity.cpp index 7930ab52d242a19f1833e77aedaabf34c56608c8..6ff700414d79095cc2f2909f1646f2bbf81eae60 100644 --- a/test/test_entity.cpp +++ b/test/test_entity.cpp @@ -38,6 +38,7 @@ namespace caosdb::entity { using caosdb::entity::v1alpha1::IdResponse; using ProtoEntity = caosdb::entity::v1alpha1::Entity; +using ProtoParent = caosdb::entity::v1alpha1::Parent; using caosdb::utility::get_arena; TEST(test_entity, test_parent_setters) { @@ -54,11 +55,11 @@ TEST(test_entity, test_append_parent) { parent.SetId("some-id"); auto entity = Entity(); - EXPECT_EQ(entity.GetParents().Size(), 0); + EXPECT_EQ(entity.GetParents().size(), 0); entity.AppendParent(parent); - EXPECT_EQ(entity.GetParents().Size(), 1); + EXPECT_EQ(entity.GetParents().size(), 1); - auto same_parent = entity.GetParents().At(0); + auto same_parent = entity.GetParents().at(0); EXPECT_EQ(same_parent.GetId(), "some-id"); } @@ -90,11 +91,11 @@ TEST(test_entity, test_append_property) { prop.SetUnit("prop_unit"); prop.SetDatatype("prop_dtype"); - EXPECT_EQ(entity.GetProperties().Size(), 0); + EXPECT_EQ(entity.GetProperties().size(), 0); entity.AppendProperty(prop); - EXPECT_EQ(entity.GetProperties().Size(), 1); + EXPECT_EQ(entity.GetProperties().size(), 1); - auto same_prop = entity.GetProperties().At(0); + auto same_prop = entity.GetProperties().at(0); EXPECT_EQ(prop.GetName(), same_prop.GetName()); EXPECT_EQ(prop.GetId(), same_prop.GetId()); @@ -128,10 +129,10 @@ TEST(test_entity, test_copy_to) { EXPECT_EQ(entity.GetRole(), copied.GetRole()); EXPECT_EQ(entity.GetName(), copied.GetName()); - EXPECT_EQ(copied.GetParents().At(0).GetId(), parent.GetId()); - EXPECT_EQ(copied.GetParents().At(0).GetName(), parent.GetName()); - EXPECT_EQ(copied.GetProperties().At(0).GetId(), prop.GetId()); - EXPECT_EQ(copied.GetProperties().At(0).GetName(), prop.GetName()); + EXPECT_EQ(copied.GetParents().at(0).GetId(), parent.GetId()); + EXPECT_EQ(copied.GetParents().at(0).GetName(), parent.GetName()); + EXPECT_EQ(copied.GetProperties().at(0).GetId(), prop.GetId()); + EXPECT_EQ(copied.GetProperties().at(0).GetName(), prop.GetName()); } TEST(test_entity, test_insert_entity) { @@ -192,8 +193,8 @@ TEST(test_entity, test_insert_with_parent) { transaction.InsertEntity(&entity); EXPECT_EQ(entity.GetName(), "entity_name"); - EXPECT_EQ(entity.GetParents().Size(), 1); - auto inserted_parent = entity.GetParents().At(0); + EXPECT_EQ(entity.GetParents().size(), 1); + auto inserted_parent = entity.GetParents().at(0); EXPECT_EQ(inserted_parent.GetId(), parent.GetId()); EXPECT_EQ(inserted_parent.GetName(), parent.GetName()); } @@ -218,9 +219,9 @@ TEST(test_entity, test_insert_with_property) { transaction.InsertEntity(&entity); - EXPECT_EQ(entity.GetProperties().Size(), 1); + EXPECT_EQ(entity.GetProperties().size(), 1); - auto inserted_prop = entity.GetProperties().At(0); + auto inserted_prop = entity.GetProperties().at(0); EXPECT_EQ(prop.GetName(), inserted_prop.GetName()); EXPECT_EQ(prop.GetId(), inserted_prop.GetId()); @@ -241,9 +242,9 @@ TEST(test_entity, test_from_id_response) { EXPECT_EQ(entity.GetId(), "entity_id"); EXPECT_TRUE(entity.HasErrors()); - EXPECT_EQ(entity.GetErrors().Size(), 1); - EXPECT_EQ(entity.GetErrors().At(0).GetDescription(), "error_desc"); - EXPECT_EQ(entity.GetErrors().At(0).GetCode(), + EXPECT_EQ(entity.GetErrors().size(), 1); + EXPECT_EQ(entity.GetErrors().at(0).GetDescription(), "error_desc"); + EXPECT_EQ(entity.GetErrors().at(0).GetCode(), MessageCode::ENTITY_DOES_NOT_EXIST); IdResponse idr_warnings_and_infos; @@ -258,14 +259,14 @@ TEST(test_entity, test_from_id_response) { Entity other_ent(&idr_warnings_and_infos); EXPECT_EQ(other_ent.GetId(), "other_entity_id"); - EXPECT_EQ(other_ent.GetWarnings().Size(), 1); + EXPECT_EQ(other_ent.GetWarnings().size(), 1); EXPECT_TRUE(other_ent.HasWarnings()); - EXPECT_EQ(other_ent.GetWarnings().At(0).GetDescription(), "warning_desc"); - EXPECT_EQ(other_ent.GetWarnings().At(0).GetCode(), + EXPECT_EQ(other_ent.GetWarnings().at(0).GetDescription(), "warning_desc"); + EXPECT_EQ(other_ent.GetWarnings().at(0).GetCode(), MessageCode::ENTITY_HAS_NO_PROPERTIES); - EXPECT_EQ(other_ent.GetInfos().Size(), 1); - EXPECT_EQ(other_ent.GetInfos().At(0).GetDescription(), "info_desc"); - EXPECT_EQ(other_ent.GetInfos().At(0).GetCode(), MessageCode::UNSPECIFIED); + EXPECT_EQ(other_ent.GetInfos().size(), 1); + EXPECT_EQ(other_ent.GetInfos().at(0).GetDescription(), "info_desc"); + EXPECT_EQ(other_ent.GetInfos().at(0).GetCode(), MessageCode::UNSPECIFIED); } TEST(test_entity, test_add_file_to_non_file_entity) { @@ -286,6 +287,27 @@ TEST(test_entity, test_add_directory_path) { EXPECT_EQ(entity.SetLocalPath("./"), StatusCode::PATH_IS_A_DIRECTORY); } +TEST(test_entity, test_description) { + Entity entity; + Property property; + Parent parent; + + EXPECT_EQ(entity.GetDescription(), ""); + EXPECT_EQ(property.GetDescription(), ""); + EXPECT_EQ(parent.GetDescription(), ""); + + entity.SetDescription("desc entity"); + property.SetDescription("desc property"); + // Parent has not setter + ProtoParent protoParent; + protoParent.set_description("desc parent"); + parent = Parent(&protoParent); + + EXPECT_EQ(entity.GetDescription(), "desc entity"); + EXPECT_EQ(property.GetDescription(), "desc property"); + EXPECT_EQ(parent.GetDescription(), "desc parent"); +} + TEST(test_entity, test_add_file) { Entity entity; entity.SetRole("File"); diff --git a/test/test_transaction.cpp b/test/test_transaction.cpp index ff64f3d256014554f685b4fa7dc492662da237a8..abecb1a2a25df106b015d644a4d09833df19a688 100644 --- a/test/test_transaction.cpp +++ b/test/test_transaction.cpp @@ -23,7 +23,7 @@ #include "caosdb/entity/v1alpha1/main.pb.h" // for Entity #include "caosdb/exceptions.h" // for ConnectionError #include "caosdb/status_code.h" -#include "caosdb/transaction.h" // for Transaction, UniqueResult +#include "caosdb/transaction.h" // for Transaction #include "caosdb/transaction_status.h" // for ConnectionError #include "caosdb_test_utility.h" // for EXPECT_THROW_MESSAGE #include "gtest/gtest-message.h" // for Message @@ -37,11 +37,32 @@ namespace caosdb::transaction { using caosdb::configuration::InsecureConnectionConfiguration; using caosdb::connection::Connection; +using caosdb::entity::Entity; using caosdb::exceptions::ConnectionError; -using caosdb::transaction::UniqueResult; using ProtoEntity = caosdb::entity::v1alpha1::Entity; using caosdb::entity::v1alpha1::RetrieveResponse; +TEST(test_transaction, test_multi_result_set) { + std::vector<std::unique_ptr<Entity>> entities; + for (int i = 0; i < 5; i++) { + entities.push_back(std::make_unique<Entity>()); + entities[i]->SetName("E" + std::to_string(i)); + } + MultiResultSet result_set(std::move(entities)); + + EXPECT_EQ(result_set.size(), 5); + EXPECT_EQ(result_set.mutable_at(3)->GetName(), "E3"); + EXPECT_EQ(result_set.at(4).GetName(), "E4"); + EXPECT_EQ(result_set.at(4).GetName(), "E4"); + EXPECT_THROW(auto &e = result_set.at(15), std::out_of_range); + + int counter = 0; + for (const auto &entity : result_set) { + EXPECT_EQ(entity.GetName(), "E" + std::to_string(counter++)); + } + EXPECT_EQ(counter, 5); +} + TEST(test_transaction, create_transaction) { const auto *host = "localhost"; auto configuration = InsecureConnectionConfiguration(host, 8000); @@ -55,18 +76,6 @@ TEST(test_transaction, create_transaction) { "connection to the server could not be established."); } -TEST(test_transaction, unique_result) { - auto *entity_response = new EntityResponse; - entity_response->mutable_entity()->set_id("test"); - UniqueResult result(entity_response); - - EXPECT_EQ("test", result.GetEntity().GetId()); - - // DON'T DELETE! The caosdb::entity::Entity takes care of that - // Try it yourself: - // delete entity; -} - TEST(test_transaction, test_unavailable) { const auto *host = "localhost"; auto configuration = InsecureConnectionConfiguration(host, 8000); @@ -96,7 +105,7 @@ TEST(test_transaction, test_retrieve_by_ids) { TEST(test_transaction, test_multi_result_set_empty) { std::vector<std::unique_ptr<Entity>> empty; MultiResultSet rs(std::move(empty)); - EXPECT_EQ(rs.Size(), 0); + EXPECT_EQ(rs.size(), 0); } TEST(test_transaction, test_multi_result_iterator) { @@ -107,19 +116,8 @@ TEST(test_transaction, test_multi_result_iterator) { std::make_unique<Entity>(response.release_entity_response())); MultiResultSet rs(std::move(one_elem)); - EXPECT_EQ(rs.Size(), 1); - - for (const Entity &entity : rs) { - EXPECT_EQ(entity.GetId(), "100"); - } -} - -TEST(test_transaction, test_unique_result_iterator) { - caosdb::entity::v1alpha1::EntityResponse response; - response.mutable_entity()->set_id("100"); + EXPECT_EQ(rs.size(), 1); - UniqueResult rs(&response); - EXPECT_EQ(rs.Size(), 1); for (const Entity &entity : rs) { EXPECT_EQ(entity.GetId(), "100"); } @@ -133,8 +131,8 @@ TEST(test_transaction, test_multi_result_set_one) { std::make_unique<Entity>(response.release_entity_response())); MultiResultSet rs(std::move(one_elem)); - EXPECT_EQ(rs.Size(), 1); - EXPECT_EQ(rs.At(0).GetId(), "100"); + EXPECT_EQ(rs.size(), 1); + EXPECT_EQ(rs.at(0).GetId(), "100"); } TEST(test_transaction, test_multi_result_set_three) { @@ -165,8 +163,8 @@ TEST(test_transaction, test_multi_result_set_three) { } MultiResultSet rs(std::move(three_elem)); - EXPECT_EQ(rs.Size(), 3); - EXPECT_TRUE(rs.At(1).HasErrors()); + EXPECT_EQ(rs.size(), 3); + EXPECT_TRUE(rs.at(1).HasErrors()); } TEST(test_transaction, test_update_entity) {