From ac4876876e9a19684095af97936318b06cab15ca Mon Sep 17 00:00:00 2001 From: bert hubert Date: Thu, 13 Dec 2018 23:16:46 +0100 Subject: [PATCH] make MDBDbi a value type, improve some error messages, make a delete with no data part --- lmdb-safe.cc | 4 ++-- lmdb-safe.hh | 47 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lmdb-safe.cc b/lmdb-safe.cc index df10c31..fcb0d7e 100644 --- a/lmdb-safe.cc +++ b/lmdb-safe.cc @@ -151,7 +151,7 @@ MDBDbi MDBEnv::openDB(const char* dbname, int flags) MDBRWTransaction::MDBRWTransaction(MDBEnv* parent, int flags) : d_parent(parent) { if(d_parent->getROTX() || d_parent->getRWTX()) - throw std::runtime_error("Duplicate transaction"); + throw std::runtime_error("Duplicate RW transaction"); for(int tries =0 ; tries < 3; ++tries) { // it might happen twice, who knows if(int rc=mdb_txn_begin(d_parent->d_env, 0, flags, &d_txn)) { @@ -171,7 +171,7 @@ MDBRWTransaction::MDBRWTransaction(MDBEnv* parent, int flags) : d_parent(parent) MDBROTransaction::MDBROTransaction(MDBEnv* parent, int flags) : d_parent(parent) { if(d_parent->getRWTX()) - throw std::runtime_error("Duplicate transaction"); + throw std::runtime_error("Duplicate RO transaction"); /* A transaction and its cursors must only be used by a single thread, and a thread may only have a single transaction at a time. If MDB_NOTLS is in use, this does not apply to read-only transactions. */ diff --git a/lmdb-safe.hh b/lmdb-safe.hh index dec982a..db38e7f 100644 --- a/lmdb-safe.hh +++ b/lmdb-safe.hh @@ -36,6 +36,10 @@ The error strategy. Anything that "should never happen" turns into an exception. class MDBDbi { public: + MDBDbi() + { + d_dbi = -1; + } explicit MDBDbi(MDB_env* env, MDB_txn* txn, const char* dbname, int flags); operator const MDB_dbi&() const @@ -222,9 +226,9 @@ public: void renew() { if(d_parent->getROTX()) - throw std::runtime_error("Duplicate transaction"); - if(mdb_txn_renew(d_txn)) - throw std::runtime_error("Renewing transaction"); + throw std::runtime_error("Duplicate RO transaction"); + if(int rc = mdb_txn_renew(d_txn)) + throw std::runtime_error("Renewing RO transaction: "+std::string(mdb_strerror(rc))); d_parent->incROTX(); } @@ -314,9 +318,19 @@ public: int get(MDBOutVal& key, MDBOutVal& data, MDB_cursor_op op) { + // XXX add rc check return mdb_cursor_get(d_cursor, &key.d_mdbval, &data.d_mdbval, op); } + int find(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data) + { + // XXX add rc check + key.d_mdbval = in.d_mdbval; + return mdb_cursor_get(d_cursor, const_cast(&key.d_mdbval), &data.d_mdbval, MDB_SET); + } + + + MDB_cursor* d_cursor; MDBROTransaction* d_parent; }; @@ -393,17 +407,20 @@ public: throw std::runtime_error("putting data: " + std::string(mdb_strerror(rc))); } - /* - void put(MDB_dbi dbi, string_view key, string_view val, int flags=0) - { - put(dbi, MDBInVal(key), MDBInVal(val), flags); - } - */ - int del(MDB_dbi dbi, const MDB_val& key) + int del(MDB_dbi dbi, const MDBInVal& key, const MDBInVal& val) { int rc; - rc=mdb_del(d_txn, dbi, (MDB_val*)&key, 0); + rc=mdb_del(d_txn, dbi, (MDB_val*)&key.d_mdbval, (MDB_val*)&val.d_mdbval); + if(rc && rc != MDB_NOTFOUND) + throw std::runtime_error("deleting data: " + std::string(mdb_strerror(rc))); + return rc; + } + + int del(MDB_dbi dbi, const MDBInVal& key) + { + int rc; + rc=mdb_del(d_txn, dbi, (MDB_val*)&key.d_mdbval, 0); if(rc && rc != MDB_NOTFOUND) throw std::runtime_error("deleting data: " + std::string(mdb_strerror(rc))); return rc; @@ -518,15 +535,21 @@ public: int put(const MDBOutVal& key, const MDBOutVal& data, int flags=0) { + // XXX check errors return mdb_cursor_put(d_cursor, const_cast(&key.d_mdbval), const_cast(&data.d_mdbval), flags); } - int del(MDB_val& key, int flags) + int del(int flags=0) { return mdb_cursor_del(d_cursor, flags); } + + operator MDB_cursor*&() + { + return d_cursor; + } MDB_cursor* d_cursor; MDBRWTransaction* d_parent;