Skip to content

Commit f5b56bb

Browse files
committed
properties: Added Bytes + support for bytes conditions #29
1 parent 7181b6a commit f5b56bb

File tree

7 files changed

+111
-2
lines changed

7 files changed

+111
-2
lines changed

objectbox/condition.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ def _apply_eq(self, qb: QueryBuilder) -> obx_qb_cond:
118118
return qb.equals_string(self._property_id, value, case_sensitive)
119119
elif isinstance(value, int):
120120
return qb.equals_int(self._property_id, value)
121+
elif isinstance(value, bytes):
122+
return qb.equals_bytes(self._property_id, value)
121123
else:
122124
raise Exception(f"Unsupported type for 'EQ': {type(value)}")
123125

@@ -164,6 +166,8 @@ def _apply_gt(self, qb: QueryBuilder) -> obx_qb_cond:
164166
return qb.greater_than_int(self._property_id, value)
165167
elif isinstance(value, float):
166168
return qb.greater_than_double(self._property_id, value)
169+
elif isinstance(value, bytes):
170+
return qb.greater_than_bytes(self._property_id, value)
167171
else:
168172
raise Exception(f"Unsupported type for 'GT': {type(value)}")
169173

@@ -176,6 +180,8 @@ def _apply_gte(self, qb: QueryBuilder) -> obx_qb_cond:
176180
return qb.greater_or_equal_int(self._property_id, value)
177181
elif isinstance(value, float):
178182
return qb.greater_or_equal_double(self._property_id, value)
183+
elif isinstance(value, bytes):
184+
return qb.greater_or_equal_bytes(self._property_id, value)
179185
else:
180186
raise Exception(f"Unsupported type for 'GTE': {type(value)}")
181187

@@ -188,6 +194,8 @@ def _apply_lt(self, qb: QueryBuilder) -> obx_qb_cond:
188194
return qb.less_than_int(self._property_id, value)
189195
elif isinstance(value, float):
190196
return qb.less_than_double(self._property_id, value)
197+
elif isinstance(value, bytes):
198+
return qb.less_than_bytes(self._property_id, value)
191199
else:
192200
raise Exception("Unsupported type for 'LT': " + str(type(value)))
193201

@@ -200,6 +208,8 @@ def _apply_lte(self, qb: QueryBuilder) -> obx_qb_cond:
200208
return qb.less_or_equal_int(self._property_id, value)
201209
elif isinstance(value, float):
202210
return qb.less_or_equal_double(self._property_id, value)
211+
elif isinstance(value, bytes):
212+
return qb.less_or_equal_bytes(self._property_id, value)
203213
else:
204214
raise Exception(f"Unsupported type for 'LTE': {type(value)}")
205215

objectbox/model/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,5 @@
5555
'Int64List',
5656
'Float32List',
5757
'Float64List',
58+
'Bytes',
5859
]

objectbox/model/properties.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,31 @@ class DateNano(_IntProperty):
311311
def __init__(self, py_type = datetime, id : int = 0, uid : int = 0, **kwargs):
312312
super(DateNano, self).__init__(py_type, type=PropertyType.dateNano, id=id, uid=uid, **kwargs)
313313

314+
# Bytes Property
315+
class Bytes(_NumericProperty):
316+
def __init__(self, id: int = 0, uid : int = 0, **kwargs):
317+
super(Bytes, self).__init__(bytes, type=PropertyType.byteVector, id=id, uid=uid, **kwargs)
318+
319+
def equals(self, value) -> PropertyQueryCondition:
320+
args = {'value': value}
321+
return PropertyQueryCondition(self._id, PropertyQueryConditionOp.EQ, args)
322+
323+
def greater_than(self, value) -> PropertyQueryCondition:
324+
args = {'value': value}
325+
return PropertyQueryCondition(self._id, PropertyQueryConditionOp.GT, args)
326+
327+
def greater_or_equal(self, value) -> PropertyQueryCondition:
328+
args = {'value': value}
329+
return PropertyQueryCondition(self._id, PropertyQueryConditionOp.GTE, args)
330+
331+
def less_than(self, value) -> PropertyQueryCondition:
332+
args = {'value': value}
333+
return PropertyQueryCondition(self._id, PropertyQueryConditionOp.LT, args)
334+
335+
def less_or_equal(self, value) -> PropertyQueryCondition:
336+
args = {'value': value}
337+
return PropertyQueryCondition(self._id, PropertyQueryConditionOp.LTE, args)
338+
314339
# Flex Property
315340
class Flex(Property):
316341
def __init__(self, id : int = 0, uid : int = 0, **kwargs):

objectbox/query_builder.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,31 @@ def between_2doubles(self, prop: Union[int, str, Property], value_a: float, valu
134134
cond = obx_qb_between_2doubles(self._c_builder, prop_id, value_a, value_b)
135135
return cond
136136

137+
def equals_bytes(self, prop: Union[int, str, Property], value: bytes) -> obx_qb_cond:
138+
prop_id = self._entity.get_property_id(prop)
139+
cond = obx_qb_equals_bytes(self._c_builder, prop_id, value, len(value))
140+
return cond
141+
142+
def greater_than_bytes(self, prop: Union[int, str, Property], value: bytes) -> obx_qb_cond:
143+
prop_id = self._entity.get_property_id(prop)
144+
cond = obx_qb_greater_than_bytes(self._c_builder, prop_id, value, len(value))
145+
return cond
146+
147+
def greater_or_equal_bytes(self, prop: Union[int, str, Property], value: bytes) -> obx_qb_cond:
148+
prop_id = self._entity.get_property_id(prop)
149+
cond = obx_qb_greater_or_equal_bytes(self._c_builder, prop_id, value, len(value))
150+
return cond
151+
152+
def less_than_bytes(self, prop: Union[int, str, Property], value: bytes) -> obx_qb_cond:
153+
prop_id = self._entity.get_property_id(prop)
154+
cond = obx_qb_less_than_bytes(self._c_builder, prop_id, value, len(value))
155+
return cond
156+
157+
def less_or_equal_bytes(self, prop: Union[int, str, Property], value: bytes) -> obx_qb_cond:
158+
prop_id = self._entity.get_property_id(prop)
159+
cond = obx_qb_less_or_equal_bytes(self._c_builder, prop_id, value, len(value))
160+
return cond
161+
137162
def nearest_neighbors_f32(self,
138163
prop: Union[int, str, Property],
139164
query_vector: Union[np.ndarray, List[float]],

tests/common.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
def create_default_model() -> objectbox.Model:
1616
model = objectbox.Model()
17-
model.entity(TestEntity, last_property_id=IdUid(27, 1027))
17+
model.entity(TestEntity, last_property_id=IdUid(28, 1028))
1818
model.last_entity_id = IdUid(2, 2)
1919
model.last_index_id = IdUid(2, 10002)
2020
return model
@@ -55,7 +55,7 @@ def create_test_store(db_name: Optional[str] = None, clear_db: bool = True) -> o
5555
shutil.rmtree(db_path)
5656

5757
model = objectbox.Model()
58-
model.entity(TestEntity, last_property_id=IdUid(27, 1027))
58+
model.entity(TestEntity, last_property_id=IdUid(28, 1028))
5959
model.entity(TestEntityDatetime, last_property_id=IdUid(4, 2004))
6060
model.entity(TestEntityFlex, last_property_id=IdUid(2, 3002))
6161
model.entity(VectorEntity, last_property_id=IdUid(5, 4005))

tests/model.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class TestEntity:
3434
date = Date(id=25, uid=1025)
3535
date_nano = DateNano(int, id=26, uid=1026)
3636
flex = Flex(id=27, uid=1027)
37+
bytes = Bytes(id=28, uid=1028)
3738
transient = "" # not "Property" so it's not stored
3839

3940

tests/test_query.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,3 +586,50 @@ def test_set_parameter_alias_advanced():
586586
query.set_parameter_alias_string("str_filter", "Zucchini")
587587
assert len(query.find_ids()) == 1 # Zucchini
588588

589+
590+
# Bytes query
591+
def test_bytes():
592+
store = create_test_store()
593+
box = store.box(TestEntity)
594+
595+
bytes_prop: Property = TestEntity.get_property("bytes")
596+
597+
598+
id1 = box.put(TestEntity(bytes=bytes([9])))
599+
id2 = box.put(TestEntity(bytes=bytes([1,0])))
600+
id3 = box.put(TestEntity(bytes=bytes([0,1])))
601+
query = box.query(bytes_prop.greater_or_equal(bytes([0]))).build()
602+
assert query.count() == 3
603+
query = box.query(bytes_prop.greater_or_equal(bytes([1]))).build()
604+
assert query.count() == 2
605+
query = box.query(bytes_prop.greater_or_equal(bytes([9]))).build()
606+
assert query.count() == 1
607+
608+
assert box.remove_all() == 3
609+
id1 = box.put(TestEntity(bytes=bytes([1,2,3,4])))
610+
id2 = box.put(TestEntity(bytes=bytes([5,6,7,8,9,10,11])))
611+
query = box.query(bytes_prop.equals(bytes([1,2,3,4]))).build()
612+
assert query.count() == 1
613+
assert query.find()[0].id == id1
614+
615+
query = box.query(bytes_prop.greater_than(bytes([1,2,3,4]))).build()
616+
assert query.count() == 1
617+
assert query.find()[0].id == id2
618+
619+
query = box.query(bytes_prop.greater_or_equal(bytes([1,2,3,4]))).build()
620+
assert query.count() == 2
621+
622+
query = box.query(bytes_prop.greater_or_equal(bytes([0]))).build()
623+
assert query.count() == 2
624+
625+
query = box.query(bytes_prop.less_than(bytes([5,6,7,8,9,10,11]))).build()
626+
assert query.count() == 1
627+
assert query.find()[0].id == id1
628+
629+
query = box.query(bytes_prop.less_or_equal(bytes([5,6,7,8,9,10,11]))).build()
630+
assert query.count() == 2
631+
632+
# bytes does not support not equals
633+
with pytest.raises(AttributeError):
634+
bytes_prop.not_equals(bytes([]))
635+

0 commit comments

Comments
 (0)