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 
13 #ifndef __cplusplus
14 #error "<lmdb++.h> requires a C++ compiler"
15 #endif
16 
17 #if __cplusplus < 201103L
18 #error "<lmdb++.h> requires a C++11 compiler (CXXFLAGS='-std=c++11')"
19 #endif
20 
22 
23 #include <lmdb.h> /* for MDB_*, mdb_*() */
24 
25 #ifdef LMDBXX_DEBUG
26 #include <cassert> /* for assert() */
27 #endif
28 #include <cstddef> /* for std::size_t */
29 #include <cstdio> /* for std::snprintf() */
30 #include <cstring> /* for std::strlen() */
31 #include <stdexcept> /* for std::runtime_error */
32 #include <string> /* for std::string */
33 #include <type_traits> /* for std::is_pod<> */
34 
35 namespace lmdb {
36  using mode = mdb_mode_t;
37 }
38 
40 /* Error Handling */
41 
42 namespace lmdb {
43  class error;
44  class logic_error;
45  class fatal_error;
46  class runtime_error;
47  class key_exist_error;
48  class not_found_error;
49  class corrupted_error;
50  class panic_error;
51  class version_mismatch_error;
52  class map_full_error;
53  class bad_dbi_error;
54 }
55 
61 class lmdb::error : public std::runtime_error {
62 protected:
63  const int _code;
64 
65 public:
69  [[noreturn]] static inline void raise(const char* origin, int rc);
70 
74  error(const char* const origin,
75  const int rc) noexcept
76  : runtime_error{origin},
77  _code{rc} {}
78 
82  int code() const noexcept {
83  return _code;
84  }
85 
89  const char* origin() const noexcept {
90  return runtime_error::what();
91  }
92 
96  virtual const char* what() const noexcept {
97  static thread_local char buffer[1024];
98  std::snprintf(buffer, sizeof(buffer),
99  "%s: %s", origin(), ::mdb_strerror(code()));
100  return buffer;
101  }
102 };
103 
108 public:
109  using error::error;
110 };
111 
116 public:
117  using error::error;
118 };
119 
124 public:
125  using error::error;
126 };
127 
134 public:
135  using runtime_error::runtime_error;
136 };
137 
144 public:
145  using runtime_error::runtime_error;
146 };
147 
154 public:
155  using fatal_error::fatal_error;
156 };
157 
163 class lmdb::panic_error final : public lmdb::fatal_error {
164 public:
165  using fatal_error::fatal_error;
166 };
167 
174 public:
175  using fatal_error::fatal_error;
176 };
177 
184 public:
185  using runtime_error::runtime_error;
186 };
187 
195 public:
196  using runtime_error::runtime_error;
197 };
198 
199 inline void
200 lmdb::error::raise(const char* const origin,
201  const int rc) {
202  switch (rc) {
203  case MDB_KEYEXIST: throw key_exist_error{origin, rc};
204  case MDB_NOTFOUND: throw not_found_error{origin, rc};
205  case MDB_CORRUPTED: throw corrupted_error{origin, rc};
206  case MDB_PANIC: throw panic_error{origin, rc};
207  case MDB_VERSION_MISMATCH: throw version_mismatch_error{origin, rc};
208  case MDB_MAP_FULL: throw map_full_error{origin, rc};
209 #ifdef MDB_BAD_DBI
210  case MDB_BAD_DBI: throw bad_dbi_error{origin, rc};
211 #endif
212  default: throw lmdb::runtime_error{origin, rc};
213  }
214 }
215 
217 /* Procedural Interface: Metadata */
218 
219 namespace lmdb {
220  // TODO: mdb_version()
221  // TODO: mdb_strerror()
222 }
223 
225 /* Procedural Interface: Environment */
226 
227 namespace lmdb {
228  static inline void env_create(MDB_env** env);
229  static inline void env_open(MDB_env* env,
230  const char* path, unsigned int flags, mode mode);
231 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
232  static inline void env_copy(MDB_env* env, const char* path, unsigned int flags);
233  static inline void env_copy_fd(MDB_env* env, mdb_filehandle_t fd, unsigned int flags);
234 #else
235  static inline void env_copy(MDB_env* env, const char* path);
236  static inline void env_copy_fd(MDB_env* env, mdb_filehandle_t fd);
237 #endif
238  static inline void env_stat(MDB_env* env, MDB_stat* stat);
239  static inline void env_info(MDB_env* env, MDB_envinfo* stat);
240  static inline void env_sync(MDB_env* env, bool force);
241  static inline void env_close(MDB_env* env) noexcept;
242  static inline void env_set_flags(MDB_env* env, unsigned int flags, bool onoff);
243  static inline void env_get_flags(MDB_env* env, unsigned int* flags);
244  static inline void env_get_path(MDB_env* env, const char** path);
245  static inline void env_get_fd(MDB_env* env, mdb_filehandle_t* fd);
246  static inline void env_set_mapsize(MDB_env* env, std::size_t size);
247  static inline void env_set_max_readers(MDB_env* env, unsigned int count);
248  static inline void env_get_max_readers(MDB_env* env, unsigned int* count);
249  static inline void env_set_max_dbs(MDB_env* env, MDB_dbi count);
250  static inline unsigned int env_get_max_keysize(MDB_env* env);
251 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
252  static inline void env_set_userctx(MDB_env* env, void* ctx);
253  static inline void* env_get_userctx(MDB_env* env);
254 #endif
255  // TODO: mdb_env_set_assert()
256  // TODO: mdb_reader_list()
257  // TODO: mdb_reader_check()
258 }
259 
264 static inline void
265 lmdb::env_create(MDB_env** env) {
266  const int rc = ::mdb_env_create(env);
267  if (rc != MDB_SUCCESS) {
268  error::raise("mdb_env_create", rc);
269  }
270 }
271 
276 static inline void
277 lmdb::env_open(MDB_env* const env,
278  const char* const path,
279  const unsigned int flags,
280  const mode mode) {
281  const int rc = ::mdb_env_open(env, path, flags, mode);
282  if (rc != MDB_SUCCESS) {
283  error::raise("mdb_env_open", rc);
284  }
285 }
286 
292 static inline void
293 lmdb::env_copy(MDB_env* const env,
294 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
295  const char* const path,
296  const unsigned int flags = 0) {
297  const int rc = ::mdb_env_copy2(env, path, flags);
298 #else
299  const char* const path) {
300  const int rc = ::mdb_env_copy(env, path);
301 #endif
302  if (rc != MDB_SUCCESS) {
303  error::raise("mdb_env_copy2", rc);
304  }
305 }
306 
312 static inline void
313 lmdb::env_copy_fd(MDB_env* const env,
314 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
315  const mdb_filehandle_t fd,
316  const unsigned int flags = 0) {
317  const int rc = ::mdb_env_copyfd2(env, fd, flags);
318 #else
319  const mdb_filehandle_t fd) {
320  const int rc = ::mdb_env_copyfd(env, fd);
321 #endif
322  if (rc != MDB_SUCCESS) {
323  error::raise("mdb_env_copyfd2", rc);
324  }
325 }
326 
331 static inline void
332 lmdb::env_stat(MDB_env* const env,
333  MDB_stat* const stat) {
334  const int rc = ::mdb_env_stat(env, stat);
335  if (rc != MDB_SUCCESS) {
336  error::raise("mdb_env_stat", rc);
337  }
338 }
339 
344 static inline void
345 lmdb::env_info(MDB_env* const env,
346  MDB_envinfo* const stat) {
347  const int rc = ::mdb_env_info(env, stat);
348  if (rc != MDB_SUCCESS) {
349  error::raise("mdb_env_info", rc);
350  }
351 }
352 
357 static inline void
358 lmdb::env_sync(MDB_env* const env,
359  const bool force = true) {
360  const int rc = ::mdb_env_sync(env, force);
361  if (rc != MDB_SUCCESS) {
362  error::raise("mdb_env_sync", rc);
363  }
364 }
365 
369 static inline void
370 lmdb::env_close(MDB_env* const env) noexcept {
371  ::mdb_env_close(env);
372 }
373 
378 static inline void
379 lmdb::env_set_flags(MDB_env* const env,
380  const unsigned int flags,
381  const bool onoff = true) {
382  const int rc = ::mdb_env_set_flags(env, flags, onoff ? 1 : 0);
383  if (rc != MDB_SUCCESS) {
384  error::raise("mdb_env_set_flags", rc);
385  }
386 }
387 
392 static inline void
393 lmdb::env_get_flags(MDB_env* const env,
394  unsigned int* const flags) {
395  const int rc = ::mdb_env_get_flags(env, flags);
396  if (rc != MDB_SUCCESS) {
397  error::raise("mdb_env_get_flags", rc);
398  }
399 }
400 
405 static inline void
406 lmdb::env_get_path(MDB_env* const env,
407  const char** path) {
408  const int rc = ::mdb_env_get_path(env, path);
409  if (rc != MDB_SUCCESS) {
410  error::raise("mdb_env_get_path", rc);
411  }
412 }
413 
418 static inline void
419 lmdb::env_get_fd(MDB_env* const env,
420  mdb_filehandle_t* const fd) {
421  const int rc = ::mdb_env_get_fd(env, fd);
422  if (rc != MDB_SUCCESS) {
423  error::raise("mdb_env_get_fd", rc);
424  }
425 }
426 
431 static inline void
432 lmdb::env_set_mapsize(MDB_env* const env,
433  const std::size_t size) {
434  const int rc = ::mdb_env_set_mapsize(env, size);
435  if (rc != MDB_SUCCESS) {
436  error::raise("mdb_env_set_mapsize", rc);
437  }
438 }
439 
444 static inline void
445 lmdb::env_set_max_readers(MDB_env* const env,
446  const unsigned int count) {
447  const int rc = ::mdb_env_set_maxreaders(env, count);
448  if (rc != MDB_SUCCESS) {
449  error::raise("mdb_env_set_maxreaders", rc);
450  }
451 }
452 
457 static inline void
458 lmdb::env_get_max_readers(MDB_env* const env,
459  unsigned int* const count) {
460  const int rc = ::mdb_env_get_maxreaders(env, count);
461  if (rc != MDB_SUCCESS) {
462  error::raise("mdb_env_get_maxreaders", rc);
463  }
464 }
465 
470 static inline void
471 lmdb::env_set_max_dbs(MDB_env* const env,
472  const MDB_dbi count) {
473  const int rc = ::mdb_env_set_maxdbs(env, count);
474  if (rc != MDB_SUCCESS) {
475  error::raise("mdb_env_set_maxdbs", rc);
476  }
477 }
478 
482 static inline unsigned int
483 lmdb::env_get_max_keysize(MDB_env* const env) {
484  const int rc = ::mdb_env_get_maxkeysize(env);
485 #ifdef LMDBXX_DEBUG
486  assert(rc >= 0);
487 #endif
488  return static_cast<unsigned int>(rc);
489 }
490 
491 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
492 
497 static inline void
498 lmdb::env_set_userctx(MDB_env* const env,
499  void* const ctx) {
500  const int rc = ::mdb_env_set_userctx(env, ctx);
501  if (rc != MDB_SUCCESS) {
502  error::raise("mdb_env_set_userctx", rc);
503  }
504 }
505 #endif
506 
507 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
508 
512 static inline void*
513 lmdb::env_get_userctx(MDB_env* const env) {
514  return ::mdb_env_get_userctx(env);
515 }
516 #endif
517 
519 /* Procedural Interface: Transactions */
520 
521 namespace lmdb {
522  static inline void txn_begin(
523  MDB_env* env, MDB_txn* parent, unsigned int flags, MDB_txn** txn);
524  static inline MDB_env* txn_env(MDB_txn* const txn) noexcept;
525  static inline void txn_commit(MDB_txn* txn);
526  static inline void txn_abort(MDB_txn* txn) noexcept;
527  static inline void txn_reset(MDB_txn* txn) noexcept;
528  static inline void txn_renew(MDB_txn* txn);
529 }
530 
535 static inline void
536 lmdb::txn_begin(MDB_env* const env,
537  MDB_txn* const parent,
538  const unsigned int flags,
539  MDB_txn** txn) {
540  const int rc = ::mdb_txn_begin(env, parent, flags, txn);
541  if (rc != MDB_SUCCESS) {
542  error::raise("mdb_txn_begin", rc);
543  }
544 }
545 
549 static inline MDB_env*
550 lmdb::txn_env(MDB_txn* const txn) noexcept {
551  return ::mdb_txn_env(txn);
552 }
553 
558 static inline void
559 lmdb::txn_commit(MDB_txn* const txn) {
560  const int rc = ::mdb_txn_commit(txn);
561  if (rc != MDB_SUCCESS) {
562  error::raise("mdb_txn_commit", rc);
563  }
564 }
565 
569 static inline void
570 lmdb::txn_abort(MDB_txn* const txn) noexcept {
571  ::mdb_txn_abort(txn);
572 }
573 
577 static inline void
578 lmdb::txn_reset(MDB_txn* const txn) noexcept {
579  ::mdb_txn_reset(txn);
580 }
581 
586 static inline void
587 lmdb::txn_renew(MDB_txn* const txn) {
588  const int rc = ::mdb_txn_renew(txn);
589  if (rc != MDB_SUCCESS) {
590  error::raise("mdb_txn_renew", rc);
591  }
592 }
593 
595 /* Procedural Interface: Databases */
596 
597 namespace lmdb {
598  static inline void dbi_open(
599  MDB_txn* txn, const char* name, unsigned int flags, MDB_dbi* dbi);
600  static inline void dbi_stat(MDB_txn* txn, MDB_dbi dbi, MDB_stat* stat);
601  static inline void dbi_flags(MDB_txn* txn, MDB_dbi dbi, unsigned int* flags);
602  static inline void dbi_close(MDB_env* env, MDB_dbi dbi) noexcept;
603  static inline void dbi_drop(MDB_txn* txn, MDB_dbi dbi, bool del);
604  static inline void dbi_set_compare(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
605  static inline void dbi_set_dupsort(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
606  static inline void dbi_set_relfunc(MDB_txn* txn, MDB_dbi dbi, MDB_rel_func* rel);
607  static inline void dbi_set_relctx(MDB_txn* txn, MDB_dbi dbi, void* ctx);
608  static inline bool dbi_get(MDB_txn* txn, MDB_dbi dbi, MDB_val* key, MDB_val* data);
609  static inline bool dbi_put(MDB_txn* txn, MDB_dbi dbi, MDB_val* key, MDB_val* data, unsigned int flags);
610  static inline bool dbi_del(MDB_txn* txn, MDB_dbi dbi, MDB_val* key, MDB_val* data);
611  // TODO: mdb_cmp()
612  // TODO: mdb_dcmp()
613 }
614 
619 static inline void
620 lmdb::dbi_open(MDB_txn* const txn,
621  const char* const name,
622  const unsigned int flags,
623  MDB_dbi* const dbi) {
624  const int rc = ::mdb_dbi_open(txn, name, flags, dbi);
625  if (rc != MDB_SUCCESS) {
626  error::raise("mdb_dbi_open", rc);
627  }
628 }
629 
634 static inline void
635 lmdb::dbi_stat(MDB_txn* const txn,
636  const MDB_dbi dbi,
637  MDB_stat* const result) {
638  const int rc = ::mdb_stat(txn, dbi, result);
639  if (rc != MDB_SUCCESS) {
640  error::raise("mdb_stat", rc);
641  }
642 }
643 
648 static inline void
649 lmdb::dbi_flags(MDB_txn* const txn,
650  const MDB_dbi dbi,
651  unsigned int* const flags) {
652  const int rc = ::mdb_dbi_flags(txn, dbi, flags);
653  if (rc != MDB_SUCCESS) {
654  error::raise("mdb_dbi_flags", rc);
655  }
656 }
657 
661 static inline void
662 lmdb::dbi_close(MDB_env* const env,
663  const MDB_dbi dbi) noexcept {
664  ::mdb_dbi_close(env, dbi);
665 }
666 
670 static inline void
671 lmdb::dbi_drop(MDB_txn* const txn,
672  const MDB_dbi dbi,
673  const bool del = false) {
674  const int rc = ::mdb_drop(txn, dbi, del ? 1 : 0);
675  if (rc != MDB_SUCCESS) {
676  error::raise("mdb_drop", rc);
677  }
678 }
679 
684 static inline void
685 lmdb::dbi_set_compare(MDB_txn* const txn,
686  const MDB_dbi dbi,
687  MDB_cmp_func* const cmp = nullptr) {
688  const int rc = ::mdb_set_compare(txn, dbi, cmp);
689  if (rc != MDB_SUCCESS) {
690  error::raise("mdb_set_compare", rc);
691  }
692 }
693 
698 static inline void
699 lmdb::dbi_set_dupsort(MDB_txn* const txn,
700  const MDB_dbi dbi,
701  MDB_cmp_func* const cmp = nullptr) {
702  const int rc = ::mdb_set_dupsort(txn, dbi, cmp);
703  if (rc != MDB_SUCCESS) {
704  error::raise("mdb_set_dupsort", rc);
705  }
706 }
707 
712 static inline void
713 lmdb::dbi_set_relfunc(MDB_txn* const txn,
714  const MDB_dbi dbi,
715  MDB_rel_func* const rel) {
716  const int rc = ::mdb_set_relfunc(txn, dbi, rel);
717  if (rc != MDB_SUCCESS) {
718  error::raise("mdb_set_relfunc", rc);
719  }
720 }
721 
726 static inline void
727 lmdb::dbi_set_relctx(MDB_txn* const txn,
728  const MDB_dbi dbi,
729  void* const ctx) {
730  const int rc = ::mdb_set_relctx(txn, dbi, ctx);
731  if (rc != MDB_SUCCESS) {
732  error::raise("mdb_set_relctx", rc);
733  }
734 }
735 
741 static inline bool
742 lmdb::dbi_get(MDB_txn* const txn,
743  const MDB_dbi dbi,
744  MDB_val* const key,
745  MDB_val* const data) {
746  const int rc = ::mdb_get(txn, dbi, key, data);
747  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
748  error::raise("mdb_get", rc);
749  }
750  return (rc == MDB_SUCCESS);
751 }
752 
758 static inline bool
759 lmdb::dbi_put(MDB_txn* const txn,
760  const MDB_dbi dbi,
761  MDB_val* const key,
762  MDB_val* const data,
763  const unsigned int flags = 0) {
764  const int rc = ::mdb_put(txn, dbi, key, data, flags);
765  if (rc != MDB_SUCCESS && rc != MDB_KEYEXIST) {
766  error::raise("mdb_put", rc);
767  }
768  return (rc == MDB_SUCCESS);
769 }
770 
776 static inline bool
777 lmdb::dbi_del(MDB_txn* const txn,
778  const MDB_dbi dbi,
779  MDB_val* const key,
780  MDB_val* const data = nullptr) {
781  const int rc = ::mdb_del(txn, dbi, key, data);
782  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
783  error::raise("mdb_del", rc);
784  }
785  return (rc == MDB_SUCCESS);
786 }
787 
789 /* Procedural Interface: Cursors */
790 
791 namespace lmdb {
792  static inline void cursor_open(MDB_txn* txn, MDB_dbi dbi, MDB_cursor** cursor);
793  static inline void cursor_close(MDB_cursor* cursor) noexcept;
794  static inline void cursor_renew(MDB_txn* txn, MDB_cursor* cursor);
795  static inline MDB_txn* cursor_txn(MDB_cursor* cursor) noexcept;
796  static inline MDB_dbi cursor_dbi(MDB_cursor* cursor) noexcept;
797  static inline bool cursor_get(MDB_cursor* cursor, MDB_val* key, MDB_val* data, MDB_cursor_op op);
798  static inline void cursor_put(MDB_cursor* cursor, MDB_val* key, MDB_val* data, unsigned int flags);
799  static inline void cursor_del(MDB_cursor* cursor, unsigned int flags);
800  static inline void cursor_count(MDB_cursor* cursor, std::size_t& count);
801 }
802 
807 static inline void
808 lmdb::cursor_open(MDB_txn* const txn,
809  const MDB_dbi dbi,
810  MDB_cursor** const cursor) {
811  const int rc = ::mdb_cursor_open(txn, dbi, cursor);
812  if (rc != MDB_SUCCESS) {
813  error::raise("mdb_cursor_open", rc);
814  }
815 }
816 
820 static inline void
821 lmdb::cursor_close(MDB_cursor* const cursor) noexcept {
822  ::mdb_cursor_close(cursor);
823 }
824 
829 static inline void
830 lmdb::cursor_renew(MDB_txn* const txn,
831  MDB_cursor* const cursor) {
832  const int rc = ::mdb_cursor_renew(txn, cursor);
833  if (rc != MDB_SUCCESS) {
834  error::raise("mdb_cursor_renew", rc);
835  }
836 }
837 
841 static inline MDB_txn*
842 lmdb::cursor_txn(MDB_cursor* const cursor) noexcept {
843  return ::mdb_cursor_txn(cursor);
844 }
845 
849 static inline MDB_dbi
850 lmdb::cursor_dbi(MDB_cursor* const cursor) noexcept {
851  return ::mdb_cursor_dbi(cursor);
852 }
853 
858 static inline bool
859 lmdb::cursor_get(MDB_cursor* const cursor,
860  MDB_val* const key,
861  MDB_val* const data,
862  const MDB_cursor_op op) {
863  const int rc = ::mdb_cursor_get(cursor, key, data, op);
864  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
865  error::raise("mdb_cursor_get", rc);
866  }
867  return (rc == MDB_SUCCESS);
868 }
869 
874 static inline void
875 lmdb::cursor_put(MDB_cursor* const cursor,
876  MDB_val* const key,
877  MDB_val* const data,
878  const unsigned int flags = 0) {
879  const int rc = ::mdb_cursor_put(cursor, key, data, flags);
880  if (rc != MDB_SUCCESS) {
881  error::raise("mdb_cursor_put", rc);
882  }
883 }
884 
889 static inline void
890 lmdb::cursor_del(MDB_cursor* const cursor,
891  const unsigned int flags = 0) {
892  const int rc = ::mdb_cursor_del(cursor, flags);
893  if (rc != MDB_SUCCESS) {
894  error::raise("mdb_cursor_del", rc);
895  }
896 }
897 
902 static inline void
903 lmdb::cursor_count(MDB_cursor* const cursor,
904  std::size_t& count) {
905  const int rc = ::mdb_cursor_count(cursor, &count);
906  if (rc != MDB_SUCCESS) {
907  error::raise("mdb_cursor_count", rc);
908  }
909 }
910 
912 /* Resource Interface: Values */
913 
914 namespace lmdb {
915  class val;
916 }
917 
924 class lmdb::val {
925 protected:
926  MDB_val _val;
927 
928 public:
932  val() noexcept = default;
933 
937  val(const std::string& data) noexcept
938  : val{data.data(), data.size()} {}
939 
943  val(const char* const data) noexcept
944  : val{data, std::strlen(data)} {}
945 
949  val(const void* const data,
950  const std::size_t size) noexcept
951  : _val{size, const_cast<void*>(data)} {}
952 
956  val(val&& other) noexcept = default;
957 
961  val& operator=(val&& other) noexcept = default;
962 
966  ~val() noexcept = default;
967 
971  operator MDB_val*() noexcept {
972  return &_val;
973  }
974 
978  operator const MDB_val*() const noexcept {
979  return &_val;
980  }
981 
985  std::size_t size() const noexcept {
986  return _val.mv_size;
987  }
988 
992  template<typename T>
993  T* data() noexcept {
994  return reinterpret_cast<T*>(_val.mv_data);
995  }
996 
1000  template<typename T>
1001  const T* data() const noexcept {
1002  return reinterpret_cast<T*>(_val.mv_data);
1003  }
1004 
1008  char* data() noexcept {
1009  return reinterpret_cast<char*>(_val.mv_data);
1010  }
1011 
1015  const char* data() const noexcept {
1016  return reinterpret_cast<char*>(_val.mv_data);
1017  }
1018 
1022  template<typename T>
1023  val& assign(const T* const data,
1024  const std::size_t size) noexcept {
1025  _val.mv_size = size;
1026  _val.mv_data = const_cast<void*>(reinterpret_cast<const void*>(data));
1027  return *this;
1028  }
1029 
1033  val& assign(const char* const data) noexcept {
1034  return assign(data, std::strlen(data));
1035  }
1036 
1040  val& assign(const std::string& data) noexcept {
1041  return assign(data.data(), data.size());
1042  }
1043 };
1044 
1045 #ifndef __COVERITY__
1046 static_assert(std::is_pod<lmdb::val>::value, "lmdb::val must be a POD type");
1047 static_assert(sizeof(lmdb::val) == sizeof(MDB_val), "sizeof(lmdb::val) != sizeof(MDB_val)");
1048 #endif
1049 
1051 /* Resource Interface: Environment */
1052 
1053 namespace lmdb {
1054  class env;
1055 }
1056 
1063 class lmdb::env {
1064 protected:
1065  MDB_env* _handle{nullptr};
1066 
1067 public:
1068  static constexpr unsigned int default_flags = 0;
1069  static constexpr mode default_mode = 0644; /* -rw-r--r-- */
1070 
1077  static env create(const unsigned int flags = default_flags) {
1078  MDB_env* handle{nullptr};
1079  lmdb::env_create(&handle);
1080 #ifdef LMDBXX_DEBUG
1081  assert(handle != nullptr);
1082 #endif
1083  if (flags) {
1084  try {
1085  lmdb::env_set_flags(handle, flags);
1086  }
1087  catch (const lmdb::error&) {
1088  lmdb::env_close(handle);
1089  throw;
1090  }
1091  }
1092  return env{handle};
1093  }
1094 
1100  env(MDB_env* const handle) noexcept
1101  : _handle{handle} {}
1102 
1106  env(env&& other) noexcept {
1107  std::swap(_handle, other._handle);
1108  }
1109 
1113  env& operator=(env&& other) noexcept {
1114  if (this != &other) {
1115  std::swap(_handle, other._handle);
1116  }
1117  return *this;
1118  }
1119 
1123  ~env() noexcept {
1124  try { close(); } catch (...) {}
1125  }
1126 
1130  operator MDB_env*() const noexcept {
1131  return _handle;
1132  }
1133 
1137  MDB_env* handle() const noexcept {
1138  return _handle;
1139  }
1140 
1147  void sync(const bool force = true) {
1148  lmdb::env_sync(handle(), force);
1149  }
1150 
1157  void close() noexcept {
1158  if (handle()) {
1159  lmdb::env_close(handle());
1160  _handle = nullptr;
1161  }
1162  }
1163 
1172  env& open(const char* const path,
1173  const unsigned int flags = default_flags,
1174  const mode mode = default_mode) {
1175  lmdb::env_open(handle(), path, flags, mode);
1176  return *this;
1177  }
1178 
1184  env& set_flags(const unsigned int flags,
1185  const bool onoff = true) {
1186  lmdb::env_set_flags(handle(), flags, onoff);
1187  return *this;
1188  }
1189 
1194  env& set_mapsize(const std::size_t size) {
1195  lmdb::env_set_mapsize(handle(), size);
1196  return *this;
1197  }
1198 
1203  env& set_max_readers(const unsigned int count) {
1204  lmdb::env_set_max_readers(handle(), count);
1205  return *this;
1206  }
1207 
1212  env& set_max_dbs(const MDB_dbi count) {
1213  lmdb::env_set_max_dbs(handle(), count);
1214  return *this;
1215  }
1216 };
1217 
1219 /* Resource Interface: Transactions */
1220 
1221 namespace lmdb {
1222  class txn;
1223 }
1224 
1231 class lmdb::txn {
1232 protected:
1233  MDB_txn* _handle{nullptr};
1234 
1235 public:
1236  static constexpr unsigned int default_flags = 0;
1237 
1246  static txn begin(MDB_env* const env,
1247  MDB_txn* const parent = nullptr,
1248  const unsigned int flags = default_flags) {
1249  MDB_txn* handle{nullptr};
1250  lmdb::txn_begin(env, parent, flags, &handle);
1251 #ifdef LMDBXX_DEBUG
1252  assert(handle != nullptr);
1253 #endif
1254  return txn{handle};
1255  }
1256 
1262  txn(MDB_txn* const handle) noexcept
1263  : _handle{handle} {}
1264 
1268  txn(txn&& other) noexcept {
1269  std::swap(_handle, other._handle);
1270  }
1271 
1275  txn& operator=(txn&& other) noexcept {
1276  if (this != &other) {
1277  std::swap(_handle, other._handle);
1278  }
1279  return *this;
1280  }
1281 
1285  ~txn() noexcept {
1286  if (_handle) {
1287  try { abort(); } catch (...) {}
1288  _handle = nullptr;
1289  }
1290  }
1291 
1295  operator MDB_txn*() const noexcept {
1296  return _handle;
1297  }
1298 
1302  MDB_txn* handle() const noexcept {
1303  return _handle;
1304  }
1305 
1309  MDB_env* env() const noexcept {
1310  return lmdb::txn_env(handle());
1311  }
1312 
1319  void commit() {
1320  lmdb::txn_commit(_handle);
1321  _handle = nullptr;
1322  }
1323 
1329  void abort() noexcept {
1330  lmdb::txn_abort(_handle);
1331  _handle = nullptr;
1332  }
1333 
1337  void reset() noexcept {
1338  lmdb::txn_reset(_handle);
1339  }
1340 
1346  void renew() {
1347  lmdb::txn_renew(_handle);
1348  }
1349 };
1350 
1352 /* Resource Interface: Databases */
1353 
1354 namespace lmdb {
1355  class dbi;
1356 }
1357 
1364 class lmdb::dbi {
1365 protected:
1366  MDB_dbi _handle{0};
1367 
1368 public:
1369  static constexpr unsigned int default_flags = 0;
1370  static constexpr unsigned int default_put_flags = 0;
1371 
1380  static dbi
1381  open(MDB_txn* const txn,
1382  const char* const name = nullptr,
1383  const unsigned int flags = default_flags) {
1384  MDB_dbi handle{};
1385  lmdb::dbi_open(txn, name, flags, &handle);
1386  return dbi{handle};
1387  }
1388 
1394  dbi(const MDB_dbi handle) noexcept
1395  : _handle{handle} {}
1396 
1400  dbi(dbi&& other) noexcept {
1401  std::swap(_handle, other._handle);
1402  }
1403 
1407  dbi& operator=(dbi&& other) noexcept {
1408  if (this != &other) {
1409  std::swap(_handle, other._handle);
1410  }
1411  return *this;
1412  }
1413 
1417  ~dbi() noexcept {
1418  if (_handle) {
1419  /* No need to call close() here. */
1420  }
1421  }
1422 
1426  operator MDB_dbi() const noexcept {
1427  return _handle;
1428  }
1429 
1433  MDB_dbi handle() const noexcept {
1434  return _handle;
1435  }
1436 
1443  MDB_stat stat(MDB_txn* const txn) const {
1444  MDB_stat result;
1445  lmdb::dbi_stat(txn, handle(), &result);
1446  return result;
1447  }
1448 
1455  unsigned int flags(MDB_txn* const txn) const {
1456  unsigned int result{};
1457  lmdb::dbi_flags(txn, handle(), &result);
1458  return result;
1459  }
1460 
1467  std::size_t size(MDB_txn* const txn) const {
1468  return stat(txn).ms_entries;
1469  }
1470 
1476  void drop(MDB_txn* const txn,
1477  const bool del = false) {
1478  lmdb::dbi_drop(txn, handle(), del);
1479  }
1480 
1488  dbi& set_compare(MDB_txn* const txn,
1489  MDB_cmp_func* const cmp = nullptr) {
1490  lmdb::dbi_set_compare(txn, handle(), cmp);
1491  return *this;
1492  }
1493 
1501  template<typename K>
1502  bool get(MDB_txn* const txn,
1503  const K& key) const {
1504  lmdb::val k{&key, sizeof(K)};
1505  lmdb::val v{};
1506  return lmdb::dbi_get(txn, handle(), k, v);
1507  }
1508 
1517  template<typename K, typename V>
1518  bool get(MDB_txn* const txn,
1519  const K& key,
1520  V& val) const {
1521  lmdb::val k{&key, sizeof(K)};
1522  lmdb::val v{};
1523  const bool result = lmdb::dbi_get(txn, handle(), k, v);
1524  if (result) {
1525  val = *v.data<const V>();
1526  }
1527  return result;
1528  }
1529 
1538  template<typename V>
1539  bool get(MDB_txn* const txn,
1540  const char* const key,
1541  V& val) const {
1542  lmdb::val k{key, std::strlen(key)};
1543  lmdb::val v{};
1544  const bool result = lmdb::dbi_get(txn, handle(), k, v);
1545  if (result) {
1546  val = *v.data<const V>();
1547  }
1548  return result;
1549  }
1550 
1559  template<typename K>
1560  bool put(MDB_txn* const txn,
1561  const K& key,
1562  const unsigned int flags = default_put_flags) {
1563  lmdb::val k{&key, sizeof(K)};
1564  lmdb::val v{};
1565  return lmdb::dbi_put(txn, handle(), k, v, flags);
1566  }
1567 
1577  template<typename K, typename V>
1578  bool put(MDB_txn* const txn,
1579  const K& key,
1580  const V& val,
1581  const unsigned int flags = default_put_flags) {
1582  lmdb::val k{&key, sizeof(K)};
1583  lmdb::val v{&val, sizeof(V)};
1584  return lmdb::dbi_put(txn, handle(), k, v, flags);
1585  }
1586 
1596  template<typename V>
1597  bool put(MDB_txn* const txn,
1598  const char* const key,
1599  const V& val,
1600  const unsigned int flags = default_put_flags) {
1601  lmdb::val k{key, std::strlen(key)};
1602  lmdb::val v{&val, sizeof(V)};
1603  return lmdb::dbi_put(txn, handle(), k, v, flags);
1604  }
1605 
1615  bool put(MDB_txn* const txn,
1616  const char* const key,
1617  const char* const val,
1618  const unsigned int flags = default_put_flags) {
1619  lmdb::val k{key, std::strlen(key)};
1620  lmdb::val v{val, std::strlen(val)};
1621  return lmdb::dbi_put(txn, handle(), k, v, flags);
1622  }
1623 
1631  template<typename K>
1632  bool del(MDB_txn* const txn,
1633  const K& key) {
1634  lmdb::val k{&key, sizeof(K)};
1635  return lmdb::dbi_del(txn, handle(), k, nullptr);
1636  }
1637 };
1638 
1640 /* Resource Interface: Cursors */
1641 
1642 namespace lmdb {
1643  class cursor;
1644 }
1645 
1653 protected:
1654  MDB_cursor* _handle{nullptr};
1655 
1656 public:
1657  static constexpr unsigned int default_flags = 0;
1658 
1666  static cursor
1667  open(MDB_txn* const txn,
1668  const MDB_dbi dbi) {
1669  MDB_cursor* handle{};
1670  lmdb::cursor_open(txn, dbi, &handle);
1671 #ifdef LMDBXX_DEBUG
1672  assert(handle != nullptr);
1673 #endif
1674  return cursor{handle};
1675  }
1676 
1682  cursor(MDB_cursor* const handle) noexcept
1683  : _handle{handle} {}
1684 
1688  cursor(cursor&& other) noexcept {
1689  std::swap(_handle, other._handle);
1690  }
1691 
1695  cursor& operator=(cursor&& other) noexcept {
1696  if (this != &other) {
1697  std::swap(_handle, other._handle);
1698  }
1699  return *this;
1700  }
1701 
1705  ~cursor() noexcept {
1706  try { close(); } catch (...) {}
1707  }
1708 
1712  operator MDB_cursor*() const noexcept {
1713  return _handle;
1714  }
1715 
1719  MDB_cursor* handle() const noexcept {
1720  return _handle;
1721  }
1722 
1729  void close() noexcept {
1730  if (_handle) {
1731  lmdb::cursor_close(_handle);
1732  _handle = nullptr;
1733  }
1734  }
1735 
1742  void renew(MDB_txn* const txn) {
1743  lmdb::cursor_renew(txn, handle());
1744  }
1745 
1749  MDB_txn* txn() const noexcept {
1750  return lmdb::cursor_txn(handle());
1751  }
1752 
1756  MDB_dbi dbi() const noexcept {
1757  return lmdb::cursor_dbi(handle());
1758  }
1759 
1767  bool get(MDB_val* const key,
1768  const MDB_cursor_op op) {
1769  return get(key, nullptr, op);
1770  }
1771 
1779  bool get(lmdb::val& key,
1780  const MDB_cursor_op op) {
1781  return get(key, nullptr, op);
1782  }
1783 
1792  bool get(MDB_val* const key,
1793  MDB_val* const val,
1794  const MDB_cursor_op op) {
1795  return lmdb::cursor_get(handle(), key, val, op);
1796  }
1797 
1806  bool get(lmdb::val& key,
1807  lmdb::val& val,
1808  const MDB_cursor_op op) {
1809  return lmdb::cursor_get(handle(), key, val, op);
1810  }
1811 
1820  bool get(std::string& key,
1821  std::string& val,
1822  const MDB_cursor_op op) {
1823  lmdb::val k{}, v{};
1824  const bool found = get(k, v, op);
1825  if (found) {
1826  key.assign(k.data(), k.size());
1827  val.assign(v.data(), v.size());
1828  }
1829  return found;
1830  }
1831 
1839  template<typename K>
1840  bool find(const K& key,
1841  const MDB_cursor_op op = MDB_SET) {
1842  lmdb::val k{&key, sizeof(K)};
1843  return get(k, nullptr, op);
1844  }
1845 };
1846 
1848 
1849 #endif /* LMDBXX_H */
static void env_create(MDB_env **env)
Definition: lmdb++.h:265
static void cursor_renew(MDB_txn *txn, MDB_cursor *cursor)
Definition: lmdb++.h:830
static MDB_env * txn_env(MDB_txn *const txn) noexcept
Definition: lmdb++.h:550
static void txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Definition: lmdb++.h:536
static void env_open(MDB_env *env, const char *path, unsigned int flags, mode mode)
Definition: lmdb++.h:277
val(const void *const data, const std::size_t size) noexcept
Constructor.
Definition: lmdb++.h:949
bool put(MDB_txn *const txn, const char *const key, const V &val, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1597
Exception class for MDB_PANIC errors.
Definition: lmdb++.h:163
env & operator=(env &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1113
cursor(MDB_cursor *const handle) noexcept
Constructor.
Definition: lmdb++.h:1682
static cursor open(MDB_txn *const txn, const MDB_dbi dbi)
Creates an LMDB cursor.
Definition: lmdb++.h:1667
bool put(MDB_txn *const txn, const K &key, const V &val, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1578
static void env_set_max_readers(MDB_env *env, unsigned int count)
Definition: lmdb++.h:445
Base class for LMDB exception conditions.
Definition: lmdb++.h:61
Base class for fatal error conditions.
Definition: lmdb++.h:115
static void env_stat(MDB_env *env, MDB_stat *stat)
Definition: lmdb++.h:332
Exception class for MDB_CORRUPTED errors.
Definition: lmdb++.h:153
const T * data() const noexcept
Returns a pointer to the data;.
Definition: lmdb++.h:1001
static void dbi_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
Definition: lmdb++.h:713
unsigned int flags(MDB_txn *const txn) const
Retrieves the flags for this database handle.
Definition: lmdb++.h:1455
static void env_sync(MDB_env *env, bool force)
Definition: lmdb++.h:358
cursor(cursor &&other) noexcept
Move constructor.
Definition: lmdb++.h:1688
static void cursor_del(MDB_cursor *cursor, unsigned int flags)
Definition: lmdb++.h:890
static void txn_reset(MDB_txn *txn) noexcept
Definition: lmdb++.h:578
MDB_stat stat(MDB_txn *const txn) const
Returns statistics for this database.
Definition: lmdb++.h:1443
dbi(dbi &&other) noexcept
Move constructor.
Definition: lmdb++.h:1400
env & open(const char *const path, const unsigned int flags=default_flags, const mode mode=default_mode)
Opens this environment.
Definition: lmdb++.h:1172
static void dbi_drop(MDB_txn *txn, MDB_dbi dbi, bool del)
Definition: lmdb++.h:671
int code() const noexcept
Returns the underlying LMDB error code.
Definition: lmdb++.h:82
static void env_set_mapsize(MDB_env *env, std::size_t size)
Definition: lmdb++.h:432
static void dbi_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
Definition: lmdb++.h:727
char * data() noexcept
Returns a pointer to the data;.
Definition: lmdb++.h:1008
Wrapper class for MDB_val structures.
Definition: lmdb++.h:924
val & assign(const char *const data) noexcept
Assigns the value.
Definition: lmdb++.h:1033
static void env_get_max_readers(MDB_env *env, unsigned int *count)
Definition: lmdb++.h:458
Resource class for MDB_cursor* handles.
Definition: lmdb++.h:1652
static void env_get_path(MDB_env *env, const char **path)
Definition: lmdb++.h:406
static void dbi_close(MDB_env *env, MDB_dbi dbi) noexcept
Definition: lmdb++.h:662
MDB_dbi handle() const noexcept
Returns the underlying MDB_dbi handle.
Definition: lmdb++.h:1433
static void cursor_close(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:821
static void env_set_userctx(MDB_env *env, void *ctx)
Definition: lmdb++.h:498
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:1246
env & set_flags(const unsigned int flags, const bool onoff=true)
Definition: lmdb++.h:1184
~val() noexcept=default
Destructor.
virtual const char * what() const noexcept
Returns the underlying LMDB error code.
Definition: lmdb++.h:96
env(MDB_env *const handle) noexcept
Constructor.
Definition: lmdb++.h:1100
MDB_env * handle() const noexcept
Returns the underlying MDB_env* handle.
Definition: lmdb++.h:1137
txn(txn &&other) noexcept
Move constructor.
Definition: lmdb++.h:1268
dbi(const MDB_dbi handle) noexcept
Constructor.
Definition: lmdb++.h:1394
void renew(MDB_txn *const txn)
Renews this cursor.
Definition: lmdb++.h:1742
static void env_set_max_dbs(MDB_env *env, MDB_dbi count)
Definition: lmdb++.h:471
static void env_close(MDB_env *env) noexcept
Definition: lmdb++.h:370
MDB_cursor * handle() const noexcept
Returns the underlying MDB_cursor* handle.
Definition: lmdb++.h:1719
MDB_txn * txn() const noexcept
Returns the cursor's transaction handle.
Definition: lmdb++.h:1749
static void env_get_flags(MDB_env *env, unsigned int *flags)
Definition: lmdb++.h:393
MDB_dbi dbi() const noexcept
Returns the cursor's database handle.
Definition: lmdb++.h:1756
void close() noexcept
Closes this cursor.
Definition: lmdb++.h:1729
val() noexcept=default
Default constructor.
mdb_mode_t mode
Definition: lmdb++.h:36
static void env_copy(MDB_env *env, const char *path, unsigned int flags)
Definition: lmdb++.h:293
void drop(MDB_txn *const txn, const bool del=false)
Definition: lmdb++.h:1476
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:1381
Exception class for MDB_BAD_DBI errors.
Definition: lmdb++.h:194
static void dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
Definition: lmdb++.h:620
cursor & operator=(cursor &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1695
bool put(MDB_txn *const txn, const K &key, const unsigned int flags=default_put_flags)
Stores a key into this database.
Definition: lmdb++.h:1560
static bool dbi_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data)
Definition: lmdb++.h:742
txn(MDB_txn *const handle) noexcept
Constructor.
Definition: lmdb++.h:1262
void abort() noexcept
Aborts this transaction.
Definition: lmdb++.h:1329
T * data() noexcept
Returns a pointer to the data;.
Definition: lmdb++.h:993
void sync(const bool force=true)
Flushes data buffers to disk.
Definition: lmdb++.h:1147
const int _code
Definition: lmdb++.h:63
void reset() noexcept
Resets this read-only transaction.
Definition: lmdb++.h:1337
error(const char *const origin, const int rc) noexcept
Constructor.
Definition: lmdb++.h:74
Exception class for MDB_KEYEXIST errors.
Definition: lmdb++.h:133
const char * origin() const noexcept
Returns the origin of the LMDB error.
Definition: lmdb++.h:89
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:1488
val(const char *const data) noexcept
Constructor.
Definition: lmdb++.h:943
MDB_val _val
Definition: lmdb++.h:926
void close() noexcept
Closes this environment, releasing the memory map.
Definition: lmdb++.h:1157
val & assign(const T *const data, const std::size_t size) noexcept
Assigns the value.
Definition: lmdb++.h:1023
Resource class for MDB_txn* handles.
Definition: lmdb++.h:1231
static MDB_dbi cursor_dbi(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:850
static void raise(const char *origin, int rc)
Throws an error based on the given LMDB return code.
Definition: lmdb++.h:200
bool del(MDB_txn *const txn, const K &key)
Removes a key/value pair from this database.
Definition: lmdb++.h:1632
MDB_env * env() const noexcept
Returns the transaction's MDB_env* handle.
Definition: lmdb++.h:1309
static void dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
Definition: lmdb++.h:649
static bool cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Definition: lmdb++.h:859
static void env_info(MDB_env *env, MDB_envinfo *stat)
Definition: lmdb++.h:345
Resource class for MDB_dbi handles.
Definition: lmdb++.h:1364
txn & operator=(txn &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1275
Resource class for MDB_env* handles.
Definition: lmdb++.h:1063
void renew()
Renews this read-only transaction.
Definition: lmdb++.h:1346
dbi & operator=(dbi &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1407
static MDB_txn * cursor_txn(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:842
~env() noexcept
Destructor.
Definition: lmdb++.h:1123
static void txn_renew(MDB_txn *txn)
Definition: lmdb++.h:587
const char * data() const noexcept
Returns a pointer to the data;.
Definition: lmdb++.h:1015
std::size_t size(MDB_txn *const txn) const
Returns the number of records in this database.
Definition: lmdb++.h:1467
static void cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Definition: lmdb++.h:808
~cursor() noexcept
Destructor.
Definition: lmdb++.h:1705
static unsigned int env_get_max_keysize(MDB_env *env)
Definition: lmdb++.h:483
- C++11 wrapper for LMDB.
Definition: lmdb++.h:35
~dbi() noexcept
Destructor.
Definition: lmdb++.h:1417
env(env &&other) noexcept
Move constructor.
Definition: lmdb++.h:1106
std::size_t size() const noexcept
Returns the size of the data.
Definition: lmdb++.h:985
static bool dbi_del(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data)
Definition: lmdb++.h:777
static void dbi_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Definition: lmdb++.h:635
static env create(const unsigned int flags=default_flags)
Creates a new LMDB environment.
Definition: lmdb++.h:1077
bool find(const K &key, const MDB_cursor_op op=MDB_SET)
Positions this cursor at the given key.
Definition: lmdb++.h:1840
env & set_max_readers(const unsigned int count)
Definition: lmdb++.h:1203
static void env_set_flags(MDB_env *env, unsigned int flags, bool onoff)
Definition: lmdb++.h:379
bool put(MDB_txn *const txn, const char *const key, const char *const val, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1615
static void txn_commit(MDB_txn *txn)
Definition: lmdb++.h:559
static void env_copy_fd(MDB_env *env, mdb_filehandle_t fd, unsigned int flags)
Definition: lmdb++.h:313
static bool dbi_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:759
env & set_mapsize(const std::size_t size)
Definition: lmdb++.h:1194
Exception class for MDB_MAP_FULL errors.
Definition: lmdb++.h:183
static void * env_get_userctx(MDB_env *env)
Definition: lmdb++.h:513
static void cursor_count(MDB_cursor *cursor, std::size_t &count)
Definition: lmdb++.h:903
MDB_txn * handle() const noexcept
Returns the underlying MDB_txn* handle.
Definition: lmdb++.h:1302
static void dbi_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:699
~txn() noexcept
Destructor.
Definition: lmdb++.h:1285
Base class for logic error conditions.
Definition: lmdb++.h:107
val & operator=(val &&other) noexcept=default
Move assignment operator.
Exception class for MDB_NOTFOUND errors.
Definition: lmdb++.h:143
Base class for runtime error conditions.
Definition: lmdb++.h:123
env & set_max_dbs(const MDB_dbi count)
Definition: lmdb++.h:1212
static void cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:875
static void env_get_fd(MDB_env *env, mdb_filehandle_t *fd)
Definition: lmdb++.h:419
val & assign(const std::string &data) noexcept
Assigns the value.
Definition: lmdb++.h:1040
Exception class for MDB_VERSION_MISMATCH errors.
Definition: lmdb++.h:173
void commit()
Commits this transaction.
Definition: lmdb++.h:1319
static void dbi_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:685
static void txn_abort(MDB_txn *txn) noexcept
Definition: lmdb++.h:570