lmdb++
lmdb++.h
Go to the documentation of this file.
1 /* This is free and unencumbered software released into the public domain. */
2 
3 #ifndef LMDBXX_H
4 #define LMDBXX_H
5 
14 #ifndef __cplusplus
15 #error "<lmdb++.h> requires a C++ compiler"
16 #endif
17 
18 #if __cplusplus < 201703L
19 #error "<lmdb++.h> requires a C++17 compiler (CXXFLAGS='-std=c++17')"
20 #endif
21 
23 
24 #include <lmdb.h> /* for MDB_*, mdb_*() */
25 
26 #ifdef LMDBXX_DEBUG
27 #include <cassert> /* for assert() */
28 #endif
29 #include <cstddef> /* for std::size_t */
30 #include <cstdio> /* for std::snprintf() */
31 #include <cstring> /* for std::memcpy() */
32 #include <stdexcept> /* for std::runtime_error */
33 #include <string_view> /* for std::string_view */
34 #include <limits> /* for std::numeric_limits<> */
35 #include <memory> /* for std::addressof */
36 
37 namespace lmdb {
38  using mode = mdb_mode_t;
39 }
40 
42 /* Error Handling */
43 
44 namespace lmdb {
45  class error;
46  class logic_error;
47  class fatal_error;
48  class runtime_error;
49  class key_exist_error;
50  class not_found_error;
51  class corrupted_error;
52  class panic_error;
53  class version_mismatch_error;
54  class map_full_error;
55  class bad_dbi_error;
56 }
57 
63 class lmdb::error : public std::runtime_error {
64 protected:
65  const int _code;
66 
67 public:
71  [[noreturn]] static inline void raise(const char* origin, int rc);
72 
76  error(const char* const origin,
77  const int rc) noexcept
79  _code{rc} {}
80 
84  int code() const noexcept {
85  return _code;
86  }
87 
91  const char* origin() const noexcept {
92  return runtime_error::what();
93  }
94 
98  virtual const char* what() const noexcept {
99  static thread_local char buffer[1024];
100  std::snprintf(buffer, sizeof(buffer),
101  "%s: %s", origin(), ::mdb_strerror(code()));
102  return buffer;
103  }
104 };
105 
110 public:
111  using error::error;
112 };
113 
118 public:
119  using error::error;
120 };
121 
126 public:
127  using error::error;
128 };
129 
136 public:
137  using runtime_error::runtime_error;
138 };
139 
146 public:
147  using runtime_error::runtime_error;
148 };
149 
156 public:
157  using fatal_error::fatal_error;
158 };
159 
165 class lmdb::panic_error final : public lmdb::fatal_error {
166 public:
167  using fatal_error::fatal_error;
168 };
169 
176 public:
177  using fatal_error::fatal_error;
178 };
179 
186 public:
187  using runtime_error::runtime_error;
188 };
189 
197 public:
198  using runtime_error::runtime_error;
199 };
200 
201 inline void
202 lmdb::error::raise(const char* const origin,
203  const int rc) {
204  switch (rc) {
205  case MDB_KEYEXIST: throw key_exist_error{origin, rc};
206  case MDB_NOTFOUND: throw not_found_error{origin, rc};
207  case MDB_CORRUPTED: throw corrupted_error{origin, rc};
208  case MDB_PANIC: throw panic_error{origin, rc};
209  case MDB_VERSION_MISMATCH: throw version_mismatch_error{origin, rc};
210  case MDB_MAP_FULL: throw map_full_error{origin, rc};
211 #ifdef MDB_BAD_DBI
212  case MDB_BAD_DBI: throw bad_dbi_error{origin, rc};
213 #endif
214  default: throw lmdb::runtime_error{origin, rc};
215  }
216 }
217 
219 /* Procedural Interface: Metadata */
220 
221 namespace lmdb {
222  // TODO: mdb_version()
223  // TODO: mdb_strerror()
224 }
225 
227 /* Procedural Interface: Environment */
228 
229 namespace lmdb {
230  static inline void env_create(MDB_env** env);
231  static inline void env_open(MDB_env* env,
232  const char* path, unsigned int flags, mode mode);
233 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
234  static inline void env_copy(MDB_env* env, const char* path, unsigned int flags);
235  static inline void env_copy_fd(MDB_env* env, mdb_filehandle_t fd, unsigned int flags);
236 #else
237  static inline void env_copy(MDB_env* env, const char* path);
238  static inline void env_copy_fd(MDB_env* env, mdb_filehandle_t fd);
239 #endif
240  static inline void env_stat(MDB_env* env, MDB_stat* stat);
241  static inline void env_info(MDB_env* env, MDB_envinfo* stat);
242  static inline void env_sync(MDB_env* env, bool force);
243  static inline void env_close(MDB_env* env) noexcept;
244  static inline void env_set_flags(MDB_env* env, unsigned int flags, bool onoff);
245  static inline void env_get_flags(MDB_env* env, unsigned int* flags);
246  static inline void env_get_path(MDB_env* env, const char** path);
247  static inline void env_get_fd(MDB_env* env, mdb_filehandle_t* fd);
248  static inline void env_set_mapsize(MDB_env* env, std::size_t size);
249  static inline void env_set_max_readers(MDB_env* env, unsigned int count);
250  static inline void env_get_max_readers(MDB_env* env, unsigned int* count);
251  static inline void env_set_max_dbs(MDB_env* env, MDB_dbi count);
252  static inline unsigned int env_get_max_keysize(MDB_env* env);
253 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
254  static inline void env_set_userctx(MDB_env* env, void* ctx);
255  static inline void* env_get_userctx(MDB_env* env);
256 #endif
257  // TODO: mdb_env_set_assert()
258  // TODO: mdb_reader_list()
259  static inline void reader_check(MDB_env *env, int *dead);
260 }
261 
266 static inline void
267 lmdb::env_create(MDB_env** env) {
268  const int rc = ::mdb_env_create(env);
269  if (rc != MDB_SUCCESS) {
270  error::raise("mdb_env_create", rc);
271  }
272 }
273 
278 static inline void
279 lmdb::env_open(MDB_env* const env,
280  const char* const path,
281  const unsigned int flags,
282  const mode mode) {
283  const int rc = ::mdb_env_open(env, path, flags, mode);
284  if (rc != MDB_SUCCESS) {
285  error::raise("mdb_env_open", rc);
286  }
287 }
288 
294 static inline void
295 lmdb::env_copy(MDB_env* const env,
296 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
297  const char* const path,
298  const unsigned int flags = 0) {
299  const int rc = ::mdb_env_copy2(env, path, flags);
300 #else
301  const char* const path) {
302  const int rc = ::mdb_env_copy(env, path);
303 #endif
304  if (rc != MDB_SUCCESS) {
305  error::raise("mdb_env_copy2", rc);
306  }
307 }
308 
314 static inline void
315 lmdb::env_copy_fd(MDB_env* const env,
316 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
317  const mdb_filehandle_t fd,
318  const unsigned int flags = 0) {
319  const int rc = ::mdb_env_copyfd2(env, fd, flags);
320 #else
321  const mdb_filehandle_t fd) {
322  const int rc = ::mdb_env_copyfd(env, fd);
323 #endif
324  if (rc != MDB_SUCCESS) {
325  error::raise("mdb_env_copyfd2", rc);
326  }
327 }
328 
333 static inline void
334 lmdb::env_stat(MDB_env* const env,
335  MDB_stat* const stat) {
336  const int rc = ::mdb_env_stat(env, stat);
337  if (rc != MDB_SUCCESS) {
338  error::raise("mdb_env_stat", rc);
339  }
340 }
341 
346 static inline void
347 lmdb::env_info(MDB_env* const env,
348  MDB_envinfo* const stat) {
349  const int rc = ::mdb_env_info(env, stat);
350  if (rc != MDB_SUCCESS) {
351  error::raise("mdb_env_info", rc);
352  }
353 }
354 
359 static inline void
360 lmdb::env_sync(MDB_env* const env,
361  const bool force = true) {
362  const int rc = ::mdb_env_sync(env, force);
363  if (rc != MDB_SUCCESS) {
364  error::raise("mdb_env_sync", rc);
365  }
366 }
367 
371 static inline void
372 lmdb::env_close(MDB_env* const env) noexcept {
373  ::mdb_env_close(env);
374 }
375 
380 static inline void
381 lmdb::env_set_flags(MDB_env* const env,
382  const unsigned int flags,
383  const bool onoff = true) {
384  const int rc = ::mdb_env_set_flags(env, flags, onoff ? 1 : 0);
385  if (rc != MDB_SUCCESS) {
386  error::raise("mdb_env_set_flags", rc);
387  }
388 }
389 
394 static inline void
395 lmdb::env_get_flags(MDB_env* const env,
396  unsigned int* const flags) {
397  const int rc = ::mdb_env_get_flags(env, flags);
398  if (rc != MDB_SUCCESS) {
399  error::raise("mdb_env_get_flags", rc);
400  }
401 }
402 
407 static inline void
408 lmdb::env_get_path(MDB_env* const env,
409  const char** path) {
410  const int rc = ::mdb_env_get_path(env, path);
411  if (rc != MDB_SUCCESS) {
412  error::raise("mdb_env_get_path", rc);
413  }
414 }
415 
420 static inline void
421 lmdb::env_get_fd(MDB_env* const env,
422  mdb_filehandle_t* const fd) {
423  const int rc = ::mdb_env_get_fd(env, fd);
424  if (rc != MDB_SUCCESS) {
425  error::raise("mdb_env_get_fd", rc);
426  }
427 }
428 
433 static inline void
434 lmdb::env_set_mapsize(MDB_env* const env,
435  const std::size_t size) {
436  const int rc = ::mdb_env_set_mapsize(env, size);
437  if (rc != MDB_SUCCESS) {
438  error::raise("mdb_env_set_mapsize", rc);
439  }
440 }
441 
446 static inline void
448  const unsigned int count) {
449  const int rc = ::mdb_env_set_maxreaders(env, count);
450  if (rc != MDB_SUCCESS) {
451  error::raise("mdb_env_set_maxreaders", rc);
452  }
453 }
454 
459 static inline void
461  unsigned int* const count) {
462  const int rc = ::mdb_env_get_maxreaders(env, count);
463  if (rc != MDB_SUCCESS) {
464  error::raise("mdb_env_get_maxreaders", rc);
465  }
466 }
467 
472 static inline void
473 lmdb::env_set_max_dbs(MDB_env* const env,
474  const MDB_dbi count) {
475  const int rc = ::mdb_env_set_maxdbs(env, count);
476  if (rc != MDB_SUCCESS) {
477  error::raise("mdb_env_set_maxdbs", rc);
478  }
479 }
480 
484 static inline unsigned int
486  const int rc = ::mdb_env_get_maxkeysize(env);
487 #ifdef LMDBXX_DEBUG
488  assert(rc >= 0);
489 #endif
490  return static_cast<unsigned int>(rc);
491 }
492 
493 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
499 static inline void
500 lmdb::env_set_userctx(MDB_env* const env,
501  void* const ctx) {
502  const int rc = ::mdb_env_set_userctx(env, ctx);
503  if (rc != MDB_SUCCESS) {
504  error::raise("mdb_env_set_userctx", rc);
505  }
506 }
507 #endif
508 
509 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
514 static inline void*
515 lmdb::env_get_userctx(MDB_env* const env) {
516  return ::mdb_env_get_userctx(env);
517 }
518 #endif
519 
520 static inline void
521 lmdb::reader_check(MDB_env *env, int *dead) {
522  const int rc = ::mdb_reader_check(env, dead);
523  if (rc != MDB_SUCCESS) {
524  error::raise("reader_check", rc);
525  }
526 }
527 
529 /* Procedural Interface: Transactions */
530 
531 namespace lmdb {
532  static inline void txn_begin(
533  MDB_env* env, MDB_txn* parent, unsigned int flags, MDB_txn** txn);
534  static inline MDB_env* txn_env(MDB_txn* txn) noexcept;
535 #ifdef LMDBXX_TXN_ID
536  static inline std::size_t txn_id(MDB_txn* txn) noexcept;
537 #endif
538  static inline void txn_commit(MDB_txn* txn);
539  static inline void txn_abort(MDB_txn* txn) noexcept;
540  static inline void txn_reset(MDB_txn* txn) noexcept;
541  static inline void txn_renew(MDB_txn* txn);
542 }
543 
548 static inline void
549 lmdb::txn_begin(MDB_env* const env,
550  MDB_txn* const parent,
551  const unsigned int flags,
552  MDB_txn** txn) {
553  const int rc = ::mdb_txn_begin(env, parent, flags, txn);
554  if (rc != MDB_SUCCESS) {
555  error::raise("mdb_txn_begin", rc);
556  }
557 }
558 
562 static inline MDB_env*
563 lmdb::txn_env(MDB_txn* const txn) noexcept {
564  return ::mdb_txn_env(txn);
565 }
566 
567 #ifdef LMDBXX_TXN_ID
571 static inline std::size_t
572 lmdb::txn_id(MDB_txn* const txn) noexcept {
573  return ::mdb_txn_id(txn);
574 }
575 #endif
576 
581 static inline void
582 lmdb::txn_commit(MDB_txn* const txn) {
583  const int rc = ::mdb_txn_commit(txn);
584  if (rc != MDB_SUCCESS) {
585  error::raise("mdb_txn_commit", rc);
586  }
587 }
588 
592 static inline void
593 lmdb::txn_abort(MDB_txn* const txn) noexcept {
594  ::mdb_txn_abort(txn);
595 }
596 
600 static inline void
601 lmdb::txn_reset(MDB_txn* const txn) noexcept {
602  ::mdb_txn_reset(txn);
603 }
604 
609 static inline void
610 lmdb::txn_renew(MDB_txn* const txn) {
611  const int rc = ::mdb_txn_renew(txn);
612  if (rc != MDB_SUCCESS) {
613  error::raise("mdb_txn_renew", rc);
614  }
615 }
616 
618 /* Procedural Interface: Databases */
619 
620 namespace lmdb {
621  static inline void dbi_open(
622  MDB_txn* txn, const char* name, unsigned int flags, MDB_dbi* dbi);
623  static inline void dbi_stat(MDB_txn* txn, MDB_dbi dbi, MDB_stat* stat);
624  static inline void dbi_flags(MDB_txn* txn, MDB_dbi dbi, unsigned int* flags);
625  static inline void dbi_close(MDB_env* env, MDB_dbi dbi) noexcept;
626  static inline void dbi_drop(MDB_txn* txn, MDB_dbi dbi, bool del);
627  static inline void dbi_set_compare(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
628  static inline void dbi_set_dupsort(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
629  static inline void dbi_set_relfunc(MDB_txn* txn, MDB_dbi dbi, MDB_rel_func* rel);
630  static inline void dbi_set_relctx(MDB_txn* txn, MDB_dbi dbi, void* ctx);
631  static inline bool dbi_get(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, MDB_val* data);
632  static inline bool dbi_put(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, MDB_val* data, unsigned int flags);
633  static inline bool dbi_del(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, const MDB_val* data);
634  // TODO: mdb_cmp()
635  // TODO: mdb_dcmp()
636 }
637 
642 static inline void
643 lmdb::dbi_open(MDB_txn* const txn,
644  const char* const name,
645  const unsigned int flags,
646  MDB_dbi* const dbi) {
647  const int rc = ::mdb_dbi_open(txn, name, flags, dbi);
648  if (rc != MDB_SUCCESS) {
649  error::raise("mdb_dbi_open", rc);
650  }
651 }
652 
657 static inline void
658 lmdb::dbi_stat(MDB_txn* const txn,
659  const MDB_dbi dbi,
660  MDB_stat* const result) {
661  const int rc = ::mdb_stat(txn, dbi, result);
662  if (rc != MDB_SUCCESS) {
663  error::raise("mdb_stat", rc);
664  }
665 }
666 
671 static inline void
672 lmdb::dbi_flags(MDB_txn* const txn,
673  const MDB_dbi dbi,
674  unsigned int* const flags) {
675  const int rc = ::mdb_dbi_flags(txn, dbi, flags);
676  if (rc != MDB_SUCCESS) {
677  error::raise("mdb_dbi_flags", rc);
678  }
679 }
680 
684 static inline void
685 lmdb::dbi_close(MDB_env* const env,
686  const MDB_dbi dbi) noexcept {
687  ::mdb_dbi_close(env, dbi);
688 }
689 
693 static inline void
694 lmdb::dbi_drop(MDB_txn* const txn,
695  const MDB_dbi dbi,
696  const bool del = false) {
697  const int rc = ::mdb_drop(txn, dbi, del ? 1 : 0);
698  if (rc != MDB_SUCCESS) {
699  error::raise("mdb_drop", rc);
700  }
701 }
702 
707 static inline void
708 lmdb::dbi_set_compare(MDB_txn* const txn,
709  const MDB_dbi dbi,
710  MDB_cmp_func* const cmp = nullptr) {
711  const int rc = ::mdb_set_compare(txn, dbi, cmp);
712  if (rc != MDB_SUCCESS) {
713  error::raise("mdb_set_compare", rc);
714  }
715 }
716 
721 static inline void
722 lmdb::dbi_set_dupsort(MDB_txn* const txn,
723  const MDB_dbi dbi,
724  MDB_cmp_func* const cmp = nullptr) {
725  const int rc = ::mdb_set_dupsort(txn, dbi, cmp);
726  if (rc != MDB_SUCCESS) {
727  error::raise("mdb_set_dupsort", rc);
728  }
729 }
730 
735 static inline void
736 lmdb::dbi_set_relfunc(MDB_txn* const txn,
737  const MDB_dbi dbi,
738  MDB_rel_func* const rel) {
739  const int rc = ::mdb_set_relfunc(txn, dbi, rel);
740  if (rc != MDB_SUCCESS) {
741  error::raise("mdb_set_relfunc", rc);
742  }
743 }
744 
749 static inline void
750 lmdb::dbi_set_relctx(MDB_txn* const txn,
751  const MDB_dbi dbi,
752  void* const ctx) {
753  const int rc = ::mdb_set_relctx(txn, dbi, ctx);
754  if (rc != MDB_SUCCESS) {
755  error::raise("mdb_set_relctx", rc);
756  }
757 }
758 
764 static inline bool
765 lmdb::dbi_get(MDB_txn* const txn,
766  const MDB_dbi dbi,
767  const MDB_val* const key,
768  MDB_val* const data) {
769  const int rc = ::mdb_get(txn, dbi, const_cast<MDB_val*>(key), data);
770  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
771  error::raise("mdb_get", rc);
772  }
773  return (rc == MDB_SUCCESS);
774 }
775 
781 static inline bool
782 lmdb::dbi_put(MDB_txn* const txn,
783  const MDB_dbi dbi,
784  const MDB_val* const key,
785  MDB_val* const data,
786  const unsigned int flags = 0) {
787  const int rc = ::mdb_put(txn, dbi, const_cast<MDB_val*>(key), data, flags);
788  if (rc != MDB_SUCCESS && rc != MDB_KEYEXIST) {
789  error::raise("mdb_put", rc);
790  }
791  return (rc == MDB_SUCCESS);
792 }
793 
799 static inline bool
800 lmdb::dbi_del(MDB_txn* const txn,
801  const MDB_dbi dbi,
802  const MDB_val* const key,
803  const MDB_val* const data = nullptr) {
804  const int rc = ::mdb_del(txn, dbi, const_cast<MDB_val*>(key), const_cast<MDB_val*>(data));
805  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
806  error::raise("mdb_del", rc);
807  }
808  return (rc == MDB_SUCCESS);
809 }
810 
812 /* Procedural Interface: Cursors */
813 
814 namespace lmdb {
815  static inline void cursor_open(MDB_txn* txn, MDB_dbi dbi, MDB_cursor** cursor);
816  static inline void cursor_close(MDB_cursor* cursor) noexcept;
817  static inline void cursor_renew(MDB_txn* txn, MDB_cursor* cursor);
818  static inline MDB_txn* cursor_txn(MDB_cursor* cursor) noexcept;
819  static inline MDB_dbi cursor_dbi(MDB_cursor* cursor) noexcept;
820  static inline bool cursor_get(MDB_cursor* cursor, MDB_val* key, MDB_val* data, MDB_cursor_op op);
821  static inline bool cursor_put(MDB_cursor* cursor, MDB_val* key, MDB_val* data, unsigned int flags);
822  static inline void cursor_del(MDB_cursor* cursor, unsigned int flags);
823  static inline void cursor_count(MDB_cursor* cursor, std::size_t& count);
824 }
825 
830 static inline void
831 lmdb::cursor_open(MDB_txn* const txn,
832  const MDB_dbi dbi,
833  MDB_cursor** const cursor) {
834  const int rc = ::mdb_cursor_open(txn, dbi, cursor);
835  if (rc != MDB_SUCCESS) {
836  error::raise("mdb_cursor_open", rc);
837  }
838 }
839 
843 static inline void
844 lmdb::cursor_close(MDB_cursor* const cursor) noexcept {
845  ::mdb_cursor_close(cursor);
846 }
847 
852 static inline void
853 lmdb::cursor_renew(MDB_txn* const txn,
854  MDB_cursor* const cursor) {
855  const int rc = ::mdb_cursor_renew(txn, cursor);
856  if (rc != MDB_SUCCESS) {
857  error::raise("mdb_cursor_renew", rc);
858  }
859 }
860 
864 static inline MDB_txn*
865 lmdb::cursor_txn(MDB_cursor* const cursor) noexcept {
866  return ::mdb_cursor_txn(cursor);
867 }
868 
872 static inline MDB_dbi
873 lmdb::cursor_dbi(MDB_cursor* const cursor) noexcept {
874  return ::mdb_cursor_dbi(cursor);
875 }
876 
881 static inline bool
882 lmdb::cursor_get(MDB_cursor* const cursor,
883  MDB_val* const key,
884  MDB_val* const data,
885  const MDB_cursor_op op) {
886  const int rc = ::mdb_cursor_get(cursor, key, data, op);
887  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
888  error::raise("mdb_cursor_get", rc);
889  }
890  return (rc == MDB_SUCCESS);
891 }
892 
897 static inline bool
898 lmdb::cursor_put(MDB_cursor* const cursor,
899  MDB_val* const key,
900  MDB_val* const data,
901  const unsigned int flags = 0) {
902  const int rc = ::mdb_cursor_put(cursor, key, data, flags);
903  if (rc != MDB_SUCCESS && rc != MDB_KEYEXIST) {
904  error::raise("mdb_cursor_put", rc);
905  }
906  return (rc == MDB_SUCCESS);
907 }
908 
913 static inline void
914 lmdb::cursor_del(MDB_cursor* const cursor,
915  const unsigned int flags = 0) {
916  const int rc = ::mdb_cursor_del(cursor, flags);
917  if (rc != MDB_SUCCESS) {
918  error::raise("mdb_cursor_del", rc);
919  }
920 }
921 
926 static inline void
927 lmdb::cursor_count(MDB_cursor* const cursor,
928  std::size_t& count) {
929  const int rc = ::mdb_cursor_count(cursor, &count);
930  if (rc != MDB_SUCCESS) {
931  error::raise("mdb_cursor_count", rc);
932  }
933 }
934 
936 /* Resource Interface: Environment */
937 
938 namespace lmdb {
939  class env;
940 }
941 
948 class lmdb::env {
949 protected:
950  MDB_env* _handle{nullptr};
951 
952 public:
953  static constexpr unsigned int default_flags = 0;
954  static constexpr mode default_mode = 0644; /* -rw-r--r-- */
955 
962  static env create(const unsigned int flags = default_flags) {
963  MDB_env* handle{nullptr};
965 #ifdef LMDBXX_DEBUG
966  assert(handle != nullptr);
967 #endif
968  if (flags) {
969  try {
970  lmdb::env_set_flags(handle, flags);
971  }
972  catch (const lmdb::error&) {
974  throw;
975  }
976  }
977  return env{handle};
978  }
979 
985  env(MDB_env* const handle) noexcept
986  : _handle{handle} {}
987 
991  env(env&& other) noexcept {
992  std::swap(_handle, other._handle);
993  }
994 
998  env& operator=(env&& other) noexcept {
999  if (this != &other) {
1000  std::swap(_handle, other._handle);
1001  }
1002  return *this;
1003  }
1004 
1008  ~env() noexcept {
1009  try { close(); } catch (...) {}
1010  }
1011 
1015  operator MDB_env*() const noexcept {
1016  return _handle;
1017  }
1018 
1022  MDB_env* handle() const noexcept {
1023  return _handle;
1024  }
1025 
1032  void sync(const bool force = true) {
1033  lmdb::env_sync(handle(), force);
1034  }
1035 
1042  void close() noexcept {
1043  if (handle()) {
1045  _handle = nullptr;
1046  }
1047  }
1048 
1050  int dead;
1051  lmdb::reader_check(handle(), &dead);
1052  return dead;
1053  }
1054 
1063  env& open(const char* const path,
1064  const unsigned int flags = default_flags,
1065  const mode mode = default_mode) {
1066  lmdb::env_open(handle(), path, flags, mode);
1067  return *this;
1068  }
1069 
1075  env& set_flags(const unsigned int flags,
1076  const bool onoff = true) {
1077  lmdb::env_set_flags(handle(), flags, onoff);
1078  return *this;
1079  }
1080 
1085  env& set_mapsize(const std::size_t size) {
1086  lmdb::env_set_mapsize(handle(), size);
1087  return *this;
1088  }
1089 
1094  env& set_max_readers(const unsigned int count) {
1096  return *this;
1097  }
1098 
1103  env& set_max_dbs(const MDB_dbi count) {
1104  lmdb::env_set_max_dbs(handle(), count);
1105  return *this;
1106  }
1107 };
1108 
1110 /* Resource Interface: Transactions */
1111 
1112 namespace lmdb {
1113  class txn;
1114 }
1115 
1122 class lmdb::txn {
1123 protected:
1124  MDB_txn* _handle{nullptr};
1125 
1126 public:
1127  static constexpr unsigned int default_flags = 0;
1128 
1137  static txn begin(MDB_env* const env,
1138  MDB_txn* const parent = nullptr,
1139  const unsigned int flags = default_flags) {
1140  MDB_txn* handle{nullptr};
1141  lmdb::txn_begin(env, parent, flags, &handle);
1142 #ifdef LMDBXX_DEBUG
1143  assert(handle != nullptr);
1144 #endif
1145  return txn{handle};
1146  }
1147 
1153  txn(MDB_txn* const handle) noexcept
1154  : _handle{handle} {}
1155 
1159  txn(txn&& other) noexcept {
1160  std::swap(_handle, other._handle);
1161  }
1162 
1166  txn& operator=(txn&& other) noexcept {
1167  if (this != &other) {
1168  std::swap(_handle, other._handle);
1169  }
1170  return *this;
1171  }
1172 
1176  ~txn() noexcept {
1177  if (_handle) {
1178  try { abort(); } catch (...) {}
1179  _handle = nullptr;
1180  }
1181  }
1182 
1186  operator MDB_txn*() const noexcept {
1187  return _handle;
1188  }
1189 
1193  MDB_txn* handle() const noexcept {
1194  return _handle;
1195  }
1196 
1200  MDB_env* env() const noexcept {
1201  return lmdb::txn_env(handle());
1202  }
1203 
1210  void commit() {
1211  auto h = _handle;
1212  _handle = nullptr;
1213  lmdb::txn_commit(h);
1214  }
1215 
1221  void abort() noexcept {
1222  auto h = _handle;
1223  _handle = nullptr;
1224  lmdb::txn_abort(h);
1225  }
1226 
1230  void reset() noexcept {
1232  }
1233 
1239  void renew() {
1241  }
1242 };
1243 
1245 /* Resource Interface: Databases */
1246 
1247 namespace lmdb {
1248  class dbi;
1249 }
1250 
1256 class lmdb::dbi {
1257 protected:
1258  MDB_dbi _handle{(std::numeric_limits<MDB_dbi>::max)()};
1259 
1260 public:
1261  static constexpr unsigned int default_flags = 0;
1262  static constexpr unsigned int default_put_flags = 0;
1263 
1272  static dbi
1273  open(MDB_txn* const txn,
1274  const char* const name = nullptr,
1275  const unsigned int flags = default_flags) {
1276  MDB_dbi handle{};
1277  lmdb::dbi_open(txn, name, flags, &handle);
1278  return dbi{handle};
1279  }
1280 
1286  dbi() noexcept
1287  : _handle{(std::numeric_limits<MDB_dbi>::max)()} {}
1288 
1294  dbi(const MDB_dbi handle) noexcept
1295  : _handle{handle} {}
1296 
1300  ~dbi() noexcept {
1301  if (_handle) {
1302  /* No need to call close() here. */
1303  }
1304  }
1305 
1309  operator MDB_dbi() const noexcept {
1310  return _handle;
1311  }
1312 
1316  MDB_dbi handle() const noexcept {
1317  return _handle;
1318  }
1319 
1326  MDB_stat stat(MDB_txn* const txn) const {
1327  MDB_stat result;
1328  lmdb::dbi_stat(txn, handle(), &result);
1329  return result;
1330  }
1331 
1338  unsigned int flags(MDB_txn* const txn) const {
1339  unsigned int result{};
1340  lmdb::dbi_flags(txn, handle(), &result);
1341  return result;
1342  }
1343 
1350  std::size_t size(MDB_txn* const txn) const {
1351  return stat(txn).ms_entries;
1352  }
1353 
1359  void drop(MDB_txn* const txn,
1360  const bool del = false) {
1362  }
1363 
1371  dbi& set_compare(MDB_txn* const txn,
1372  MDB_cmp_func* const cmp = nullptr) {
1373  lmdb::dbi_set_compare(txn, handle(), cmp);
1374  return *this;
1375  }
1376 
1386  bool get(MDB_txn* const txn,
1387  const std::string_view key,
1388  std::string_view& data) {
1389  const MDB_val keyV{key.size(), const_cast<char*>(key.data())};
1390  MDB_val dataV{data.size(), const_cast<char*>(data.data())};
1391  bool ret = lmdb::dbi_get(txn, handle(), &keyV, &dataV);
1392  if (ret) {
1393  data = std::string_view(static_cast<char*>(dataV.mv_data), dataV.mv_size);
1394  }
1395  return ret;
1396  }
1397 
1407  bool put(MDB_txn* const txn,
1408  const std::string_view key,
1409  std::string_view data,
1410  const unsigned int flags = default_put_flags) {
1411  const MDB_val keyV{key.size(), const_cast<char*>(key.data())};
1412  MDB_val dataV{data.size(), const_cast<char*>(data.data())};
1413  return lmdb::dbi_put(txn, handle(), &keyV, &dataV, flags);
1414  }
1415 
1423  bool del(MDB_txn* const txn,
1424  const std::string_view key) {
1425  const MDB_val keyV{key.size(), const_cast<char*>(key.data())};
1426  return lmdb::dbi_del(txn, handle(), &keyV);
1427  }
1428 
1437  bool del(MDB_txn* const txn,
1438  const std::string_view key,
1439  const std::string_view val) {
1440  const MDB_val keyV{key.size(), const_cast<char*>(key.data())};
1441  const MDB_val valV{val.size(), const_cast<char*>(val.data())};
1442  return lmdb::dbi_del(txn, handle(), &keyV, &valV);
1443  }
1444 };
1445 
1447 /* Resource Interface: Cursors */
1448 
1449 namespace lmdb {
1450  class cursor;
1451 }
1452 
1460 protected:
1461  MDB_cursor* _handle{nullptr};
1462 
1463 public:
1464  static constexpr unsigned int default_flags = 0;
1465 
1473  static cursor
1474  open(MDB_txn* const txn,
1475  const MDB_dbi dbi) {
1476  MDB_cursor* handle{};
1478 #ifdef LMDBXX_DEBUG
1479  assert(handle != nullptr);
1480 #endif
1481  return cursor{handle};
1482  }
1483 
1489  cursor(MDB_cursor* const handle) noexcept
1490  : _handle{handle} {}
1491 
1495  cursor(cursor&& other) noexcept {
1496  std::swap(_handle, other._handle);
1497  }
1498 
1502  cursor& operator=(cursor&& other) noexcept {
1503  if (this != &other) {
1504  std::swap(_handle, other._handle);
1505  }
1506  return *this;
1507  }
1508 
1512  ~cursor() noexcept {
1513  try { close(); } catch (...) {}
1514  }
1515 
1519  operator MDB_cursor*() const noexcept {
1520  return _handle;
1521  }
1522 
1526  MDB_cursor* handle() const noexcept {
1527  return _handle;
1528  }
1529 
1536  void close() noexcept {
1537  if (_handle) {
1539  _handle = nullptr;
1540  }
1541  }
1542 
1549  void renew(MDB_txn* const txn) {
1551  }
1552 
1556  MDB_txn* txn() const noexcept {
1557  return lmdb::cursor_txn(handle());
1558  }
1559 
1563  MDB_dbi dbi() const noexcept {
1564  return lmdb::cursor_dbi(handle());
1565  }
1566 
1574  bool get(std::string_view &key,
1575  const MDB_cursor_op op) {
1576  MDB_val keyV{key.size(), const_cast<char*>(key.data())};
1577  bool ret = lmdb::cursor_get(handle(), &keyV, nullptr, op);
1578  if (ret) {
1579  key = std::string_view(static_cast<char*>(keyV.mv_data), keyV.mv_size);
1580  }
1581  return ret;
1582  }
1583 
1592  bool get(std::string_view &key,
1593  std::string_view &val,
1594  const MDB_cursor_op op) {
1595  MDB_val keyV{key.size(), const_cast<char*>(key.data())};
1596  MDB_val valV{val.size(), const_cast<char*>(val.data())};
1597  bool ret = lmdb::cursor_get(handle(), &keyV, &valV, op);
1598  if (ret) {
1599  key = std::string_view(static_cast<char*>(keyV.mv_data), keyV.mv_size);
1600  val = std::string_view(static_cast<char*>(valV.mv_data), valV.mv_size);
1601  }
1602  return ret;
1603  }
1604 
1615  bool put(const std::string_view &key,
1616  const std::string_view &val,
1617  const unsigned int flags = 0) {
1618  MDB_val keyV{key.size(), const_cast<char*>(key.data())};
1619  MDB_val valV{val.size(), const_cast<char*>(val.data())};
1620  return lmdb::cursor_put(handle(), &keyV, &valV, flags);
1621  }
1622 
1629  void del(unsigned int flags = 0) {
1630  lmdb::cursor_del(handle(), flags);
1631  }
1632 
1636  size_t count() {
1637  std::size_t countp;
1638  lmdb::cursor_count(handle(), countp);
1639  return countp;
1640  }
1641 };
1642 
1643 namespace lmdb {
1649  template<typename T>
1650  static inline std::string_view ptr_to_sv(T* v) {
1651  return std::string_view(reinterpret_cast<char*>(v), sizeof(*v));
1652  }
1653 
1659  template<typename T>
1660  static inline std::string_view to_sv(const T &v) {
1661  return std::string_view(reinterpret_cast<const char*>(std::addressof(v)), sizeof(v));
1662  }
1663 
1669  template<typename T>
1670  static inline T* ptr_from_sv(std::string_view v) {
1671  if (v.size() != sizeof(T)) error::raise("from_sv", MDB_BAD_VALSIZE);
1672  return reinterpret_cast<T*>(const_cast<char*>(v.data()));
1673  }
1674 
1680  template<typename T>
1681  static inline T from_sv(std::string_view v) {
1682  if (v.size() != sizeof(T)) error::raise("from_sv", MDB_BAD_VALSIZE);
1683  T ret;
1684  std::memcpy(&ret, const_cast<char*>(v.data()), sizeof(T));
1685  return ret;
1686  }
1687 }
1688 
1690 
1691 #endif /* LMDBXX_H */
Exception class for MDB_BAD_DBI errors.
Definition: lmdb++.h:196
Exception class for MDB_CORRUPTED errors.
Definition: lmdb++.h:155
Resource class for MDB_cursor* handles.
Definition: lmdb++.h:1459
MDB_cursor * handle() const noexcept
Returns the underlying MDB_cursor* handle.
Definition: lmdb++.h:1526
static constexpr unsigned int default_flags
Definition: lmdb++.h:1464
MDB_txn * txn() const noexcept
Returns the cursor's transaction handle.
Definition: lmdb++.h:1556
MDB_cursor * _handle
Definition: lmdb++.h:1461
void close() noexcept
Closes this cursor.
Definition: lmdb++.h:1536
~cursor() noexcept
Destructor.
Definition: lmdb++.h:1512
bool put(const std::string_view &key, const std::string_view &val, const unsigned int flags=0)
Stores key/data pairs into the database.
Definition: lmdb++.h:1615
bool get(std::string_view &key, std::string_view &val, const MDB_cursor_op op)
Retrieves a key/value pair from the database.
Definition: lmdb++.h:1592
size_t count()
Return count of duplicates for current key.
Definition: lmdb++.h:1636
cursor(cursor &&other) noexcept
Move constructor.
Definition: lmdb++.h:1495
MDB_dbi dbi() const noexcept
Returns the cursor's database handle.
Definition: lmdb++.h:1563
static cursor open(MDB_txn *const txn, const MDB_dbi dbi)
Creates an LMDB cursor.
Definition: lmdb++.h:1474
cursor(MDB_cursor *const handle) noexcept
Constructor.
Definition: lmdb++.h:1489
void del(unsigned int flags=0)
Delete current key/data pair.
Definition: lmdb++.h:1629
cursor & operator=(cursor &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1502
bool get(std::string_view &key, const MDB_cursor_op op)
Retrieves a key from the database.
Definition: lmdb++.h:1574
void renew(MDB_txn *const txn)
Renews this cursor.
Definition: lmdb++.h:1549
Resource class for MDB_dbi handles.
Definition: lmdb++.h:1256
bool put(MDB_txn *const txn, const std::string_view key, std::string_view data, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1407
std::size_t size(MDB_txn *const txn) const
Returns the number of records in this database.
Definition: lmdb++.h:1350
static constexpr unsigned int default_put_flags
Definition: lmdb++.h:1262
dbi(const MDB_dbi handle) noexcept
Constructor.
Definition: lmdb++.h:1294
bool del(MDB_txn *const txn, const std::string_view key)
Removes a key from this database.
Definition: lmdb++.h:1423
~dbi() noexcept
Destructor.
Definition: lmdb++.h:1300
MDB_stat stat(MDB_txn *const txn) const
Returns statistics for this database.
Definition: lmdb++.h:1326
unsigned int flags(MDB_txn *const txn) const
Retrieves the flags for this database handle.
Definition: lmdb++.h:1338
dbi() noexcept
Constructor.
Definition: lmdb++.h:1286
static dbi open(MDB_txn *const txn, const char *const name=nullptr, const unsigned int flags=default_flags)
Opens a database handle.
Definition: lmdb++.h:1273
static constexpr unsigned int default_flags
Definition: lmdb++.h:1261
dbi & set_compare(MDB_txn *const txn, MDB_cmp_func *const cmp=nullptr)
Sets a custom key comparison function for this database.
Definition: lmdb++.h:1371
bool del(MDB_txn *const txn, const std::string_view key, const std::string_view val)
Removes a key/value pair from this database.
Definition: lmdb++.h:1437
void drop(MDB_txn *const txn, const bool del=false)
Definition: lmdb++.h:1359
MDB_dbi _handle
Definition: lmdb++.h:1258
MDB_dbi handle() const noexcept
Returns the underlying MDB_dbi handle.
Definition: lmdb++.h:1316
bool get(MDB_txn *const txn, const std::string_view key, std::string_view &data)
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1386
Resource class for MDB_env* handles.
Definition: lmdb++.h:948
void close() noexcept
Closes this environment, releasing the memory map.
Definition: lmdb++.h:1042
static constexpr mode default_mode
Definition: lmdb++.h:954
env & set_flags(const unsigned int flags, const bool onoff=true)
Definition: lmdb++.h:1075
~env() noexcept
Destructor.
Definition: lmdb++.h:1008
MDB_env * handle() const noexcept
Returns the underlying MDB_env* handle.
Definition: lmdb++.h:1022
MDB_env * _handle
Definition: lmdb++.h:950
env(MDB_env *const handle) noexcept
Constructor.
Definition: lmdb++.h:985
env(env &&other) noexcept
Move constructor.
Definition: lmdb++.h:991
env & operator=(env &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:998
env & open(const char *const path, const unsigned int flags=default_flags, const mode mode=default_mode)
Opens this environment.
Definition: lmdb++.h:1063
void sync(const bool force=true)
Flushes data buffers to disk.
Definition: lmdb++.h:1032
static constexpr unsigned int default_flags
Definition: lmdb++.h:953
static env create(const unsigned int flags=default_flags)
Creates a new LMDB environment.
Definition: lmdb++.h:962
int reader_check()
Definition: lmdb++.h:1049
env & set_max_readers(const unsigned int count)
Definition: lmdb++.h:1094
env & set_max_dbs(const MDB_dbi count)
Definition: lmdb++.h:1103
env & set_mapsize(const std::size_t size)
Definition: lmdb++.h:1085
Base class for LMDB exception conditions.
Definition: lmdb++.h:63
const int _code
Definition: lmdb++.h:65
error(const char *const origin, const int rc) noexcept
Constructor.
Definition: lmdb++.h:76
virtual const char * what() const noexcept
Returns the underlying LMDB error code.
Definition: lmdb++.h:98
static void raise(const char *origin, int rc)
Throws an error based on the given LMDB return code.
Definition: lmdb++.h:202
int code() const noexcept
Returns the underlying LMDB error code.
Definition: lmdb++.h:84
const char * origin() const noexcept
Returns the origin of the LMDB error.
Definition: lmdb++.h:91
Base class for fatal error conditions.
Definition: lmdb++.h:117
Exception class for MDB_KEYEXIST errors.
Definition: lmdb++.h:135
Base class for logic error conditions.
Definition: lmdb++.h:109
Exception class for MDB_MAP_FULL errors.
Definition: lmdb++.h:185
Exception class for MDB_NOTFOUND errors.
Definition: lmdb++.h:145
Exception class for MDB_PANIC errors.
Definition: lmdb++.h:165
Base class for runtime error conditions.
Definition: lmdb++.h:125
Resource class for MDB_txn* handles.
Definition: lmdb++.h:1122
void commit()
Commits this transaction.
Definition: lmdb++.h:1210
MDB_env * env() const noexcept
Returns the transaction's MDB_env* handle.
Definition: lmdb++.h:1200
txn & operator=(txn &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1166
void abort() noexcept
Aborts this transaction.
Definition: lmdb++.h:1221
MDB_txn * _handle
Definition: lmdb++.h:1124
void reset() noexcept
Resets this read-only transaction.
Definition: lmdb++.h:1230
static constexpr unsigned int default_flags
Definition: lmdb++.h:1127
~txn() noexcept
Destructor.
Definition: lmdb++.h:1176
void renew()
Renews this read-only transaction.
Definition: lmdb++.h:1239
txn(txn &&other) noexcept
Move constructor.
Definition: lmdb++.h:1159
txn(MDB_txn *const handle) noexcept
Constructor.
Definition: lmdb++.h:1153
static txn begin(MDB_env *const env, MDB_txn *const parent=nullptr, const unsigned int flags=default_flags)
Creates a new LMDB transaction.
Definition: lmdb++.h:1137
MDB_txn * handle() const noexcept
Returns the underlying MDB_txn* handle.
Definition: lmdb++.h:1193
Exception class for MDB_VERSION_MISMATCH errors.
Definition: lmdb++.h:175
<lmdb++.h> - C++17 wrapper for LMDB.
Definition: lmdb++.h:37
static void env_info(MDB_env *env, MDB_envinfo *stat)
Definition: lmdb++.h:347
static void * env_get_userctx(MDB_env *env)
Definition: lmdb++.h:515
static void dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
Definition: lmdb++.h:672
static void cursor_renew(MDB_txn *txn, MDB_cursor *cursor)
Definition: lmdb++.h:853
mdb_mode_t mode
Definition: lmdb++.h:38
static void env_copy_fd(MDB_env *env, mdb_filehandle_t fd, unsigned int flags)
Definition: lmdb++.h:315
static void txn_commit(MDB_txn *txn)
Definition: lmdb++.h:582
static void env_open(MDB_env *env, const char *path, unsigned int flags, mode mode)
Definition: lmdb++.h:279
static MDB_txn * cursor_txn(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:865
static void dbi_drop(MDB_txn *txn, MDB_dbi dbi, bool del)
Definition: lmdb++.h:694
static bool dbi_put(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:782
static void env_create(MDB_env **env)
Definition: lmdb++.h:267
static std::string_view to_sv(const T &v)
Creates a std::string_view that points to the memory occupied by v.
Definition: lmdb++.h:1660
static unsigned int env_get_max_keysize(MDB_env *env)
Definition: lmdb++.h:485
static void cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Definition: lmdb++.h:831
static void reader_check(MDB_env *env, int *dead)
Definition: lmdb++.h:521
static void env_get_fd(MDB_env *env, mdb_filehandle_t *fd)
Definition: lmdb++.h:421
static void cursor_del(MDB_cursor *cursor, unsigned int flags)
Definition: lmdb++.h:914
static T from_sv(std::string_view v)
Takes a std::string_view and dereferences it, returning a value of the parameterized type.
Definition: lmdb++.h:1681
static void dbi_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
Definition: lmdb++.h:736
static void dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
Definition: lmdb++.h:643
static void dbi_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:708
static void env_set_max_readers(MDB_env *env, unsigned int count)
Definition: lmdb++.h:447
static MDB_env * txn_env(MDB_txn *txn) noexcept
Definition: lmdb++.h:563
static void env_set_mapsize(MDB_env *env, std::size_t size)
Definition: lmdb++.h:434
static void env_set_max_dbs(MDB_env *env, MDB_dbi count)
Definition: lmdb++.h:473
static void env_close(MDB_env *env) noexcept
Definition: lmdb++.h:372
static void env_set_flags(MDB_env *env, unsigned int flags, bool onoff)
Definition: lmdb++.h:381
static void txn_renew(MDB_txn *txn)
Definition: lmdb++.h:610
static bool cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:898
static void cursor_close(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:844
static bool cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Definition: lmdb++.h:882
static void cursor_count(MDB_cursor *cursor, std::size_t &count)
Definition: lmdb++.h:927
static void env_get_max_readers(MDB_env *env, unsigned int *count)
Definition: lmdb++.h:460
static MDB_dbi cursor_dbi(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:873
static void txn_abort(MDB_txn *txn) noexcept
Definition: lmdb++.h:593
static void env_get_path(MDB_env *env, const char **path)
Definition: lmdb++.h:408
static void dbi_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Definition: lmdb++.h:658
static bool dbi_del(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, const MDB_val *data)
Definition: lmdb++.h:800
static bool dbi_get(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, MDB_val *data)
Definition: lmdb++.h:765
static void env_copy(MDB_env *env, const char *path, unsigned int flags)
Definition: lmdb++.h:295
static void txn_reset(MDB_txn *txn) noexcept
Definition: lmdb++.h:601
static void env_set_userctx(MDB_env *env, void *ctx)
Definition: lmdb++.h:500
static void dbi_close(MDB_env *env, MDB_dbi dbi) noexcept
Definition: lmdb++.h:685
static void env_stat(MDB_env *env, MDB_stat *stat)
Definition: lmdb++.h:334
static void env_sync(MDB_env *env, bool force)
Definition: lmdb++.h:360
static void dbi_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:722
static void env_get_flags(MDB_env *env, unsigned int *flags)
Definition: lmdb++.h:395
static void txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Definition: lmdb++.h:549
static T * ptr_from_sv(std::string_view v)
Takes a std::string_view and casts its pointer as a pointer to the parameterized type.
Definition: lmdb++.h:1670
static std::string_view ptr_to_sv(T *v)
Creates a std::string_view that points to the memory pointed to by v.
Definition: lmdb++.h:1650
static void dbi_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
Definition: lmdb++.h:750