2#ifndef _MDBX_CONTAINERS_ANY_VALUE_TABLE_HPP_INCLUDED
3#define _MDBX_CONTAINERS_ANY_VALUE_TABLE_HPP_INCLUDED
24 std::string name =
"any_store",
25 MDBX_db_flags_t flags = MDBX_DB_DEFAULTS | MDBX_CREATE)
33 std::string name =
"any_store",
34 MDBX_db_flags_t flags = MDBX_DB_DEFAULTS | MDBX_CREATE)
48 void set(
const KeyT& key,
const T& value, MDBX_txn* txn =
nullptr) {
63 bool insert(
const KeyT& key,
const T& value, MDBX_txn* txn =
nullptr) {
84 template <
class T,
class Fn>
85 void update(
const KeyT& key, Fn&& fn,
bool create_if_missing =
false, MDBX_txn* txn =
nullptr) {
90 if (!create_if_missing) {
91 throw std::out_of_range(
"Key not found");
100 template <
class T,
class Fn>
113 T
get(
const KeyT& key, MDBX_txn* txn =
nullptr)
const {
120 throw std::out_of_range(
"Key not found");
133#if __cplusplus >= 201703L
135 std::optional<T> find(
const KeyT& key, MDBX_txn* txn =
nullptr)
const {
136 std::optional<T> result;
141 result = std::move(tmp);
143 }
catch (
const std::bad_cast&) {
152 std::optional<T> find(
const KeyT& key,
const Transaction& txn)
const {
153 return find<T>(key, txn.handle());
162 T
get_or(
const KeyT& key, T default_value, MDBX_txn* txn =
nullptr)
const {
163 if (
auto val = find<T>(key, txn)) {
164 return *std::move(val);
166 return default_value;
175 T
get_or(
const KeyT& key, T default_value,
const Transaction& txn)
const {
176 return get_or<T>(key, std::move(default_value), txn.handle());
185 std::pair<bool, T>
find_compat(
const KeyT& key, MDBX_txn* txn =
nullptr)
const {
186 std::pair<bool, T> result{
false, T{}};
192 }
catch (
const std::bad_cast&) {
216 T
get_or(
const KeyT& key, T default_value, MDBX_txn* txn =
nullptr)
const {
219 return std::move(res.second);
221 return default_value;
243 template <
class KT = KeyT>
244 bool contains(
const KT& key, MDBX_txn* txn =
nullptr)
const {
262 bool erase(
const KeyT& key, MDBX_txn* txn =
nullptr) {
279 std::vector<KeyT>
keys(MDBX_txn* txn =
nullptr)
const {
280 std::vector<KeyT> out;
312 action(txn_guard.handle());
315 try { txn_guard.rollback(); }
catch (...) {}
321 bool put_typed(
const KeyT& key,
const T& value,
bool upsert, MDBX_txn* txn) {
327 MDBX_put_flags_t flags = upsert ? MDBX_UPSERT : MDBX_NOOVERWRITE;
328 int rc = mdbx_put(txn,
m_dbi, &db_key, &db_val, flags);
329 if (!upsert && rc == MDBX_KEYEXIST) {
332 check_mdbx(rc, upsert ?
"Failed to set value" :
"Failed to insert value");
337 bool get_typed(
const KeyT& key, T& out, MDBX_txn* txn)
const {
341 int rc = mdbx_get(txn,
m_dbi, &db_key, &db_val);
342 if (rc == MDBX_NOTFOUND)
return false;
352 int rc = mdbx_get(txn,
m_dbi, &db_key,
nullptr);
353 if (rc == MDBX_SUCCESS)
return true;
354 if (rc == MDBX_NOTFOUND)
return false;
355 check_mdbx(rc,
"Failed to check key presence");
362 int rc = mdbx_del(txn,
m_dbi, &db_key,
nullptr);
363 if (rc == MDBX_SUCCESS)
return true;
364 if (rc == MDBX_NOTFOUND)
return false;
370 MDBX_cursor* cursor =
nullptr;
371 check_mdbx(mdbx_cursor_open(txn,
m_dbi, &cursor),
"Failed to open MDBX cursor");
372 MDBX_val db_key, db_val;
373 while (mdbx_cursor_get(cursor, &db_key, &db_val, MDBX_NEXT) == MDBX_SUCCESS) {
376 mdbx_cursor_close(cursor);
std::vector< KeyT > keys(MDBX_txn *txn=nullptr) const
List all keys stored in table.
bool insert(const KeyT &key, const T &value, MDBX_txn *txn=nullptr)
Insert value if key does not exist.
std::pair< bool, T > find_compat(const KeyT &key, const Transaction &txn) const
Find value by key using external transaction (C++11 mode).
MDBX_val wrap_with_type_tag(const MDBX_val &raw) const
~AnyValueTable() override=default
Destructor.
void set(const KeyT &key, const T &value, const Transaction &txn)
Set value using external transaction.
void set(const KeyT &key, const T &value, MDBX_txn *txn=nullptr)
Set value for key, replacing existing value.
AnyValueTable(const Config &cfg, std::string name="any_store", MDBX_db_flags_t flags=MDBX_DB_DEFAULTS|MDBX_CREATE)
Constructs table using configuration.
std::vector< KeyT > keys(const Transaction &txn) const
List keys using external transaction.
bool get_typed(const KeyT &key, T &out, MDBX_txn *txn) const
void set_type_tag_check(bool enabled) noexcept
Enable or disable type-tag checking.
T get_or(const KeyT &key, T default_value, MDBX_txn *txn=nullptr) const
Get value or default if missing (C++11 mode).
bool db_erase(const KeyT &key, MDBX_txn *txn)
bool insert(const KeyT &key, const T &value, const Transaction &txn)
Insert value using external transaction.
void with_transaction(F &&action, TransactionMode mode, MDBX_txn *txn) const
bool erase(const KeyT &key, const Transaction &txn)
Erase using external transaction.
AnyValueTable(std::shared_ptr< Connection > conn, std::string name="any_store", MDBX_db_flags_t flags=MDBX_DB_DEFAULTS|MDBX_CREATE)
Constructs table using existing connection.
bool db_contains(const KeyT &key, MDBX_txn *txn) const
void update(const KeyT &key, Fn &&fn, bool create_if_missing, const Transaction &txn)
Update using external transaction.
bool m_check_type_tag
Flag enabling type-tag verification.
T get_or(const KeyT &key, T default_value, const Transaction &txn) const
Get value or default using external transaction (C++11 mode).
bool contains(const KT &key, MDBX_txn *txn=nullptr) const
Check if key exists.
bool put_typed(const KeyT &key, const T &value, bool upsert, MDBX_txn *txn)
std::pair< bool, T > find_compat(const KeyT &key, MDBX_txn *txn=nullptr) const
Find value by key.
void update(const KeyT &key, Fn &&fn, bool create_if_missing=false, MDBX_txn *txn=nullptr)
Update value using functor.
T get(const KeyT &key, const Transaction &txn) const
Retrieve using external transaction.
T get(const KeyT &key, MDBX_txn *txn=nullptr) const
Retrieve stored value or throw if missing.
bool contains(const KeyT &key, const Transaction &txn) const
Check key existence using external transaction.
bool erase(const KeyT &key, MDBX_txn *txn=nullptr)
Erase key from table.
MDBX_val unwrap_and_check_type_tag(const MDBX_val &raw) const
void db_list_keys(std::vector< KeyT > &out, MDBX_txn *txn) const
MDBX_txn * thread_txn() const
Returns the transaction bound to the current thread, if any.
MDBX_dbi m_dbi
DBI handle for the opened table.
BaseTable(std::shared_ptr< Connection > connection, std::string name, MDBX_db_flags_t flags)
Construct the database table accessor.
std::shared_ptr< Connection > m_connection
Shared connection to MDBX environment.
Parameters used by Connection to create the MDBX environment.
Manages a single MDBX environment and an optional read-only transaction.
Manages MDBX transactions with automatic cleanup and error handling.
MDBX_txn * handle() const noexcept
Returns the internal MDBX transaction handle.
Publicly usable low-level components of the MDBX Containers library.
std::enable_if<!has_value_type< T >::value &&!std::is_same< T, std::vector< typenameT::value_type > >::value &&!std::is_trivially_copyable< typenameT::value_type >::value &&!has_to_bytes< T >::value &&!std::is_same< T, std::string >::value &&!std::is_trivially_copyable< T >::value, MDBX_val >::type serialize_value(const T &value, SerializeScratch &sc)
Serializes a general value into MDBX_val.
std::enable_if<!has_value_type< T >::value &&!has_from_bytes< T >::value &&!std::is_same< T, std::string >::value &&!std::is_trivially_copyable< T >::value, T >::type deserialize_value(const MDBX_val &val)
Deserializes a value from MDBX_val into type T.
MDBX_db_flags_t get_mdbx_flags()
Returns MDBX flags for a given key type.
std::enable_if<!has_to_bytes< T >::value &&!std::is_same< T, std::string >::value &&!std::is_trivially_copyable< T >::value, MDBX_val >::type serialize_key(const T &key, SerializeScratch &sc)
Serializes a key into MDBX_val for database operations.
void check_mdbx(int rc, const std::string &context)
Throws an MdbxException if MDBX return code indicates an error.
TransactionMode
Specifies the access mode of a transaction.
@ READ_ONLY
Read-only transaction (no write operations allowed).
@ WRITABLE
Writable transaction (allows inserts, updates, deletes).
Per-call scratch buffer to produce MDBX_val without using thread_local.