templates

package
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2020 License: GPL-3.0 Imports: 4 Imported by: 0

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL