Skip to content

Commit 440b0ff

Browse files
committed
feat: support all objectbox numeric types
1 parent 14dc06c commit 440b0ff

File tree

6 files changed

+77
-32
lines changed

6 files changed

+77
-32
lines changed

objectbox/model/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@
2222
'Entity',
2323
'Id',
2424
'IdUid',
25-
'Property'
25+
'Property',
26+
'PropertyType'
2627
]

objectbox/model/entity.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ def fill_properties(self):
6464
"programming error - invalid type OB & FB type combination"
6565
self.offset_properties.append(prop)
6666

67+
# print('Property {}.{}: {} (ob:{} fb:{})'.format(self.name, prop._name, prop._py_type, prop._ob_type, prop._fb_type))
68+
6769
if not self.id_property:
6870
raise Exception("ID property is not defined")
6971
elif self.id_property._ob_type != OBXPropertyType_Long:

objectbox/model/properties.py

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,54 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from enum import IntEnum
1516

1617
from objectbox.c import *
1718
import flatbuffers.number_types
1819

1920

20-
# base property
21+
class PropertyType(IntEnum):
22+
bool = OBXPropertyType_Bool
23+
byte = OBXPropertyType_Byte
24+
short = OBXPropertyType_Short
25+
char = OBXPropertyType_Char
26+
int = OBXPropertyType_Int
27+
long = OBXPropertyType_Long
28+
float = OBXPropertyType_Float
29+
double = OBXPropertyType_Double
30+
string = OBXPropertyType_String
31+
# date = OBXPropertyType_Date
32+
# relation = OBXPropertyType_Relation
33+
byteVector = OBXPropertyType_ByteVector
34+
# stringVector = OBXPropertyType_StringVector
35+
36+
37+
fb_type_map = {
38+
PropertyType.bool: flatbuffers.number_types.BoolFlags,
39+
PropertyType.byte: flatbuffers.number_types.Int8Flags,
40+
PropertyType.short: flatbuffers.number_types.Int16Flags,
41+
PropertyType.char: flatbuffers.number_types.Int8Flags,
42+
PropertyType.int: flatbuffers.number_types.Int32Flags,
43+
PropertyType.long: flatbuffers.number_types.Int64Flags,
44+
PropertyType.float: flatbuffers.number_types.Float32Flags,
45+
PropertyType.double: flatbuffers.number_types.Float64Flags,
46+
PropertyType.string: flatbuffers.number_types.UOffsetTFlags,
47+
# PropertyType.date: flatbuffers.number_types.Int64Flags,
48+
# PropertyType.relation: flatbuffers.number_types.Int64Flags,
49+
PropertyType.byteVector: flatbuffers.number_types.UOffsetTFlags,
50+
# PropertyType.stringVector: flatbuffers.number_types.UOffsetTFlags,
51+
}
52+
53+
2154
class Property:
22-
def __init__(self, py_type: type, id: int, uid: int):
55+
def __init__(self, py_type: type, id: int, uid: int, type: PropertyType = None):
2356
self._id = id
2457
self._uid = uid
25-
self._name = "" # set in Entity.fillProperties()
58+
self._name = "" # set in Entity.fill_properties()
2659

27-
self._fb_type = None # flatbuffers.number_types
2860
self._py_type = py_type
29-
self._ob_type = OBXPropertyType(0)
30-
self.__set_basic_type()
61+
self._ob_type: OBXPropertyType = type if type != None else self.__determine_ob_type()
62+
self._fb_type = fb_type_map[self._ob_type]
3163

3264
self._is_id = isinstance(self, Id)
3365
self._flags = OBXPropertyFlags(0)
@@ -37,23 +69,18 @@ def __init__(self, py_type: type, id: int, uid: int):
3769
self._fb_slot = self._id - 1
3870
self._fb_v_offset = 4 + 2*self._fb_slot
3971

40-
def __set_basic_type(self) -> OBXPropertyType:
72+
def __determine_ob_type(self) -> OBXPropertyType:
4173
ts = self._py_type
4274
if ts == str:
43-
self._ob_type = OBXPropertyType_String
44-
self._fb_type = flatbuffers.number_types.UOffsetTFlags
75+
return OBXPropertyType_String
4576
elif ts == int:
46-
self._ob_type = OBXPropertyType_Long
47-
self._fb_type = flatbuffers.number_types.Int64Flags
77+
return OBXPropertyType_Long
4878
elif ts == bytes: # or ts == bytearray: might require further tests on read objects due to mutability
49-
self._ob_type = OBXPropertyType_ByteVector
50-
self._fb_type = flatbuffers.number_types.UOffsetTFlags
79+
return OBXPropertyType_ByteVector
5180
elif ts == float:
52-
self._ob_type = OBXPropertyType_Double
53-
self._fb_type = flatbuffers.number_types.Float64Flags
81+
return OBXPropertyType_Double
5482
elif ts == bool:
55-
self._ob_type = OBXPropertyType_Bool
56-
self._fb_type = flatbuffers.number_types.BoolFlags
83+
return OBXPropertyType_Bool
5784
else:
5885
raise Exception("unknown property type %s" % ts)
5986

tests/common.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,26 @@ def autocleanup():
2323
def load_empty_test_objectbox(name: str = "") -> objectbox.ObjectBox:
2424
model = objectbox.Model()
2525
from objectbox.model import IdUid
26-
model.entity(TestEntity, last_property_id=IdUid(6, 1006))
26+
model.entity(TestEntity, last_property_id=IdUid(10, 1010))
2727
model.last_entity_id = IdUid(1, 1)
2828

2929
db_name = test_dir if len(name) == 0 else test_dir + "/" + name
3030

3131
return objectbox.Builder().model(model).directory(db_name).build()
3232

3333

34-
def assert_equal(actual, expected):
34+
def assert_equal_prop(actual, expected, default):
35+
assert actual == expected or (isinstance(
36+
expected, objectbox.model.Property) and actual == default)
37+
38+
39+
def assert_equal(actual: TestEntity, expected: TestEntity):
3540
"""Check that two TestEntity objects have the same property data"""
3641
assert actual.id == expected.id
37-
assert isinstance(expected.bool, objectbox.model.Property) or actual.bool == expected.bool
38-
assert isinstance(expected.int, objectbox.model.Property) or actual.int == expected.int
39-
assert isinstance(expected.str, objectbox.model.Property) or actual.str == expected.str
40-
assert isinstance(expected.float, objectbox.model.Property) or actual.float == expected.float
41-
assert isinstance(expected.bytes, objectbox.model.Property) or actual.bytes == expected.bytes
42-
42+
assert_equal_prop(actual.int64, expected.int64, 0)
43+
assert_equal_prop(actual.int32, expected.int32, 0)
44+
assert_equal_prop(actual.int16, expected.int16, 0)
45+
assert_equal_prop(actual.int8, expected.int8, 0)
46+
assert_equal_prop(actual.float64, expected.float64, 0)
47+
assert_equal_prop(actual.float32, expected.float32, 0)
48+
assert_equal_prop(actual.bytes, expected.bytes, b'')

tests/model.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ class TestEntity:
66
id = Id(id=1, uid=1001)
77
str = Property(str, id=2, uid=1002)
88
bool = Property(bool, id=3, uid=1003)
9-
int = Property(int, id=4, uid=1004)
10-
float = Property(float, id=5, uid=1005)
11-
bytes = Property(bytes, id=6, uid=1006)
9+
int64 = Property(int, type=PropertyType.long, id=4, uid=1004)
10+
int32 = Property(int, type=PropertyType.int, id=5, uid=1005)
11+
int16 = Property(int, type=PropertyType.short, id=6, uid=1006)
12+
int8 = Property(int, type=PropertyType.byte, id=7, uid=1007)
13+
float64 = Property(float, type=PropertyType.double, id=8, uid=1008)
14+
float32 = Property(float, type=PropertyType.float, id=9, uid=1009)
15+
bytes = Property(bytes, id=10, uid=1010)
1216
transient = "" # not "Property" so it's not stored
1317

1418
def __init__(self, string: str = ""):

tests/test_box.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@ def test_box_basics():
2121
object = TestEntity()
2222
object.id = 5
2323
object.bool = True
24-
object.int = 42
24+
object.int64 = 9223372036854775807
25+
object.int32 = 2147483647
26+
object.int16 = 32767
27+
object.int8 = 127
2528
object.str = "foo"
26-
object.float = 4.2
29+
object.float64 = 4.2
30+
object.float32 = 1.5
2731
object.bytes = bytes([1, 1, 2, 3, 5])
2832
object.transient = "abcd"
2933

@@ -67,7 +71,8 @@ def test_box_bulk():
6771

6872
box.put(TestEntity("first"))
6973

70-
objects = [TestEntity("second"), TestEntity("third"), TestEntity("fourth"), box.get(1)]
74+
objects = [TestEntity("second"), TestEntity("third"),
75+
TestEntity("fourth"), box.get(1)]
7176
box.put(objects)
7277
assert box.count() == 4
7378
assert objects[0].id == 2

0 commit comments

Comments
 (0)