diff --git a/internal/generator/binding/field.go b/internal/generator/binding/field.go index 0fb17df..a28c5e5 100644 --- a/internal/generator/binding/field.go +++ b/internal/generator/binding/field.go @@ -35,6 +35,7 @@ type Field struct { Name string Optional string IsSkipped bool + IsFlex bool } func CreateField(prop *model.Property) *Field { @@ -110,6 +111,15 @@ func (field *Field) ProcessAnnotations(a map[string]*Annotation) error { field.ModelProperty.AddFlag(model.PropertyFlagIdCompanion) } + if a["flex"] != nil { + if field.ModelProperty.Type != model.PropertyTypeByteVector { + return errors.New("flex must be used with type [byte]") + } + // Overwrite recognized type. + field.ModelProperty.Type = model.PropertyTypeFlex + field.IsFlex = true + } + if a["unique"] != nil { field.ModelProperty.AddFlag(model.PropertyFlagUnique) diff --git a/internal/generator/c/cgenerator.go b/internal/generator/c/cgenerator.go index 5eaa1a7..4ba0d69 100644 --- a/internal/generator/c/cgenerator.go +++ b/internal/generator/c/cgenerator.go @@ -124,13 +124,33 @@ func (gen *CGenerator) generateBindingFile(bindingFile, headerFile string, m *mo var fileIdentifier = strings.ToLower(filepath.Base(bindingFile)) fileIdentifier = replaceSpecialChars.Replace(fileIdentifier) + // Remove flex properties only for binding code generation: + // create a (shallow) copy of the ModelInfo struct, + // create copies of each Entity and replace the list + // of properties with a filtered one. + storedModelCopy := *m + storedModelCopy.Entities = nil + for _, e := range m.Entities { + entityCopy := *e + storedModelCopy.Entities = append(storedModelCopy.Entities, &entityCopy) + } + for _, e := range storedModelCopy.Entities { + var filteredProperties []*model.Property + for _, p := range e.Properties { + if p.Meta == nil || !p.Meta.(*fbsField).IsFlex { + filteredProperties = append(filteredProperties, p) + } + } + e.Properties = filteredProperties + } + var tplArguments = struct { Model *model.ModelInfo GeneratorVersion int FileIdentifier string HeaderFile string Optional string - }{m, generator.VersionId, fileIdentifier, filepath.Base(headerFile), gen.Optional} + }{&storedModelCopy, generator.VersionId, fileIdentifier, filepath.Base(headerFile), gen.Optional} var tpl *template.Template diff --git a/internal/generator/c/schema-reader.go b/internal/generator/c/schema-reader.go index b67cc42..edde651 100644 --- a/internal/generator/c/schema-reader.go +++ b/internal/generator/c/schema-reader.go @@ -41,6 +41,7 @@ var supportedEntityAnnotations = map[string]bool{ var supportedPropertyAnnotations = map[string]bool{ "date": true, "date-nano": true, + "flex": true, "id": true, "id-companion": true, "index": true, diff --git a/internal/generator/model/constants.go b/internal/generator/model/constants.go index d4fe79a..e3d34ac 100644 --- a/internal/generator/model/constants.go +++ b/internal/generator/model/constants.go @@ -77,18 +77,23 @@ var PropertyFlagNames = map[PropertyFlags]string{ type PropertyType int8 const ( - PropertyTypeBool PropertyType = 1 - PropertyTypeByte PropertyType = 2 - PropertyTypeShort PropertyType = 3 - PropertyTypeChar PropertyType = 4 - PropertyTypeInt PropertyType = 5 - PropertyTypeLong PropertyType = 6 - PropertyTypeFloat PropertyType = 7 - PropertyTypeDouble PropertyType = 8 - PropertyTypeString PropertyType = 9 - PropertyTypeDate PropertyType = 10 - PropertyTypeRelation PropertyType = 11 - PropertyTypeDateNano PropertyType = 12 + PropertyTypeBool PropertyType = 1 + PropertyTypeByte PropertyType = 2 + PropertyTypeShort PropertyType = 3 + PropertyTypeChar PropertyType = 4 + PropertyTypeInt PropertyType = 5 + PropertyTypeLong PropertyType = 6 + PropertyTypeFloat PropertyType = 7 + PropertyTypeDouble PropertyType = 8 + PropertyTypeString PropertyType = 9 + // Date/time stored as a 64 bit long representing milliseconds since 1970-01-01 (unix epoch). + PropertyTypeDate PropertyType = 10 + PropertyTypeRelation PropertyType = 11 + // High precision date/time stored as a 64 bit long representing nanoseconds since 1970-01-01 (unix epoch). + PropertyTypeDateNano PropertyType = 12 + // "Flexible" type, which may contain scalars (integers, floating points), strings or containers (lists and maps). + // Note: a flex map must use string keys. + PropertyTypeFlex PropertyType = 13 PropertyTypeByteVector PropertyType = 23 PropertyTypeStringVector PropertyType = 30 ) @@ -107,6 +112,7 @@ var PropertyTypeNames = map[PropertyType]string{ PropertyTypeDate: "Date", PropertyTypeRelation: "Relation", PropertyTypeDateNano: "DateNano", + PropertyTypeFlex: "Flex", PropertyTypeByteVector: "ByteVector", PropertyTypeStringVector: "StringVector", } diff --git a/test/comparison/testdata/fbs/typeful/c/objectbox-model.h.expected b/test/comparison/testdata/fbs/typeful/c/objectbox-model.h.expected index f379d04..9b337ab 100644 --- a/test/comparison/testdata/fbs/typeful/c/objectbox-model.h.expected +++ b/test/comparison/testdata/fbs/typeful/c/objectbox-model.h.expected @@ -85,27 +85,28 @@ static inline OBX_model* create_obx_model() { obx_model_property(model, "uid", OBXPropertyType_Int, 9, 6972732843819909978); obx_model_property_flags(model, (OBXPropertyFlags) (OBXPropertyFlags_INDEXED | OBXPropertyFlags_UNIQUE)); obx_model_property_index_id(model, 8, 5558237345453186302); - obx_model_relation(model, 1, 7845762441295307478, 1, 8717895732742165505); - obx_model_relation(model, 2, 771642788862502430, 1, 8717895732742165505); - obx_model_entity_last_property_id(model, 9, 6972732843819909978); + obx_model_property(model, "flexValue", OBXPropertyType_Flex, 10, 7845762441295307478); + obx_model_relation(model, 1, 771642788862502430, 1, 8717895732742165505); + obx_model_relation(model, 2, 8514850266767180993, 1, 8717895732742165505); + obx_model_entity_last_property_id(model, 10, 7845762441295307478); obx_model_entity(model, "TSDate", 3, 6050128673802995827); - obx_model_property(model, "id", OBXPropertyType_Long, 1, 8514850266767180993); + obx_model_property(model, "id", OBXPropertyType_Long, 1, 8683452355129068124); obx_model_property_flags(model, OBXPropertyFlags_ID); - obx_model_property(model, "timestamp", OBXPropertyType_Date, 2, 8683452355129068124); + obx_model_property(model, "timestamp", OBXPropertyType_Date, 2, 4345851588384648695); obx_model_property_flags(model, OBXPropertyFlags_ID_COMPANION); - obx_model_entity_last_property_id(model, 2, 8683452355129068124); + obx_model_entity_last_property_id(model, 2, 4345851588384648695); obx_model_entity(model, "TSDateNano", 4, 501233450539197794); - obx_model_property(model, "id", OBXPropertyType_Long, 1, 4345851588384648695); + obx_model_property(model, "id", OBXPropertyType_Long, 1, 7699391924090763411); obx_model_property_flags(model, OBXPropertyFlags_ID); - obx_model_property(model, "timestamp", OBXPropertyType_DateNano, 2, 7699391924090763411); + obx_model_property(model, "timestamp", OBXPropertyType_DateNano, 2, 388440063886460141); obx_model_property_flags(model, OBXPropertyFlags_ID_COMPANION); - obx_model_entity_last_property_id(model, 2, 7699391924090763411); + obx_model_entity_last_property_id(model, 2, 388440063886460141); obx_model_last_entity_id(model, 4, 501233450539197794); obx_model_last_index_id(model, 8, 5558237345453186302); - obx_model_last_relation_id(model, 2, 771642788862502430); + obx_model_last_relation_id(model, 2, 8514850266767180993); return model; // NOTE: the returned model will contain error information if an error occurred. } diff --git a/test/comparison/testdata/fbs/typeful/cpp/objectbox-model.h.expected b/test/comparison/testdata/fbs/typeful/cpp/objectbox-model.h.expected index f379d04..9b337ab 100644 --- a/test/comparison/testdata/fbs/typeful/cpp/objectbox-model.h.expected +++ b/test/comparison/testdata/fbs/typeful/cpp/objectbox-model.h.expected @@ -85,27 +85,28 @@ static inline OBX_model* create_obx_model() { obx_model_property(model, "uid", OBXPropertyType_Int, 9, 6972732843819909978); obx_model_property_flags(model, (OBXPropertyFlags) (OBXPropertyFlags_INDEXED | OBXPropertyFlags_UNIQUE)); obx_model_property_index_id(model, 8, 5558237345453186302); - obx_model_relation(model, 1, 7845762441295307478, 1, 8717895732742165505); - obx_model_relation(model, 2, 771642788862502430, 1, 8717895732742165505); - obx_model_entity_last_property_id(model, 9, 6972732843819909978); + obx_model_property(model, "flexValue", OBXPropertyType_Flex, 10, 7845762441295307478); + obx_model_relation(model, 1, 771642788862502430, 1, 8717895732742165505); + obx_model_relation(model, 2, 8514850266767180993, 1, 8717895732742165505); + obx_model_entity_last_property_id(model, 10, 7845762441295307478); obx_model_entity(model, "TSDate", 3, 6050128673802995827); - obx_model_property(model, "id", OBXPropertyType_Long, 1, 8514850266767180993); + obx_model_property(model, "id", OBXPropertyType_Long, 1, 8683452355129068124); obx_model_property_flags(model, OBXPropertyFlags_ID); - obx_model_property(model, "timestamp", OBXPropertyType_Date, 2, 8683452355129068124); + obx_model_property(model, "timestamp", OBXPropertyType_Date, 2, 4345851588384648695); obx_model_property_flags(model, OBXPropertyFlags_ID_COMPANION); - obx_model_entity_last_property_id(model, 2, 8683452355129068124); + obx_model_entity_last_property_id(model, 2, 4345851588384648695); obx_model_entity(model, "TSDateNano", 4, 501233450539197794); - obx_model_property(model, "id", OBXPropertyType_Long, 1, 4345851588384648695); + obx_model_property(model, "id", OBXPropertyType_Long, 1, 7699391924090763411); obx_model_property_flags(model, OBXPropertyFlags_ID); - obx_model_property(model, "timestamp", OBXPropertyType_DateNano, 2, 7699391924090763411); + obx_model_property(model, "timestamp", OBXPropertyType_DateNano, 2, 388440063886460141); obx_model_property_flags(model, OBXPropertyFlags_ID_COMPANION); - obx_model_entity_last_property_id(model, 2, 7699391924090763411); + obx_model_entity_last_property_id(model, 2, 388440063886460141); obx_model_last_entity_id(model, 4, 501233450539197794); obx_model_last_index_id(model, 8, 5558237345453186302); - obx_model_last_relation_id(model, 2, 771642788862502430); + obx_model_last_relation_id(model, 2, 8514850266767180993); return model; // NOTE: the returned model will contain error information if an error occurred. } diff --git a/test/comparison/testdata/fbs/typeful/objectbox-model.json.expected b/test/comparison/testdata/fbs/typeful/objectbox-model.json.expected index dd8a206..4ca503f 100644 --- a/test/comparison/testdata/fbs/typeful/objectbox-model.json.expected +++ b/test/comparison/testdata/fbs/typeful/objectbox-model.json.expected @@ -138,7 +138,7 @@ }, { "id": "2:2259404117704393152", - "lastPropertyId": "9:6972732843819909978", + "lastPropertyId": "10:7845762441295307478", "name": "AnnotatedEntity", "flags": 2, "properties": [ @@ -202,16 +202,21 @@ "indexId": "8:5558237345453186302", "type": 5, "flags": 40 + }, + { + "id": "10:7845762441295307478", + "name": "flexValue", + "type": 13 } ], "relations": [ { - "id": "1:7845762441295307478", + "id": "1:771642788862502430", "name": "typefuls", "targetId": "1:8717895732742165505" }, { - "id": "2:771642788862502430", + "id": "2:8514850266767180993", "name": "m2m", "targetId": "1:8717895732742165505" } @@ -219,17 +224,17 @@ }, { "id": "3:6050128673802995827", - "lastPropertyId": "2:8683452355129068124", + "lastPropertyId": "2:4345851588384648695", "name": "TSDate", "properties": [ { - "id": "1:8514850266767180993", + "id": "1:8683452355129068124", "name": "id", "type": 6, "flags": 1 }, { - "id": "2:8683452355129068124", + "id": "2:4345851588384648695", "name": "timestamp", "type": 10, "flags": 16384 @@ -238,17 +243,17 @@ }, { "id": "4:501233450539197794", - "lastPropertyId": "2:7699391924090763411", + "lastPropertyId": "2:388440063886460141", "name": "TSDateNano", "properties": [ { - "id": "1:4345851588384648695", + "id": "1:7699391924090763411", "name": "id", "type": 6, "flags": 1 }, { - "id": "2:7699391924090763411", + "id": "2:388440063886460141", "name": "timestamp", "type": 12, "flags": 16384 @@ -258,7 +263,7 @@ ], "lastEntityId": "4:501233450539197794", "lastIndexId": "8:5558237345453186302", - "lastRelationId": "2:771642788862502430", + "lastRelationId": "2:8514850266767180993", "modelVersion": 5, "modelVersionParserMinimum": 5, "retiredEntityUids": [], diff --git a/test/comparison/testdata/fbs/typeful/schema.fbs b/test/comparison/testdata/fbs/typeful/schema.fbs index 35f529c..7fabfa1 100644 --- a/test/comparison/testdata/fbs/typeful/schema.fbs +++ b/test/comparison/testdata/fbs/typeful/schema.fbs @@ -68,6 +68,10 @@ table Annotated { /// unique on string without index type implies HASH index /// objectbox:unique uid:int; + + /// mark byte vector as flexible type + /// objectbox:flex + flexValue:[byte]; } /// objectbox: transient diff --git a/third_party/objectbox-c/get-objectbox-c.sh b/third_party/objectbox-c/get-objectbox-c.sh index efe8bfd..2c5ec27 100755 --- a/third_party/objectbox-c/get-objectbox-c.sh +++ b/third_party/objectbox-c/get-objectbox-c.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -cVersion=0.14.0 +cVersion=0.15.0 scriptDir=$(dirname "${BASH_SOURCE[0]}")