From e7e073c232085d4a95c897fe471411d472e3d09a Mon Sep 17 00:00:00 2001 From: Timm Fitschen <t.fitschen@indiscale.com> Date: Mon, 2 Aug 2021 12:06:43 +0200 Subject: [PATCH] WIP: retrieve multi --- include/caosdb/entity.h | 306 +++++++++++++++++------------------ include/caosdb/exceptions.h | 2 + include/caosdb/transaction.h | 20 ++- src/caosdb/configuration.cpp | 2 +- src/caosdb/transaction.cpp | 1 - test/test_transaction.cpp | 14 +- 6 files changed, 185 insertions(+), 160 deletions(-) diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h index c84f044..2d098c5 100644 --- a/include/caosdb/entity.h +++ b/include/caosdb/entity.h @@ -64,187 +64,187 @@ private: }; /** -* Container for Messages. -*/ + * Container for Messages. + */ class Messages { public: -[[nodiscard]] inline auto Size() const -> int { return wrapped->size(); } -[[nodiscard]] inline auto At(int index) const -> const Message { - return Message(&(wrapped->at(index))); -} + [[nodiscard]] inline auto Size() const -> int { return wrapped->size(); } + [[nodiscard]] inline auto At(int index) const -> const Message { + return Message(&(wrapped->at(index))); + } -friend class Entity; + friend class Entity; private: -inline Messages() : wrapped(nullptr){}; + inline Messages() : wrapped(nullptr){}; -::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Message> - *wrapped; + ::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Message> + *wrapped; }; /** -* Parent of an Entity. -* -* This implementation uses protobuf messages as storage backends. In other -* words, this class wraps a protobuf message and provides getter and setter -* methods. -*/ + * Parent of an Entity. + * + * This implementation uses protobuf messages as storage backends. In other + * words, this class wraps a protobuf message and provides getter and setter + * methods. + */ class Parent { public: -explicit inline Parent(caosdb::entity::v1alpha1::Parent *wrapped) - : wrapped(wrapped){}; -Parent(); - -/** - * Return the id of the parent entity. - */ -[[nodiscard]] auto GetId() const -> const std::string &; -/** - * Return the name of the parent entity. - */ -[[nodiscard]] auto GetName() const -> const std::string &; -/** - * Return the description of the parent entity. - */ -[[nodiscard]] auto GetDescription() const -> const std::string &; + explicit inline Parent(caosdb::entity::v1alpha1::Parent *wrapped) + : wrapped(wrapped){}; + Parent(); + + /** + * Return the id of the parent entity. + */ + [[nodiscard]] auto GetId() const -> const std::string &; + /** + * Return the name of the parent entity. + */ + [[nodiscard]] auto GetName() const -> const std::string &; + /** + * Return the description of the parent entity. + */ + [[nodiscard]] auto GetDescription() const -> const std::string &; + + /** + * Set the id of the parent. + */ + auto SetId(const std::string &id) -> void; + /** + * Set the name of the parent. + */ + auto SetName(const std::string &name) -> void; -/** - * Set the id of the parent. - */ -auto SetId(const std::string &id) -> void; -/** - * Set the name of the parent. - */ -auto SetName(const std::string &name) -> void; + /** + * Return a json string representing this parent. + * + * This is intended for debugging. + */ + inline auto ToString() const -> const std::string { + google::protobuf::util::JsonOptions options; + std::string out; + google::protobuf::util::MessageToJsonString(*(this->wrapped), &out, + options); + return out; + } -/** - * Return a json string representing this parent. - * - * This is intended for debugging. - */ -inline auto ToString() const -> const std::string { - google::protobuf::util::JsonOptions options; - std::string out; - google::protobuf::util::MessageToJsonString(*(this->wrapped), &out, - options); - return out; -} - -// TODO(fspreck) These need implementations. See Entity::GetErrors for -// inspiration. -/** - * Return the error messages of this parent. - */ -[[nodiscard]] inline auto GetErrors() const -> const Messages &; -/** - * Return the warning messages of this parent. - */ -[[nodiscard]] inline auto GetWarnings() const -> const Messages &; -/** - * Return the info messages of this parent. - */ -[[nodiscard]] inline auto GetInfos() const -> const Messages &; + // TODO(fspreck) These need implementations. See Entity::GetErrors for + // inspiration. + /** + * Return the error messages of this parent. + */ + [[nodiscard]] inline auto GetErrors() const -> const Messages &; + /** + * Return the warning messages of this parent. + */ + [[nodiscard]] inline auto GetWarnings() const -> const Messages &; + /** + * Return the info messages of this parent. + */ + [[nodiscard]] inline auto GetInfos() const -> const Messages &; -friend class Entity; -friend class Parents; + friend class Entity; + friend class Parents; private: -/** - * Return an empty protobuf message pointer. - * - * This function is called by the default constructor of the - * caosdb::entity::Parent class and the protobuf message is used as the - * storage-backend for the new Parent instance. - * - * An 'Arena' takes care of the the memory management. Don't try to delete - * this. - */ -static auto CreateProtoParent() -> ProtoParent *; - -/** - * Message which serves as storage backend. - */ -mutable caosdb::entity::v1alpha1::Parent *wrapped; + /** + * Return an empty protobuf message pointer. + * + * This function is called by the default constructor of the + * caosdb::entity::Parent class and the protobuf message is used as the + * storage-backend for the new Parent instance. + * + * An 'Arena' takes care of the the memory management. Don't try to delete + * this. + */ + static auto CreateProtoParent() -> ProtoParent *; + + /** + * Message which serves as storage backend. + */ + mutable caosdb::entity::v1alpha1::Parent *wrapped; }; /** -* Container for parents of entities. -* -* Should only be instantiated and write-accessed by the owning entity. -*/ -class Parents { -public: -/** - * Return the current size of the parent container. + * Container for parents of entities. * - * That is also the number of parents the owning entity currently has. - */ -[[nodiscard]] inline auto Size() const -> int { return wrapped->size(); } -/** - * Return the parent at the given index. + * Should only be instantiated and write-accessed by the owning entity. */ -[[nodiscard]] inline auto At(int index) const -> const Parent { - return Parent(&(wrapped->at(index))); -} +class Parents { +public: + /** + * Return the current size of the parent container. + * + * That is also the number of parents the owning entity currently has. + */ + [[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 { + return Parent(&(wrapped->at(index))); + } -friend class Entity; + friend class Entity; private: -inline Parents(){}; -explicit inline Parents( + inline Parents(){}; + explicit inline Parents( + ::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Parent> + *wrapped) + : wrapped(wrapped){}; + + /** + * Append a parent. + * + * This increases the Size() by one. + */ + auto Append(const Parent &parent) -> void; + /** + * The collection of parent messages which serves as a backend for this + * class. + */ ::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Parent> - *wrapped) - : wrapped(wrapped){}; + *wrapped; +}; /** - * Append a parent. + * Property of an Entity. * - * This increases the Size() by one. - */ -auto Append(const Parent &parent) -> void; -/** - * The collection of parent messages which serves as a backend for this - * class. + * This is a property which belongs to another entity. Don't confuse it with + * an Entity with the "Property" role. */ -::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Parent> - *wrapped; -}; - -/** -* Property of an Entity. -* -* This is a property which belongs to another entity. Don't confuse it with -* an Entity with the "Property" role. -*/ class Property { public: -explicit inline Property(caosdb::entity::v1alpha1::Property *wrapped) - : wrapped(wrapped){}; - -// TODO(fspreck) All of these methods need implementations. -[[nodiscard]] auto GetId() const -> const std::string &; -[[nodiscard]] auto GetName() const -> const std::string &; -[[nodiscard]] auto GetDescription() const -> const std::string &; -[[nodiscard]] auto GetImportance() const -> const std::string &; -[[nodiscard]] auto GetValue() const -> const std::string &; -[[nodiscard]] auto GetUnit() const -> const std::string &; -[[nodiscard]] auto GetDatatype() const -> const std::string &; -[[nodiscard]] auto GetErrors() const -> const Messages &; -[[nodiscard]] auto GetWarnings() const -> const Messages &; -[[nodiscard]] auto GetInfos() const -> const Messages &; - -auto SetId(const std::string &id) -> void; -auto SetName(const std::string &name) -> void; -auto SetImportance(const std::string &importance) -> void; -auto SetValue(const std::string &value) -> void; -auto SetUnit(const std::string &unit) -> void; -auto SetDatatype(const std::string &datatype) -> void; - -friend class Entity; -friend class Properties; + explicit inline Property(caosdb::entity::v1alpha1::Property *wrapped) + : wrapped(wrapped){}; + + // TODO(fspreck) All of these methods need implementations. + [[nodiscard]] auto GetId() const -> const std::string &; + [[nodiscard]] auto GetName() const -> const std::string &; + [[nodiscard]] auto GetDescription() const -> const std::string &; + [[nodiscard]] auto GetImportance() const -> const std::string &; + [[nodiscard]] auto GetValue() const -> const std::string &; + [[nodiscard]] auto GetUnit() const -> const std::string &; + [[nodiscard]] auto GetDatatype() const -> const std::string &; + [[nodiscard]] auto GetErrors() const -> const Messages &; + [[nodiscard]] auto GetWarnings() const -> const Messages &; + [[nodiscard]] auto GetInfos() const -> const Messages &; + + auto SetId(const std::string &id) -> void; + auto SetName(const std::string &name) -> void; + auto SetImportance(const std::string &importance) -> void; + auto SetValue(const std::string &value) -> void; + auto SetUnit(const std::string &unit) -> void; + auto SetDatatype(const std::string &datatype) -> void; + + friend class Entity; + friend class Properties; private: -caosdb::entity::v1alpha1::Property *wrapped; + caosdb::entity::v1alpha1::Property *wrapped; }; /** @@ -254,12 +254,12 @@ caosdb::entity::v1alpha1::Property *wrapped; */ class Properties { public: -// TODO(fspreck) Implementations needed (basically everything). See Parents -// container for inspiration. -[[nodiscard]] auto At(int index) const -> const Property &; -auto Append(const Property &property) -> void; + // TODO(fspreck) Implementations needed (basically everything). See Parents + // container for inspiration. + [[nodiscard]] auto At(int index) const -> const Property &; + auto Append(const Property &property) -> void; -friend class Entity; + friend class Entity; private: inline Properties(){}; diff --git a/include/caosdb/exceptions.h b/include/caosdb/exceptions.h index 4fd5192..a1e7e40 100644 --- a/include/caosdb/exceptions.h +++ b/include/caosdb/exceptions.h @@ -65,6 +65,8 @@ public: */ class TransactionError : public Exception { public: + TransactionError(StatusCode code, const std::string &what_arg) + : Exception(code, what_arg) {} explicit TransactionError(const std::string &what_arg) : Exception(StatusCode::GENERIC_TRANSACTION_ERROR, what_arg) {} }; diff --git a/include/caosdb/transaction.h b/include/caosdb/transaction.h index 56bd966..80d77d1 100644 --- a/include/caosdb/transaction.h +++ b/include/caosdb/transaction.h @@ -24,16 +24,22 @@ /** * @brief Creation and execution of transactions. */ -#include "caosdb/entity.h" // for Entity +#include "boost/log/core/record.hpp" // for record +#include "boost/log/sources/record_ostream.hpp" // for basic_record_o... +#include "boost/preprocessor/seq/limits/enum_256.hpp" // for BOOST_PP_SEQ_E... +#include "boost/preprocessor/seq/limits/size_256.hpp" // for BOOST_PP_SEQ_S... +#include "caosdb/entity.h" // for Entity #include "caosdb/logging.h" #include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransactionSe... #include "caosdb/entity/v1alpha1/main.pb.h" // for Entity, RetrieveReq... #include "caosdb/transaction_status.h" // for TransactionStatus #include "caosdb/status_code.h" // for StatusCode #include "google/protobuf/util/json_util.h" // for MessageToJsonString, Jso... +#include <stdexcept> #include <iterator> #include <memory> // for shared_ptr, unique_ptr #include <string> // for string +#include <vector> // for vector /* * Do all necessary checks and assure that another retrieval (by id or by @@ -117,6 +123,7 @@ class ResultSet { public: virtual ~ResultSet() = default; [[nodiscard]] virtual auto Size() const noexcept -> int = 0; + [[nodiscard]] virtual auto At(const int index) const -> const Entity & = 0; }; class MultiResultSet : public ResultSet { @@ -150,6 +157,10 @@ public: [[nodiscard]] inline auto Size() const noexcept -> int override { return this->entities.size(); } + [[nodiscard]] inline auto At(const int index) const + -> const Entity & override { + return *(this->entities.at(index)); + } std::vector<std::unique_ptr<Entity>> entities; }; @@ -162,6 +173,13 @@ public: : 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); + } private: std::unique_ptr<Entity> entity; diff --git a/src/caosdb/configuration.cpp b/src/caosdb/configuration.cpp index ba15dce..c6c1e9c 100644 --- a/src/caosdb/configuration.cpp +++ b/src/caosdb/configuration.cpp @@ -35,9 +35,9 @@ #include "caosdb/log_level.h" // for CAOSDB_DEFAULT... #include "caosdb/status_code.h" // for StatusCode #include "caosdb/utility.h" // for get_home_direc... -#include <bits/exception.h> // for exception #include <cassert> // for assert #include <cstdlib> // for getenv +#include <exception> // IWYU pragma: keep #include <grpcpp/security/credentials.h> // for SslCredentials #include <iterator> // for next #include <map> // for map diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp index 688472e..72b59e8 100644 --- a/src/caosdb/transaction.cpp +++ b/src/caosdb/transaction.cpp @@ -20,7 +20,6 @@ #include "caosdb/transaction.h" #include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransactionS... #include "caosdb/entity/v1alpha1/main.pb.h" // for SingleRetrieveRequest -#include "caosdb/exceptions.h" // for TransactionError, ... #include "caosdb/logging.h" #include "caosdb/protobuf_helper.h" // for get_arena #include "caosdb/status_code.h" // for StatusCode, AUTHEN... diff --git a/test/test_transaction.cpp b/test/test_transaction.cpp index a36eb4d..6f5638c 100644 --- a/test/test_transaction.cpp +++ b/test/test_transaction.cpp @@ -29,7 +29,10 @@ #include "gtest/gtest-message.h" // for Message #include "gtest/gtest-test-part.h" // for SuiteApiResolver, TestPa... #include "gtest/gtest_pred_impl.h" // for Test, TestInfo, TEST +#include <iostream> #include <memory> // for allocator, unique_ptr +#include <string> // for string, basic_string +#include <vector> // for vector namespace caosdb::transaction { using caosdb::configuration::InsecureConnectionConfiguration; @@ -105,6 +108,7 @@ TEST(test_transaction, test_multi_result_set_one) { MultiResultSet rs(&response); EXPECT_EQ(rs.Size(), 1); + EXPECT_EQ(rs.At(0).GetId(), "100"); } TEST(test_transaction, test_multi_result_set_three) { @@ -113,10 +117,10 @@ TEST(test_transaction, test_multi_result_set_three) { ->mutable_retrieve_response() ->mutable_entity() ->set_id("100"); - response.add_responses() - ->mutable_retrieve_response() - ->mutable_entity() - ->set_id("101"); + auto *entity_with_error = + response.add_responses()->mutable_retrieve_response()->mutable_entity(); + entity_with_error->set_id("101"); + entity_with_error->add_errors()->set_code(1); response.add_responses() ->mutable_retrieve_response() ->mutable_entity() @@ -124,6 +128,8 @@ TEST(test_transaction, test_multi_result_set_three) { MultiResultSet rs(&response); EXPECT_EQ(rs.Size(), 3); + EXPECT_TRUE(rs.At(1).HasErrors()); + std::cout << rs.At(1).ToString(); } } // namespace caosdb::transaction -- GitLab