Commit e7b1b8dc authored by Timm Fitschen's avatar Timm Fitschen
Browse files

Merge branch 'f-value-data-structs' into 'dev'

API: Introduce value and datatype structs to Extern C

See merge request !24
parents 7fbe4ad1 083478f9
Pipeline #13787 passed with stages
in 8 minutes and 14 seconds
......@@ -20,7 +20,7 @@
cmake_minimum_required(VERSION 3.13)
set(libcaosdb_VERSION 0.0.16)
set(libcaosdb_VERSION 0.0.17)
set(libcaosdb_COMPATIBLE_SERVER_VERSION_MAJOR 0)
set(libcaosdb_COMPATIBLE_SERVER_VERSION_MINOR 5)
set(libcaosdb_COMPATIBLE_SERVER_VERSION_PATCH 0)
......
......@@ -3,7 +3,7 @@ from conans import ConanFile, CMake, tools
class CaosdbConan(ConanFile):
name = "caosdb"
version = "0.0.16"
version = "0.0.17"
license = "AGPL-3.0-or-later"
author = "Timm C. Fitschen <t.fitschen@indiscale.com>"
url = "https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib.git"
......
......@@ -179,14 +179,14 @@ public:
[[nodiscard]] inline auto IsAtomic() const noexcept -> bool {
return this->wrapped->data_type_case() == DataTypeCase::kAtomicDataType;
}
[[nodiscard]] inline auto AsAtomic() const noexcept -> AtomicDataType {
[[nodiscard]] inline auto GetAsAtomic() 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 & {
[[nodiscard]] inline auto GetAsReference() const noexcept -> const ReferenceDataType & {
if (!IsReference()) {
return ReferenceDataType::GetEmptyInstance();
} else if (reference_data_type == nullptr) {
......@@ -200,7 +200,7 @@ public:
return this->wrapped->data_type_case() == DataTypeCase::kListDataType;
}
[[nodiscard]] inline auto AsList() const noexcept -> const ListDataType & {
[[nodiscard]] inline auto GetAsList() const noexcept -> const ListDataType & {
if (!IsList()) {
return ListDataType::GetEmptyInstance();
} else if (list_data_type == nullptr) {
......
......@@ -515,6 +515,7 @@ public:
* Set the value of this property.
*/
auto SetValue(const Value &value) -> StatusCode;
auto SetValue(const AbstractValue &value) -> StatusCode;
auto SetValue(const std::string &value) -> StatusCode;
auto SetValue(const char *value) -> StatusCode;
auto SetValue(const double value) -> StatusCode;
......@@ -687,6 +688,7 @@ public:
*/
auto SetDescription(const std::string &description) -> void;
auto SetValue(const AbstractValue &value) -> StatusCode;
auto SetValue(const Value &value) -> StatusCode;
auto SetValue(const std::string &value) -> StatusCode;
auto SetValue(const char *value) -> StatusCode;
......
......@@ -22,12 +22,17 @@
#ifndef CAOSDB_VALUE_H
#define CAOSDB_VALUE_H
#include "caosdb/protobuf_helper.h" // for ProtoMessageWrapper
#include "caosdb/logging.h" // IWYU pragma: keep
#include "caosdb/entity/v1alpha1/main.pb.h" // for RepeatedPtrField, Message
#include "caosdb/logging.h"
#include <google/protobuf/util/json_util.h> // for MessageToJson...
#include <memory> // for unique_ptr
#include <string> // for string
#include <vector> // for vector
#include <cstdint> // for int64_t
#include <google/protobuf/arena.h> // for Arena
#include <google/protobuf/generated_message_util.h> // for Arena
#include <google/protobuf/util/json_util.h> // IWYU pragma: keep
#include <memory> // for unique_ptr
#include <string> // for string, operator==
#include <utility> // for move
#include <vector> // for vector
#define LIST_VALUE_CONSTRUCTOR(TYPE, SETTER) \
explicit inline Value(const std::vector<TYPE> &values) : ProtoMessageWrapper<ProtoValue>() { \
......@@ -37,15 +42,17 @@
}
namespace caosdb::entity {
using caosdb::utility::get_arena;
using caosdb::utility::ProtoMessageWrapper;
using google::protobuf::Arena;
using ProtoSpecialValue = caosdb::entity::v1alpha1::SpecialValue;
using ProtoValue = caosdb::entity::v1alpha1::Value;
using ProtoScalarValue = caosdb::entity::v1alpha1::ScalarValue;
using ValueCase = caosdb::entity::v1alpha1::Value::ValueCase;
using ScalarValueCase = caosdb::entity::v1alpha1::ScalarValue::ScalarValueCase;
class Entity;
class Property;
class ScalarValue;
class Value;
// Represents special values which are otherwise hard to tranfer via protobuf.
enum SpecialValue {
......@@ -55,46 +62,239 @@ enum SpecialValue {
EMPTY_STRING = ProtoSpecialValue::SPECIAL_VALUE_EMPTY_STRING,
};
class ScalarValue : public ProtoMessageWrapper<ProtoScalarValue> {
/**
* Pure abstract base class for values.
*/
class AbstractValue {
public:
inline ScalarValue(ProtoScalarValue *wrapped) : ProtoMessageWrapper<ProtoScalarValue>(wrapped) {}
/**
* Pure virtual destructor.
*/
virtual ~AbstractValue() = 0;
/**
* Return true iff the value is a NULL value (NULL in the CaosDB sense).
*/
[[nodiscard]] virtual auto IsNull() const noexcept -> bool = 0;
/**
* Return true iff the value is best represented in C++ types as a
* std::string.
*
* If true, clients may call GetAsString to receive a std::string
* representation of the value.
*/
[[nodiscard]] virtual auto IsString() const noexcept -> bool = 0;
/**
* Return true iff the value is best represented in C++ types as a
* bool.
*
* If true, clients may call GetAsBool to receive a bool
* representation of the value.
*/
[[nodiscard]] virtual auto IsBool() const noexcept -> bool = 0;
/**
* Return true iff the value is best represented in C++ types as a
* double.
*
* If true, clients may call GetAsDouble to receive a double
* representation of the value.
*/
[[nodiscard]] virtual auto IsDouble() const noexcept -> bool = 0;
/**
* Return true iff the value is best represented in C++ types as an
* int64_t.
*
* If true, clients may call GetAsInt64 to receive an int64_t
* representation of the value.
*/
[[nodiscard]] virtual auto IsInt64() const noexcept -> bool = 0;
/**
* Return true iff the value is best represented in C++ types as a
* std::vector<ScalarValue>.
*
* If true, clients may call GetAsVector to receive a
* std::vector<ScalarValue> representation of the value.
*/
[[nodiscard]] virtual auto IsVector() const noexcept -> bool = 0;
/**
* Return a std::string representation of this value.
*
* Clients should call IsString before calling this function in order to
* assure that this value is indeed best represented by a std::string.
*
* The return value is undefined if IsString is false.
*/
[[nodiscard]] virtual auto GetAsString() const noexcept -> const std::string & = 0;
/**
* Return a bool representation of this value.
*
* Clients should call IsBool before calling this function in order to
* assure that this value is indeed best represented by a bool.
*
* The return value is undefined if IsBool is false.
*/
[[nodiscard]] virtual auto GetAsBool() const noexcept -> bool = 0;
/**
* Return a double representation of this value.
*
* Clients should call IsDouble before calling this function in order to
* assure that this value is indeed best represented by a double.
*
* The return value is undefined if IsDouble is false.
*/
[[nodiscard]] virtual auto GetAsDouble() const noexcept -> double = 0;
/**
* Return an int64_t representation of this value.
*
* Clients should call IsInt64 before calling this function in order to
* assure that this value is indeed best represented by an int64_t.
*
* The return value is undefined if IsInt64 is false.
*/
[[nodiscard]] virtual auto GetAsInt64() const noexcept -> int64_t = 0;
/**
* Return a std::vector<ScalarValue> representation of this value.
*
* Clients should call IsVector before calling this function in order to
* assure that this value is indeed best represented by a
* std::vector<ScalarValue>.
*
* The return value is undefined if IsVector is false.
*/
[[nodiscard]] virtual auto GetAsVector() const noexcept -> const std::vector<ScalarValue> & = 0;
[[nodiscard]] virtual auto ToString() const noexcept -> const std::string = 0;
friend class Value;
protected:
[[nodiscard]] virtual auto GetProtoValue() const noexcept -> const ProtoValue * = 0;
};
inline AbstractValue::~AbstractValue() {}
class ScalarValue : public AbstractValue, public ProtoMessageWrapper<ProtoScalarValue> {
public:
/**
* Destructor.
*/
inline ~ScalarValue(){};
/**
* Copy constructor.
*/
inline ScalarValue(const ScalarValue &original) : ScalarValue() {
this->wrapped->CopyFrom(*original.wrapped);
}
/**
* Move constructor.
*/
inline ScalarValue(ScalarValue &&other) : ScalarValue(std::move(other.wrapped)){};
/**
* Copy assignment operator.
*/
inline auto operator=(const ScalarValue &original) -> ScalarValue & {
if (&original != this) {
this->wrapped->CopyFrom(*original.wrapped);
}
return *this;
}
/**
* Move assignment operator.
*/
inline auto operator=(ScalarValue &&other) -> ScalarValue & {
if (&other != this) {
this->wrapped = std::move(other.wrapped);
}
return *this;
}
inline ScalarValue(ProtoScalarValue *wrapped)
: ProtoMessageWrapper<ProtoScalarValue>(wrapped), proto_value(nullptr) {}
[[nodiscard]] inline auto IsNull() const noexcept -> bool {
return (this->wrapped->scalar_value_case() == ScalarValueCase::kSpecialValue &&
this->wrapped->special_value() == ProtoSpecialValue::SPECIAL_VALUE_UNSPECIFIED);
}
[[nodiscard]] inline auto IsString() const noexcept -> bool {
return (this->wrapped->scalar_value_case() == ScalarValueCase::kStringValue) ||
(this->wrapped->scalar_value_case() == ScalarValueCase::kSpecialValue &&
this->wrapped->special_value() == ProtoSpecialValue::SPECIAL_VALUE_EMPTY_STRING);
}
[[nodiscard]] inline auto AsString() const noexcept -> const std::string & {
[[nodiscard]] inline auto GetAsString() const noexcept -> const std::string & {
return this->wrapped->string_value();
}
[[nodiscard]] inline auto IsDouble() const noexcept -> bool {
return (this->wrapped->scalar_value_case() == ScalarValueCase::kDoubleValue);
}
[[nodiscard]] inline auto AsDouble() const noexcept -> double {
[[nodiscard]] inline auto GetAsDouble() const noexcept -> double {
return this->wrapped->double_value();
}
[[nodiscard]] inline auto IsInteger() const noexcept -> bool {
[[nodiscard]] inline auto IsInt64() const noexcept -> bool {
return (this->wrapped->scalar_value_case() == ScalarValueCase::kIntegerValue);
}
[[nodiscard]] inline auto AsInteger() const noexcept -> int64_t {
[[nodiscard]] inline auto GetAsInt64() const noexcept -> int64_t {
return this->wrapped->integer_value();
}
[[nodiscard]] inline auto IsBool() const noexcept -> bool {
return (this->wrapped->scalar_value_case() == ScalarValueCase::kBooleanValue);
}
[[nodiscard]] inline auto AsBool() const noexcept -> bool {
[[nodiscard]] inline auto GetAsBool() const noexcept -> bool {
return this->wrapped->boolean_value();
}
[[nodiscard]] auto IsVector() const noexcept -> bool {
// Always false b/c a scalar value is never a collection.
return false;
}
[[nodiscard]] auto GetAsVector() const noexcept -> const std::vector<ScalarValue> & {
// Always return an empty vector.
static const std::vector<ScalarValue> empty_collection;
return empty_collection;
}
inline auto ToString() const noexcept -> const std::string {
CAOSDB_DEBUG_MESSAGE_STRING(*wrapped, out)
return out;
}
friend class Value;
protected:
[[nodiscard]] auto GetProtoValue() const noexcept -> const ProtoValue * {
if (this->proto_value == nullptr) {
this->proto_value = Arena::CreateMessage<ProtoValue>(get_arena());
this->proto_value->mutable_scalar_value()->CopyFrom(*this->wrapped);
}
return this->proto_value;
};
inline ScalarValue() : ProtoMessageWrapper<ProtoScalarValue>(), proto_value(nullptr) {}
private:
mutable ProtoValue *proto_value;
};
class Value : public ProtoMessageWrapper<ProtoValue> {
class Value : public AbstractValue, public ProtoMessageWrapper<ProtoValue> {
public:
/**
* Copy constructor.
*/
inline Value(const Value &original) : Value() { this->wrapped->CopyFrom(*original.wrapped); }
/**
* Move constructor.
*/
inline Value(Value &&other) : Value(std::move(other.wrapped)) {}
/**
* Destructor.
*/
inline ~Value() {}
inline Value() : ProtoMessageWrapper<ProtoValue>() {
// has NULL_VALUE now
}
explicit inline Value(const ScalarValue &value) : Value() {
this->wrapped->mutable_scalar_value()->CopyFrom(*value.wrapped);
}
explicit inline Value(const AbstractValue &value) : Value() {
this->wrapped->CopyFrom(*value.GetProtoValue());
}
explicit inline Value(ProtoValue *wrapped) : ProtoMessageWrapper<ProtoValue>(wrapped) {}
explicit inline Value(const std::string &value) : ProtoMessageWrapper<ProtoValue>() {
this->wrapped->mutable_scalar_value()->set_string_value(value);
......@@ -121,7 +321,10 @@ public:
LIST_VALUE_CONSTRUCTOR(bool, set_boolean_value)
[[nodiscard]] inline auto IsNull() const noexcept -> bool {
return this->wrapped->value_case() == ValueCase::VALUE_NOT_SET;
return this->wrapped->value_case() == ValueCase::VALUE_NOT_SET ||
(this->wrapped->scalar_value().scalar_value_case() == ScalarValueCase::kSpecialValue &&
this->wrapped->scalar_value().special_value() ==
ProtoSpecialValue::SPECIAL_VALUE_UNSPECIFIED);
}
[[nodiscard]] inline auto IsString() const noexcept -> bool {
......@@ -134,7 +337,7 @@ public:
}
return false;
}
[[nodiscard]] inline auto AsString() const noexcept -> const std::string & {
[[nodiscard]] inline auto GetAsString() const noexcept -> const std::string & {
return this->wrapped->scalar_value().string_value();
;
}
......@@ -146,18 +349,18 @@ public:
}
return false;
}
[[nodiscard]] inline auto AsDouble() const noexcept -> double {
[[nodiscard]] inline auto GetAsDouble() const noexcept -> double {
return this->wrapped->scalar_value().double_value();
}
[[nodiscard]] inline auto IsInteger() const noexcept -> bool {
[[nodiscard]] inline auto IsInt64() const noexcept -> bool {
if (this->wrapped->value_case() == ValueCase::kScalarValue) {
return (this->wrapped->scalar_value().scalar_value_case() == ScalarValueCase::kIntegerValue);
}
return false;
}
[[nodiscard]] inline auto AsInteger() const noexcept -> int64_t {
[[nodiscard]] inline auto GetAsInt64() const noexcept -> int64_t {
return this->wrapped->scalar_value().integer_value();
}
......@@ -168,31 +371,55 @@ public:
}
return false;
}
[[nodiscard]] inline auto AsBool() const noexcept -> bool {
[[nodiscard]] inline auto GetAsBool() const noexcept -> bool {
return this->wrapped->scalar_value().boolean_value();
}
[[nodiscard]] inline auto IsList() const noexcept -> bool {
[[nodiscard]] inline auto IsVector() const noexcept -> bool {
return this->wrapped->value_case() == ValueCase::kListValues;
}
[[nodiscard]] inline auto AsList() const noexcept -> const std::vector<ScalarValue> & {
if (!IsList()) {
[[nodiscard]] inline auto GetAsVector() const noexcept -> const std::vector<ScalarValue> & {
if (!IsVector()) {
// create empty list
this->list_values = std::make_unique<std::vector<ScalarValue>>();
this->collection_values = std::make_unique<std::vector<ScalarValue>>();
}
if (this->list_values == nullptr) {
this->list_values = std::make_unique<std::vector<ScalarValue>>();
if (this->collection_values == nullptr) {
this->collection_values = std::make_unique<std::vector<ScalarValue>>();
for (auto &scalar : *(this->wrapped->mutable_list_values()->mutable_values())) {
this->list_values->push_back(ScalarValue(&scalar));
this->collection_values->push_back(ScalarValue(&scalar));
}
}
return *(this->list_values);
return *(this->collection_values);
}
/**
* Return true if the underlying Protobuf messages have the same
* serialization.
*/
inline auto operator==(const Value &other) const noexcept -> bool {
return this->wrapped->SerializeAsString() == other.wrapped->SerializeAsString();
}
/**
* Copy assignment operator.
*/
inline auto operator=(const Value &other) -> Value & {
if (&other != this) {
this->wrapped->CopyFrom(*other.wrapped);
}
return *this;
}
/**
* Move assignment operator.
*/
inline auto operator=(Value &&other) -> Value & {
if (&other != this) {
this->wrapped = std::move(other.wrapped);
}
return *this;
}
inline auto ToString() const noexcept -> const std::string {
CAOSDB_DEBUG_MESSAGE_STRING(*wrapped, out)
return out;
......@@ -201,8 +428,11 @@ public:
friend class Entity;
friend class Property;
protected:
[[nodiscard]] auto GetProtoValue() const noexcept -> const ProtoValue * { return this->wrapped; };
private:
mutable std::unique_ptr<std::vector<ScalarValue>> list_values;
mutable std::unique_ptr<std::vector<ScalarValue>> collection_values;
};
} // namespace caosdb::entity
......
......@@ -264,8 +264,6 @@ int caosdb_connection_connection_manager_get_connection(caosdb_connection_connec
* ENTITY STUFF AND TRANSACTIONS
****************************************************************************/
// TODO(fspreck) implementations needed, and probably these declarations are
// not sufficient yet.
typedef struct caosdb_transaction_transaction {
void *wrapped_transaction;
bool _deletable = false;
......@@ -363,33 +361,25 @@ typedef struct caosdb_entity_message {
bool _deletable = false;
} caosdb_entity_message;
typedef struct caosdb_entity_value {
void *wrapped_value;
bool _deletable = false;
} caosdb_entity_value;
typedef struct caosdb_entity_datatype {
void *wrapped_datatype;
bool _deletable = false;
} caosdb_entity_datatype;
// GETTERS FOR EVERYTHING
int caosdb_entity_entity_get_id(caosdb_entity_entity *entity, char **out);
int caosdb_entity_entity_get_role(caosdb_entity_entity *entity, char **out);
int caosdb_entity_entity_get_name(caosdb_entity_entity *entity, char **out);
int caosdb_entity_entity_get_description(caosdb_entity_entity *entity, char **out);
int caosdb_entity_entity_get_local_path(caosdb_entity_entity *entity, char **out);
/**
* Get the name of the entity's datatype, whether it is a reference, and whether it is a list.
*/
int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, char **name, bool *is_ref,
bool *is_list);
int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, caosdb_entity_datatype *out);
int caosdb_entity_entity_get_unit(caosdb_entity_entity *entity, char **out);
int caosdb_entity_entity_get_int_value(caosdb_entity_entity *entity, int64_t *out);
int caosdb_entity_entity_get_double_value(caosdb_entity_entity *entity, double *out);
int caosdb_entity_entity_get_boolean_value(caosdb_entity_entity *entity, bool *out);
int caosdb_entity_entity_get_string_value(caosdb_entity_entity *entity, char **out);
int caosdb_entity_entity_get_int_list_value_at(caosdb_entity_entity *entity, int64_t *out,
const int index);
int caosdb_entity_entity_get_double_list_value_at(caosdb_entity_entity *entity, double *out,
const int index);
int caosdb_entity_entity_get_boolean_list_value_at(caosdb_entity_entity *entity, bool *out,
const int index);
int caosdb_entity_entity_get_string_list_value_at(caosdb_entity_entity *entity, char **out,
const int index);
int caosdb_entity_entity_get_value_list_length(caosdb_entity_entity *entity, int *out);
int caosdb_entity_entity_get_value(caosdb_entity_entity *entity, caosdb_entity_value *out);
int caosdb_entity_entity_get_version_id(caosdb_entity_entity *entity, char **out);
int caosdb_entity_entity_get_errors_size(caosdb_entity_entity *entity, int *out);
int caosdb_entity_entity_get_error(caosdb_entity_entity *entity, caosdb_entity_message *out,
......@@ -411,27 +401,10 @@ int caosdb_entity_property_get_id(caosdb_entity_property *property, char **out);
int caosdb_entity_property_get_name(caosdb_entity_property *property, char **out);
int caosdb_entity_property_get_description(caosdb_entity_property *property, char **out);
int caosdb_entity_property_get_importance(caosdb_entity_property *property, char **out);
/**
* Get the name of the property's datatype, whether it is a reference, and whether it is a list.
*/
int caosdb_entity_property_get_datatype(caosdb_entity_property *property, char **name, bool *is_ref,
bool *is_list);
int caosdb_entity_property_get_datatype(caosdb_entity_property *property,
caosdb_entity_datatype *out);
int caosdb_entity_property_get_unit(caosdb_entity_property *property, char **out);
int caosdb_entity_property_get_int_value(caosdb_entity_property *property, int64_t *out);
int caosdb_entity_property_get_double_value(caosdb_entity_property *property, double *out);
int caosdb_entity_property_get_boolean_value(caosdb_entity_property *property, bool *out);
int caosdb_entity_property_get_string_value(caosdb_entity_property *property, char **out);
int caosdb_entity_property_get_int_list_value_at(caosdb_entity_property *property, int64_t *out,
const int index);
int caosdb_entity_property_get_double_list_value_at(caosdb_entity_property *property, double *out,
const int index);
int caosdb_entity_property_get_boolean_list_value_at(caosdb_entity_property *property, bool *out,
const int index);
int caosdb_entity_property_get_string_list_value_at(caosdb_entity_property *property, char **out,
const int index);
int caosdb_entity_property_get_value_list_length(caosdb_entity_property *property, int *out);
int caosdb_entity_property_get_value(caosdb_entity_property *property, caosdb_entity_value *out);
int caosdb_entity_parent_get_id(caosdb_entity_parent *parent, char **out);
int caosdb_entity_parent_get_name(caosdb_entity_parent *parent, char **out);
int caosdb_entity_parent_get_description(caosdb_entity_parent *parent, char **out);
......@@ -439,6 +412,26 @@ int caosdb_entity_parent_get_description(caosdb_entity_parent *parent, char **ou
int caosdb_entity_message_get_code(caosdb_entity_message *message, int *out);
int caosdb_entity_message_get_description(caosdb_entity_message *message, char **out);
int caosdb_entity_datatype_is_atomic(caosdb_entity_datatype *datatype, bool *out);
int caosdb_entity_datatype_is_reference(caosdb_entity_datatype *datatype, bool *out);
int caosdb_entity_datatype_is_list_of_atomic(caosdb_entity_datatype *datatype, bool *out);
int caosdb_entity_datatype_is_list_of_reference(caosdb_entity_datatype *datatype, bool *out);
int caosdb_entity_datatype_get_datatype_name(caosdb_entity_datatype *datatype, char **out);
int caosdb_entity_value_is_null(caosdb_entity_value *value, bool *out);
int caosdb_entity_value_is_string(caosdb_entity_value *value, bool *out);
int caosdb_entity_value_is_double(caosdb_entity_value *value, bool *out);
int caosdb_entity_value_is_integer(caosdb_entity_value *value, bool *out);
int caosdb_entity_value_is_bool(caosdb_entity_value *value, bool *out);
int caosdb_entity_value_is_vector(caosdb_entity_value *value, bool *out);
int caosdb_entity_value_get_as_string(caosdb_entity_value *value, char **out);
int caosdb_entity_value_get_as_double(caosdb_entity_value *value, double *out);
int caosdb_entity_value_get_as_integer(caosdb_entity_value *value, int64_t *out);
int caosdb_entity_value_get_as_bool(caosdb_entity_value *value, bool *out);
int caosdb_entity_value_get_as_vector_size(caosdb_entity_value *value, int *out);
int caosdb_entity_value_get_as_vector_at(caosdb_entity_value *value, caosdb_entity_value *out,
const int index);
// CONSTRUCTORS AND DESTRUCTORS
int caosdb_entity_create_entity(caosdb_entity_entity *out);
int caosdb_entity_delete_entity(caosdb_entity_entity *out);
......@@ -447,31 +440,38 @@ int caosdb_entity_delete_property(caosdb_entity_property *out);
int caosdb_entity_create_parent(caosdb_entity_parent *out);
int caosdb_entity_delete_parent(caosdb_entity_parent *out);
// DATATYPE CONSTRUCTORS for atomic and reference datatypes and lists thereof
int caosdb_entity_create_atomic_datatype(caosdb_entity_datatype *out, const char *name);
int caosdb_entity_create_reference_datatype(caosdb_entity_datatype *out, const char *name);
int caosdb_entity_create_atomic_list_datatype(caosdb_entity_datatype *out, const char *name);
int caosdb_entity_create_reference_list_datatype(caosdb_entity_datatype *out, const char *name);
int caosdb_entity_delete_datatype(caosdb_entity_datatype *out);
// VALUE CONSTRUCTORS (resolve overloaded constructors)
int caosdb_entity_create_int_value(caosdb_entity_value *out, const int64_t value);
int caosdb_entity_create_string_value(caosdb_entity_value *out, const char *value);
int caosdb_entity_create_double_value(caosdb_entity_value *out, const double value);
int caosdb_entity_create_bool_value(caosdb_entity_value *out, const bool value);
int caosdb_entity_create_int_vector_value(caosdb_entity_value *out, const int64_t *value,
const int length);
int caosdb_entity_create_string_vector_value(caosdb_entity_value *out, const char **value,
const int length);