diff options
| -rw-r--r-- | extmod/modbtree.c | 22 | ||||
| -rw-r--r-- | tests/extmod/btree_closed.py | 39 | ||||
| -rw-r--r-- | tests/extmod/btree_closed.py.exp | 5 |
3 files changed, 65 insertions, 1 deletions
diff --git a/extmod/modbtree.c b/extmod/modbtree.c index 55c13ac91..f48645a82 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -89,6 +89,12 @@ void __dbpanic(DB *db) { mp_printf(&mp_plat_print, "__dbpanic(%p)\n", db); } +static void check_btree_is_open(mp_obj_btree_t *self) { + if (!self->db) { + mp_raise_ValueError(MP_ERROR_TEXT("database closed")); + } +} + static mp_obj_btree_t *btree_new(DB *db, mp_obj_t stream) { mp_obj_btree_t *o = mp_obj_malloc(mp_obj_btree_t, (mp_obj_type_t *)&btree_type); o->stream = stream; @@ -114,19 +120,28 @@ static void btree_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind static mp_obj_t btree_flush(mp_obj_t self_in) { mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); + check_btree_is_open(self); return MP_OBJ_NEW_SMALL_INT(__bt_sync(self->db, 0)); } static MP_DEFINE_CONST_FUN_OBJ_1(btree_flush_obj, btree_flush); static mp_obj_t btree_close(mp_obj_t self_in) { mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(__bt_close(self->db)); + int res; + if (self->db) { + res = __bt_close(self->db); + self->db = NULL; + } else { + res = RET_SUCCESS; // Closing an already-closed DB always succeeds. + } + return MP_OBJ_NEW_SMALL_INT(res); } static MP_DEFINE_CONST_FUN_OBJ_1(btree_close_obj, btree_close); static mp_obj_t btree_put(size_t n_args, const mp_obj_t *args) { (void)n_args; mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]); + check_btree_is_open(self); DBT key, val; buf_to_dbt(args[1], &key); buf_to_dbt(args[2], &val); @@ -136,6 +151,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_put_obj, 3, 4, btree_put); static mp_obj_t btree_get(size_t n_args, const mp_obj_t *args) { mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]); + check_btree_is_open(self); DBT key, val; buf_to_dbt(args[1], &key); int res = __bt_get(self->db, &key, &val, 0); @@ -153,6 +169,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_get_obj, 2, 3, btree_get); static mp_obj_t btree_seq(size_t n_args, const mp_obj_t *args) { mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]); + check_btree_is_open(self); int flags = MP_OBJ_SMALL_INT_VALUE(args[1]); DBT key, val; if (n_args > 2) { @@ -225,6 +242,7 @@ static mp_obj_t btree_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { static mp_obj_t btree_iternext(mp_obj_t self_in) { mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); + check_btree_is_open(self); DBT key, val; int res; bool desc = self->flags & FLAG_DESC; @@ -281,6 +299,7 @@ static mp_obj_t btree_iternext(mp_obj_t self_in) { static mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); + check_btree_is_open(self); if (value == MP_OBJ_NULL) { // delete DBT key; @@ -314,6 +333,7 @@ static mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { static mp_obj_t btree_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { mp_obj_btree_t *self = MP_OBJ_TO_PTR(lhs_in); + check_btree_is_open(self); switch (op) { case MP_BINARY_OP_CONTAINS: { DBT key, val; diff --git a/tests/extmod/btree_closed.py b/tests/extmod/btree_closed.py new file mode 100644 index 000000000..ae61cd008 --- /dev/null +++ b/tests/extmod/btree_closed.py @@ -0,0 +1,39 @@ +try: + import btree + import io +except ImportError: + print("SKIP") + raise SystemExit + +f = io.BytesIO() +db = btree.open(f) + +db[b"foo"] = b"42" + +db.close() + +# Accessing an already-closed database should fail. +try: + print(db[b"foo"]) +except ValueError: + print("ValueError") + +try: + db[b"bar"] = b"43" +except ValueError: + print("ValueError") + +try: + db.flush() +except ValueError: + print("ValueError") + +try: + for k, v in db.items(): + pass +except ValueError: + print("ValueError") + +# Closing and printing an already-closed database should not fail. +db.close() +print(db) diff --git a/tests/extmod/btree_closed.py.exp b/tests/extmod/btree_closed.py.exp new file mode 100644 index 000000000..312edfd13 --- /dev/null +++ b/tests/extmod/btree_closed.py.exp @@ -0,0 +1,5 @@ +ValueError +ValueError +ValueError +ValueError +<btree 0> |
