Skip to content

Commit 04588ca

Browse files
committed
Merge branch '64-exceptions' into dev
2 parents f9fc86a + 527e061 commit 04588ca

File tree

7 files changed

+328
-100
lines changed

7 files changed

+328
-100
lines changed

objectbox/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
from objectbox.model.entity import Entity
2020
from objectbox.model.properties import Id, String, Index, Bool, Int8, Int16, Int32, Int64, Float32, Float64, Bytes, BoolVector, Int8Vector, Int16Vector, Int32Vector, Int64Vector, Float32Vector, Float64Vector, CharVector, BoolList, Int8List, Int16List, Int32List, Int64List, Float32List, Float64List, CharList, Date, DateNano, Flex, HnswIndex, VectorDistanceType, HnswFlags
2121
from objectbox.model.model import Model
22-
from objectbox.c import DbException, CoreException, NotFoundException, version_core, DebugFlags
22+
from objectbox.c import version_core, DebugFlags
23+
from objectbox.exceptions import DbError
2324
from objectbox.version import Version
2425
from objectbox.condition import PropertyQueryCondition
2526
from objectbox.query import Query
@@ -66,8 +67,7 @@
6667
'VectorDistanceType',
6768
'Store',
6869
'ObjectBox',
69-
'CoreException',
70-
'NotFoundException',
70+
'DbError',
7171
'version',
7272
'version_info',
7373
'DebugFlags',

objectbox/box.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from objectbox.query_builder import QueryBuilder
1919
from objectbox.condition import QueryCondition
2020
from objectbox.c import *
21+
from objectbox.exceptions import DbError
2122

2223

2324
class Box:
@@ -121,7 +122,7 @@ def get(self, id: int):
121122
if code == 404:
122123
return None
123124
elif code != 0:
124-
raise CoreException(code)
125+
raise DbError.from_code(code)
125126
data = c_voidp_as_bytes(c_data, c_size.value)
126127
return self._entity._unmarshal(data)
127128

@@ -156,7 +157,7 @@ def remove(self, id_or_object) -> bool:
156157
if code == 404:
157158
return False
158159
elif code != 0:
159-
raise CoreException(code)
160+
raise DbError.from_code(code)
160161
return True
161162

162163
def remove_all(self) -> int:

objectbox/c.py

Lines changed: 97 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -94,32 +94,33 @@ class LogLevel(IntEnum):
9494
Warn = 40
9595
Error = 50
9696

97+
9798
class DebugFlags(IntEnum):
9899
"""Debug flags"""
99-
100+
100101
NONE = 0,
101-
102+
102103
LOG_TRANSACTIONS_READ = 1,
103104
""" Log read transactions """
104-
105+
105106
LOG_TRANSACTIONS_WRITE = 2,
106107
""" Log write transactions """
107-
108+
108109
LOG_QUERIES = 3,
109110
""" Log queries """
110-
111+
111112
LOG_QUERY_PARAMETERS = 8,
112113
""" Log query parameters """
113-
114+
114115
LOG_ASYNC_QUEUE = 16,
115116
""" Log async queue """
116-
117+
117118
LOG_CACHE_HITS = 32,
118119
""" Log cache hits """
119-
120+
120121
LOG_CACHE_ALL = 64,
121122
""" Log cache hits """
122-
123+
123124
LOG_TREE = 128
124125
""" Log tree operations """
125126

@@ -255,82 +256,74 @@ class OBX_query(ctypes.Structure):
255256
C.obx_last_error_code.restype = obx_err
256257

257258

258-
class DbException(Exception):
259-
""" Base class for database exceptions. """
260-
pass
261-
262-
263-
# TODO rename?
264-
class CoreException(DbException):
265-
""" A database exception having a ``code`` attribute for error details. """
266-
267-
codes = {
268-
0: "SUCCESS",
269-
404: "NOT_FOUND",
270-
10001: "ILLEGAL_STATE",
271-
10002: "ILLEGAL_ARGUMENT",
272-
10003: "ALLOCATION",
273-
10097: "NO_ERROR_INFO",
274-
10098: "GENERAL",
275-
10099: "UNKNOWN",
276-
10101: "DB_FULL",
277-
10102: "MAX_READERS_EXCEEDED",
278-
10103: "STORE_MUST_SHUTDOWN",
279-
10199: "STORAGE_GENERAL",
280-
10201: "UNIQUE_VIOLATED",
281-
10202: "NON_UNIQUE_RESULT",
282-
10203: "PROPERTY_TYPE_MISMATCH",
283-
10299: "CONSTRAINT_VIOLATED",
284-
10301: "STD_ILLEGAL_ARGUMENT",
285-
10302: "STD_OUT_OF_RANGE",
286-
10303: "STD_LENGTH",
287-
10304: "STD_BAD_ALLOC",
288-
10305: "STD_RANGE",
289-
10306: "STD_OVERFLOW",
290-
10399: "STD_OTHER",
291-
10501: "SCHEMA",
292-
10502: "FILE_CORRUPT"
293-
}
294-
295-
def __init__(self, code: int):
296-
self.code = code
297-
self.message = py_str(C.obx_last_error_message())
298-
name = self.codes[code] if code in self.codes else "n/a"
299-
super(CoreException, self).__init__("%d (%s) - %s" % (code, name, self.message))
300-
301-
@staticmethod
302-
def last():
303-
""" Creates a CoreException of the last error that was generated in core. """
304-
return CoreException(C.obx_last_error())
305-
306-
307-
class NotFoundException(CoreException):
308-
""" Raised when an object is not found. """
309-
310-
def __init__(self):
311-
super().__init__(404)
259+
class DbErrorCode(IntEnum):
260+
OBX_SUCCESS = 0
261+
OBX_NOT_FOUND = 404
262+
OBX_NO_SUCCESS = 1001
263+
OBX_TIMEOUT = 1002
264+
OBX_ERROR_ILLEGAL_STATE = 10001
265+
OBX_ERROR_ILLEGAL_ARGUMENT = 10002
266+
OBX_ERROR_ALLOCATION = 10003
267+
OBX_ERROR_NUMERIC_OVERFLOW = 10004
268+
OBX_ERROR_FEATURE_NOT_AVAILABLE = 10005
269+
OBX_ERROR_SHUTTING_DOWN = 10006
270+
OBX_ERROR_IO = 10007
271+
OBX_ERROR_BACKUP_FILE_INVALID = 10008
272+
OBX_ERROR_NO_ERROR_INFO = 10097
273+
OBX_ERROR_GENERAL = 10098
274+
OBX_ERROR_UNKNOWN = 10099
275+
OBX_ERROR_DB_FULL = 10101
276+
OBX_ERROR_MAX_READERS_EXCEEDED = 10102
277+
OBX_ERROR_STORE_MUST_SHUTDOWN = 10103
278+
OBX_ERROR_MAX_DATA_SIZE_EXCEEDED = 10104
279+
OBX_ERROR_DB_GENERAL = 10198
280+
OBX_ERROR_STORAGE_GENERAL = 10199
281+
OBX_ERROR_UNIQUE_VIOLATED = 10201
282+
OBX_ERROR_NON_UNIQUE_RESULT = 10202
283+
OBX_ERROR_PROPERTY_TYPE_MISMATCH = 10203
284+
OBX_ERROR_ID_ALREADY_EXISTS = 10210
285+
OBX_ERROR_ID_NOT_FOUND = 10211
286+
OBX_ERROR_TIME_SERIES = 10212
287+
OBX_ERROR_CONSTRAINT_VIOLATED = 10299
288+
OBX_ERROR_STD_ILLEGAL_ARGUMENT = 10301
289+
OBX_ERROR_STD_OUT_OF_RANGE = 10302
290+
OBX_ERROR_STD_LENGTH = 10303
291+
OBX_ERROR_STD_BAD_ALLOC = 10304
292+
OBX_ERROR_STD_RANGE = 10305
293+
OBX_ERROR_STD_OVERFLOW = 10306
294+
OBX_ERROR_STD_OTHER = 10399
295+
OBX_ERROR_SCHEMA = 10501
296+
OBX_ERROR_FILE_CORRUPT = 10502
297+
OBX_ERROR_FILE_PAGES_CORRUPT = 10503
298+
OBX_ERROR_SCHEMA_OBJECT_NOT_FOUND = 10504
299+
OBX_ERROR_TREE_MODEL_INVALID = 10601
300+
OBX_ERROR_TREE_VALUE_TYPE_MISMATCH = 10602
301+
OBX_ERROR_TREE_PATH_NON_UNIQUE = 10603
302+
OBX_ERROR_TREE_PATH_ILLEGAL = 10604
303+
OBX_ERROR_TREE_OTHER = 10699
312304

313305

314306
def check_obx_err(code: obx_err, func, args) -> obx_err:
315307
""" Raises an exception if obx_err is not successful. """
316-
if code == 404:
317-
raise NotFoundException()
318-
elif code != 0:
319-
raise CoreException(code)
308+
if code != DbErrorCode.OBX_SUCCESS:
309+
from objectbox.exceptions import create_db_error
310+
raise create_db_error(code)
320311
return code
321312

322313

323-
def check_obx_qb_cond(code: obx_qb_cond, func, args) -> obx_qb_cond:
314+
def check_obx_qb_cond(qb_cond: obx_qb_cond, func, args) -> obx_qb_cond:
324315
""" Raises an exception if obx_qb_cond is not successful. """
325-
if code == 0:
326-
raise CoreException(code)
327-
return code
316+
if qb_cond == 0:
317+
from objectbox.exceptions import create_db_error
318+
raise create_db_error(C.obx_last_error_code())
319+
return qb_cond
328320

329321

330322
# assert that the returned pointer/int is non-empty
331323
def check_result(result, func, args):
332324
if not result:
333-
raise CoreException(C.obx_last_error_code())
325+
from objectbox.exceptions import create_db_error
326+
raise create_db_error(C.obx_last_error_code())
334327
return result
335328

336329

@@ -411,10 +404,13 @@ def c_array_pointer(py_list: Union[List[Any], np.ndarray], c_type):
411404

412405

413406
# OBX_C_API float obx_vector_distance_float32(OBXVectorDistanceType type, const float* vector1, const float* vector2, size_t dimension);
414-
obx_vector_distance_float32 = c_fn("obx_vector_distance_float32", ctypes.c_float, [OBXVectorDistanceType, ctypes.POINTER(ctypes.c_float), ctypes.POINTER(ctypes.c_float), ctypes.c_size_t])
407+
obx_vector_distance_float32 = c_fn("obx_vector_distance_float32", ctypes.c_float,
408+
[OBXVectorDistanceType, ctypes.POINTER(ctypes.c_float),
409+
ctypes.POINTER(ctypes.c_float), ctypes.c_size_t])
415410

416411
# OBX_C_API float obx_vector_distance_to_relevance(OBXVectorDistanceType type, float distance);
417-
obx_vector_distance_to_relevance = c_fn("obx_vector_distance_to_relevance", ctypes.c_float, [OBXVectorDistanceType, ctypes.c_float])
412+
obx_vector_distance_to_relevance = c_fn("obx_vector_distance_to_relevance", ctypes.c_float,
413+
[OBXVectorDistanceType, ctypes.c_float])
418414

419415
# OBX_model* (void);
420416
obx_model = c_fn('obx_model', OBX_model_p, [])
@@ -450,7 +446,8 @@ def c_array_pointer(py_list: Union[List[Any], np.ndarray], c_type):
450446
c_fn_rc('obx_model_property_index_hnsw_flags', [OBX_model_p, OBXHnswFlags])
451447

452448
# obx_err obx_model_property_index_hnsw_distance_type(OBX_model* model, OBXVectorDistanceType value)
453-
obx_model_property_index_hnsw_distance_type = c_fn_rc('obx_model_property_index_hnsw_distance_type', [OBX_model_p, OBXVectorDistanceType])
449+
obx_model_property_index_hnsw_distance_type = c_fn_rc('obx_model_property_index_hnsw_distance_type',
450+
[OBX_model_p, OBXVectorDistanceType])
454451

455452
# obx_err obx_model_property_index_hnsw_reparation_backlink_probability(OBX_model* model, float value)
456453
obx_model_property_index_hnsw_reparation_backlink_probability = \
@@ -504,10 +501,12 @@ def c_array_pointer(py_list: Union[List[Any], np.ndarray], c_type):
504501
obx_opt_model_bytes = c_fn_rc('obx_opt_model_bytes', [OBX_store_options_p, ctypes.c_void_p, ctypes.c_size_t])
505502

506503
# OBX_C_API obx_err obx_opt_model_bytes_direct(OBX_store_options* opt, const void* bytes, size_t size);
507-
obx_opt_model_bytes_direct = c_fn_rc('obx_opt_model_bytes_direct', [OBX_store_options_p, ctypes.c_void_p, ctypes.c_size_t])
504+
obx_opt_model_bytes_direct = c_fn_rc('obx_opt_model_bytes_direct',
505+
[OBX_store_options_p, ctypes.c_void_p, ctypes.c_size_t])
508506

509507
# OBX_C_API void obx_opt_validate_on_open_pages(OBX_store_options* opt, size_t page_limit, uint32_t flags);
510-
obx_opt_validate_on_open_pages = c_fn('obx_opt_validate_on_open_pages', None, [OBX_store_options_p, ctypes.c_size_t, OBXValidateOnOpenPagesFlags])
508+
obx_opt_validate_on_open_pages = c_fn('obx_opt_validate_on_open_pages', None,
509+
[OBX_store_options_p, ctypes.c_size_t, OBXValidateOnOpenPagesFlags])
511510

512511
# OBX_C_API void obx_opt_validate_on_open_kv(OBX_store_options* opt, uint32_t flags);
513512
obx_opt_validate_on_open_kv = c_fn('obx_opt_validate_on_open_kv', None, [OBX_store_options_p, OBXValidateOnOpenKvFlags])
@@ -534,43 +533,53 @@ def c_array_pointer(py_list: Union[List[Any], np.ndarray], c_type):
534533
obx_opt_async_max_queue_length = c_fn('obx_opt_async_max_queue_length', None, [OBX_store_options_p, ctypes.c_size_t])
535534

536535
# OBX_C_API void obx_opt_async_throttle_at_queue_length(OBX_store_options* opt, size_t value);
537-
obx_opt_async_throttle_at_queue_length = c_fn('obx_opt_async_throttle_at_queue_length', None, [OBX_store_options_p, ctypes.c_size_t])
536+
obx_opt_async_throttle_at_queue_length = c_fn('obx_opt_async_throttle_at_queue_length', None,
537+
[OBX_store_options_p, ctypes.c_size_t])
538538

539539
# OBX_C_API void obx_opt_async_throttle_micros(OBX_store_options* opt, uint32_t value);
540540
obx_opt_async_throttle_micros = c_fn('obx_opt_async_throttle_micros', None, [OBX_store_options_p, ctypes.c_uint32])
541541

542542
# OBX_C_API void obx_opt_async_max_in_tx_duration(OBX_store_options* opt, uint32_t micros);
543-
obx_opt_async_max_in_tx_duration = c_fn('obx_opt_async_max_in_tx_duration', None, [OBX_store_options_p, ctypes.c_uint32])
543+
obx_opt_async_max_in_tx_duration = c_fn('obx_opt_async_max_in_tx_duration', None,
544+
[OBX_store_options_p, ctypes.c_uint32])
544545

545546
# OBX_C_API void obx_opt_async_max_in_tx_operations(OBX_store_options* opt, uint32_t value);
546-
obx_opt_async_max_in_tx_operations = c_fn('obx_opt_async_max_in_tx_operations', None, [OBX_store_options_p, ctypes.c_uint32])
547+
obx_opt_async_max_in_tx_operations = c_fn('obx_opt_async_max_in_tx_operations', None,
548+
[OBX_store_options_p, ctypes.c_uint32])
547549

548550
# OBX_C_API void obx_opt_async_pre_txn_delay(OBX_store_options* opt, uint32_t delay_micros);
549551
obx_opt_async_pre_txn_delay = c_fn('obx_opt_async_pre_txn_delay', None, [OBX_store_options_p, ctypes.c_uint32])
550552

551553
# OBX_C_API void obx_opt_async_pre_txn_delay4(OBX_store_options* opt, uint32_t delay_micros, uint32_t delay2_micros, size_t min_queue_length_for_delay2);
552-
obx_opt_async_pre_txn_delay4 = c_fn('obx_opt_async_pre_txn_delay4', None, [OBX_store_options_p, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_size_t])
554+
obx_opt_async_pre_txn_delay4 = c_fn('obx_opt_async_pre_txn_delay4', None,
555+
[OBX_store_options_p, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_size_t])
553556

554557
# OBX_C_API void obx_opt_async_post_txn_delay(OBX_store_options* opt, uint32_t delay_micros);
555558
obx_opt_async_post_txn_delay = c_fn('obx_opt_async_post_txn_delay', None, [OBX_store_options_p, ctypes.c_uint32])
556559

557560
# OBX_C_API void obx_opt_async_post_txn_delay5(OBX_store_options* opt, uint32_t delay_micros, uint32_t delay2_micros, size_t min_queue_length_for_delay2, bool subtract_processing_time);
558-
obx_opt_async_post_txn_delay5 = c_fn('obx_opt_async_post_txn_delay5', None, [OBX_store_options_p, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_size_t, ctypes.c_bool])
561+
obx_opt_async_post_txn_delay5 = c_fn('obx_opt_async_post_txn_delay5', None,
562+
[OBX_store_options_p, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_size_t,
563+
ctypes.c_bool])
559564

560565
# OBX_C_API void obx_opt_async_minor_refill_threshold(OBX_store_options* opt, size_t queue_length);
561-
obx_opt_async_minor_refill_threshold = c_fn('obx_opt_async_minor_refill_threshold', None, [OBX_store_options_p, ctypes.c_size_t])
566+
obx_opt_async_minor_refill_threshold = c_fn('obx_opt_async_minor_refill_threshold', None,
567+
[OBX_store_options_p, ctypes.c_size_t])
562568

563569
# OBX_C_API void obx_opt_async_minor_refill_max_count(OBX_store_options* opt, uint32_t value);
564-
obx_opt_async_minor_refill_max_count = c_fn('obx_opt_async_minor_refill_max_count', None, [OBX_store_options_p, ctypes.c_uint32])
570+
obx_opt_async_minor_refill_max_count = c_fn('obx_opt_async_minor_refill_max_count', None,
571+
[OBX_store_options_p, ctypes.c_uint32])
565572

566573
# OBX_C_API void obx_opt_async_max_tx_pool_size(OBX_store_options* opt, size_t value);
567574
obx_opt_async_max_tx_pool_size = c_fn('obx_opt_async_max_tx_pool_size', None, [OBX_store_options_p, ctypes.c_size_t])
568575

569576
# OBX_C_API void obx_opt_async_object_bytes_max_cache_size(OBX_store_options* opt, uint64_t value);
570-
obx_opt_async_object_bytes_max_cache_size = c_fn('obx_opt_async_object_bytes_max_cache_size', None, [OBX_store_options_p, ctypes.c_uint64])
577+
obx_opt_async_object_bytes_max_cache_size = c_fn('obx_opt_async_object_bytes_max_cache_size', None,
578+
[OBX_store_options_p, ctypes.c_uint64])
571579

572580
# OBX_C_API void obx_opt_async_object_bytes_max_size_to_cache(OBX_store_options* opt, uint64_t value);
573-
obx_opt_async_object_bytes_max_size_to_cache = c_fn('obx_opt_async_object_bytes_max_size_to_cache', None, [OBX_store_options_p, ctypes.c_uint64])
581+
obx_opt_async_object_bytes_max_size_to_cache = c_fn('obx_opt_async_object_bytes_max_size_to_cache', None,
582+
[OBX_store_options_p, ctypes.c_uint64])
574583

575584
#typedef void obx_log_callback(OBXLogLevel log_level, const char* message, size_t message_size, void* user_data);
576585
obx_log_callback_fn = ctypes.CFUNCTYPE(None, OBXLogLevel, ctypes.c_char_p, ctypes.c_size_t, ctypes.c_voidp)
@@ -579,7 +588,8 @@ def c_array_pointer(py_list: Union[List[Any], np.ndarray], c_type):
579588
obx_opt_log_callback = c_fn('obx_opt_log_callback', None, [OBX_store_options_p, obx_log_callback_fn, ctypes.c_voidp])
580589

581590
# OBX_C_API void obx_opt_backup_restore(OBX_store_options* opt, const char* backup_file, uint32_t flags);
582-
obx_opt_backup_restore = c_fn('obx_opt_backup_restore', None, [OBX_store_options_p, ctypes.c_char_p, OBXBackupRestoreFlags])
591+
obx_opt_backup_restore = c_fn('obx_opt_backup_restore', None,
592+
[OBX_store_options_p, ctypes.c_char_p, OBXBackupRestoreFlags])
583593

584594
# OBX_C_API const char* obx_opt_get_directory(OBX_store_options* opt);
585595
obx_opt_get_directory = c_fn('obx_opt_get_directory', ctypes.c_char_p, [OBX_store_options_p])

0 commit comments

Comments
 (0)