Skip to content
Snippets Groups Projects
Verified Commit e1e12e85 authored by Timm Fitschen's avatar Timm Fitschen
Browse files

WIP: update entity

parent 6ebcedc8
No related branches found
No related tags found
1 merge request!6F update
Pipeline #11091 passed
Pipeline: caosdb-cppinttest

#11098

    ......@@ -3,7 +3,7 @@ from conans import ConanFile, CMake, tools
    class CaosdbConan(ConanFile):
    name = "caosdb"
    version = "0.0.8"
    version = "0.0.9"
    license = "AGPL-3.0-or-later"
    author = "Timm C. Fitschen <t.fitschen@indiscale.com>"
    url = "https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib.git"
    ......
    ......@@ -278,6 +278,9 @@ private:
    class Entity {
    public:
    Entity();
    inline Entity(const Entity &original) : Entity(CreateProtoEntity()) {
    this->wrapped->CopyFrom(*original.wrapped);
    };
    explicit Entity(IdResponse *idResponse);
    explicit inline Entity(ProtoEntity *wrapped) : wrapped(wrapped) {
    errors.wrapped = this->wrapped->mutable_errors();
    ......@@ -287,9 +290,12 @@ public:
    parents.wrapped = this->wrapped->mutable_parents();
    };
    [[nodiscard]] inline auto GetId() const -> const std::string & {
    [[nodiscard]] inline auto GetId() const noexcept -> const std::string & {
    return wrapped->id();
    };
    [[nodiscard]] inline auto HasId() const noexcept -> bool {
    return !wrapped->id().empty();
    }
    [[nodiscard]] inline auto GetVersionId() const -> const std::string & {
    return wrapped->version().id();
    };
    ......@@ -333,9 +339,7 @@ public:
    }
    auto SetRole(const std::string &role) -> void;
    auto SetId(const std::string &id) -> void;
    auto SetName(const std::string &name) -> void;
    auto SetVersionId(const std::string &id) -> void;
    // TODO(fspreck) ... and also these
    auto SetValue(const std::string &value) -> void;
    ......@@ -348,8 +352,12 @@ public:
    auto AppendParent(const Parent &parent) -> void;
    auto Switch(ProtoEntity *entity) -> void;
    private:
    protected:
    static auto CreateProtoEntity() -> ProtoEntity *;
    auto SetId(const std::string &id) -> void;
    auto SetVersionId(const std::string &id) -> void;
    private:
    ProtoEntity *wrapped;
    Properties properties;
    Parents parents;
    ......
    ......@@ -35,6 +35,8 @@
    namespace caosdb {
    enum StatusCode {
    READY = -4,
    GO_ON = -3,
    INITIAL = -2,
    EXECUTING = -1,
    SUCCESS = 0,
    ......@@ -48,6 +50,7 @@ enum StatusCode {
    TRANSACTION_STATUS_ERROR = 25,
    TRANSACTION_TYPE_ERROR = 26,
    UNSUPPORTED_FEATURE = 27,
    ORIGINAL_ENTITY_MISSING_ID = 28,
    };
    auto get_status_description(int code) -> const std::string &;
    ......
    ......@@ -106,6 +106,35 @@
    "wrong TransactionType.") \
    }
    /*
    * Do all necessary checks and assure that another update can be added as a
    * sub-request to a transaction.
    */
    #define ASSERT_CAN_ADD_UPDATE \
    if (!IsStatus(TransactionStatus::INITIAL())) { \
    return StatusCode::TRANSACTION_STATUS_ERROR; \
    } \
    switch (this->transaction_type) { \
    case NONE: \
    this->transaction_type = TransactionType::INSERT; \
    case INSERT: \
    case MIXED_WRITE: \
    case MIXED_READ_AND_WRITE: \
    break; \
    default: \
    CAOSDB_LOG_ERROR_AND_RETURN_STATUS( \
    logger_name, StatusCode::TRANSACTION_TYPE_ERROR, \
    "You cannot add an update to this transaction because it has the " \
    "wrong TransactionType.") \
    } \
    if (!entity->HasId()) { \
    CAOSDB_LOG_ERROR_AND_RETURN_STATUS( \
    logger_name, StatusCode::ORIGINAL_ENTITY_MISSING_ID, \
    "You cannot update this entity without any id. Probably you did not " \
    "retrieve it first? Entity updates should always start with the " \
    "retrieval of the existing entity which may then be changed.") \
    }
    namespace caosdb::transaction {
    using caosdb::entity::Entity;
    using ProtoEntity = caosdb::entity::v1alpha1::Entity;
    ......@@ -233,6 +262,16 @@ public:
    */
    auto InsertEntity(Entity *entity) noexcept -> StatusCode;
    /**
    * Add the entity to this transaction for an update.
    *
    * The update is being processed when the Execute() or
    * ExecuteAsynchronously() methods of this transaction are called.
    *
    * Changing the entity afterwards results in undefined behavior.
    */
    auto UpdateEntity(Entity *entity) noexcept -> StatusCode;
    /**
    * Add an entity id to this transaction for deletion.
    *
    ......
    ......@@ -37,6 +37,7 @@
    #include "caosdb/utility.h" // for get_home_direc...
    #include <cassert> // for assert
    #include <cstdlib> // for getenv
    #include <cstring> // IWYU pragma: keep
    #include <exception> // IWYU pragma: keep
    #include <grpcpp/security/credentials.h> // for SslCredentials
    #include <iterator> // for next
    ......
    ......@@ -42,8 +42,14 @@ namespace caosdb {
    auto get_status_description(int code) -> const std::string & {
    static const std::string MISSING_DESCRIPTION = "MISSING DESCRIPTION";
    static const std::map<int, std::string> descriptions = {
    {StatusCode::INITIAL, "The transaction has not been executed yet and "
    "clients can stil change it."},
    {StatusCode::INITIAL,
    "The transaction has just been intialized. It has not been executed yet "
    "and clients can still change it and add sub-transactions."},
    {StatusCode::GO_ON,
    "The transaction has a transaction_type yet and clients may add matching "
    "sub-transaction or execute it right-away."},
    {StatusCode::READY,
    "The transaction is ready for execution and cannot be changed anymore."},
    {StatusCode::EXECUTING, "The transaction is currently being executed."},
    {StatusCode::SUCCESS, "The action was successful"},
    {StatusCode::CONNECTION_ERROR,
    ......@@ -68,6 +74,10 @@ auto get_status_description(int code) -> const std::string & {
    {StatusCode::TRANSACTION_TYPE_ERROR,
    "The Transaction has a transaction type which does not allow the "
    "attempted action."},
    {StatusCode::ORIGINAL_ENTITY_MISSING_ID,
    "The attempt to update this entity failed because this entity does have "
    "an id. This is the case when you did not retrieve it before applying any "
    "changes and instantiated the Entity class explicitely."},
    {StatusCode::UNSUPPORTED_FEATURE,
    "This feature is not available in the this client implementation."}};
    try {
    ......@@ -142,6 +152,17 @@ auto Transaction::InsertEntity(Entity *entity) noexcept -> StatusCode {
    return StatusCode::INITIAL;
    }
    auto Transaction::UpdateEntity(Entity *entity) noexcept -> StatusCode {
    ASSERT_CAN_ADD_UPDATE
    auto *sub_request = this->request->add_requests();
    auto *proto_entity = sub_request->mutable_update_request();
    entity->Switch(proto_entity);
    return StatusCode::INITIAL;
    }
    auto Transaction::Execute() -> TransactionStatus {
    ExecuteAsynchronously();
    this->status.ThrowExceptionIfError();
    ......@@ -221,6 +242,14 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus {
    }
    this->result_set = std::make_unique<UniqueResult>(entity);
    } 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()) {
    ......
    ......@@ -61,16 +61,16 @@ TEST(test_entity, test_insert_entity) {
    std::shared_ptr<transaction::EntityTransactionService::Stub>(nullptr));
    auto entity = Entity();
    entity.SetId("entity_id");
    entity.SetVersionId("version_id");
    entity.SetRole("entity_role");
    entity.SetName("entity_name");
    EXPECT_EQ(entity.GetId(), "entity_id");
    EXPECT_EQ(entity.GetVersionId(), "version_id");
    EXPECT_EQ(entity.GetRole(), "entity_role");
    EXPECT_EQ(entity.GetName(), "entity_name");
    transaction.InsertEntity(&entity);
    EXPECT_EQ(entity.GetId(), "entity_id");
    EXPECT_EQ(entity.GetVersionId(), "version_id");
    EXPECT_EQ(entity.GetRole(), "entity_role");
    EXPECT_EQ(entity.GetName(), "entity_name");
    }
    // TODO(tf) cognitive complexity > 25 (threshold)
    ......@@ -83,7 +83,6 @@ TEST(test_entity, test_from_id_response) { // NOLINT
    Entity entity(&idResponse);
    std::cout << entity.ToString() << std::endl;
    EXPECT_EQ(entity.GetId(), "entity_id");
    EXPECT_EQ(entity.GetErrors().Size(), 1);
    EXPECT_EQ(entity.GetErrors().At(0).GetDescription(), "error_desc");
    ......@@ -99,16 +98,19 @@ TEST(test_entity, test_from_id_response) { // NOLINT
    info->set_description("info_desc");
    info->set_code(MessageCode::UNSPECIFIED);
    std::cout << entity.ToString() << std::endl;
    Entity other_ent(&idr_warnings_and_infos);
    std::cout << entity.ToString() << std::endl;
    EXPECT_EQ(other_ent.GetId(), "other_entity_id");
    std::cout << entity.ToString() << std::endl;
    EXPECT_EQ(other_ent.GetWarnings().Size(), 1);
    EXPECT_EQ(other_ent.GetWarnings().At(0).GetDescription(), "warning_desc");
    EXPECT_EQ(other_ent.GetWarnings().At(0).GetCode(),
    MessageCode::ENTITY_HAS_NO_PROPERTIES);
    std::cout << entity.ToString() << std::endl;
    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);
    }
    } // namespace caosdb::entity
    ......@@ -133,4 +133,17 @@ TEST(test_transaction, test_multi_result_set_three) {
    std::cout << rs.At(1).ToString();
    }
    TEST(test_transaction, test_update_entity) {
    const auto *host = "localhost";
    auto configuration = InsecureConnectionConfiguration(host, 8000);
    Connection connection(configuration);
    auto transaction = connection.CreateTransaction();
    caosdb::entity::Entity update_entity;
    update_entity.SetRole("New role");
    auto error = transaction->UpdateEntity(&update_entity);
    EXPECT_EQ(error, StatusCode::ORIGINAL_ENTITY_MISSING_ID);
    }
    } // namespace caosdb::transaction
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment