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

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

parents 53198ae1 7bb6d230
No related branches found
No related tags found
1 merge request!6F update
......@@ -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;
};
......@@ -370,11 +447,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;
protected:
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);
}
......
......@@ -147,8 +147,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));
......@@ -94,6 +172,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