Skip to content

Commit 9de5471

Browse files
author
Ivan Dlugos
committed
add transaction support
1 parent c9f9036 commit 9de5471

File tree

4 files changed

+87
-23
lines changed

4 files changed

+87
-23
lines changed

objectbox/box.py

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -105,31 +105,33 @@ def _put_many(self, objects) -> None:
105105
self._entity.set_object_id(objects[k], ids[k])
106106

107107
def get(self, id: int):
108-
c_data = ctypes.c_void_p()
109-
c_size = ctypes.c_size_t()
110-
obx_box_get(self._c_box, id, ctypes.byref(c_data), ctypes.byref(c_size))
108+
with self._ob.read_tx():
109+
c_data = ctypes.c_void_p()
110+
c_size = ctypes.c_size_t()
111+
obx_box_get(self._c_box, id, ctypes.byref(c_data), ctypes.byref(c_size))
111112

112-
data = c_voidp_as_bytes(c_data, c_size.value)
113-
return self._entity.unmarshal(data)
113+
data = c_voidp_as_bytes(c_data, c_size.value)
114+
return self._entity.unmarshal(data)
114115

115116
def get_all(self) -> list:
116-
# OBX_bytes_array*
117-
c_bytes_array_p = obx_box_get_all(self._c_box)
118-
119-
try:
120-
# OBX_bytes_array
121-
c_bytes_array = c_bytes_array_p.contents
122-
123-
result = list()
124-
for i in range(c_bytes_array.count):
125-
# OBX_bytes
126-
c_bytes = c_bytes_array.data[i]
127-
data = c_voidp_as_bytes(c_bytes.data, c_bytes.size)
128-
result.append(self._entity.unmarshal(data))
129-
130-
return result
131-
finally:
132-
obx_bytes_array_free(c_bytes_array_p)
117+
with self._ob.read_tx():
118+
# OBX_bytes_array*
119+
c_bytes_array_p = obx_box_get_all(self._c_box)
120+
121+
try:
122+
# OBX_bytes_array
123+
c_bytes_array = c_bytes_array_p.contents
124+
125+
result = list()
126+
for i in range(c_bytes_array.count):
127+
# OBX_bytes
128+
c_bytes = c_bytes_array.data[i]
129+
data = c_voidp_as_bytes(c_bytes.data, c_bytes.size)
130+
result.append(self._entity.unmarshal(data))
131+
132+
return result
133+
finally:
134+
obx_bytes_array_free(c_bytes_array_p)
133135

134136
def remove(self, id_or_object):
135137
if isinstance(id_or_object, self._entity.cls):

objectbox/c.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,21 @@ def c_voidp_as_bytes(voidp, size):
300300
# obx_err (OBX_store* store);
301301
obx_store_close = fn('obx_store_close', obx_err, [OBX_store_p])
302302

303+
# OBX_txn* (OBX_store* store);
304+
obx_txn_begin = fn('obx_txn_begin', OBX_txn_p, [OBX_store_p])
305+
306+
# OBX_txn* (OBX_store* store);
307+
obx_txn_begin_read = fn('obx_txn_begin_read', OBX_txn_p, [OBX_store_p])
308+
309+
# obx_err (OBX_txn* txn)
310+
obx_txn_close = fn('obx_txn_close', obx_err, [OBX_txn_p])
311+
312+
# obx_err (OBX_txn* txn);
313+
obx_txn_abort = fn('obx_txn_abort', obx_err, [OBX_txn_p])
314+
315+
# obx_err (OBX_txn* txn);
316+
obx_txn_commit = fn('obx_txn_commit', obx_err, [OBX_txn_p])
317+
303318
# OBX_box* (OBX_store* store, obx_schema_id entity_id);
304319
obx_box = fn('obx_box', OBX_box_p, [OBX_store_p, obx_schema_id])
305320

objectbox/objectbox.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@
1414

1515

1616
from objectbox.c import *
17-
17+
import objectbox.transaction
1818

1919
class ObjectBox:
2020
def __init__(self, c_store: OBX_store_p):
2121
self._c_store = c_store
2222

2323
def __del__(self):
2424
obx_store_close(self._c_store)
25+
26+
def read_tx(self):
27+
return objectbox.transaction.read(self)
28+
29+

objectbox/transaction.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright 2019 ObjectBox Ltd. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from objectbox.c import *
16+
from contextlib import contextmanager
17+
18+
19+
@contextmanager
20+
def read(ob: 'ObjectBox'):
21+
tx = obx_txn_begin_read(ob._c_store)
22+
try:
23+
yield
24+
finally:
25+
obx_txn_close(tx)
26+
27+
28+
@contextmanager
29+
def write(ob: 'ObjectBox'):
30+
tx = obx_txn_begin(ob._c_store)
31+
successful = False
32+
try:
33+
yield
34+
successful = True
35+
finally:
36+
# this is better than bare `except:` because it doesn't catch stuff like KeyboardInterrupt
37+
if successful:
38+
obx_txn_commit(tx)
39+
else:
40+
obx_txn_abort(tx)
41+
42+
obx_txn_close(tx)

0 commit comments

Comments
 (0)