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 #if !defined(_MSC_VER) || _MSC_VER < 1900
19 #error "<lmdb++.h> requires a C++11 compiler (CXXFLAGS='-std=c++11')"
20 #endif // _MSC_VER check
21 #endif
22 
24 
25 #include <lmdb.h> /* for MDB_*, mdb_*() */
26 
27 #ifdef LMDBXX_DEBUG
28 #include <cassert> /* for assert() */
29 #endif
30 #include <cstddef> /* for std::size_t */
31 #include <cstdio> /* for std::snprintf() */
32 #include <cstring> /* for std::strlen() */
33 #include <stdexcept> /* for std::runtime_error */
34 #include <string> /* for std::string */
35 #include <type_traits> /* for std::is_pod<> */
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  // TODO: mdb_reader_check()
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)
494 
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)
510 
514 static inline void*
515 lmdb::env_get_userctx(MDB_env* const env) {
516  return ::mdb_env_get_userctx(env);
517 }
518 #endif
519 
521 /* Procedural Interface: Transactions */
522 
523 namespace lmdb {
524  static inline void txn_begin(
525  MDB_env* env, MDB_txn* parent, unsigned int flags, MDB_txn** txn);
526  static inline MDB_env* txn_env(MDB_txn* txn) noexcept;
527 #ifdef LMDBXX_TXN_ID
528  static inline std::size_t txn_id(MDB_txn* txn) noexcept;
529 #endif
530  static inline void txn_commit(MDB_txn* txn);
531  static inline void txn_abort(MDB_txn* txn) noexcept;
532  static inline void txn_reset(MDB_txn* txn) noexcept;
533  static inline void txn_renew(MDB_txn* txn);
534 }
535 
540 static inline void
541 lmdb::txn_begin(MDB_env* const env,
542  MDB_txn* const parent,
543  const unsigned int flags,
544  MDB_txn** txn) {
545  const int rc = ::mdb_txn_begin(env, parent, flags, txn);
546  if (rc != MDB_SUCCESS) {
547  error::raise("mdb_txn_begin", rc);
548  }
549 }
550 
554 static inline MDB_env*
555 lmdb::txn_env(MDB_txn* const txn) noexcept {
556  return ::mdb_txn_env(txn);
557 }
558 
559 #ifdef LMDBXX_TXN_ID
560 
563 static inline std::size_t
564 lmdb::txn_id(MDB_txn* const txn) noexcept {
565  return ::mdb_txn_id(txn);
566 }
567 #endif
568 
573 static inline void
574 lmdb::txn_commit(MDB_txn* const txn) {
575  const int rc = ::mdb_txn_commit(txn);
576  if (rc != MDB_SUCCESS) {
577  error::raise("mdb_txn_commit", rc);
578  }
579 }
580 
584 static inline void
585 lmdb::txn_abort(MDB_txn* const txn) noexcept {
586  ::mdb_txn_abort(txn);
587 }
588 
592 static inline void
593 lmdb::txn_reset(MDB_txn* const txn) noexcept {
594  ::mdb_txn_reset(txn);
595 }
596 
601 static inline void
602 lmdb::txn_renew(MDB_txn* const txn) {
603  const int rc = ::mdb_txn_renew(txn);
604  if (rc != MDB_SUCCESS) {
605  error::raise("mdb_txn_renew", rc);
606  }
607 }
608 
610 /* Procedural Interface: Databases */
611 
612 namespace lmdb {
613  static inline void dbi_open(
614  MDB_txn* txn, const char* name, unsigned int flags, MDB_dbi* dbi);
615  static inline void dbi_stat(MDB_txn* txn, MDB_dbi dbi, MDB_stat* stat);
616  static inline void dbi_flags(MDB_txn* txn, MDB_dbi dbi, unsigned int* flags);
617  static inline void dbi_close(MDB_env* env, MDB_dbi dbi) noexcept;
618  static inline void dbi_drop(MDB_txn* txn, MDB_dbi dbi, bool del);
619  static inline void dbi_set_compare(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
620  static inline void dbi_set_dupsort(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
621  static inline void dbi_set_relfunc(MDB_txn* txn, MDB_dbi dbi, MDB_rel_func* rel);
622  static inline void dbi_set_relctx(MDB_txn* txn, MDB_dbi dbi, void* ctx);
623  static inline bool dbi_get(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, MDB_val* data);
624  static inline bool dbi_put(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, MDB_val* data, unsigned int flags);
625  static inline bool dbi_del(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, const MDB_val* data);
626  // TODO: mdb_cmp()
627  // TODO: mdb_dcmp()
628 }
629 
634 static inline void
635 lmdb::dbi_open(MDB_txn* const txn,
636  const char* const name,
637  const unsigned int flags,
638  MDB_dbi* const dbi) {
639  const int rc = ::mdb_dbi_open(txn, name, flags, dbi);
640  if (rc != MDB_SUCCESS) {
641  error::raise("mdb_dbi_open", rc);
642  }
643 }
644 
649 static inline void
650 lmdb::dbi_stat(MDB_txn* const txn,
651  const MDB_dbi dbi,
652  MDB_stat* const result) {
653  const int rc = ::mdb_stat(txn, dbi, result);
654  if (rc != MDB_SUCCESS) {
655  error::raise("mdb_stat", rc);
656  }
657 }
658 
663 static inline void
664 lmdb::dbi_flags(MDB_txn* const txn,
665  const MDB_dbi dbi,
666  unsigned int* const flags) {
667  const int rc = ::mdb_dbi_flags(txn, dbi, flags);
668  if (rc != MDB_SUCCESS) {
669  error::raise("mdb_dbi_flags", rc);
670  }
671 }
672 
676 static inline void
677 lmdb::dbi_close(MDB_env* const env,
678  const MDB_dbi dbi) noexcept {
679  ::mdb_dbi_close(env, dbi);
680 }
681 
685 static inline void
686 lmdb::dbi_drop(MDB_txn* const txn,
687  const MDB_dbi dbi,
688  const bool del = false) {
689  const int rc = ::mdb_drop(txn, dbi, del ? 1 : 0);
690  if (rc != MDB_SUCCESS) {
691  error::raise("mdb_drop", rc);
692  }
693 }
694 
699 static inline void
700 lmdb::dbi_set_compare(MDB_txn* const txn,
701  const MDB_dbi dbi,
702  MDB_cmp_func* const cmp = nullptr) {
703  const int rc = ::mdb_set_compare(txn, dbi, cmp);
704  if (rc != MDB_SUCCESS) {
705  error::raise("mdb_set_compare", rc);
706  }
707 }
708 
713 static inline void
714 lmdb::dbi_set_dupsort(MDB_txn* const txn,
715  const MDB_dbi dbi,
716  MDB_cmp_func* const cmp = nullptr) {
717  const int rc = ::mdb_set_dupsort(txn, dbi, cmp);
718  if (rc != MDB_SUCCESS) {
719  error::raise("mdb_set_dupsort", rc);
720  }
721 }
722 
727 static inline void
728 lmdb::dbi_set_relfunc(MDB_txn* const txn,
729  const MDB_dbi dbi,
730  MDB_rel_func* const rel) {
731  const int rc = ::mdb_set_relfunc(txn, dbi, rel);
732  if (rc != MDB_SUCCESS) {
733  error::raise("mdb_set_relfunc", rc);
734  }
735 }
736 
741 static inline void
742 lmdb::dbi_set_relctx(MDB_txn* const txn,
743  const MDB_dbi dbi,
744  void* const ctx) {
745  const int rc = ::mdb_set_relctx(txn, dbi, ctx);
746  if (rc != MDB_SUCCESS) {
747  error::raise("mdb_set_relctx", rc);
748  }
749 }
750 
756 static inline bool
757 lmdb::dbi_get(MDB_txn* const txn,
758  const MDB_dbi dbi,
759  const MDB_val* const key,
760  MDB_val* const data) {
761  const int rc = ::mdb_get(txn, dbi, const_cast<MDB_val*>(key), data);
762  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
763  error::raise("mdb_get", rc);
764  }
765  return (rc == MDB_SUCCESS);
766 }
767 
773 static inline bool
774 lmdb::dbi_put(MDB_txn* const txn,
775  const MDB_dbi dbi,
776  const MDB_val* const key,
777  MDB_val* const data,
778  const unsigned int flags = 0) {
779  const int rc = ::mdb_put(txn, dbi, const_cast<MDB_val*>(key), data, flags);
780  if (rc != MDB_SUCCESS && rc != MDB_KEYEXIST) {
781  error::raise("mdb_put", rc);
782  }
783  return (rc == MDB_SUCCESS);
784 }
785 
791 static inline bool
792 lmdb::dbi_del(MDB_txn* const txn,
793  const MDB_dbi dbi,
794  const MDB_val* const key,
795  const MDB_val* const data = nullptr) {
796  const int rc = ::mdb_del(txn, dbi, const_cast<MDB_val*>(key), const_cast<MDB_val*>(data));
797  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
798  error::raise("mdb_del", rc);
799  }
800  return (rc == MDB_SUCCESS);
801 }
802 
804 /* Procedural Interface: Cursors */
805 
806 namespace lmdb {
807  static inline void cursor_open(MDB_txn* txn, MDB_dbi dbi, MDB_cursor** cursor);
808  static inline void cursor_close(MDB_cursor* cursor) noexcept;
809  static inline void cursor_renew(MDB_txn* txn, MDB_cursor* cursor);
810  static inline MDB_txn* cursor_txn(MDB_cursor* cursor) noexcept;
811  static inline MDB_dbi cursor_dbi(MDB_cursor* cursor) noexcept;
812  static inline bool cursor_get(MDB_cursor* cursor, MDB_val* key, MDB_val* data, MDB_cursor_op op);
813  static inline void cursor_put(MDB_cursor* cursor, MDB_val* key, MDB_val* data, unsigned int flags);
814  static inline void cursor_del(MDB_cursor* cursor, unsigned int flags);
815  static inline void cursor_count(MDB_cursor* cursor, std::size_t& count);
816 }
817 
822 static inline void
823 lmdb::cursor_open(MDB_txn* const txn,
824  const MDB_dbi dbi,
825  MDB_cursor** const cursor) {
826  const int rc = ::mdb_cursor_open(txn, dbi, cursor);
827  if (rc != MDB_SUCCESS) {
828  error::raise("mdb_cursor_open", rc);
829  }
830 }
831 
835 static inline void
836 lmdb::cursor_close(MDB_cursor* const cursor) noexcept {
837  ::mdb_cursor_close(cursor);
838 }
839 
844 static inline void
845 lmdb::cursor_renew(MDB_txn* const txn,
846  MDB_cursor* const cursor) {
847  const int rc = ::mdb_cursor_renew(txn, cursor);
848  if (rc != MDB_SUCCESS) {
849  error::raise("mdb_cursor_renew", rc);
850  }
851 }
852 
856 static inline MDB_txn*
857 lmdb::cursor_txn(MDB_cursor* const cursor) noexcept {
858  return ::mdb_cursor_txn(cursor);
859 }
860 
864 static inline MDB_dbi
865 lmdb::cursor_dbi(MDB_cursor* const cursor) noexcept {
866  return ::mdb_cursor_dbi(cursor);
867 }
868 
873 static inline bool
874 lmdb::cursor_get(MDB_cursor* const cursor,
875  MDB_val* const key,
876  MDB_val* const data,
877  const MDB_cursor_op op) {
878  const int rc = ::mdb_cursor_get(cursor, key, data, op);
879  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
880  error::raise("mdb_cursor_get", rc);
881  }
882  return (rc == MDB_SUCCESS);
883 }
884 
889 static inline void
890 lmdb::cursor_put(MDB_cursor* const cursor,
891  MDB_val* const key,
892  MDB_val* const data,
893  const unsigned int flags = 0) {
894  const int rc = ::mdb_cursor_put(cursor, key, data, flags);
895  if (rc != MDB_SUCCESS) {
896  error::raise("mdb_cursor_put", rc);
897  }
898 }
899 
904 static inline void
905 lmdb::cursor_del(MDB_cursor* const cursor,
906  const unsigned int flags = 0) {
907  const int rc = ::mdb_cursor_del(cursor, flags);
908  if (rc != MDB_SUCCESS) {
909  error::raise("mdb_cursor_del", rc);
910  }
911 }
912 
917 static inline void
918 lmdb::cursor_count(MDB_cursor* const cursor,
919  std::size_t& count) {
920  const int rc = ::mdb_cursor_count(cursor, &count);
921  if (rc != MDB_SUCCESS) {
922  error::raise("mdb_cursor_count", rc);
923  }
924 }
925 
927 /* Resource Interface: Values */
928 
929 namespace lmdb {
930  class val;
931 }
932 
939 class lmdb::val {
940 protected:
941  MDB_val _val;
942 
943 public:
947  val() noexcept = default;
948 
952  val(const std::string& data) noexcept
953  : val{data.data(), data.size()} {}
954 
958  val(const char* const data) noexcept
959  : val{data, std::strlen(data)} {}
960 
964  val(const void* const data,
965  const std::size_t size) noexcept
966  : _val{size, const_cast<void*>(data)} {}
967 
971  val(val&& other) noexcept = default;
972 
976  val& operator=(val&& other) noexcept = default;
977 
981  ~val() noexcept = default;
982 
986  operator MDB_val*() noexcept {
987  return &_val;
988  }
989 
993  operator const MDB_val*() const noexcept {
994  return &_val;
995  }
996 
1000  bool empty() const noexcept {
1001  return size() == 0;
1002  }
1003 
1007  std::size_t size() const noexcept {
1008  return _val.mv_size;
1009  }
1010 
1014  template<typename T>
1015  T* data() noexcept {
1016  return reinterpret_cast<T*>(_val.mv_data);
1017  }
1018 
1022  template<typename T>
1023  const T* data() const noexcept {
1024  return reinterpret_cast<T*>(_val.mv_data);
1025  }
1026 
1030  char* data() noexcept {
1031  return reinterpret_cast<char*>(_val.mv_data);
1032  }
1033 
1037  const char* data() const noexcept {
1038  return reinterpret_cast<char*>(_val.mv_data);
1039  }
1040 
1044  template<typename T>
1045  val& assign(const T* const data,
1046  const std::size_t size) noexcept {
1047  _val.mv_size = size;
1048  _val.mv_data = const_cast<void*>(reinterpret_cast<const void*>(data));
1049  return *this;
1050  }
1051 
1055  val& assign(const char* const data) noexcept {
1056  return assign(data, std::strlen(data));
1057  }
1058 
1062  val& assign(const std::string& data) noexcept {
1063  return assign(data.data(), data.size());
1064  }
1065 };
1066 
1067 #if !(defined(__COVERITY__) || defined(_MSC_VER))
1068 static_assert(std::is_pod<lmdb::val>::value, "lmdb::val must be a POD type");
1069 static_assert(sizeof(lmdb::val) == sizeof(MDB_val), "sizeof(lmdb::val) != sizeof(MDB_val)");
1070 #endif
1071 
1073 /* Resource Interface: Environment */
1074 
1075 namespace lmdb {
1076  class env;
1077 }
1078 
1085 class lmdb::env {
1086 protected:
1087  MDB_env* _handle{nullptr};
1088 
1089 public:
1090  static constexpr unsigned int default_flags = 0;
1091  static constexpr mode default_mode = 0644; /* -rw-r--r-- */
1092 
1099  static env create(const unsigned int flags = default_flags) {
1100  MDB_env* handle{nullptr};
1102 #ifdef LMDBXX_DEBUG
1103  assert(handle != nullptr);
1104 #endif
1105  if (flags) {
1106  try {
1107  lmdb::env_set_flags(handle, flags);
1108  }
1109  catch (const lmdb::error&) {
1111  throw;
1112  }
1113  }
1114  return env{handle};
1115  }
1116 
1122  env(MDB_env* const handle) noexcept
1123  : _handle{handle} {}
1124 
1128  env(env&& other) noexcept {
1129  std::swap(_handle, other._handle);
1130  }
1131 
1135  env& operator=(env&& other) noexcept {
1136  if (this != &other) {
1137  std::swap(_handle, other._handle);
1138  }
1139  return *this;
1140  }
1141 
1145  ~env() noexcept {
1146  try { close(); } catch (...) {}
1147  }
1148 
1152  operator MDB_env*() const noexcept {
1153  return _handle;
1154  }
1155 
1159  MDB_env* handle() const noexcept {
1160  return _handle;
1161  }
1162 
1169  void sync(const bool force = true) {
1170  lmdb::env_sync(handle(), force);
1171  }
1172 
1179  void close() noexcept {
1180  if (handle()) {
1182  _handle = nullptr;
1183  }
1184  }
1185 
1194  env& open(const char* const path,
1195  const unsigned int flags = default_flags,
1196  const mode mode = default_mode) {
1197  lmdb::env_open(handle(), path, flags, mode);
1198  return *this;
1199  }
1200 
1206  env& set_flags(const unsigned int flags,
1207  const bool onoff = true) {
1208  lmdb::env_set_flags(handle(), flags, onoff);
1209  return *this;
1210  }
1211 
1216  env& set_mapsize(const std::size_t size) {
1217  lmdb::env_set_mapsize(handle(), size);
1218  return *this;
1219  }
1220 
1225  env& set_max_readers(const unsigned int count) {
1227  return *this;
1228  }
1229 
1234  env& set_max_dbs(const MDB_dbi count) {
1235  lmdb::env_set_max_dbs(handle(), count);
1236  return *this;
1237  }
1238 };
1239 
1241 /* Resource Interface: Transactions */
1242 
1243 namespace lmdb {
1244  class txn;
1245 }
1246 
1253 class lmdb::txn {
1254 protected:
1255  MDB_txn* _handle{nullptr};
1256 
1257 public:
1258  static constexpr unsigned int default_flags = 0;
1259 
1268  static txn begin(MDB_env* const env,
1269  MDB_txn* const parent = nullptr,
1270  const unsigned int flags = default_flags) {
1271  MDB_txn* handle{nullptr};
1272  lmdb::txn_begin(env, parent, flags, &handle);
1273 #ifdef LMDBXX_DEBUG
1274  assert(handle != nullptr);
1275 #endif
1276  return txn{handle};
1277  }
1278 
1284  txn(MDB_txn* const handle) noexcept
1285  : _handle{handle} {}
1286 
1290  txn(txn&& other) noexcept {
1291  std::swap(_handle, other._handle);
1292  }
1293 
1297  txn& operator=(txn&& other) noexcept {
1298  if (this != &other) {
1299  std::swap(_handle, other._handle);
1300  }
1301  return *this;
1302  }
1303 
1307  ~txn() noexcept {
1308  if (_handle) {
1309  try { abort(); } catch (...) {}
1310  _handle = nullptr;
1311  }
1312  }
1313 
1317  operator MDB_txn*() const noexcept {
1318  return _handle;
1319  }
1320 
1324  MDB_txn* handle() const noexcept {
1325  return _handle;
1326  }
1327 
1331  MDB_env* env() const noexcept {
1332  return lmdb::txn_env(handle());
1333  }
1334 
1341  void commit() {
1343  _handle = nullptr;
1344  }
1345 
1351  void abort() noexcept {
1353  _handle = nullptr;
1354  }
1355 
1359  void reset() noexcept {
1361  }
1362 
1368  void renew() {
1370  }
1371 };
1372 
1374 /* Resource Interface: Databases */
1375 
1376 namespace lmdb {
1377  class dbi;
1378 }
1379 
1386 class lmdb::dbi {
1387 protected:
1388  MDB_dbi _handle{0};
1389 
1390 public:
1391  static constexpr unsigned int default_flags = 0;
1392  static constexpr unsigned int default_put_flags = 0;
1393 
1402  static dbi
1403  open(MDB_txn* const txn,
1404  const char* const name = nullptr,
1405  const unsigned int flags = default_flags) {
1406  MDB_dbi handle{};
1407  lmdb::dbi_open(txn, name, flags, &handle);
1408  return dbi{handle};
1409  }
1410 
1416  dbi(const MDB_dbi handle) noexcept
1417  : _handle{handle} {}
1418 
1422  dbi(dbi&& other) noexcept {
1423  std::swap(_handle, other._handle);
1424  }
1425 
1429  dbi& operator=(dbi&& other) noexcept {
1430  if (this != &other) {
1431  std::swap(_handle, other._handle);
1432  }
1433  return *this;
1434  }
1435 
1439  ~dbi() noexcept {
1440  if (_handle) {
1441  /* No need to call close() here. */
1442  }
1443  }
1444 
1448  operator MDB_dbi() const noexcept {
1449  return _handle;
1450  }
1451 
1455  MDB_dbi handle() const noexcept {
1456  return _handle;
1457  }
1458 
1465  MDB_stat stat(MDB_txn* const txn) const {
1466  MDB_stat result;
1467  lmdb::dbi_stat(txn, handle(), &result);
1468  return result;
1469  }
1470 
1477  unsigned int flags(MDB_txn* const txn) const {
1478  unsigned int result{};
1479  lmdb::dbi_flags(txn, handle(), &result);
1480  return result;
1481  }
1482 
1489  std::size_t size(MDB_txn* const txn) const {
1490  return stat(txn).ms_entries;
1491  }
1492 
1498  void drop(MDB_txn* const txn,
1499  const bool del = false) {
1501  }
1502 
1510  dbi& set_compare(MDB_txn* const txn,
1511  MDB_cmp_func* const cmp = nullptr) {
1512  lmdb::dbi_set_compare(txn, handle(), cmp);
1513  return *this;
1514  }
1515 
1524  bool get(MDB_txn* const txn,
1525  const val& key,
1526  val& data) {
1527  return lmdb::dbi_get(txn, handle(), key, data);
1528  }
1529 
1537  template<typename K>
1538  bool get(MDB_txn* const txn,
1539  const K& key) const {
1540  const lmdb::val k{&key, sizeof(K)};
1541  lmdb::val v{};
1542  return lmdb::dbi_get(txn, handle(), k, v);
1543  }
1544 
1553  template<typename K, typename V>
1554  bool get(MDB_txn* const txn,
1555  const K& key,
1556  V& val) const {
1557  const lmdb::val k{&key, sizeof(K)};
1558  lmdb::val v{};
1559  const bool result = lmdb::dbi_get(txn, handle(), k, v);
1560  if (result) {
1561  val = *v.data<const V>();
1562  }
1563  return result;
1564  }
1565 
1574  template<typename V>
1575  bool get(MDB_txn* const txn,
1576  const char* const key,
1577  V& val) const {
1578  const lmdb::val k{key, std::strlen(key)};
1579  lmdb::val v{};
1580  const bool result = lmdb::dbi_get(txn, handle(), k, v);
1581  if (result) {
1582  val = *v.data<const V>();
1583  }
1584  return result;
1585  }
1586 
1596  bool put(MDB_txn* const txn,
1597  const val& key,
1598  val& data,
1599  const unsigned int flags = default_put_flags) {
1600  return lmdb::dbi_put(txn, handle(), key, data, flags);
1601  }
1602 
1611  template<typename K>
1612  bool put(MDB_txn* const txn,
1613  const K& key,
1614  const unsigned int flags = default_put_flags) {
1615  const lmdb::val k{&key, sizeof(K)};
1616  lmdb::val v{};
1617  return lmdb::dbi_put(txn, handle(), k, v, flags);
1618  }
1619 
1629  template<typename K, typename V>
1630  bool put(MDB_txn* const txn,
1631  const K& key,
1632  const V& val,
1633  const unsigned int flags = default_put_flags) {
1634  const lmdb::val k{&key, sizeof(K)};
1635  lmdb::val v{&val, sizeof(V)};
1636  return lmdb::dbi_put(txn, handle(), k, v, flags);
1637  }
1638 
1648  template<typename V>
1649  bool put(MDB_txn* const txn,
1650  const char* const key,
1651  const V& val,
1652  const unsigned int flags = default_put_flags) {
1653  const lmdb::val k{key, std::strlen(key)};
1654  lmdb::val v{&val, sizeof(V)};
1655  return lmdb::dbi_put(txn, handle(), k, v, flags);
1656  }
1657 
1667  bool put(MDB_txn* const txn,
1668  const char* const key,
1669  const char* const val,
1670  const unsigned int flags = default_put_flags) {
1671  const lmdb::val k{key, std::strlen(key)};
1672  lmdb::val v{val, std::strlen(val)};
1673  return lmdb::dbi_put(txn, handle(), k, v, flags);
1674  }
1675 
1683  bool del(MDB_txn* const txn,
1684  const val& key) {
1685  return lmdb::dbi_del(txn, handle(), key);
1686  }
1687 
1695  template<typename K>
1696  bool del(MDB_txn* const txn,
1697  const K& key) {
1698  const lmdb::val k{&key, sizeof(K)};
1699  return lmdb::dbi_del(txn, handle(), k);
1700  }
1701 };
1702 
1704 /* Resource Interface: Cursors */
1705 
1706 namespace lmdb {
1707  class cursor;
1708 }
1709 
1717 protected:
1718  MDB_cursor* _handle{nullptr};
1719 
1720 public:
1721  static constexpr unsigned int default_flags = 0;
1722 
1730  static cursor
1731  open(MDB_txn* const txn,
1732  const MDB_dbi dbi) {
1733  MDB_cursor* handle{};
1735 #ifdef LMDBXX_DEBUG
1736  assert(handle != nullptr);
1737 #endif
1738  return cursor{handle};
1739  }
1740 
1746  cursor(MDB_cursor* const handle) noexcept
1747  : _handle{handle} {}
1748 
1752  cursor(cursor&& other) noexcept {
1753  std::swap(_handle, other._handle);
1754  }
1755 
1759  cursor& operator=(cursor&& other) noexcept {
1760  if (this != &other) {
1761  std::swap(_handle, other._handle);
1762  }
1763  return *this;
1764  }
1765 
1769  ~cursor() noexcept {
1770  try { close(); } catch (...) {}
1771  }
1772 
1776  operator MDB_cursor*() const noexcept {
1777  return _handle;
1778  }
1779 
1783  MDB_cursor* handle() const noexcept {
1784  return _handle;
1785  }
1786 
1793  void close() noexcept {
1794  if (_handle) {
1796  _handle = nullptr;
1797  }
1798  }
1799 
1806  void renew(MDB_txn* const txn) {
1808  }
1809 
1813  MDB_txn* txn() const noexcept {
1814  return lmdb::cursor_txn(handle());
1815  }
1816 
1820  MDB_dbi dbi() const noexcept {
1821  return lmdb::cursor_dbi(handle());
1822  }
1823 
1831  bool get(MDB_val* const key,
1832  const MDB_cursor_op op) {
1833  return get(key, nullptr, op);
1834  }
1835 
1843  bool get(lmdb::val& key,
1844  const MDB_cursor_op op) {
1845  return get(key, nullptr, op);
1846  }
1847 
1856  bool get(MDB_val* const key,
1857  MDB_val* const val,
1858  const MDB_cursor_op op) {
1859  return lmdb::cursor_get(handle(), key, val, op);
1860  }
1861 
1870  bool get(lmdb::val& key,
1871  lmdb::val& val,
1872  const MDB_cursor_op op) {
1873  return lmdb::cursor_get(handle(), key, val, op);
1874  }
1875 
1884  bool get(std::string& key,
1885  std::string& val,
1886  const MDB_cursor_op op) {
1887  lmdb::val k{}, v{};
1888  const bool found = get(k, v, op);
1889  if (found) {
1890  key.assign(k.data(), k.size());
1891  val.assign(v.data(), v.size());
1892  }
1893  return found;
1894  }
1895 
1903  template<typename K>
1904  bool find(const K& key,
1905  const MDB_cursor_op op = MDB_SET) {
1906  lmdb::val k{&key, sizeof(K)};
1907  return get(k, nullptr, op);
1908  }
1909 };
1910 
1912 
1913 #endif /* LMDBXX_H */
static void env_create(MDB_env **env)
Definition: lmdb++.h:267
static void cursor_renew(MDB_txn *txn, MDB_cursor *cursor)
Definition: lmdb++.h:845
std::size_t size(MDB_txn *const txn) const
Returns the number of records in this database.
Definition: lmdb++.h:1489
static void txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Definition: lmdb++.h:541
static void env_open(MDB_env *env, const char *path, unsigned int flags, mode mode)
Definition: lmdb++.h:279
val(const void *const data, const std::size_t size) noexcept
Constructor.
Definition: lmdb++.h:964
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:1649
MDB_dbi _handle
Definition: lmdb++.h:1388
Exception class for MDB_PANIC errors.
Definition: lmdb++.h:165
env & operator=(env &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1135
cursor(MDB_cursor *const handle) noexcept
Constructor.
Definition: lmdb++.h:1746
static cursor open(MDB_txn *const txn, const MDB_dbi dbi)
Creates an LMDB cursor.
Definition: lmdb++.h:1731
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:1630
static void env_set_max_readers(MDB_env *env, unsigned int count)
Definition: lmdb++.h:447
Base class for LMDB exception conditions.
Definition: lmdb++.h:63
Base class for fatal error conditions.
Definition: lmdb++.h:117
static void env_stat(MDB_env *env, MDB_stat *stat)
Definition: lmdb++.h:334
Exception class for MDB_CORRUPTED errors.
Definition: lmdb++.h:155
static constexpr unsigned int default_put_flags
Definition: lmdb++.h:1392
const T * data() const noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1023
static void dbi_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
Definition: lmdb++.h:728
bool get(lmdb::val &key, lmdb::val &val, const MDB_cursor_op op)
Retrieves a key/value pair from the database.
Definition: lmdb++.h:1870
static void env_sync(MDB_env *env, bool force)
Definition: lmdb++.h:360
cursor(cursor &&other) noexcept
Move constructor.
Definition: lmdb++.h:1752
bool put(MDB_txn *const txn, const val &key, val &data, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1596
static void cursor_del(MDB_cursor *cursor, unsigned int flags)
Definition: lmdb++.h:905
unsigned int flags(MDB_txn *const txn) const
Retrieves the flags for this database handle.
Definition: lmdb++.h:1477
static void txn_reset(MDB_txn *txn) noexcept
Definition: lmdb++.h:593
dbi(dbi &&other) noexcept
Move constructor.
Definition: lmdb++.h:1422
env & open(const char *const path, const unsigned int flags=default_flags, const mode mode=default_mode)
Opens this environment.
Definition: lmdb++.h:1194
static void dbi_drop(MDB_txn *txn, MDB_dbi dbi, bool del)
Definition: lmdb++.h:686
int code() const noexcept
Returns the underlying LMDB error code.
Definition: lmdb++.h:84
static void env_set_mapsize(MDB_env *env, std::size_t size)
Definition: lmdb++.h:434
static void dbi_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
Definition: lmdb++.h:742
char * data() noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1030
Wrapper class for MDB_val structures.
Definition: lmdb++.h:939
val & assign(const char *const data) noexcept
Assigns the value.
Definition: lmdb++.h:1055
MDB_cursor * _handle
Definition: lmdb++.h:1718
static void env_get_max_readers(MDB_env *env, unsigned int *count)
Definition: lmdb++.h:460
Resource class for MDB_cursor* handles.
Definition: lmdb++.h:1716
bool get(MDB_val *const key, MDB_val *const val, const MDB_cursor_op op)
Retrieves a key/value pair from the database.
Definition: lmdb++.h:1856
static void env_get_path(MDB_env *env, const char **path)
Definition: lmdb++.h:408
static void dbi_close(MDB_env *env, MDB_dbi dbi) noexcept
Definition: lmdb++.h:677
MDB_dbi handle() const noexcept
Returns the underlying MDB_dbi handle.
Definition: lmdb++.h:1455
static void cursor_close(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:836
static void env_set_userctx(MDB_env *env, void *ctx)
Definition: lmdb++.h:500
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:1268
env & set_flags(const unsigned int flags, const bool onoff=true)
Definition: lmdb++.h:1206
~val() noexcept=default
Destructor.
virtual const char * what() const noexcept
Returns the underlying LMDB error code.
Definition: lmdb++.h:98
env(MDB_env *const handle) noexcept
Constructor.
Definition: lmdb++.h:1122
MDB_env * handle() const noexcept
Returns the underlying MDB_env* handle.
Definition: lmdb++.h:1159
txn(txn &&other) noexcept
Move constructor.
Definition: lmdb++.h:1290
dbi(const MDB_dbi handle) noexcept
Constructor.
Definition: lmdb++.h:1416
static constexpr unsigned int default_flags
Definition: lmdb++.h:1090
void renew(MDB_txn *const txn)
Renews this cursor.
Definition: lmdb++.h:1806
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
MDB_cursor * handle() const noexcept
Returns the underlying MDB_cursor* handle.
Definition: lmdb++.h:1783
MDB_txn * txn() const noexcept
Returns the cursor's transaction handle.
Definition: lmdb++.h:1813
static void env_get_flags(MDB_env *env, unsigned int *flags)
Definition: lmdb++.h:395
MDB_dbi dbi() const noexcept
Returns the cursor's database handle.
Definition: lmdb++.h:1820
static bool dbi_put(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:774
void close() noexcept
Closes this cursor.
Definition: lmdb++.h:1793
val() noexcept=default
Default constructor.
bool get(std::string &key, std::string &val, const MDB_cursor_op op)
Retrieves a key/value pair from the database.
Definition: lmdb++.h:1884
mdb_mode_t mode
Definition: lmdb++.h:38
static void env_copy(MDB_env *env, const char *path, unsigned int flags)
Definition: lmdb++.h:295
bool get(lmdb::val &key, const MDB_cursor_op op)
Retrieves a key from the database.
Definition: lmdb++.h:1843
void drop(MDB_txn *const txn, const bool del=false)
Definition: lmdb++.h:1498
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:1403
Exception class for MDB_BAD_DBI errors.
Definition: lmdb++.h:196
static void dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
Definition: lmdb++.h:635
cursor & operator=(cursor &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1759
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:1612
bool get(MDB_txn *const txn, const K &key, V &val) const
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1554
txn(MDB_txn *const handle) noexcept
Constructor.
Definition: lmdb++.h:1284
void abort() noexcept
Aborts this transaction.
Definition: lmdb++.h:1351
T * data() noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1015
void sync(const bool force=true)
Flushes data buffers to disk.
Definition: lmdb++.h:1169
const int _code
Definition: lmdb++.h:65
bool get(MDB_txn *const txn, const K &key) const
Retrieves a key from this database.
Definition: lmdb++.h:1538
static MDB_env * txn_env(MDB_txn *txn) noexcept
Definition: lmdb++.h:555
bool get(MDB_txn *const txn, const char *const key, V &val) const
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1575
void reset() noexcept
Resets this read-only transaction.
Definition: lmdb++.h:1359
error(const char *const origin, const int rc) noexcept
Constructor.
Definition: lmdb++.h:76
Exception class for MDB_KEYEXIST errors.
Definition: lmdb++.h:135
const char * origin() const noexcept
Returns the origin of the LMDB error.
Definition: lmdb++.h:91
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:1510
val(const char *const data) noexcept
Constructor.
Definition: lmdb++.h:958
MDB_val _val
Definition: lmdb++.h:941
void close() noexcept
Closes this environment, releasing the memory map.
Definition: lmdb++.h:1179
val & assign(const T *const data, const std::size_t size) noexcept
Assigns the value.
Definition: lmdb++.h:1045
static bool dbi_del(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, const MDB_val *data)
Definition: lmdb++.h:792
Resource class for MDB_txn* handles.
Definition: lmdb++.h:1253
static bool dbi_get(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, MDB_val *data)
Definition: lmdb++.h:757
static MDB_dbi cursor_dbi(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:865
static void raise(const char *origin, int rc)
Throws an error based on the given LMDB return code.
Definition: lmdb++.h:202
bool empty() const noexcept
Determines whether this value is empty.
Definition: lmdb++.h:1000
MDB_stat stat(MDB_txn *const txn) const
Returns statistics for this database.
Definition: lmdb++.h:1465
bool del(MDB_txn *const txn, const K &key)
Removes a key/value pair from this database.
Definition: lmdb++.h:1696
MDB_env * env() const noexcept
Returns the transaction's MDB_env* handle.
Definition: lmdb++.h:1331
MDB_env * _handle
Definition: lmdb++.h:1087
static void dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
Definition: lmdb++.h:664
static constexpr unsigned int default_flags
Definition: lmdb++.h:1721
static bool cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Definition: lmdb++.h:874
static void env_info(MDB_env *env, MDB_envinfo *stat)
Definition: lmdb++.h:347
Resource class for MDB_dbi handles.
Definition: lmdb++.h:1386
txn & operator=(txn &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1297
Resource class for MDB_env* handles.
Definition: lmdb++.h:1085
void renew()
Renews this read-only transaction.
Definition: lmdb++.h:1368
bool get(MDB_txn *const txn, const val &key, val &data)
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1524
static constexpr unsigned int default_flags
Definition: lmdb++.h:1391
dbi & operator=(dbi &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1429
static MDB_txn * cursor_txn(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:857
~env() noexcept
Destructor.
Definition: lmdb++.h:1145
static void txn_renew(MDB_txn *txn)
Definition: lmdb++.h:602
static constexpr unsigned int default_flags
Definition: lmdb++.h:1258
const char * data() const noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1037
static void cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Definition: lmdb++.h:823
~cursor() noexcept
Destructor.
Definition: lmdb++.h:1769
static unsigned int env_get_max_keysize(MDB_env *env)
Definition: lmdb++.h:485
<lmdb++.h> - C++11 wrapper for LMDB.
Definition: lmdb++.h:37
static constexpr mode default_mode
Definition: lmdb++.h:1091
~dbi() noexcept
Destructor.
Definition: lmdb++.h:1439
MDB_txn * _handle
Definition: lmdb++.h:1255
bool del(MDB_txn *const txn, const val &key)
Removes a key/value pair from this database.
Definition: lmdb++.h:1683
env(env &&other) noexcept
Move constructor.
Definition: lmdb++.h:1128
std::size_t size() const noexcept
Returns the size of the data.
Definition: lmdb++.h:1007
static void dbi_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Definition: lmdb++.h:650
static env create(const unsigned int flags=default_flags)
Creates a new LMDB environment.
Definition: lmdb++.h:1099
bool find(const K &key, const MDB_cursor_op op=MDB_SET)
Positions this cursor at the given key.
Definition: lmdb++.h:1904
env & set_max_readers(const unsigned int count)
Definition: lmdb++.h:1225
static void env_set_flags(MDB_env *env, unsigned int flags, bool onoff)
Definition: lmdb++.h:381
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:1667
static void txn_commit(MDB_txn *txn)
Definition: lmdb++.h:574
static void env_copy_fd(MDB_env *env, mdb_filehandle_t fd, unsigned int flags)
Definition: lmdb++.h:315
env & set_mapsize(const std::size_t size)
Definition: lmdb++.h:1216
Exception class for MDB_MAP_FULL errors.
Definition: lmdb++.h:185
static void * env_get_userctx(MDB_env *env)
Definition: lmdb++.h:515
static void cursor_count(MDB_cursor *cursor, std::size_t &count)
Definition: lmdb++.h:918
bool get(MDB_val *const key, const MDB_cursor_op op)
Retrieves a key from the database.
Definition: lmdb++.h:1831
MDB_txn * handle() const noexcept
Returns the underlying MDB_txn* handle.
Definition: lmdb++.h:1324
static void dbi_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:714
~txn() noexcept
Destructor.
Definition: lmdb++.h:1307
Base class for logic error conditions.
Definition: lmdb++.h:109
val & operator=(val &&other) noexcept=default
Move assignment operator.
Exception class for MDB_NOTFOUND errors.
Definition: lmdb++.h:145
Base class for runtime error conditions.
Definition: lmdb++.h:125
env & set_max_dbs(const MDB_dbi count)
Definition: lmdb++.h:1234
static void cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:890
static void env_get_fd(MDB_env *env, mdb_filehandle_t *fd)
Definition: lmdb++.h:421
val & assign(const std::string &data) noexcept
Assigns the value.
Definition: lmdb++.h:1062
Exception class for MDB_VERSION_MISMATCH errors.
Definition: lmdb++.h:175
void commit()
Commits this transaction.
Definition: lmdb++.h:1341
static void dbi_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:700
static void txn_abort(MDB_txn *txn) noexcept
Definition: lmdb++.h:585