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

WIP: consolidation

parent 87da45df
Branches
Tags
1 merge request!12F consolidation
......@@ -27,10 +27,16 @@
namespace caosdb::entity {
using ProtoAtomicDataType = caosdb::entity::v1alpha1::AtomicDataType;
using ProtoDataType = caosdb::entity::v1alpha1::DataType;
using ProtoListDataType = caosdb::entity::v1alpha1::ListDataType;
using ProtoReferenceDataType = caosdb::entity::v1alpha1::ReferenceDataType;
using DataTypeCase = caosdb::entity::v1alpha1::DataType::DataTypeCase;
using ListDataTypeCase =
caosdb::entity::v1alpha1::ListDataType::ListDataTypeCase;
using caosdb::utility::ProtoMessageWrapper;
class Entity;
class Property;
// Atomic data types.
enum AtomicDataType {
// The data type is unset/unknown.
......@@ -48,52 +54,136 @@ enum AtomicDataType {
};
class DataType;
class ListDataType;
class ReferenceDataType : ProtoMessageWrapper<ProtoReferenceDataType> {
class ReferenceDataType : public ProtoMessageWrapper<ProtoDataType> {
public:
[[nodiscard]] inline auto GetName() const noexcept -> const std::string & {
return this->wrapped->name();
return this->wrapped->reference_data_type().name();
}
friend class DataType;
friend class ListDataType;
protected:
static auto GetEmptyInstance() -> const ReferenceDataType & {
static ReferenceDataType instance;
return instance;
}
inline static auto Create(ProtoDataType *wrapped)
-> std::unique_ptr<ReferenceDataType> {
return std::unique_ptr<ReferenceDataType>(new ReferenceDataType(wrapped));
}
ReferenceDataType() : ProtoMessageWrapper<ProtoDataType>() {}
ReferenceDataType(ProtoDataType *wrapped)
: ProtoMessageWrapper<ProtoDataType>(wrapped) {}
};
class ListDataType : public ProtoMessageWrapper<ProtoDataType> {
public:
[[nodiscard]] inline auto IsListOfReference() const noexcept -> bool {
return this->wrapped->list_data_type().list_data_type_case() ==
ListDataTypeCase::kReferenceDataType;
}
[[nodiscard]] inline auto GetReferenceDataType() const
-> const ReferenceDataType & {
if (!IsListOfReference()) {
return ReferenceDataType::GetEmptyInstance();
}
if (reference_data_type == nullptr) {
this->reference_data_type = std::unique_ptr<ReferenceDataType>(
ReferenceDataType::Create(this->wrapped).release());
}
return *this->reference_data_type;
}
ReferenceDataType() : ProtoMessageWrapper<ProtoReferenceDataType>() {}
[[nodiscard]] inline auto IsListOfAtomic() const noexcept -> bool {
return this->wrapped->list_data_type().list_data_type_case() ==
ListDataTypeCase::kAtomicDataType;
}
[[nodiscard]] inline auto GetAtomicDataType() const -> AtomicDataType {
return static_cast<AtomicDataType>(
this->wrapped->list_data_type().atomic_data_type());
}
friend class DataType;
protected:
static auto GetEmptyInstance() -> const ListDataType & {
static auto empty_instance = ListDataType();
return empty_instance;
}
inline static auto Create(ProtoDataType *wrapped)
-> std::unique_ptr<ListDataType> {
return std::unique_ptr<ListDataType>(new ListDataType(wrapped));
}
ListDataType() : ProtoMessageWrapper<ProtoDataType>() {}
ListDataType(ProtoDataType *wrapped)
: ProtoMessageWrapper<ProtoDataType>(wrapped) {}
mutable std::unique_ptr<ReferenceDataType> reference_data_type;
};
class DataType : public ProtoMessageWrapper<ProtoDataType> {
public:
DataType(ProtoDataType *wrapped)
: ProtoMessageWrapper<ProtoDataType>(wrapped) {}
DataType() : ProtoMessageWrapper<ProtoDataType>() {}
DataType(AtomicDataType data_type) : DataType() {
this->wrapped->set_atomic_data_type(
static_cast<ProtoAtomicDataType>(data_type));
}
DataType(const std::string &data_type) : DataType() {
this->wrapped->mutable_reference_type()->set_name(data_type);
this->wrapped->mutable_reference_data_type()->set_name(data_type);
}
[[nodiscard]] inline auto IsAtomic() const noexcept -> bool {
return this->wrapped->data_type_case() == DataTypeCase::kAtomicType;
return this->wrapped->data_type_case() == DataTypeCase::kAtomicDataType;
}
[[nodiscard]] inline auto AsAtomic() const noexcept -> AtomicDataType {
return static_cast<AtomicDataType>(this->wrapped->atomic_type());
return static_cast<AtomicDataType>(this->wrapped->atomic_data_type());
}
[[nodiscard]] inline auto IsReference() const noexcept -> bool {
return this->wrapped->data_type_case() == DataTypeCase::kReferenceType;
return this->wrapped->data_type_case() == DataTypeCase::kReferenceDataType;
}
[[nodiscard]] inline auto AsReference() const noexcept -> ReferenceDataType {
[[nodiscard]] inline auto AsReference() const noexcept
-> const ReferenceDataType & {
if (!IsReference()) {
return ReferenceDataType{};
return ReferenceDataType::GetEmptyInstance();
} else if (reference_data_type == nullptr) {
reference_data_type = std::make_unique<ReferenceDataType>();
this->reference_data_type->wrapped =
this->wrapped->mutable_reference_type();
reference_data_type = std::unique_ptr<ReferenceDataType>(
ReferenceDataType::Create(this->wrapped).release());
}
return *reference_data_type;
}
[[nodiscard]] inline auto IsList() const noexcept -> bool {
return this->wrapped->data_type_case() == DataTypeCase::kListDataType;
}
[[nodiscard]] inline auto AsList() const noexcept -> const ListDataType & {
if (!IsList()) {
return ListDataType::GetEmptyInstance();
} else if (list_data_type == nullptr) {
list_data_type = std::unique_ptr<ListDataType>(
ListDataType::Create(this->wrapped).release());
}
return *list_data_type;
}
inline auto operator==(const DataType &other) const noexcept -> bool {
// TODO(tf) Is this safe?
return this->wrapped->SerializeAsString() ==
other.wrapped->SerializeAsString();
}
private:
friend class Entity;
friend class Property;
protected:
mutable std::unique_ptr<ReferenceDataType> reference_data_type;
mutable std::unique_ptr<ListDataType> list_data_type;
};
} // namespace caosdb::entity
......
......@@ -46,6 +46,8 @@ using ProtoMessage = caosdb::entity::v1alpha1::Message;
using caosdb::entity::v1alpha1::EntityRole;
using ProtoImportance = caosdb::entity::v1alpha1::Importance;
const static std::string logger_name = "caosdb::entity";
/**
* The property importance.
*/
......@@ -268,7 +270,10 @@ private:
*/
class Property {
public:
explicit inline Property(ProtoProperty *wrapped) : wrapped(wrapped){};
explicit inline Property(ProtoProperty *wrapped) : wrapped(wrapped) {
data_type.wrapped = this->wrapped->mutable_data_type();
value.wrapped = this->wrapped->mutable_value();
};
Property();
/**
......@@ -337,6 +342,7 @@ public:
* Set the datatype of this property.
*/
auto SetDataType(const DataType &new_data_type) -> StatusCode;
auto SetDataType(const AtomicDataType new_data_type) -> StatusCode;
auto SetDataType(const std::string &new_data_type) -> StatusCode;
/**
......@@ -488,8 +494,9 @@ public:
// auto SetValue(const bool value) -> StatusCode;
auto SetUnit(const std::string &unit) -> void;
// Currently no references or lists.
auto SetDataType(const DataType &new_data_type) -> StatusCode;
auto SetDataType(const AtomicDataType new_data_type) -> StatusCode;
auto SetDataType(const std::string &new_data_type) -> StatusCode;
auto AppendProperty(const Property &property) -> void;
......@@ -503,14 +510,14 @@ 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;
Messages errors;
Messages warnings;
Messages infos;
private:
Value value;
DataType data_type;
};
......
......@@ -40,9 +40,9 @@ public:
}
protected:
ProtoMessageWrapper() {
this->wrapped = Arena::CreateMessage<P>(get_arena());
}
ProtoMessageWrapper()
: ProtoMessageWrapper(Arena::CreateMessage<P>(get_arena())) {}
ProtoMessageWrapper(P *wrapped) : wrapped(wrapped) {}
P *wrapped;
};
......
......@@ -31,6 +31,9 @@ using ProtoValue = caosdb::entity::v1alpha1::Value;
using ValueCase = caosdb::entity::v1alpha1::Value::ValueCase;
using ScalarValueCase = caosdb::entity::v1alpha1::ScalarValue::ScalarValueCase;
class Entity;
class Property;
// Represents special values which are otherwise hard to tranfer via protobuf.
enum SpecialValue {
// Represent the NULL value.
......@@ -80,13 +83,15 @@ public:
}
[[nodiscard]] inline auto AsDouble() const noexcept -> double {
return this->wrapped->scalar_value().double_value();
;
}
inline auto operator==(const Value &other) const noexcept -> bool {
return this->wrapped->SerializeAsString() ==
other.wrapped->SerializeAsString();
}
friend class Entity;
friend class Property;
};
} // namespace caosdb::entity
......
Subproject commit 780c89e86cb9c3b17171b88827aaedee3c3a9595
Subproject commit f7388e18e0908d2b675159176f9c9a8a6f52637e
......@@ -76,7 +76,7 @@ auto Parents::Append(const Parent &parent) -> void {
parent.wrapped = destination;
}
Property::Property() : wrapped(Property::CreateProtoProperty()) {}
Property::Property() : Property(Property::CreateProtoProperty()) {}
auto Property::CreateProtoProperty() -> ProtoProperty * {
return google::protobuf::Arena::CreateMessage<ProtoProperty>(get_arena());
......@@ -146,6 +146,10 @@ auto Property::SetDataType(const DataType &new_data_type) -> StatusCode {
return this->data_type.CopyFrom(new_data_type);
}
auto Property::SetDataType(const AtomicDataType new_data_type) -> StatusCode {
return SetDataType(DataType(new_data_type));
}
auto Property::SetDataType(const std::string &new_data_type) -> StatusCode {
return SetDataType(DataType(new_data_type));
}
......@@ -180,6 +184,7 @@ auto Entity::CreateProtoEntity() -> ProtoEntity * {
}
Entity::Entity() : wrapped(Entity::CreateProtoEntity()) {
data_type.wrapped = this->wrapped->mutable_data_type();
properties.wrapped = this->wrapped->mutable_properties();
parents.wrapped = this->wrapped->mutable_parents();
errors.wrapped = this->wrapped->mutable_errors();
......@@ -244,6 +249,10 @@ auto Entity::SetDataType(const DataType &new_data_type) -> StatusCode {
return this->data_type.CopyFrom(new_data_type);
}
auto Entity::SetDataType(const AtomicDataType new_data_type) -> StatusCode {
return SetDataType(DataType(new_data_type));
}
auto Entity::SetDataType(const std::string &new_data_type) -> StatusCode {
return SetDataType(DataType(new_data_type));
}
......
......@@ -20,6 +20,7 @@
# append all the test cases here (file name without the ".cpp" suffix)
set(test_cases
test_data_type
test_configuration
test_connection
test_entity
......
/*
*
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com>
* Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "caosdb/data_type.h" // for DataType, AtomicDataType
#include "caosdb/entity/v1alpha1/main.pb.h" // for AtomicDataType, DataType
#include <gtest/gtest-message.h> // for Message
#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApi...
#include <gtest/gtest_pred_impl.h> // for AssertionResult, Test
#include <memory> // for allocator
namespace caosdb::entity {
using ProtoEntity = caosdb::entity::v1alpha1::Entity;
using ProtoParent = caosdb::entity::v1alpha1::Parent;
using ProtoDataType = caosdb::entity::v1alpha1::DataType;
using ProtoAtomicDataType = caosdb::entity::v1alpha1::AtomicDataType;
TEST(test_data_type, test_atomic) {
ProtoDataType proto_data_type;
for (int i = 1; i < 6; i++) {
proto_data_type.set_atomic_data_type(static_cast<ProtoAtomicDataType>(i));
DataType data_type(&proto_data_type);
EXPECT_FALSE(data_type.IsReference());
EXPECT_FALSE(data_type.IsList());
EXPECT_TRUE(data_type.IsAtomic());
EXPECT_EQ(data_type.AsAtomic(), static_cast<AtomicDataType>(i));
}
}
TEST(test_data_type, test_list_of_atomic) {
ProtoDataType proto_data_type;
auto *proto_list_data_type = proto_data_type.mutable_list_data_type();
for (int i = 1; i < 6; i++) {
proto_list_data_type->set_atomic_data_type(
static_cast<ProtoAtomicDataType>(i));
DataType data_type(&proto_data_type);
EXPECT_FALSE(data_type.IsReference());
EXPECT_FALSE(data_type.IsAtomic());
EXPECT_TRUE(data_type.IsList());
const auto &list_data_type = data_type.AsList();
EXPECT_TRUE(list_data_type.IsListOfAtomic());
EXPECT_EQ(list_data_type.GetAtomicDataType(),
static_cast<AtomicDataType>(i));
}
}
} // namespace caosdb::entity
......@@ -24,15 +24,20 @@
#include "caosdb/entity.h" // for Entity, Parent, Par...
#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 "caosdb/value.h" // for Value
#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
#include <memory> // for allocator, shared_ptr
#include "caosdb/logging.h"
#include "caosdb/message_code.h" // for MessageCode
#include "caosdb/protobuf_helper.h" // for get_arena
#include "caosdb/transaction.h" // for Transaction
#include "caosdb/value.h" // for Value
#include <boost/log/core/record.hpp> // for record
#include <boost/log/sources/record_ostream.hpp> // for record_pump<>:...
#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 <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
#include <memory> // for allocator, shared_ptr
namespace caosdb::entity {
using caosdb::entity::v1alpha1::IdResponse;
......@@ -63,22 +68,38 @@ TEST(test_entity, test_append_parent) {
}
TEST(test_entity, test_property_setters) {
CAOSDB_LOG_DEBUG(logger_name) << "HERE 1";
auto prop = Property();
CAOSDB_LOG_DEBUG(logger_name) << "HERE 2";
prop.SetName("prop_name");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 3";
prop.SetId("prop_id");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 4";
prop.SetImportance(Importance::OBLIGATORY);
CAOSDB_LOG_DEBUG(logger_name) << "HERE 5";
prop.SetValue("prop_value");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 6";
prop.SetUnit("prop_unit");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 7";
prop.SetDataType("prop_dtype");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 8";
EXPECT_EQ(prop.GetName(), "prop_name");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 1";
EXPECT_EQ(prop.GetId(), "prop_id");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 2";
EXPECT_EQ(prop.GetImportance(), Importance::OBLIGATORY);
CAOSDB_LOG_DEBUG(logger_name) << "HERE 3";
EXPECT_TRUE(prop.GetValue().IsString());
CAOSDB_LOG_DEBUG(logger_name) << "HERE 4";
EXPECT_EQ(prop.GetValue().AsString(), "prop_value");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 5";
EXPECT_EQ(prop.GetUnit(), "prop_unit");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 6";
EXPECT_TRUE(prop.GetDataType().IsReference());
CAOSDB_LOG_DEBUG(logger_name) << "HERE 7";
EXPECT_EQ(prop.GetDataType().AsReference().GetName(), "prop_dtype");
CAOSDB_LOG_DEBUG(logger_name) << "HERE 8";
}
TEST(test_entity, test_append_property) {
......@@ -159,7 +180,7 @@ TEST(test_entity, test_insert_with_role) {
auto entity = Entity();
entity.SetRole(Role::PROPERTY);
entity.SetDataType("DOUBLE");
entity.SetDataType(AtomicDataType::DOUBLE);
entity.SetName("Length");
entity.SetUnit("m");
entity.SetValue(5.5);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment