Skip to content

Commit 6a9ca1f

Browse files
committed
Box: remove insert, update takes ID from object #64
- Remove Box.insert(): IDs shall not be managed by the user - Box.update(obj) uses the object's ID; raises ValueError if it has none - Fix obx_box_remove_many binding missing the box argument - Tests: check object IDs, failed update does not re-create the object
1 parent 05e0dec commit 6a9ca1f

3 files changed

Lines changed: 22 additions & 52 deletions

File tree

‎objectbox/box.py‎

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -118,25 +118,15 @@ def _put_many(self, objects) -> None:
118118
for k in new.keys():
119119
self._entity._set_object_id(objects[k], ids[k])
120120

121-
def insert(self, object_id: int, object_):
122-
"""Inserts an object with the given ID.
121+
def update(self, object_):
122+
"""Updates the existing object having the same ID as the given object.
123123
124-
Raises if the ID already exists.
125-
"""
126-
object_.id = object_id
127-
data = self._entity._marshal(object_, object_id)
128-
obx_box_insert(self._c_box, object_id, bytes(data), len(data))
129-
if object_id != self._entity._get_object_id(object_):
130-
self._entity._set_object_id(object_, object_id)
131-
132-
def update(self, object_id: int, object_):
133-
"""Updates an existing object given by its ID, with the given object.
134-
135-
Raises if the ID doesn't match any object."""
124+
Raises if the object has no ID (i.e. it was never put) or the ID doesn't match any stored object."""
125+
object_id = self._entity._get_object_id(object_)
126+
if not object_id:
127+
raise ValueError("Cannot update an object without an ID; use put() for new objects")
136128
data = self._entity._marshal(object_, object_id)
137129
obx_box_update(self._c_box, object_id, bytes(data), len(data))
138-
if object_id != self._entity._get_object_id(object_):
139-
self._entity._set_object_id(object_, object_id)
140130

141131
def get(self, id: int):
142132
"""Get object by given Id or None if not found."""
@@ -162,11 +152,8 @@ def get_many(self, id_array: List[int]) -> list:
162152
if not id_array: # Empty
163153
return []
164154

165-
c_ids = (ctypes.c_uint64 * len(id_array))(*id_array)
166-
167-
c_id_array = OBX_id_array()
168-
c_id_array.ids = ctypes.cast(c_ids, ctypes.POINTER(obx_id))
169-
c_id_array.count = len(id_array)
155+
c_ids = (obx_id * len(id_array))(*id_array)
156+
c_id_array = OBX_id_array(ctypes.cast(c_ids, ctypes.POINTER(obx_id)), len(id_array))
170157

171158
with self._store.read_tx():
172159
c_bytes_array_p = obx_box_get_many(self._c_box, ctypes.byref(c_id_array))

‎objectbox/c.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ def c_array_pointer(py_list: Union[List[Any], np.ndarray], c_type):
671671
obx_box_remove = c_fn_nocheck('obx_box_remove', obx_err, [OBX_box_p, obx_id])
672672

673673
# OBX_C_API obx_err obx_box_remove_many(OBX_box* box, const OBX_id_array* ids, uint64_t* out_count);
674-
obx_box_remove_many = c_fn_rc('obx_box_remove_many', [OBX_id_array_p, ctypes.POINTER(ctypes.c_uint64)])
674+
obx_box_remove_many = c_fn_rc('obx_box_remove_many', [OBX_box_p, OBX_id_array_p, ctypes.POINTER(ctypes.c_uint64)])
675675

676676
# OBX_C_API obx_err obx_box_remove_all(OBX_box* box, uint64_t* out_count);
677677
obx_box_remove_all = c_fn_rc('obx_box_remove_all', [OBX_box_p, ctypes.POINTER(ctypes.c_uint64)])

‎tests/test_box.py‎

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -298,30 +298,10 @@ def test_contains(test_store):
298298
assert not box.contains(4)
299299
assert not box.contains(3248)
300300

301-
with pytest.raises(IllegalArgumentError, match="Illegal ID value: 0") as e:
301+
with pytest.raises(IllegalArgumentError, match="Illegal ID value: 0"):
302302
box.contains(0)
303303

304304

305-
def test_insert(test_store):
306-
box = test_store.box(TestEntity)
307-
308-
box.insert(38, TestEntity(str="Object 38"))
309-
box.insert(2, TestEntity(str="Object 2"))
310-
box.insert(98, TestEntity(str="Object 98"))
311-
assert box.count() == 3
312-
313-
with pytest.raises(IdAlreadyExistsError, match="Insert failed, given ID already exists: 98") as e:
314-
box.insert(98, TestEntity(str="Object 98"))
315-
316-
assert box.put(TestEntity(str="Object 1")) == 1
317-
assert box.count() == 4
318-
319-
assert box.get(2).str == "Object 2"
320-
assert box.put(TestEntity(str="Object 2 (updated)")) == 2
321-
assert box.get(2).str == "Object 2 (updated)"
322-
assert box.count() == 4
323-
324-
325305
def test_update(test_store):
326306
box = test_store.box(TestEntity)
327307

@@ -330,20 +310,23 @@ def test_update(test_store):
330310
box.put(TestEntity(str="Object 3"))
331311
assert box.count() == 3
332312

333-
assert box.get(1).str == "Object 1"
334-
assert box.get(2).str == "Object 2"
335-
assert box.get(3).str == "Object 3"
336-
337-
box.update(1, TestEntity(str="Object 1 (updated)"))
338-
box.update(2, TestEntity(str="Object 2 (updated)"))
339-
box.update(3, TestEntity(str="Object 3 (updated)"))
313+
for obj in box.get_all():
314+
obj.str += " (updated)"
315+
box.update(obj)
340316

341317
assert box.get(1).str == "Object 1 (updated)"
342318
assert box.get(2).str == "Object 2 (updated)"
343319
assert box.get(3).str == "Object 3 (updated)"
320+
assert box.count() == 3
321+
322+
with pytest.raises(ValueError, match="without an ID"):
323+
box.update(TestEntity(str="New object"))
344324

345-
with pytest.raises(IdNotFoundError, match="Update failed, given ID doesn't exist: 100") as e:
346-
box.update(100, TestEntity(str="Object 100 (updated)"))
325+
obj = box.get(1)
326+
box.remove(1)
327+
with pytest.raises(IdNotFoundError, match="Update failed, given ID doesn't exist: 1"):
328+
box.update(obj)
329+
assert not box.contains(1) # Failed update must not re-create the object
347330

348331

349332
def test_get_many(test_store):

0 commit comments

Comments
 (0)