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));
{{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}} {{$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 (!(p = flatcc_builder_table_add(B, {{$property.FbSlot}}, {{$property.Meta.FbTypeSize}}, {{$property.Meta.FbTypeSize}}))) return false;
{{$property.Meta.FlatccFnPrefix}}_write_to_pe(p, 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(out_object);
const uint8_t* table = (const uint8_t*) data + __flatbuffers_uoffset_read_from_pe(data);
assert(table);
flatbuffers_voffset_t *vt = (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;
{{range $property := $entity.Properties}}{{$propType := PropTypeName $property.Type -}}
{{if $property.Meta.FbIsVector}}
if ((offset = (vs < sizeof(vt[0]) * ({{$property.FbSlot}} + 3)) ? {{$property.Meta.FbDefaultValue}} : __flatbuffers_voffset_read_from_pe(vt + {{$property.FbSlot}} + 2))) {
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}}out_object->{{$property.Meta.CppName}} = (vs < sizeof(vt[0]) * ({{$property.FbSlot}} + 3)) ? {{$property.Meta.FbDefaultValue}} : {{$property.Meta.FlatccFnPrefix}}_read_from_pe(table + __flatbuffers_voffset_read_from_pe(vt + {{$property.FbSlot}} + 2));
{{- 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}}
}
{{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;
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;
}
`))
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.
#include "{{.HeaderFile}}"
{{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}}_::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}} = fbb.{{$factory}}(object.{{$property.Meta.CppName}});
{{- end}}{{end}}
flatbuffers::uoffset_t fbStart = fbb.StartTable();
{{range $property := $entity.Properties}}
{{- if $property.Meta.FbOffsetFactory}}fbb.AddOffset({{$property.FbvTableOffset}}, offset{{$property.Meta.CppName}});
{{- else if eq "bool" $property.Meta.CppType}}fbb.TrackField({{$property.FbvTableOffset}}, fbb.PushElement<uint8_t>(object.{{$property.Meta.CppName}} ? 1 : 0));
{{- else}}fbb.TrackField({{$property.FbvTableOffset}}, fbb.PushElement<{{$property.Meta.CppType}}>(object.{{$property.Meta.CppName}}));
{{- 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}}_::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}}_::newFromFlatBuffer(const void* data, size_t size) {
auto object = std::unique_ptr<{{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}>(new {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}());
fromFlatBuffer(data, size, *object);
return object;
}
void {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}_::fromFlatBuffer(const void* data, size_t size, {{$entity.Meta.CppNamespacePrefix}}{{$entity.Meta.CppName}}& outObject) {
const auto* table = flatbuffers::GetRoot<flatbuffers::Table>(data);
assert(table);
{{range $property := $entity.Properties}}
{{- if eq "std::vector<std::string>" $property.Meta.CppType}}{
auto* ptr = table->GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>*>({{$property.FbvTableOffset}});
if (ptr) {
outObject.{{$property.Meta.CppName}}.reserve(ptr->size());
for (size_t i = 0; i < ptr->size(); i++) {
auto* itemPtr = ptr->Get(i);
if (itemPtr) outObject.{{$property.Meta.CppName}}.emplace_back(itemPtr->c_str());
}
}
}{{else if eq "std::string" $property.Meta.CppType}}{
auto* ptr = table->GetPointer<const flatbuffers::String*>({{$property.FbvTableOffset}});
if (ptr) outObject.{{$property.Meta.CppName}}.assign(ptr->c_str());
}{{else if $property.Meta.FbIsVector}}{
auto* ptr = table->GetPointer<const {{$property.Meta.FbOffsetType}}*>({{$property.FbvTableOffset}});
if (ptr) outObject.{{$property.Meta.CppName}}.assign(ptr->begin(), ptr->end());
}{{- else if eq "bool" $property.Meta.CppType}}outObject.{{$property.Meta.CppName}} = table->GetField<uint8_t>({{$property.FbvTableOffset}}, 0) != 0;
{{- else}}outObject.{{$property.Meta.CppName}} = table->GetField<{{$property.Meta.CppType}}>({{$property.FbvTableOffset}}, {{$property.Meta.FbDefaultValue}});
{{- 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>
#include "flatbuffers/flatbuffers.h"
#include "objectbox-cpp.h"
#include "objectbox.h"
{{range $entity := .Model.EntitiesWithMeta}}
{{$entity.Meta.PreDeclareCppRelTargets -}}
{{with $entity.Meta.CppNamespaceStart}}
{{.}}{{end}}
struct {{$entity.Meta.CppName}}_;
{{PrintComments 0 $entity.Comments}}struct {{$entity.Meta.CppName}} {
using _OBX_MetaInfo = {{$entity.Meta.CppName}}_;
{{range $property := $entity.Properties}}
{{PrintComments 1 $property.Comments}}{{$property.Meta.CppType}} {{$property.Meta.CppName}};
{{- end}}
};
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}}
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);
};
{{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}});
{{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.