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

Merge branch 'f-insert' into f-multi-retrieve

parents 664b4033 6d22e2e2
No related branches found
No related tags found
1 merge request!5F multi retrieve
Pipeline #11215 passed
Pipeline: caosdb-cppinttest

#11224

    This commit is part of merge request !5. Comments created here will be created in the context of that merge request.
    ......@@ -2,6 +2,7 @@
    * This file is a part of the CaosDB Project.
    *
    * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
    * Copyright (C) 2021 Florian Spreckelsen <f.spreckelsen@indiscale.com>
    * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
    *
    * This program is free software: you can redistribute it and/or modify
    ......@@ -36,6 +37,7 @@
    namespace caosdb::entity {
    using caosdb::entity::v1alpha1::IdResponse;
    using ProtoParent = caosdb::entity::v1alpha1::Parent;
    using ProtoProperty = caosdb::entity::v1alpha1::Property;
    using ProtoEntity = caosdb::entity::v1alpha1::Entity;
    /**
    ......@@ -54,8 +56,10 @@ public:
    }
    friend class Entity;
    friend class Parent;
    friend class Property;
    // TODO(fspreck) Re-enable once we have decided how messages are
    // appended to parents and properties
    // friend class Parent;
    // friend class Property;
    friend class Messages;
    private:
    ......@@ -76,8 +80,9 @@ public:
    }
    friend class Entity;
    friend class Parent;
    friend class Property;
    // TODO(fspreck) Same here.
    // friend class Parent;
    // friend class Property;
    private:
    inline Messages() : wrapped(nullptr){};
    ......@@ -134,32 +139,32 @@ public:
    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 errors;
    }
    [[nodiscard]] inline auto HasErrors() const -> bool {
    return this->errors.wrapped->size() > 0;
    }
    /**
    * Return the warning messages of this parent.
    */
    [[nodiscard]] inline auto GetWarnings() const -> const Messages & {
    return warnings;
    }
    [[nodiscard]] inline auto HasWarnings() const -> bool {
    return this->warnings.wrapped->size() > 0;
    }
    /**
    * Return the info messages of this parent.
    */
    [[nodiscard]] inline auto GetInfos() const -> const Messages & {
    return infos;
    }
    // TODO(fspreck) Finish the following implementations once we have
    // decided how to attach messages to parents.
    // /**
    // * Return the error messages of this parent.
    // */
    // [[nodiscard]] inline auto GetErrors() const -> const Messages & {
    // return errors;
    // }
    // [[nodiscard]] inline auto HasErrors() const -> bool {
    // return this->errors.wrapped->size() > 0;
    // }
    // /**
    // * Return the warning messages of this parent.
    // */
    // [[nodiscard]] inline auto GetWarnings() const -> const Messages & {
    // return warnings;
    // }
    // [[nodiscard]] inline auto HasWarnings() const -> bool {
    // return this->warnings.wrapped->size() > 0;
    // }
    // /**
    // * Return the info messages of this parent.
    // */
    // [[nodiscard]] inline auto GetInfos() const -> const Messages & {
    // return infos;
    // }
    friend class Entity;
    friend class Parents;
    ......@@ -181,9 +186,9 @@ private:
    * Message which serves as storage backend.
    */
    mutable caosdb::entity::v1alpha1::Parent *wrapped;
    Messages errors;
    Messages warnings;
    Messages infos;
    // Messages errors;
    // Messages warnings;
    // Messages infos;
    };
    /**
    ......@@ -239,31 +244,88 @@ class Property {
    public:
    explicit inline Property(caosdb::entity::v1alpha1::Property *wrapped)
    : wrapped(wrapped){};
    Property();
    // TODO(fspreck) All of these methods need implementations.
    /**
    * Return the id of this property
    */
    [[nodiscard]] auto GetId() const -> const std::string &;
    /**
    * Return the name of this property
    */
    [[nodiscard]] auto GetName() const -> const std::string &;
    /**
    * Return the description of this property
    */
    [[nodiscard]] auto GetDescription() const -> const std::string &;
    /**
    * Return the importance of this property
    */
    [[nodiscard]] auto GetImportance() const -> const std::string &;
    /**
    * Return the value of this property
    */
    [[nodiscard]] auto GetValue() const -> const std::string &;
    /**
    * Return the unit of this property
    */
    [[nodiscard]] auto GetUnit() const -> const std::string &;
    /**
    * Return the datatype of this property
    */
    [[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 &;
    // TODO(fspreck) Implement these when we have decided how to attach
    // messages to properties.
    // [[nodiscard]] auto GetErrors() const -> const Messages &;
    // [[nodiscard]] auto GetWarnings() const -> const Messages &;
    // [[nodiscard]] auto GetInfos() const -> const Messages &;
    /**
    * Set the id of this property.
    */
    auto SetId(const std::string &id) -> void;
    /**
    * Set the name of this property.
    */
    auto SetName(const std::string &name) -> void;
    /**
    * Set the importance of this property.
    */
    auto SetImportance(const std::string &importance) -> void;
    /**
    * Set the value of this property.
    */
    auto SetValue(const std::string &value) -> void;
    /**
    * Set the unit of this property.
    */
    auto SetUnit(const std::string &unit) -> void;
    /**
    * Set the datatype of this property.
    */
    auto SetDatatype(const std::string &datatype) -> void;
    /**
    * Return a json string representing this property.
    *
    * 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;
    }
    friend class Entity;
    friend class Properties;
    private:
    caosdb::entity::v1alpha1::Property *wrapped;
    static auto CreateProtoProperty() -> ProtoProperty *;
    mutable caosdb::entity::v1alpha1::Property *wrapped;
    };
    /**
    ......@@ -273,10 +335,18 @@ private:
    */
    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;
    /**
    * Return the current size of the properties container.
    *
    * This is also the number of properties the owningn entity currently has.
    */
    [[nodiscard]] inline auto Size() const -> int { return wrapped->size(); }
    /**
    * Return the property at the given index.
    */
    [[nodiscard]] auto At(int index) const -> const Property {
    return Property(&(wrapped->at(index)));
    }
    friend class Entity;
    ......@@ -287,6 +357,13 @@ private:
    *wrapped)
    : wrapped(wrapped){};
    /**
    * Append a property
    *
    * This increases the Size() by one.
    */
    auto Append(const Property &property) -> void;
    ::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Property>
    *wrapped;
    };
    ......@@ -366,11 +443,14 @@ public:
    auto SetUnit(const std::string &unit) -> void;
    // Currently no references or lists.
    auto SetDatatype(const std::string &datatype) -> void;
    // TODO(fspreck) this one is tricky. See AppendParent
    auto AppendProperty(const Property &property) -> void;
    auto AppendParent(const Parent &parent) -> void;
    auto Switch(ProtoEntity *entity) -> void;
    /**
    * Copy all of this entity's features to the target ProtoEntity.
    */
    auto CopyTo(ProtoEntity *target) -> void;
    private:
    static auto CreateProtoEntity() -> ProtoEntity *;
    ......
    /*
    * This file is a part of the CaosDB Project.
    *
    * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
    * Copyright (C) 2021 Florian Spreckelsen <f.spreckelsen@indiscale.com>
    * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
    *
    * This program is free software: you can redistribute it and/or modify
    ......@@ -25,13 +27,16 @@
    namespace caosdb::entity {
    using caosdb::entity::v1alpha1::IdResponse;
    using ProtoParent = caosdb::entity::v1alpha1::Parent;
    using ProtoProperty = caosdb::entity::v1alpha1::Property;
    using ProtoEntity = caosdb::entity::v1alpha1::Entity;
    using caosdb::utility::get_arena;
    Parent::Parent() : wrapped(Parent::CreateProtoParent()) {
    errors.wrapped = this->wrapped->mutable_errors();
    warnings.wrapped = this->wrapped->mutable_warnings();
    infos.wrapped = this->wrapped->mutable_infos();
    // TODO(fspreck) Re-enable once we have decided how to attach
    // messages to parents.
    // errors.wrapped = this->wrapped->mutable_errors();
    // warnings.wrapped = this->wrapped->mutable_warnings();
    // infos.wrapped = this->wrapped->mutable_infos();
    }
    auto Parent::CreateProtoParent() -> ProtoParent * {
    ......@@ -63,6 +68,73 @@ auto Parents::Append(const Parent &parent) -> void {
    parent.wrapped = destination;
    }
    Property::Property() : wrapped(Property::CreateProtoProperty()) {}
    auto Property::CreateProtoProperty() -> ProtoProperty * {
    return google::protobuf::Arena::CreateMessage<ProtoProperty>(get_arena());
    }
    [[nodiscard]] auto Property::GetId() const -> const std::string & {
    return this->wrapped->id();
    }
    [[nodiscard]] auto Property::GetName() const -> const std::string & {
    return this->wrapped->name();
    }
    [[nodiscard]] auto Property::GetDescription() const -> const std::string & {
    return this->wrapped->description();
    }
    [[nodiscard]] auto Property::GetImportance() const -> const std::string & {
    return this->wrapped->importance();
    }
    [[nodiscard]] auto Property::GetValue() const -> const std::string & {
    return this->wrapped->value();
    }
    [[nodiscard]] auto Property::GetUnit() const -> const std::string & {
    return this->wrapped->unit();
    }
    [[nodiscard]] auto Property::GetDatatype() const -> const std::string & {
    return this->wrapped->datatype();
    }
    auto Property::SetId(const std::string &id) -> void {
    this->wrapped->set_id(id);
    }
    auto Property::SetName(const std::string &name) -> void {
    this->wrapped->set_name(name);
    }
    auto Property::SetImportance(const std::string &importance) -> void {
    this->wrapped->set_importance(importance);
    }
    auto Property::SetValue(const std::string &value) -> void {
    this->wrapped->set_value(value);
    }
    auto Property::SetUnit(const std::string &unit) -> void {
    this->wrapped->set_unit(unit);
    }
    auto Property::SetDatatype(const std::string &datatype) -> void {
    this->wrapped->set_datatype(datatype);
    }
    auto Properties::Append(const Property &property) -> void {
    auto *destination = this->wrapped->Add();
    destination->Swap(property.wrapped);
    property.wrapped->Clear();
    property.wrapped = destination;
    }
    [[nodiscard]] auto Entity::GetParents() const -> const Parents & {
    return parents;
    }
    ......@@ -71,6 +143,14 @@ auto Entity::AppendParent(const Parent &parent) -> void {
    this->parents.Append(parent);
    }
    [[nodiscard]] auto Entity::GetProperties() const -> const Properties & {
    return properties;
    }
    auto Entity::AppendProperty(const Property &property) -> void {
    this->properties.Append(property);
    }
    auto Entity::CreateProtoEntity() -> ProtoEntity * {
    return google::protobuf::Arena::CreateMessage<ProtoEntity>(get_arena());
    }
    ......@@ -97,12 +177,17 @@ auto Entity::SetVersionId(const std::string &id) -> void {
    this->wrapped->mutable_version()->set_id(id);
    }
    // TODO(tf) Re-implement s.th. properties and parents are kept.
    auto Entity::Switch(ProtoEntity *entity) -> void {
    this->wrapped->Swap(entity);
    this->wrapped->Clear();
    this->wrapped = entity;
    }
    auto Entity::CopyTo(ProtoEntity *target) -> void {
    target->CopyFrom(*(this->wrapped));
    }
    auto Entity::SetRole(const std::string &role) -> void {
    this->wrapped->set_role(role);
    }
    ......
    ......@@ -137,8 +137,8 @@ auto Transaction::InsertEntity(Entity *entity) noexcept -> StatusCode {
    auto *sub_request = this->request->add_requests();
    auto *proto_entity = sub_request->mutable_insert_request();
    entity->Switch(proto_entity);
    // copy the original entity for the transaction
    entity->CopyTo(proto_entity);
    return StatusCode::INITIAL;
    }
    ......
    ......@@ -3,6 +3,7 @@
    * This file is a part of the CaosDB Project.
    *
    * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
    * Copyright (C) 2021 Florian Spreckelsen <f.spreckelsen@indiscale.com>
    * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
    *
    * This program is free software: you can redistribute it and/or modify
    ......@@ -23,7 +24,9 @@
    #include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for EntityTransactionSe...
    #include "caosdb/entity/v1alpha1/main.pb.h" // for IdResponse, Message
    #include "caosdb/message_code.h" // for MessageCode
    #include "caosdb/protobuf_helper.h" // for get_arena
    #include "caosdb/transaction.h" // for Transaction
    #include "google/protobuf/arena.h" // for Arena
    #include "gtest/gtest-message.h" // for Message
    #include "gtest/gtest-test-part.h" // for TestPartResult, Sui...
    #include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ
    ......@@ -33,6 +36,8 @@
    namespace caosdb::entity {
    using caosdb::entity::v1alpha1::IdResponse;
    using ProtoEntity = caosdb::entity::v1alpha1::Entity;
    using caosdb::utility::get_arena;
    TEST(test_entity, test_parent_setters) {
    auto parent = Parent();
    ......@@ -56,6 +61,79 @@ TEST(test_entity, test_append_parent) {
    EXPECT_EQ(same_parent.GetId(), "some-id");
    }
    TEST(test_entity, test_property_setters) {
    auto prop = Property();
    prop.SetName("prop_name");
    prop.SetId("prop_id");
    prop.SetImportance("prop_importance");
    prop.SetValue("prop_value");
    prop.SetUnit("prop_unit");
    prop.SetDatatype("prop_dtype");
    EXPECT_EQ(prop.GetName(), "prop_name");
    EXPECT_EQ(prop.GetId(), "prop_id");
    EXPECT_EQ(prop.GetImportance(), "prop_importance");
    EXPECT_EQ(prop.GetValue(), "prop_value");
    EXPECT_EQ(prop.GetUnit(), "prop_unit");
    EXPECT_EQ(prop.GetDatatype(), "prop_dtype");
    }
    // TODO(fspreck) cognitive complexity > 25 (threshold)
    TEST(test_entity, test_append_property) { // NOLINT
    auto entity = Entity();
    auto prop = Property();
    prop.SetName("prop_name");
    prop.SetId("prop_id");
    prop.SetImportance("prop_importance");
    prop.SetValue("prop_value");
    prop.SetUnit("prop_unit");
    prop.SetDatatype("prop_dtype");
    EXPECT_EQ(entity.GetProperties().Size(), 0);
    entity.AppendProperty(prop);
    EXPECT_EQ(entity.GetProperties().Size(), 1);
    auto same_prop = entity.GetProperties().At(0);
    EXPECT_EQ(prop.GetName(), same_prop.GetName());
    EXPECT_EQ(prop.GetId(), same_prop.GetId());
    EXPECT_EQ(prop.GetImportance(), same_prop.GetImportance());
    EXPECT_EQ(prop.GetValue(), same_prop.GetValue());
    EXPECT_EQ(prop.GetUnit(), same_prop.GetUnit());
    EXPECT_EQ(prop.GetDatatype(), same_prop.GetDatatype());
    }
    TEST(test_entity, test_copy_to) {
    auto entity = Entity();
    entity.SetId("original_id");
    entity.SetName("orignial_name");
    auto parent = Parent();
    parent.SetId("parent_id");
    parent.SetName("parent_name");
    entity.AppendParent(parent);
    auto prop = Property();
    prop.SetId("prop_id");
    prop.SetName("prop_name");
    entity.AppendProperty(prop);
    // create protobuf entity to which all fields ae copied and then a
    // CaoosDB entity from that protobuf entity.
    auto *proto_copy =
    google::protobuf::Arena::CreateMessage<ProtoEntity>(get_arena());
    entity.CopyTo(proto_copy);
    auto copied = Entity(proto_copy);
    EXPECT_EQ(entity.GetId(), copied.GetId());
    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());
    }
    TEST(test_entity, test_insert_entity) {
    auto transaction = caosdb::transaction::Transaction(
    std::shared_ptr<transaction::EntityTransactionService::Stub>(nullptr));
    ......@@ -98,6 +176,63 @@ TEST(test_entity, test_insert_with_role) { // NOLINT
    EXPECT_EQ(entity.GetValue(), "5.5");
    }
    TEST(test_entity, test_insert_with_parent) {
    auto transaction = caosdb::transaction::Transaction(
    std::shared_ptr<transaction::EntityTransactionService::Stub>(nullptr));
    auto entity = Entity();
    entity.SetId("entity_id");
    auto parent = Parent();
    parent.SetId("parent_id");
    parent.SetName("parent_name");
    EXPECT_EQ(parent.GetId(), "parent_id");
    EXPECT_EQ(parent.GetName(), "parent_name");
    entity.AppendParent(parent);
    transaction.InsertEntity(&entity);
    std::cout << entity.ToString() << std::endl;
    EXPECT_EQ(entity.GetId(), "entity_id");
    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());
    }
    // TODO(fspreck) cognitive complexity > 25 (threshold)
    TEST(test_entity, test_insert_with_property) { // NOLINT
    auto transaction = caosdb::transaction::Transaction(
    std::shared_ptr<transaction::EntityTransactionService::Stub>(nullptr));
    auto entity = Entity();
    entity.SetId("entity_id");
    auto prop = Property();
    prop.SetName("prop_name");
    prop.SetId("prop_id");
    prop.SetImportance("prop_importance");
    prop.SetValue("prop_value");
    prop.SetUnit("prop_unit");
    prop.SetDatatype("prop_dtype");
    entity.AppendProperty(prop);
    transaction.InsertEntity(&entity);
    EXPECT_EQ(entity.GetProperties().Size(), 1);
    auto inserted_prop = entity.GetProperties().At(0);
    EXPECT_EQ(prop.GetName(), inserted_prop.GetName());
    EXPECT_EQ(prop.GetId(), inserted_prop.GetId());
    EXPECT_EQ(prop.GetImportance(), inserted_prop.GetImportance());
    EXPECT_EQ(prop.GetValue(), inserted_prop.GetValue());
    EXPECT_EQ(prop.GetUnit(), inserted_prop.GetUnit());
    EXPECT_EQ(prop.GetDatatype(), inserted_prop.GetDatatype());
    }
    // TODO(tf) cognitive complexity > 25 (threshold)
    TEST(test_entity, test_from_id_response) { // NOLINT
    IdResponse idResponse;
    ......
    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