Skip to content
Snippets Groups Projects

F consolidation

Merged Timm Fitschen requested to merge f-consolidation into dev
6 files
+ 209
11
Compare changes
  • Side-by-side
  • Inline
Files
6
+ 227
0
/*
* 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/>.
*
*/
/**
* DataTypes have 2 dimensions: They may be atomic or reference typed, and they
* may be scalar or list valued. If they are atomic, they have an
* AtomicDataType. If they are reference typed, the reference name can be
* obtained with GetName().
*/
#ifndef CAOSDB_DATA_TYPE_H
#define CAOSDB_DATA_TYPE_H
#include "caosdb/protobuf_helper.h" // for ProtoMessageWrapper
#include "caosdb/entity/v1alpha1/main.pb.h" // for RepeatedPtrField, Message
#include <memory> // for unique_ptr
#include <string> // for string
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 class AtomicDataType {
// The data type is unset/unknown.
UNSPECIFIED = ProtoAtomicDataType::ATOMIC_DATA_TYPE_UNSPECIFIED,
// TEXT data type.
TEXT = ProtoAtomicDataType::ATOMIC_DATA_TYPE_TEXT,
// DOUBLE data type.
DOUBLE = ProtoAtomicDataType::ATOMIC_DATA_TYPE_DOUBLE,
// DATETIME data type.
DATETIME = ProtoAtomicDataType::ATOMIC_DATA_TYPE_DATETIME,
// INTEGER data type.
INTEGER = ProtoAtomicDataType::ATOMIC_DATA_TYPE_INTEGER,
// BOOLEAN data type.
BOOLEAN = ProtoAtomicDataType::ATOMIC_DATA_TYPE_BOOLEAN,
};
const std::map<AtomicDataType, std::string> atomicdatatype_names = {
{AtomicDataType::UNSPECIFIED, "UNSPECIFIED"}, {AtomicDataType::TEXT, "TEXT"},
{AtomicDataType::DOUBLE, "DOUBLE"}, {AtomicDataType::DATETIME, "DATETIME"},
{AtomicDataType::INTEGER, "INTEGER"}, {AtomicDataType::BOOLEAN, "BOOLEAN"}};
class DataType;
class ListDataType;
class ReferenceDataType : public ProtoMessageWrapper<ProtoDataType> {
public:
[[nodiscard]] inline auto GetName() const noexcept -> const std::string & {
// is list of reference?
if (this->wrapped->data_type_case() == DataTypeCase::kListDataType) {
return this->wrapped->list_data_type().reference_data_type().name();
}
return this->wrapped->reference_data_type().name();
}
friend class DataType;
friend class ListDataType;
inline auto GetWrapped() const -> const ProtoDataType * { return wrapped; }
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;
}
[[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>() {}
/**
* Create an AtomicDataType typed DataType. For references, use the std::string constructor.
*/
DataType(AtomicDataType data_type, bool list_type = false) : DataType() {
if (list_type) {
this->wrapped->mutable_list_data_type()->set_atomic_data_type(
static_cast<ProtoAtomicDataType>(data_type));
} else {
this->wrapped->set_atomic_data_type(static_cast<ProtoAtomicDataType>(data_type));
}
}
/**
* Create a reference typed DataType.
*/
DataType(const std::string &data_type, bool list_type = false) : DataType() {
if (list_type) {
this->wrapped->mutable_list_data_type()->mutable_reference_data_type()->set_name(data_type);
} else {
this->wrapped->mutable_reference_data_type()->set_name(data_type);
}
}
inline static auto ListOf(const AtomicDataType &atomic_data_type) -> DataType {
DataType result;
result.wrapped->mutable_list_data_type()->set_atomic_data_type(
static_cast<ProtoAtomicDataType>(atomic_data_type));
return result;
}
inline static auto ListOf(const std::string reference_data_type) -> DataType {
DataType result;
result.wrapped->mutable_list_data_type()->mutable_reference_data_type()->set_name(
reference_data_type);
return result;
}
[[nodiscard]] inline auto IsAtomic() const noexcept -> bool {
return this->wrapped->data_type_case() == DataTypeCase::kAtomicDataType;
}
[[nodiscard]] inline auto AsAtomic() const noexcept -> AtomicDataType {
return static_cast<AtomicDataType>(this->wrapped->atomic_data_type());
}
[[nodiscard]] inline auto IsReference() const noexcept -> bool {
return this->wrapped->data_type_case() == DataTypeCase::kReferenceDataType;
}
[[nodiscard]] inline auto AsReference() const noexcept -> const ReferenceDataType & {
if (!IsReference()) {
return ReferenceDataType::GetEmptyInstance();
} else if (reference_data_type == nullptr) {
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();
}
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
#endif
Loading