Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var CBindingTemplate = template.Must(template.New("binding-c").Funcs(funcMap).Parse(
`// Code generated by ObjectBox; DO NOT EDIT.
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "flatcc/flatcc.h"
#include "flatcc/flatcc_builder.h"
#include "objectbox.h"
/// Internal function used in other generated functions to put (write) explicitly typed objects.
static obx_id {{.FileIdentifier}}_put_object(OBX_box* box, void* object,
bool (*to_flatbuffer)(flatcc_builder_t*, const void*, void**, size_t*), OBXPutMode mode);
/// Internal function used in other generated functions to get (read) explicitly typed objects.
static void* {{.FileIdentifier}}_get_object(OBX_box* box, obx_id id, void* (*from_flatbuffer)(const void*, size_t));
/// Internal function used in other generated functions to get a vTable offset for a given field.
static flatbuffers_voffset_t {{.FileIdentifier}}_fb_field_offset(flatbuffers_voffset_t vs, const flatbuffers_voffset_t* vt, size_t field);
{{range $entity := .Model.EntitiesWithMeta}}
{{PrintComments 0 $entity.Comments}}typedef struct {{$entity.Meta.CName}} {
{{range $property := $entity.Properties}}{{$propType := PropTypeName $property.Type -}}
{{PrintComments 1 $property.Comments}}{{if $property.Meta.FbIsVector}}{{$property.Meta.CElementType}}* {{$property.Meta.CppName}};
{{- if or (eq $propType "StringVector") (eq $propType "ByteVector")}}
size_t {{$property.Meta.CppName}}_len;{{end}}
{{else}}{{$property.Meta.CppType}}{{if $property.Meta.Optional}}*{{end}} {{$property.Meta.CppName}};
{{end}}{{end}}
} {{$entity.Meta.CName}};
enum {{$entity.Meta.CName}}_ {
{{$entity.Meta.CName}}_ENTITY_ID = {{$entity.Id.GetId}},
{{- range $property := $entity.Properties}}
{{$entity.Meta.CName}}_PROP_ID_{{$property.Meta.CppName}} = {{$property.Id.GetId}},
{{- end}}
{{- range $relation := $entity.Relations}}
{{$entity.Meta.CName}}_REL_ID_{{$relation.Meta.CppName}} = {{$relation.Id.GetId}},
{{- end}}
};
/// Write given object to the FlatBufferBuilder
static bool {{$entity.Meta.CName}}_to_flatbuffer(flatcc_builder_t* B, const {{$entity.Meta.CName}}* object, void** out_buffer, size_t* out_size);
/// Read an object from a valid FlatBuffer.
/// If the read object contains vectors or strings, those are allocated on heap and must be freed after use by calling {{$entity.Meta.CName}}_free_pointers().
/// Thus, when calling this function multiple times on the same object, ensure to call {{$entity.Meta.CName}}_free_pointers() before subsequent calls to avoid leaks.
/// @returns true if the object was deserialized successfully or false on (allocation) error in which case any memory
/// allocated by this function will also be freed before returning, allowing you to retry.
static bool {{$entity.Meta.CName}}_from_flatbuffer(const void* data, size_t size, {{$entity.Meta.CName}}* out_object);
/// Read an object from a valid FlatBuffer, allocating the object on heap.
/// The object must be freed after use by calling {{$entity.Meta.CName}}_free();
static {{$entity.Meta.CName}}* {{$entity.Meta.CName}}_new_from_flatbuffer(const void* data, size_t size);
/// Free memory allocated for vector and string properties, setting the freed pointers to NULL.
static void {{$entity.Meta.CName}}_free_pointers({{$entity.Meta.CName}}* object);
/// Free {{$entity.Meta.CName}}* object pointer and all its property pointers (vectors and strings).
/// Equivalent to calling {{$entity.Meta.CName}}_free_pointers() followed by free();
static void {{$entity.Meta.CName}}_free({{$entity.Meta.CName}}* object);
{{end}}
{{- range $entity := .Model.EntitiesWithMeta}}
static bool {{$entity.Meta.CName}}_to_flatbuffer(flatcc_builder_t* B, const {{$entity.Meta.CName}}* object, void** out_buffer, size_t* out_size) {
assert(B);
assert(object);
assert(out_buffer);
assert(out_size);
flatcc_builder_reset(B);
flatcc_builder_start_buffer(B, 0, 0, 0);
{{range $property := $entity.Properties}}{{$propType := PropTypeName $property.Type}}
{{- if eq $propType "String"}}
flatcc_builder_ref_t offset_{{$property.Meta.CppName}} = !object->{{$property.Meta.CppName}} ? 0 : flatcc_builder_create_string_str(B, object->{{$property.Meta.CppName}});
{{- else if eq $propType "ByteVector"}}
flatcc_builder_ref_t offset_{{$property.Meta.CppName}} = !object->{{$property.Meta.CppName}} ? 0 : flatcc_builder_create_vector(B, object->{{$property.Meta.CppName}}, object->{{$property.Meta.CppName}}_len, sizeof({{$property.Meta.CElementType}}), sizeof({{$property.Meta.CElementType}}), FLATBUFFERS_COUNT_MAX(sizeof({{$property.Meta.CElementType}})));
{{- else if eq $propType "StringVector"}}
flatcc_builder_ref_t offset_{{$property.Meta.CppName}} = 0;
if (object->{{$property.Meta.CppName}}) {
flatcc_builder_start_offset_vector(B);
for (size_t i = 0; i < object->{{$property.Meta.CppName}}_len; i++) {
flatcc_builder_ref_t ref = !object->{{$property.Meta.CppName}}[i] ? 0 : flatcc_builder_create_string_str(B, object->{{$property.Meta.CppName}}[i]);
if (ref) flatcc_builder_offset_vector_push(B, ref);
}
offset_{{$property.Meta.CppName}} = flatcc_builder_end_offset_vector(B);
}
{{- end}}{{end}}
if (flatcc_builder_start_table(B, {{len $entity.Properties}}) != 0) return false;
void* p;
flatcc_builder_ref_t* _p;
{{range $property := $entity.Properties}}
{{- if $property.Meta.FbIsVector}}
if (offset_{{$property.Meta.CppName}}) {
if (!(_p = flatcc_builder_table_add_offset(B, {{$property.FbSlot}}))) return false;
*_p = offset_{{$property.Meta.CppName}};
}
{{- else}}
{{if $property.Meta.Optional}}if (object->{{$property.Meta.CppName}}) {{end}}{
if (!(p = flatcc_builder_table_add(B, {{$property.FbSlot}}, {{$property.Meta.FbTypeSize}}, {{$property.Meta.FbTypeSize}}))) return false;
{{$property.Meta.FlatccFnPrefix}}_write_to_pe(p, {{if $property.Meta.Optional}}*{{end}}object->{{$property.Meta.CppName}});
}{{- end}}
{{end}}
flatcc_builder_ref_t ref;
if (!(ref = flatcc_builder_end_table(B))) return false;
if (!flatcc_builder_end_buffer(B, ref)) return false;
return (*out_buffer = flatcc_builder_finalize_aligned_buffer(B, out_size)) != NULL;
}
static bool {{$entity.Meta.CName}}_from_flatbuffer(const void* data, size_t size, {{$entity.Meta.CName}}* out_object) {
assert(data);
assert(size > 0);
assert(out_object);
const uint8_t* table = (const uint8_t*) data + __flatbuffers_uoffset_read_from_pe(data);
assert(table);
const flatbuffers_voffset_t* vt = (const flatbuffers_voffset_t*) (table - __flatbuffers_soffset_read_from_pe(table));
flatbuffers_voffset_t vs = __flatbuffers_voffset_read_from_pe(vt);
// variables reused when reading strings and vectors
flatbuffers_voffset_t offset;
const flatbuffers_uoffset_t* val;
size_t len;
// reset so that dangling pointers are freed properly on malloc() failures
#ifdef __cplusplus
*out_object = {};
#else
*out_object = ({{$entity.Meta.CName}}){0};{{/* Only works in C99, fails to compile on MSVC in a C++ project*/}}
#endif
{{range $property := $entity.Properties}}{{$propType := PropTypeName $property.Type -}}
if ((offset = {{$.FileIdentifier}}_fb_field_offset(vs, vt, {{$property.FbSlot}}))) {
{{- if $property.Meta.FbIsVector}}
val = (const flatbuffers_uoffset_t*)(table + offset + sizeof(flatbuffers_uoffset_t) + __flatbuffers_uoffset_read_from_pe(table + offset));
len = (size_t) __flatbuffers_uoffset_read_from_pe(val - 1);
out_object->{{$property.Meta.CppName}} = ({{$property.Meta.CElementType}}*) malloc({{if eq $propType "String"}}(len+1){{else}}len{{end}} * sizeof({{$property.Meta.CElementType}}));
if (out_object->{{$property.Meta.CppName}} == NULL) {
{{$entity.Meta.CName}}_free_pointers(out_object);
return false;
}
{{- if not (eq $propType "String")}}
out_object->{{$property.Meta.CppName}}_len = len;
{{- end -}}
{{/*Note: direct copy for string and byte vectors*/}}
{{if eq $propType "String"}}memcpy((void*)out_object->{{$property.Meta.CppName}}, (const void*)val, len+1);
{{else if eq $propType "ByteVector"}}memcpy((void*)out_object->{{$property.Meta.CppName}}, (const void*)val, len);
{{else}}{{/* StringVector - FB vector contains offsets to strings, each must be read separately*/ -}}
for (size_t i = 0; i < len; i++, val++) {
const uint8_t* str = (const uint8_t*) val + (size_t)__flatbuffers_uoffset_read_from_pe(val) + sizeof(val[0]);
out_object->{{$property.Meta.CppName}}[i] = (char*) malloc((strlen((const char*)str) + 1) * sizeof(char));
if (out_object->{{$property.Meta.CppName}}[i] == NULL) {
out_object->{{$property.Meta.CppName}}_len = i; // only free() indexes before the current "i"
{{$entity.Meta.CName}}_free_pointers(out_object);
return false;
}
strcpy((char*)out_object->{{$property.Meta.CppName}}[i], (const char*)str);
}{{end}}
} else {
out_object->{{$property.Meta.CppName}} = NULL;
{{- if not (eq $propType "String")}}
out_object->{{$property.Meta.CppName}}_len = 0;
{{- end}}
{{- else}}
{{if $property.Meta.Optional -}}
out_object->{{$property.Meta.CppName}} = ({{$property.Meta.CppType}}*) malloc(sizeof({{$property.Meta.CppType}}));
if (out_object->{{$property.Meta.CppName}} == NULL) {
{{$entity.Meta.CName}}_free_pointers(out_object);
return false;
}
*{{end}}out_object->{{$property.Meta.CppName}} = {{$property.Meta.FlatccFnPrefix}}_read_from_pe(table + offset);
{{- end}}
}
{{end}}return true;
}
static {{$entity.Meta.CName}}* {{$entity.Meta.CName}}_new_from_flatbuffer(const void* data, size_t size) {
{{$entity.Meta.CName}}* object = ({{$entity.Meta.CName}}*) malloc(sizeof({{$entity.Meta.CName}}));
if (object) {
if (!{{$entity.Meta.CName}}_from_flatbuffer(data, size, object)) {
free(object);
object = NULL;
}
}
return object;
}
static void {{$entity.Meta.CName}}_free_pointers({{$entity.Meta.CName}}* object) {
if (object == NULL) return;
{{range $property := $entity.Properties}}{{$propType := PropTypeName $property.Type}}{{if $property.Meta.FbIsVector -}}
if (object->{{$property.Meta.CppName}}) {
{{- if eq $propType "StringVector"}}
for (size_t i = 0; i < object->{{$property.Meta.CppName}}_len; i++) {
if (object->{{$property.Meta.CppName}}[i]) free(object->{{$property.Meta.CppName}}[i]);
}{{end}}
free(object->{{$property.Meta.CppName}});
object->{{$property.Meta.CppName}} = NULL;
{{- if not (eq $propType "String")}}
object->{{$property.Meta.CppName}}_len = 0;
} else {
assert(object->{{$property.Meta.CppName}}_len == 0);
{{- end}}
}
{{else if $property.Meta.Optional -}}
if (object->{{$property.Meta.CppName}}) {
free(object->{{$property.Meta.CppName}});
object->{{$property.Meta.CppName}} = NULL;
}
{{end}}
{{- end}}
}
static void {{$entity.Meta.CName}}_free({{$entity.Meta.CName}}* object) {
{{$entity.Meta.CName}}_free_pointers(object);
free(object);
}
/// Insert or update the given object in the database.
/// @param object (in & out) will be updated with a newly inserted ID if the one specified previously was zero. If an ID
/// was already specified (non-zero), it will remain unchanged.
/// @return object ID from the object param (see object param docs) or a zero on error. If a zero was returned, you can
/// check obx_last_error_*() to get the error details. In an unlikely event that those functions return no error
/// code/message, the error occurred in FlatBuffers serialization, e.g. due to memory allocation issues.
static obx_id {{$entity.Meta.CName}}_put(OBX_box* box, {{$entity.Meta.CName}}* object) {
obx_id id = {{$.FileIdentifier}}_put_object(box, object,
(bool (*)(flatcc_builder_t*, const void*, void**, size_t*)) {{$entity.Meta.CName}}_to_flatbuffer,
OBXPutMode_PUT);
if (id != 0) {
object->{{$entity.IdProperty.Meta.CppName}} = id; // update the ID property on new objects for convenience
}
return id;
}
/// Read an object from the database, returning a pointer.
/// @return an object pointer or NULL if an object with the given ID doesn't exist or any other error occurred. You can
/// check obx_last_error_*() if NULL is returned to get the error details. In an unlikely event that those functions
/// return no error code/message, the error occurred in FlatBuffers serialization, e.g. due to memory allocation issues.
/// @note: The returned object must be freed after use by calling {{$entity.Meta.CName}}_free();
static {{$entity.Meta.CName}}* {{$entity.Meta.CName}}_get(OBX_box* box, obx_id id) {
return ({{$entity.Meta.CName}}*) {{$.FileIdentifier}}_get_object(box, id, (void* (*) (const void*, size_t)) {{$entity.Meta.CName}}_new_from_flatbuffer);
}
{{end}}
static obx_id {{.FileIdentifier}}_put_object(OBX_box* box, void* object,
bool (*to_flatbuffer)(flatcc_builder_t*, const void*, void**, size_t*), OBXPutMode mode) {
flatcc_builder_t builder;
flatcc_builder_init(&builder);
obx_id id = 0;
size_t size = 0;
void* buffer = NULL;
if (!to_flatbuffer(&builder, object, &buffer, &size)) {
obx_last_error_set(OBX_ERROR_STD_OTHER, 0, "FlatBuffer serialization failed");
} else {
id = obx_box_put_object4(box, buffer, size, mode); // 0 on error
}
flatcc_builder_clear(&builder);
if (buffer) flatcc_builder_aligned_free(buffer);
return id;
}
static void* {{.FileIdentifier}}_get_object(OBX_box* box, obx_id id, void* (*from_flatbuffer)(const void*, size_t)) {
// We need an explicit TX - read data lifecycle is bound to the open TX.
OBX_txn* tx = obx_txn_read(obx_box_store(box));
if (!tx) return NULL;
void* result = NULL;
const void* data;
size_t size;
if (obx_box_get(box, id, &data, &size) == OBX_SUCCESS) {
result = from_flatbuffer(data, size);
if (result == NULL) {
obx_last_error_set(OBX_ERROR_STD_OTHER, 0, "FlatBuffer deserialization failed");
}
}
obx_txn_close(tx);
return result;
}
static flatbuffers_voffset_t {{.FileIdentifier}}_fb_field_offset(flatbuffers_voffset_t vs, const flatbuffers_voffset_t* vt, size_t field) {
return (vs < sizeof(vt[0]) * (field + 3)) ? 0 : __flatbuffers_voffset_read_from_pe(vt + field + 2);
}
`))
CBindingTemplate is used to generated the binding code
View Source
var CppBindingTemplate = template.Must(template.New("binding-cpp").Funcs(funcMap).Parse(
`// Code generated by ObjectBox; DO NOT EDIT.
{{define "field-value"}}{{if .Optional}}*{{end}}object.{{.CppName}}{{end -}}
{{define "field-value-assign-pre"}}{{if IsOptionalPtr .Optional}}.reset(new {{.CppType}}({{else}} = {{end}}{{end -}}
{{define "field-value-assign-post"}}{{if IsOptionalPtr .Optional}})){{end}}{{end -}}
#include "{{.HeaderFile}}"
{{if .NaNAsNull}}
#include <cmath>
{{end -}}
{{range $entity := .Model.EntitiesWithMeta}}
{{- range $property := $entity.Properties}}
const
{{- if $property.RelationTarget}} obx::RelationProperty<{{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}, {{$property.Meta.CppNameRelationTarget}}>
{{- else}} obx::Property<{{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}, OBXPropertyType_{{PropTypeName $property.Type}}>
{{- end}} {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}_::{{$property.Meta.CppName}}({{$property.Id.GetId}});
{{- end}}
{{- range $relation := $entity.Relations}}
const obx::RelationStandalone<{{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}, {{$relation.Target.Meta.CppNamespacePrefix}}{{$relation.Target.Meta.CppName}}> {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}_::{{$relation.Meta.CppName}}({{$relation.Id.GetId}});
{{- end}}
void {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}::_OBX_MetaInfo::toFlatBuffer(flatbuffers::FlatBufferBuilder& fbb, const {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}& object) {
fbb.Clear();
{{- range $property := $entity.Properties}}{{$factory := $property.Meta.FbOffsetFactory}}{{if $factory}}
auto offset{{$property.Meta.CppName}} =
{{- if $property.Meta.Optional}} !object.{{$property.Meta.CppName}} ? 0 : {{end -}}
{{- if and $.EmptyStringAsNull (eq "std::string" $property.Meta.CppType) }} ({{template "field-value" $property.Meta}}).empty() ? 0 :
{{- end }} fbb.{{$factory}}({{template "field-value" $property.Meta}});
{{- end}}{{end}}
flatbuffers::uoffset_t fbStart = fbb.StartTable();
{{range $property := $entity.Properties}}
{{- if $property.Meta.Optional}}if (object.{{$property.Meta.CppName}}) {{end}}
{{- if $property.Meta.FbOffsetFactory}}fbb.AddOffset({{$property.FbvTableOffset}}, offset{{$property.Meta.CppName}});
{{- else -}}
{{- if and $.NaNAsNull $property.Meta.FbIsFloatingPoint -}} if (!std::isnan({{template "field-value" $property.Meta}})) {{end -}} fbb.AddElement({{$property.FbvTableOffset}}, {{template "field-value" $property.Meta}}{{if eq "bool" $property.Meta.CppType}} ? 1 : 0{{end}});
{{- end}}
{{end -}}
flatbuffers::Offset<flatbuffers::Table> offset;
offset.o = fbb.EndTable(fbStart);
fbb.Finish(offset);
}
{{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}} {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}::_OBX_MetaInfo::fromFlatBuffer(const void* data, size_t size) {
{{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}} object;
fromFlatBuffer(data, size, object);
return object;
}
std::unique_ptr<{{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}> {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}::_OBX_MetaInfo::newFromFlatBuffer(const void* data, size_t size) {
{{- if ge $.LangVersion 14 }}
auto object = std::make_unique<{{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}>();
{{- else}}
auto object = std::unique_ptr<{{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}>(new {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}());
{{- end}}
fromFlatBuffer(data, size, *object);
return object;
}
void {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}::_OBX_MetaInfo::fromFlatBuffer(const void* data, size_t, {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}& outObject) {
const auto* table = flatbuffers::GetRoot<flatbuffers::Table>(data);
assert(table);
{{- range $property := $entity.Properties}}
{{- if eq "std::string" $property.Meta.CppType}}
{
auto* ptr = table->GetPointer<const flatbuffers::String*>({{$property.FbvTableOffset}});
if (ptr) {
outObject.{{$property.Meta.CppName}}
{{- if $property.Meta.Optional}}
{{- if IsOptionalPtr $.Optional -}}
.reset(new std::string(ptr->c_str(), ptr->size()));
{{- else -}}
.emplace(ptr->c_str(), ptr->size());
{{- end}}
{{- else -}}
.assign(ptr->c_str(), ptr->size());
{{- end}}
} else {
outObject.{{$property.Meta.CppName}}
{{- if $property.Meta.Optional -}}
.reset();
{{- else -}}
.clear();
{{- end}}
}
}
{{- else if eq "std::vector<std::string>" $property.Meta.CppType}}
{
auto* ptr = table->GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>*>({{$property.FbvTableOffset}});
if (ptr) {
{{- if $property.Meta.Optional}}
outObject.{{$property.Meta.CppName}}{{if IsOptionalPtr $property.Meta.Optional}}.reset(new {{$property.Meta.CppType}}({{else}} = {{$property.Meta.CppType}}(){{end}}{{template "field-value-assign-post" $property.Meta}};
{{- end}}
outObject.{{$property.Meta.CppName}}{{$property.Meta.CppValOp}}reserve(ptr->size());
for (flatbuffers::uoffset_t i = 0; i < ptr->size(); i++) {
auto* itemPtr = ptr->Get(i);
if (itemPtr) outObject.{{$property.Meta.CppName}}{{$property.Meta.CppValOp}}emplace_back(itemPtr->c_str());
}
} else {
outObject.{{$property.Meta.CppName}}
{{- if $property.Meta.Optional -}}
.reset();
{{- else -}}
.clear();
{{- end}}
}
}
{{- else if $property.Meta.FbIsVector}}
{
auto* ptr = table->GetPointer<const {{$property.Meta.FbOffsetType}}*>({{$property.FbvTableOffset}});
if (ptr) outObject.{{$property.Meta.CppName}}
{{- if IsOptionalPtr $property.Meta.Optional}}{{template "field-value-assign-pre" $property.Meta}}ptr->begin(), ptr->end(){{template "field-value-assign-post" $property.Meta}}
{{- else if $property.Meta.Optional}} = {{$property.Meta.CppType}}(ptr->begin(), ptr->end())
{{- else}}.assign(ptr->begin(), ptr->end())
{{- end}};
else {
outObject.{{$property.Meta.CppName}}
{{- if $property.Meta.Optional -}}
.reset();
{{- else -}}
.clear();
{{- end}}
}
}
{{- else }}
{{ if $property.Meta.Optional -}}
if (table->CheckField({{$property.FbvTableOffset}})) {{end -}}
outObject.{{$property.Meta.CppName}}
{{- template "field-value-assign-pre" $property.Meta -}}
table->GetField<{{$property.Meta.CppFbType}}>({{- $property.FbvTableOffset}}, {{$property.Meta.FbDefaultValue}}){{if eq "bool" $property.Meta.CppType}} != 0{{end}}
{{- template "field-value-assign-post" $property.Meta}};
{{- if $property.Meta.Optional}} else outObject.{{$property.Meta.CppName}}.reset();{{- end}}
{{- end }}
{{- end}}
}
{{end}}
`))
CppBindingTemplate is used to generated the binding code
View Source
var CppBindingTemplateHeader = template.Must(template.New("binding-hpp").Funcs(funcMap).Parse(
`// Code generated by ObjectBox; DO NOT EDIT.
#pragma once
#include <cstdbool>
#include <cstdint>
{{- if eq "std::optional" .Optional}}
#include <optional>
{{- else if .Optional}}
#include <memory>
{{end}}
#include "flatbuffers/flatbuffers.h"
#include "objectbox.h"
#include "objectbox.hpp"
{{range $entity := .Model.EntitiesWithMeta}}
{{$entity.Meta.PreDeclareCppRelTargets -}}
{{with $entity.Meta.CppNamespaceStart}}
{{.}}{{end}}
struct {{$entity.Meta.CppName}}_;
{{PrintComments 0 $entity.Comments}}struct {{$entity.Meta.CppName}} {
{{- range $property := $entity.Properties}}
{{PrintComments 1 $property.Comments}}{{$property.Meta.CppTypeWithOptional}} {{$property.Meta.CppName}};
{{- end}}
struct _OBX_MetaInfo {
static constexpr obx_schema_id entityId() { return {{$entity.Id.GetId}}; }
static void setObjectId({{$entity.Meta.CppName}}& object, obx_id newId) { object.{{$entity.IdProperty.Meta.CppName}} = newId; }
/// Write given object to the FlatBufferBuilder
static void toFlatBuffer(flatbuffers::FlatBufferBuilder& fbb, const {{$entity.Meta.CppName}}& object);
/// Read an object from a valid FlatBuffer
static {{$entity.Meta.CppName}} fromFlatBuffer(const void* data, size_t size);
/// Read an object from a valid FlatBuffer
static std::unique_ptr<{{$entity.Meta.CppName}}> newFromFlatBuffer(const void* data, size_t size);
/// Read an object from a valid FlatBuffer
static void fromFlatBuffer(const void* data, size_t size, {{$entity.Meta.CppName}}& outObject);
};
};
struct {{$entity.Meta.CppName}}_ {
{{- range $property := $entity.Properties}}
static const
{{- if $property.RelationTarget}} obx::RelationProperty<{{$entity.Meta.CppName}}, {{$property.Meta.CppNameRelationTarget}}>
{{- else}} obx::Property<{{$entity.Meta.CppName}}, OBXPropertyType_{{PropTypeName $property.Type}}>
{{- end}} {{$property.Meta.CppName}};
{{- end}}
{{- range $relation := $entity.Relations}}
static const obx::RelationStandalone<{{$entity.Meta.CppName}}, {{$relation.Target.Meta.CppName}}> {{$relation.Meta.CppName}};
{{- end}}
};
{{with $entity.Meta.CppNamespaceEnd}}{{.}}{{end -}}
{{end}}
`))
CppBindingTemplateHeader is used to generated the binding code
View Source
var ModelTemplate = template.Must(template.New("model").Funcs(funcMap).Parse(
`// Code generated by ObjectBox; DO NOT EDIT.
#pragma once
#ifdef __cplusplus
#include <cstdbool>
#include <cstdint>
extern "C" {
#else
#include <stdbool.h>
#include <stdint.h>
#endif
#include "objectbox.h"
/// Initializes an ObjectBox model for all entities.
/// The returned pointer may be NULL if the allocation failed. If the returned model is not NULL, you should check if
/// any error occurred by calling obx_model_error_code() and/or obx_model_error_message(). If an error occurred, you're
/// responsible for freeing the resources by calling obx_model_free().
/// In case there was no error when setting the model up (i.e. obx_model_error_code() returned 0), you may configure
/// OBX_store_options with the model by calling obx_opt_model() and subsequently opening a store with obx_store_open().
/// As soon as you call obx_store_open(), the model pointer is consumed and MUST NOT be freed manually.
static inline OBX_model* create_obx_model() {
OBX_model* model = obx_model();
if (!model) return NULL;
{{range $entity := .Model.Entities}}
obx_model_entity(model, "{{$entity.Name}}", {{$entity.Id.GetId}}, {{$entity.Id.GetUid}});
{{with $entity.Flags}}obx_model_entity_flags(model, {{CoreEntityFlags .}});
{{end -}}
{{range $property := $entity.Properties -}}
obx_model_property(model, "{{$property.Name}}", OBXPropertyType_{{PropTypeName $property.Type}}, {{$property.Id.GetId}}, {{$property.Id.GetUid}});
{{with $property.Flags}}obx_model_property_flags(model, {{CorePropFlags .}});
{{end -}}
{{if $property.RelationTarget}}obx_model_property_relation(model, "{{$property.RelationTarget}}", {{$property.IndexId.GetId}}, {{$property.IndexId.GetUid}});
{{else if $property.IndexId}}obx_model_property_index_id(model, {{$property.IndexId.GetId}}, {{$property.IndexId.GetUid}});
{{end -}}
{{end -}}
{{range $relation := $entity.Relations -}}
obx_model_relation(model, {{$relation.Id.GetId}}, {{$relation.Id.GetUid}}, {{$relation.Target.Id.GetId}}, {{$relation.Target.Id.GetUid}});
{{end -}}
obx_model_entity_last_property_id(model, {{$entity.LastPropertyId.GetId}}, {{$entity.LastPropertyId.GetUid}});
{{end}}
obx_model_last_entity_id(model, {{.Model.LastEntityId.GetId}}, {{.Model.LastEntityId.GetUid}});
{{- if .Model.LastIndexId}}
obx_model_last_index_id(model, {{.Model.LastIndexId.GetId}}, {{.Model.LastIndexId.GetUid}});
{{- end}}
{{- if .Model.LastRelationId}}
obx_model_last_relation_id(model, {{.Model.LastRelationId.GetId}}, {{.Model.LastRelationId.GetUid}});
{{- end}}
return model; // NOTE: the returned model will contain error information if an error occurred.
}
#ifdef __cplusplus
}
#endif
`))
ModelTemplate is used to generate the model initialization code
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.