NCBI C++ ToolKit
lmdb++.h
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* This is free and unencumbered software released into the public domain.
2 
3  Original repository:
4  https://github.com/bendiken/lmdbxx
5  Adoptation for NCBI (Dmitrienko, Dmitry):
6  https://bitbucket.ncbi.nlm.nih.gov/projects/ID/repos/lmdbxx/browse
7  Adaptation for NCBI/VS2013 (Denis Vakatov):
8  here
9  Original version is available here:
10  src/util/lmdbxx/lmdb++.h.orig
11 */
12 
13 #ifndef LMDBXX_H
14 #define LMDBXX_H
15 
16 /**
17  * <lmdb++.h> - C++11 wrapper for LMDB.
18  *
19  * @author Arto Bendiken <arto@bendiken.net>
20  * @see https://sourceforge.net/projects/lmdbxx/
21  */
22 
23 #ifndef __cplusplus
24 #error "<lmdb++.h> requires a C++ compiler"
25 #endif
26 
27 #if __cplusplus < 201103L
28 #if !defined(_MSC_VER) || _MSC_VER < 1800
29 #error "<lmdb++.h> requires a C++11 compiler (CXXFLAGS='-std=c++11')"
30 #endif // _MSC_VER check
31 #endif
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 
35 #include <lmdb.h> /* for MDB_*, mdb_*() */
36 
37 #ifdef LMDBXX_DEBUG
38 #include <cassert> /* for assert() */
39 #endif
40 #include <cstddef> /* for std::size_t */
41 #include <cstdio> /* for std::snprintf() */
42 #include <cstring> /* for std::strlen() */
43 #include <stdexcept> /* for std::runtime_error */
44 #include <string> /* for std::string */
45 #include <type_traits> /* for std::is_pod<> */
46 
47 #if defined(_MSC_VER) && _MSC_VER < 1900
48 # define NCBI_VS2013
49 #endif
50 
51 #ifdef NCBI_VS2013
52 # define LMDB_NOEXCEPT
53 # define LMDB_CONSTEXPR const
54 # define LMDB_SNPRINTF _snprintf
55 #else
56 # define LMDB_NOEXCEPT noexcept
57 # define LMDB_CONSTEXPR constexpr
58 # define LMDB_SNPRINTF snprintf
59 #endif
60 
61 namespace lmdb {
62  using mode = mdb_mode_t;
63 }
64 
65 ////////////////////////////////////////////////////////////////////////////////
66 /* Error Handling */
67 
68 namespace lmdb {
69  class error;
70  class logic_error;
71  class fatal_error;
72  class runtime_error;
73  class key_exist_error;
74  class not_found_error;
75  class corrupted_error;
76  class panic_error;
77  class version_mismatch_error;
78  class map_full_error;
79  class bad_dbi_error;
80 }
81 
82 /**
83  * Base class for LMDB exception conditions.
84  *
85  * @see http://symas.com/mdb/doc/group__errors.html
86  */
87 class lmdb::error : public std::runtime_error {
88 protected:
89  const int _code;
90 
91 #ifdef NCBI_VS2013
92 private:
93  mutable char buffer[1024];
94 #endif
95 
96 public:
97  /**
98  * Throws an error based on the given LMDB return code.
99  */
100 #ifndef NCBI_VS2013
101  [[noreturn]]
102 #endif
103  static inline void raise(const char* origin, int rc);
104 
105  /**
106  * Constructor.
107  */
108  error(const char* const origin,
109  const int rc) LMDB_NOEXCEPT
111  _code{rc} {}
112 
113  /**
114  * Returns the underlying LMDB error code.
115  */
117  return _code;
118  }
119 
120  /**
121  * Returns the origin of the LMDB error.
122  */
123  const char* origin() const LMDB_NOEXCEPT {
124  return runtime_error::what();
125  }
126 
127  /**
128  * Returns the underlying LMDB error code.
129  */
130  virtual const char* what() const LMDB_NOEXCEPT {
131 #ifndef NCBI_VS2013
132  static thread_local char buffer[1024];
133 #endif
134 #ifndef _MSC_VER
135  std::
136 #endif
137  LMDB_SNPRINTF(buffer, sizeof(buffer),
138  "%s: %s", origin(), ::mdb_strerror(code()));
139  return buffer;
140  }
141 };
142 
143 
144 /**
145  * Base class for logic error conditions.
146  */
147 class lmdb::logic_error : public lmdb::error {
148 public:
149  using error::error;
150 #ifdef NCBI_VS2013
151  logic_error(const char* const origin,
152  const int rc) : lmdb::error(origin, rc) {}
153 #endif
154 };
155 
156 /**
157  * Base class for fatal error conditions.
158  */
159 class lmdb::fatal_error : public lmdb::error {
160 public:
161  using error::error;
162 #ifdef NCBI_VS2013
163  fatal_error(const char* const origin,
164  const int rc) : lmdb::error(origin, rc) {}
165 #endif
166 };
167 
168 /**
169  * Base class for runtime error conditions.
170  */
171 class lmdb::runtime_error : public lmdb::error {
172 public:
173  using error::error;
174 #ifdef NCBI_VS2013
175  runtime_error(const char* const origin,
176  const int rc) : lmdb::error(origin, rc) {}
177 #endif
178 };
179 
180 /**
181  * Exception class for `MDB_KEYEXIST` errors.
182  *
183  * @see http://symas.com/mdb/doc/group__errors.html#ga05dc5bbcc7da81a7345bd8676e8e0e3b
184  */
185 class lmdb::key_exist_error final : public lmdb::runtime_error {
186 public:
187  using runtime_error::runtime_error;
188 #ifdef NCBI_VS2013
189  key_exist_error(const char* const origin,
190  const int rc) : lmdb::runtime_error(origin, rc) {}
191 #endif
192 };
193 
194 /**
195  * Exception class for `MDB_NOTFOUND` errors.
196  *
197  * @see http://symas.com/mdb/doc/group__errors.html#gabeb52e4c4be21b329e31c4add1b71926
198  */
199 class lmdb::not_found_error final : public lmdb::runtime_error {
200 public:
201  using runtime_error::runtime_error;
202 #ifdef NCBI_VS2013
203  not_found_error(const char* const origin,
204  const int rc) : lmdb::runtime_error(origin, rc) {}
205 #endif
206 };
207 
208 /**
209  * Exception class for `MDB_CORRUPTED` errors.
210  *
211  * @see http://symas.com/mdb/doc/group__errors.html#gaf8148bf1b85f58e264e57194bafb03ef
212  */
213 class lmdb::corrupted_error final : public lmdb::fatal_error {
214 public:
216 #ifdef NCBI_VS2013
217  corrupted_error(const char* const origin,
218  const int rc) : lmdb::fatal_error(origin, rc) {}
219 #endif
220 };
221 
222 /**
223  * Exception class for `MDB_PANIC` errors.
224  *
225  * @see http://symas.com/mdb/doc/group__errors.html#gae37b9aedcb3767faba3de8c1cf6d3473
226  */
227 class lmdb::panic_error final : public lmdb::fatal_error {
228 public:
230 #ifdef NCBI_VS2013
231  panic_error(const char* const origin,
232  const int rc) : lmdb::fatal_error(origin, rc) {}
233 #endif
234 };
235 
236 /**
237  * Exception class for `MDB_VERSION_MISMATCH` errors.
238  *
239  * @see http://symas.com/mdb/doc/group__errors.html#ga909b2db047fa90fb0d37a78f86a6f99b
240  */
241 class lmdb::version_mismatch_error final : public lmdb::fatal_error {
242 public:
244 #ifdef NCBI_VS2013
245  version_mismatch_error(const char* const origin,
246  const int rc) : lmdb::fatal_error(origin, rc) {}
247 #endif
248 };
249 
250 /**
251  * Exception class for `MDB_MAP_FULL` errors.
252  *
253  * @see http://symas.com/mdb/doc/group__errors.html#ga0a83370402a060c9175100d4bbfb9f25
254  */
255 class lmdb::map_full_error final : public lmdb::runtime_error {
256 public:
257  using runtime_error::runtime_error;
258 #ifdef NCBI_VS2013
259  map_full_error(const char* const origin,
260  const int rc) : lmdb::runtime_error(origin, rc) {}
261 #endif
262 };
263 
264 /**
265  * Exception class for `MDB_BAD_DBI` errors.
266  *
267  * @since 0.9.14 (2014/09/20)
268  * @see http://symas.com/mdb/doc/group__errors.html#gab4c82e050391b60a18a5df08d22a7083
269  */
270 class lmdb::bad_dbi_error final : public lmdb::runtime_error {
271 public:
272  using runtime_error::runtime_error;
273 #ifdef NCBI_VS2013
274  bad_dbi_error(const char* const origin,
275  const int rc) : lmdb::runtime_error(origin, rc) {}
276 #endif
277 };
278 
279 inline void
280 lmdb::error::raise(const char* const origin,
281  const int rc) {
282  switch (rc) {
283  case MDB_KEYEXIST: throw key_exist_error{origin, rc};
284  case MDB_NOTFOUND: throw not_found_error{origin, rc};
285  case MDB_CORRUPTED: throw corrupted_error{origin, rc};
286  case MDB_PANIC: throw panic_error{origin, rc};
287  case MDB_VERSION_MISMATCH: throw version_mismatch_error{origin, rc};
288  case MDB_MAP_FULL: throw map_full_error{origin, rc};
289 #ifdef MDB_BAD_DBI
290  case MDB_BAD_DBI: throw bad_dbi_error{origin, rc};
291 #endif
292  default: throw lmdb::runtime_error{origin, rc};
293  }
294 }
295 
296 ////////////////////////////////////////////////////////////////////////////////
297 /* Procedural Interface: Metadata */
298 
299 namespace lmdb {
300  // TODO: mdb_version()
301  // TODO: mdb_strerror()
302 }
303 
304 ////////////////////////////////////////////////////////////////////////////////
305 /* Procedural Interface: Environment */
306 
307 namespace lmdb {
308  static inline void env_create(MDB_env** env);
309  static inline void env_open(MDB_env* env,
310  const char* path, unsigned int flags, mode mode);
311 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
312  static inline void env_copy(MDB_env* env, const char* path, unsigned int flags);
313  static inline void env_copy_fd(MDB_env* env, mdb_filehandle_t fd, unsigned int flags);
314 #else
315  static inline void env_copy(MDB_env* env, const char* path);
316  static inline void env_copy_fd(MDB_env* env, mdb_filehandle_t fd);
317 #endif
318  static inline void env_stat(MDB_env* env, MDB_stat* stat);
319  static inline void env_info(MDB_env* env, MDB_envinfo* stat);
320  static inline void env_sync(MDB_env* env, bool force);
321  static inline void env_close(MDB_env* env) LMDB_NOEXCEPT;
322  static inline void env_set_flags(MDB_env* env, unsigned int flags, bool onoff);
323  static inline void env_get_flags(MDB_env* env, unsigned int* flags);
324  static inline void env_get_path(MDB_env* env, const char** path);
325  static inline void env_get_fd(MDB_env* env, mdb_filehandle_t* fd);
326  static inline void env_set_mapsize(MDB_env* env, std::size_t size);
327  static inline void env_set_max_readers(MDB_env* env, unsigned int count);
328  static inline void env_get_max_readers(MDB_env* env, unsigned int* count);
329  static inline void env_set_max_dbs(MDB_env* env, MDB_dbi count);
330  static inline unsigned int env_get_max_keysize(MDB_env* env);
331 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
332  static inline void env_set_userctx(MDB_env* env, void* ctx);
333  static inline void* env_get_userctx(MDB_env* env);
334 #endif
335  // TODO: mdb_env_set_assert()
336  // TODO: mdb_reader_list()
337  // TODO: mdb_reader_check()
338 }
339 
340 /**
341  * @throws lmdb::error on failure
342  * @see http://symas.com/mdb/doc/group__mdb.html#gaad6be3d8dcd4ea01f8df436f41d158d4
343  */
344 static inline void
346  const int rc = ::mdb_env_create(env);
347  if (rc != MDB_SUCCESS) {
348  error::raise("mdb_env_create", rc);
349  }
350 }
351 
352 /**
353  * @throws lmdb::error on failure
354  * @see http://symas.com/mdb/doc/group__mdb.html#ga32a193c6bf4d7d5c5d579e71f22e9340
355  */
356 static inline void
358  const char* const path,
359  const unsigned int flags,
360  const mode mode) {
361  const int rc = ::mdb_env_open(env, path, flags, mode);
362  if (rc != MDB_SUCCESS) {
363  error::raise("mdb_env_open", rc);
364  }
365 }
366 
367 /**
368  * @throws lmdb::error on failure
369  * @see http://symas.com/mdb/doc/group__mdb.html#ga3bf50d7793b36aaddf6b481a44e24244
370  * @see http://symas.com/mdb/doc/group__mdb.html#ga5d51d6130325f7353db0955dbedbc378
371  */
372 static inline void
374 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
375  const char* const path,
376  const unsigned int flags = 0) {
377  const int rc = ::mdb_env_copy2(env, path, flags);
378 #else
379  const char* const path) {
380  const int rc = ::mdb_env_copy(env, path);
381 #endif
382  if (rc != MDB_SUCCESS) {
383  error::raise("mdb_env_copy2", rc);
384  }
385 }
386 
387 /**
388  * @throws lmdb::error on failure
389  * @see http://symas.com/mdb/doc/group__mdb.html#ga5040d0de1f14000fa01fc0b522ff1f86
390  * @see http://symas.com/mdb/doc/group__mdb.html#ga470b0bcc64ac417de5de5930f20b1a28
391  */
392 static inline void
394 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
395  const mdb_filehandle_t fd,
396  const unsigned int flags = 0) {
397  const int rc = ::mdb_env_copyfd2(env, fd, flags);
398 #else
399  const mdb_filehandle_t fd) {
400  const int rc = ::mdb_env_copyfd(env, fd);
401 #endif
402  if (rc != MDB_SUCCESS) {
403  error::raise("mdb_env_copyfd2", rc);
404  }
405 }
406 
407 /**
408  * @throws lmdb::error on failure
409  * @see http://symas.com/mdb/doc/group__mdb.html#gaf881dca452050efbd434cd16e4bae255
410  */
411 static inline void
413  MDB_stat* const stat) {
414  const int rc = ::mdb_env_stat(env, stat);
415  if (rc != MDB_SUCCESS) {
416  error::raise("mdb_env_stat", rc);
417  }
418 }
419 
420 /**
421  * @throws lmdb::error on failure
422  * @see http://symas.com/mdb/doc/group__mdb.html#ga18769362c7e7d6cf91889a028a5c5947
423  */
424 static inline void
426  MDB_envinfo* const stat) {
427  const int rc = ::mdb_env_info(env, stat);
428  if (rc != MDB_SUCCESS) {
429  error::raise("mdb_env_info", rc);
430  }
431 }
432 
433 /**
434  * @throws lmdb::error on failure
435  * @see http://symas.com/mdb/doc/group__mdb.html#ga85e61f05aa68b520cc6c3b981dba5037
436  */
437 static inline void
439  const bool force = true) {
440  const int rc = ::mdb_env_sync(env, force);
441  if (rc != MDB_SUCCESS) {
442  error::raise("mdb_env_sync", rc);
443  }
444 }
445 
446 /**
447  * @see http://symas.com/mdb/doc/group__mdb.html#ga4366c43ada8874588b6a62fbda2d1e95
448  */
449 static inline void
452 }
453 
454 /**
455  * @throws lmdb::error on failure
456  * @see http://symas.com/mdb/doc/group__mdb.html#ga83f66cf02bfd42119451e9468dc58445
457  */
458 static inline void
460  const unsigned int flags,
461  const bool onoff = true) {
462  const int rc = ::mdb_env_set_flags(env, flags, onoff ? 1 : 0);
463  if (rc != MDB_SUCCESS) {
464  error::raise("mdb_env_set_flags", rc);
465  }
466 }
467 
468 /**
469  * @throws lmdb::error on failure
470  * @see http://symas.com/mdb/doc/group__mdb.html#ga2733aefc6f50beb49dd0c6eb19b067d9
471  */
472 static inline void
474  unsigned int* const flags) {
475  const int rc = ::mdb_env_get_flags(env, flags);
476  if (rc != MDB_SUCCESS) {
477  error::raise("mdb_env_get_flags", rc);
478  }
479 }
480 
481 /**
482  * @throws lmdb::error on failure
483  * @see http://symas.com/mdb/doc/group__mdb.html#gac699fdd8c4f8013577cb933fb6a757fe
484  */
485 static inline void
487  const char** path) {
488  const int rc = ::mdb_env_get_path(env, path);
489  if (rc != MDB_SUCCESS) {
490  error::raise("mdb_env_get_path", rc);
491  }
492 }
493 
494 /**
495  * @throws lmdb::error on failure
496  * @see http://symas.com/mdb/doc/group__mdb.html#gaf1570e7c0e5a5d860fef1032cec7d5f2
497  */
498 static inline void
500  mdb_filehandle_t* const fd) {
501  const int rc = ::mdb_env_get_fd(env, fd);
502  if (rc != MDB_SUCCESS) {
503  error::raise("mdb_env_get_fd", rc);
504  }
505 }
506 
507 /**
508  * @throws lmdb::error on failure
509  * @see http://symas.com/mdb/doc/group__mdb.html#gaa2506ec8dab3d969b0e609cd82e619e5
510  */
511 static inline void
513  const std::size_t size) {
514  const int rc = ::mdb_env_set_mapsize(env, size);
515  if (rc != MDB_SUCCESS) {
516  error::raise("mdb_env_set_mapsize", rc);
517  }
518 }
519 
520 /**
521  * @throws lmdb::error on failure
522  * @see http://symas.com/mdb/doc/group__mdb.html#gae687966c24b790630be2a41573fe40e2
523  */
524 static inline void
526  const unsigned int count) {
527  const int rc = ::mdb_env_set_maxreaders(env, count);
528  if (rc != MDB_SUCCESS) {
529  error::raise("mdb_env_set_maxreaders", rc);
530  }
531 }
532 
533 /**
534  * @throws lmdb::error on failure
535  * @see http://symas.com/mdb/doc/group__mdb.html#ga70e143cf11760d869f754c9c9956e6cc
536  */
537 static inline void
539  unsigned int* const count) {
540  const int rc = ::mdb_env_get_maxreaders(env, count);
541  if (rc != MDB_SUCCESS) {
542  error::raise("mdb_env_get_maxreaders", rc);
543  }
544 }
545 
546 /**
547  * @throws lmdb::error on failure
548  * @see http://symas.com/mdb/doc/group__mdb.html#gaa2fc2f1f37cb1115e733b62cab2fcdbc
549  */
550 static inline void
552  const MDB_dbi count) {
553  const int rc = ::mdb_env_set_maxdbs(env, count);
554  if (rc != MDB_SUCCESS) {
555  error::raise("mdb_env_set_maxdbs", rc);
556  }
557 }
558 
559 /**
560  * @see http://symas.com/mdb/doc/group__mdb.html#gaaf0be004f33828bf2fb09d77eb3cef94
561  */
562 static inline unsigned int
564  const int rc = ::mdb_env_get_maxkeysize(env);
565 #ifdef LMDBXX_DEBUG
566  assert(rc >= 0);
567 #endif
568  return static_cast<unsigned int>(rc);
569 }
570 
571 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
572 /**
573  * @throws lmdb::error on failure
574  * @since 0.9.11 (2014/01/15)
575  * @see http://symas.com/mdb/doc/group__mdb.html#gaf2fe09eb9c96eeb915a76bf713eecc46
576  */
577 static inline void
579  void* const ctx) {
580  const int rc = ::mdb_env_set_userctx(env, ctx);
581  if (rc != MDB_SUCCESS) {
582  error::raise("mdb_env_set_userctx", rc);
583  }
584 }
585 #endif
586 
587 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
588 /**
589  * @since 0.9.11 (2014/01/15)
590  * @see http://symas.com/mdb/doc/group__mdb.html#ga45df6a4fb150cda2316b5ae224ba52f1
591  */
592 static inline void*
595 }
596 #endif
597 
598 ////////////////////////////////////////////////////////////////////////////////
599 /* Procedural Interface: Transactions */
600 
601 namespace lmdb {
602  static inline void txn_begin(
603  MDB_env* env, MDB_txn* parent, unsigned int flags, MDB_txn** txn);
604  static inline MDB_env* txn_env(MDB_txn* txn) LMDB_NOEXCEPT;
605 #ifdef LMDBXX_TXN_ID
606  static inline std::size_t txn_id(MDB_txn* txn) LMDB_NOEXCEPT;
607 #endif
608  static inline void txn_commit(MDB_txn* txn);
609  static inline void txn_abort(MDB_txn* txn) LMDB_NOEXCEPT;
610  static inline void txn_reset(MDB_txn* txn) LMDB_NOEXCEPT;
611  static inline void txn_renew(MDB_txn* txn);
612 }
613 
614 /**
615  * @throws lmdb::error on failure
616  * @see http://symas.com/mdb/doc/group__mdb.html#gad7ea55da06b77513609efebd44b26920
617  */
618 static inline void
620  MDB_txn* const parent,
621  const unsigned int flags,
622  MDB_txn** txn) {
623  const int rc = ::mdb_txn_begin(env, parent, flags, txn);
624  if (rc != MDB_SUCCESS) {
625  error::raise("mdb_txn_begin", rc);
626  }
627 }
628 
629 /**
630  * @see http://symas.com/mdb/doc/group__mdb.html#gaeb17735b8aaa2938a78a45cab85c06a0
631  */
632 static inline MDB_env*
635 }
636 
637 #ifdef LMDBXX_TXN_ID
638 /**
639  * @note Only available in HEAD, not yet in any 0.9.x release (as of 0.9.16).
640  */
641 static inline std::size_t
642 lmdb::txn_id(MDB_txn* const txn) LMDB_NOEXCEPT {
643  return ::mdb_txn_id(txn);
644 }
645 #endif
646 
647 /**
648  * @throws lmdb::error on failure
649  * @see http://symas.com/mdb/doc/group__mdb.html#ga846fbd6f46105617ac9f4d76476f6597
650  */
651 static inline void
653  const int rc = ::mdb_txn_commit(txn);
654  if (rc != MDB_SUCCESS) {
655  error::raise("mdb_txn_commit", rc);
656  }
657 }
658 
659 /**
660  * @see http://symas.com/mdb/doc/group__mdb.html#ga73a5938ae4c3239ee11efa07eb22b882
661  */
662 static inline void
665 }
666 
667 /**
668  * @see http://symas.com/mdb/doc/group__mdb.html#ga02b06706f8a66249769503c4e88c56cd
669  */
670 static inline void
673 }
674 
675 /**
676  * @throws lmdb::error on failure
677  * @see http://symas.com/mdb/doc/group__mdb.html#ga6c6f917959517ede1c504cf7c720ce6d
678  */
679 static inline void
681  const int rc = ::mdb_txn_renew(txn);
682  if (rc != MDB_SUCCESS) {
683  error::raise("mdb_txn_renew", rc);
684  }
685 }
686 
687 ////////////////////////////////////////////////////////////////////////////////
688 /* Procedural Interface: Databases */
689 
690 namespace lmdb {
691  static inline void dbi_open(
692  MDB_txn* txn, const char* name, unsigned int flags, MDB_dbi* dbi);
693  static inline void dbi_stat(MDB_txn* txn, MDB_dbi dbi, MDB_stat* stat);
694  static inline void dbi_flags(MDB_txn* txn, MDB_dbi dbi, unsigned int* flags);
695  static inline void dbi_close(MDB_env* env, MDB_dbi dbi) LMDB_NOEXCEPT;
696  static inline void dbi_drop(MDB_txn* txn, MDB_dbi dbi, bool del);
697  static inline void dbi_set_compare(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
698  static inline void dbi_set_dupsort(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
699  static inline void dbi_set_relfunc(MDB_txn* txn, MDB_dbi dbi, MDB_rel_func* rel);
700  static inline void dbi_set_relctx(MDB_txn* txn, MDB_dbi dbi, void* ctx);
701  static inline bool dbi_get(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, MDB_val* data);
702  static inline bool dbi_put(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, const MDB_val* data, unsigned int flags);
703  static inline bool dbi_del(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, const MDB_val* data);
704  // TODO: mdb_cmp()
705  // TODO: mdb_dcmp()
706 }
707 
708 /**
709  * @throws lmdb::error on failure
710  * @see http://symas.com/mdb/doc/group__mdb.html#gac08cad5b096925642ca359a6d6f0562a
711  */
712 static inline void
714  const char* const name,
715  const unsigned int flags,
716  MDB_dbi* const dbi) {
717  const int rc = ::mdb_dbi_open(txn, name, flags, dbi);
718  if (rc != MDB_SUCCESS) {
719  error::raise("mdb_dbi_open", rc);
720  }
721 }
722 
723 /**
724  * @throws lmdb::error on failure
725  * @see http://symas.com/mdb/doc/group__mdb.html#gae6c1069febe94299769dbdd032fadef6
726  */
727 static inline void
729  const MDB_dbi dbi,
730  MDB_stat* const result) {
731  const int rc = ::mdb_stat(txn, dbi, result);
732  if (rc != MDB_SUCCESS) {
733  error::raise("mdb_stat", rc);
734  }
735 }
736 
737 /**
738  * @throws lmdb::error on failure
739  * @see http://symas.com/mdb/doc/group__mdb.html#ga95ba4cb721035478a8705e57b91ae4d4
740  */
741 static inline void
743  const MDB_dbi dbi,
744  unsigned int* const flags) {
745  const int rc = ::mdb_dbi_flags(txn, dbi, flags);
746  if (rc != MDB_SUCCESS) {
747  error::raise("mdb_dbi_flags", rc);
748  }
749 }
750 
751 /**
752  * @see http://symas.com/mdb/doc/group__mdb.html#ga52dd98d0c542378370cd6b712ff961b5
753  */
754 static inline void
756  const MDB_dbi dbi) LMDB_NOEXCEPT {
758 }
759 
760 /**
761  * @see http://symas.com/mdb/doc/group__mdb.html#gab966fab3840fc54a6571dfb32b00f2db
762  */
763 static inline void
765  const MDB_dbi dbi,
766  const bool del = false) {
767  const int rc = ::mdb_drop(txn, dbi, del ? 1 : 0);
768  if (rc != MDB_SUCCESS) {
769  error::raise("mdb_drop", rc);
770  }
771 }
772 
773 /**
774  * @throws lmdb::error on failure
775  * @see http://symas.com/mdb/doc/group__mdb.html#ga68e47ffcf72eceec553c72b1784ee0fe
776  */
777 static inline void
779  const MDB_dbi dbi,
780  MDB_cmp_func* const cmp = nullptr) {
781  const int rc = ::mdb_set_compare(txn, dbi, cmp);
782  if (rc != MDB_SUCCESS) {
783  error::raise("mdb_set_compare", rc);
784  }
785 }
786 
787 /**
788  * @throws lmdb::error on failure
789  * @see http://symas.com/mdb/doc/group__mdb.html#gacef4ec3dab0bbd9bc978b73c19c879ae
790  */
791 static inline void
793  const MDB_dbi dbi,
794  MDB_cmp_func* const cmp = nullptr) {
795  const int rc = ::mdb_set_dupsort(txn, dbi, cmp);
796  if (rc != MDB_SUCCESS) {
797  error::raise("mdb_set_dupsort", rc);
798  }
799 }
800 
801 /**
802  * @throws lmdb::error on failure
803  * @see http://symas.com/mdb/doc/group__mdb.html#ga697d82c7afe79f142207ad5adcdebfeb
804  */
805 static inline void
807  const MDB_dbi dbi,
808  MDB_rel_func* const rel) {
809  const int rc = ::mdb_set_relfunc(txn, dbi, rel);
810  if (rc != MDB_SUCCESS) {
811  error::raise("mdb_set_relfunc", rc);
812  }
813 }
814 
815 /**
816  * @throws lmdb::error on failure
817  * @see http://symas.com/mdb/doc/group__mdb.html#ga7c34246308cee01724a1839a8f5cc594
818  */
819 static inline void
821  const MDB_dbi dbi,
822  void* const ctx) {
823  const int rc = ::mdb_set_relctx(txn, dbi, ctx);
824  if (rc != MDB_SUCCESS) {
825  error::raise("mdb_set_relctx", rc);
826  }
827 }
828 
829 /**
830  * @retval true if the key/value pair was retrieved
831  * @retval false if the key wasn't found
832  * @see http://symas.com/mdb/doc/group__mdb.html#ga8bf10cd91d3f3a83a34d04ce6b07992d
833  */
834 static inline bool
836  const MDB_dbi dbi,
837  const MDB_val* const key,
838  MDB_val* const data) {
839  const int rc = ::mdb_get(txn, dbi, const_cast<MDB_val*>(key), data);
840  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
841  error::raise("mdb_get", rc);
842  }
843  return (rc == MDB_SUCCESS);
844 }
845 
846 /**
847  * @retval true if the key/value pair was inserted
848  * @retval false if the key already existed
849  * @see http://symas.com/mdb/doc/group__mdb.html#ga4fa8573d9236d54687c61827ebf8cac0
850  */
851 static inline bool
853  const MDB_dbi dbi,
854  const MDB_val* const key,
855  const MDB_val* const data,
856  const unsigned int flags = 0) {
857  const int rc = ::mdb_put(txn, dbi, const_cast<MDB_val*>(key), const_cast<MDB_val*>(data), flags);
858  if (rc != MDB_SUCCESS && rc != MDB_KEYEXIST) {
859  error::raise("mdb_put", rc);
860  }
861  return (rc == MDB_SUCCESS);
862 }
863 
864 /**
865  * @retval true if the key/value pair was removed
866  * @retval false if the key wasn't found
867  * @see http://symas.com/mdb/doc/group__mdb.html#gab8182f9360ea69ac0afd4a4eaab1ddb0
868  */
869 static inline bool
871  const MDB_dbi dbi,
872  const MDB_val* const key,
873  const MDB_val* const data = nullptr) {
874  const int rc = ::mdb_del(txn, dbi, const_cast<MDB_val*>(key), const_cast<MDB_val*>(data));
875  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
876  error::raise("mdb_del", rc);
877  }
878  return (rc == MDB_SUCCESS);
879 }
880 
881 ////////////////////////////////////////////////////////////////////////////////
882 /* Procedural Interface: Cursors */
883 
884 namespace lmdb {
885  static inline void cursor_open(MDB_txn* txn, MDB_dbi dbi, MDB_cursor** cursor);
886  static inline void cursor_close(MDB_cursor* cursor) LMDB_NOEXCEPT;
887  static inline void cursor_renew(MDB_txn* txn, MDB_cursor* cursor);
888  static inline MDB_txn* cursor_txn(MDB_cursor* cursor) LMDB_NOEXCEPT;
889  static inline MDB_dbi cursor_dbi(MDB_cursor* cursor) LMDB_NOEXCEPT;
890  static inline bool cursor_get(MDB_cursor* cursor, MDB_val* key, MDB_val* data, MDB_cursor_op op);
891  static inline void cursor_put(MDB_cursor* cursor, MDB_val* key, MDB_val* data, unsigned int flags);
892  static inline void cursor_del(MDB_cursor* cursor, unsigned int flags);
893  static inline void cursor_count(MDB_cursor* cursor, std::size_t& count);
894 }
895 
896 /**
897  * @throws lmdb::error on failure
898  * @see http://symas.com/mdb/doc/group__mdb.html#ga9ff5d7bd42557fd5ee235dc1d62613aa
899  */
900 static inline void
902  const MDB_dbi dbi,
903  MDB_cursor** const cursor) {
904  const int rc = ::mdb_cursor_open(txn, dbi, cursor);
905  if (rc != MDB_SUCCESS) {
906  error::raise("mdb_cursor_open", rc);
907  }
908 }
909 
910 /**
911  * @see http://symas.com/mdb/doc/group__mdb.html#gad685f5d73c052715c7bd859cc4c05188
912  */
913 static inline void
916 }
917 
918 /**
919  * @throws lmdb::error on failure
920  * @see http://symas.com/mdb/doc/group__mdb.html#gac8b57befb68793070c85ea813df481af
921  */
922 static inline void
924  MDB_cursor* const cursor) {
925  const int rc = ::mdb_cursor_renew(txn, cursor);
926  if (rc != MDB_SUCCESS) {
927  error::raise("mdb_cursor_renew", rc);
928  }
929 }
930 
931 /**
932  * @see http://symas.com/mdb/doc/group__mdb.html#ga7bf0d458f7f36b5232fcb368ebda79e0
933  */
934 static inline MDB_txn*
937 }
938 
939 /**
940  * @see http://symas.com/mdb/doc/group__mdb.html#ga2f7092cf70ee816fb3d2c3267a732372
941  */
942 static inline MDB_dbi
945 }
946 
947 /**
948  * @throws lmdb::error on failure
949  * @see http://symas.com/mdb/doc/group__mdb.html#ga48df35fb102536b32dfbb801a47b4cb0
950  */
951 static inline bool
953  MDB_val* const key,
954  MDB_val* const data,
955  const MDB_cursor_op op) {
956  const int rc = ::mdb_cursor_get(cursor, key, data, op);
957  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
958  error::raise("mdb_cursor_get", rc);
959  }
960  return (rc == MDB_SUCCESS);
961 }
962 
963 /**
964  * @throws lmdb::error on failure
965  * @see http://symas.com/mdb/doc/group__mdb.html#ga1f83ccb40011837ff37cc32be01ad91e
966  */
967 static inline void
969  MDB_val* const key,
970  MDB_val* const data,
971  const unsigned int flags = 0) {
972  const int rc = ::mdb_cursor_put(cursor, key, data, flags);
973  if (rc != MDB_SUCCESS) {
974  error::raise("mdb_cursor_put", rc);
975  }
976 }
977 
978 /**
979  * @throws lmdb::error on failure
980  * @see http://symas.com/mdb/doc/group__mdb.html#ga26a52d3efcfd72e5bf6bd6960bf75f95
981  */
982 static inline void
984  const unsigned int flags = 0) {
985  const int rc = ::mdb_cursor_del(cursor, flags);
986  if (rc != MDB_SUCCESS) {
987  error::raise("mdb_cursor_del", rc);
988  }
989 }
990 
991 /**
992  * @throws lmdb::error on failure
993  * @see http://symas.com/mdb/doc/group__mdb.html#ga4041fd1e1862c6b7d5f10590b86ffbe2
994  */
995 static inline void
997  std::size_t& count) {
998  const int rc = ::mdb_cursor_count(cursor, &count);
999  if (rc != MDB_SUCCESS) {
1000  error::raise("mdb_cursor_count", rc);
1001  }
1002 }
1003 
1004 ////////////////////////////////////////////////////////////////////////////////
1005 /* Resource Interface: Values */
1006 
1007 namespace lmdb {
1008  class val;
1009 }
1010 
1011 /**
1012  * Wrapper class for `MDB_val` structures.
1013  *
1014  * @note Instances of this class are movable and copyable both.
1015  * @see http://symas.com/mdb/doc/group__mdb.html#structMDB__val
1016  */
1017 class lmdb::val {
1018 protected:
1019  MDB_val _val;
1020 
1021 public:
1022  /**
1023  * Default constructor.
1024  */
1025  val() LMDB_NOEXCEPT = default;
1026 
1027  /**
1028  * Constructor.
1029  */
1030  val(const std::string& data) LMDB_NOEXCEPT
1031  : val{data.data(), data.size()} {}
1032 
1033  /**
1034  * Constructor.
1035  */
1036  val(const std::string::const_iterator& data, std::size_t len) LMDB_NOEXCEPT
1037  : val{&*data, len} {}
1038 
1039  /**
1040  * Template Constructor.
1041  */
1042  template<typename T>
1044  : val{&t, sizeof(T)} {}
1045 
1046  /**
1047  * Constructor.
1048  */
1049  val(const char* const data) LMDB_NOEXCEPT
1050  : val{data, std::strlen(data)} {}
1051 
1052  /**
1053  * Constructor.
1054  */
1055  val(const void* const data,
1056  const std::size_t size) LMDB_NOEXCEPT
1057 #ifndef NCBI_VS2013
1058  : _val{size, const_cast<void*>(data)} {}
1059 #else
1060  { _val.mv_size = size; _val.mv_data = const_cast<void*>(data); }
1061 #endif
1062 
1063 #ifndef NCBI_VS2013
1064  /**
1065  * Move constructor.
1066  */
1067  val(val&& other) LMDB_NOEXCEPT = default;
1068 #endif
1069 
1070  /**
1071  * Copy constructor.
1072  */
1073  val(const val& other) LMDB_NOEXCEPT = default;
1074 
1075 #ifndef NCBI_VS2013
1076  /**
1077  * Move assignment operator.
1078  */
1079  val& operator=(val&& other) LMDB_NOEXCEPT = default;
1080 #endif
1081 
1082  /**
1083  * Destructor.
1084  */
1085  ~val() LMDB_NOEXCEPT = default;
1086 
1087  /**
1088  * Returns an `MDB_val*` pointer.
1089  */
1090  operator MDB_val*() LMDB_NOEXCEPT {
1091  return &_val;
1092  }
1093 
1094  /**
1095  * Returns an `MDB_val*` pointer.
1096  */
1097  operator const MDB_val*() const LMDB_NOEXCEPT {
1098  return &_val;
1099  }
1100 
1101  /**
1102  * Determines whether this value is empty.
1103  */
1105  return size() == 0;
1106  }
1107 
1108  /**
1109  * Returns the size of the data.
1110  */
1111  std::size_t size() const LMDB_NOEXCEPT {
1112  return _val.mv_size;
1113  }
1114 
1115  /**
1116  * Returns a pointer to the data.
1117  */
1118  template<typename T>
1120  return reinterpret_cast<T*>(_val.mv_data);
1121  }
1122 
1123  /**
1124  * Returns a pointer to the data.
1125  */
1126  template<typename T>
1128  return reinterpret_cast<T*>(_val.mv_data);
1129  }
1130 
1131  /**
1132  * Returns a pointer to the data.
1133  */
1135  return reinterpret_cast<char*>(_val.mv_data);
1136  }
1137 
1138  /**
1139  * Returns a pointer to the data.
1140  */
1141  const char* data() const LMDB_NOEXCEPT {
1142  return reinterpret_cast<char*>(_val.mv_data);
1143  }
1144 
1145  /**
1146  * Assigns the value.
1147  */
1148  template<typename T>
1149  val& assign(const T* const data,
1150  const std::size_t size) LMDB_NOEXCEPT {
1151  _val.mv_size = size;
1152  _val.mv_data = const_cast<void*>(reinterpret_cast<const void*>(data));
1153  return *this;
1154  }
1155 
1156  /**
1157  * Assigns the value.
1158  */
1159  template<typename T>
1161  _val.mv_size = sizeof(T);
1162  _val.mv_data = const_cast<void*>(reinterpret_cast<const void*>(&data));
1163  return *this;
1164  }
1165 
1166  /**
1167  * Assigns the value.
1168  */
1169  val& assign(const char* const data) LMDB_NOEXCEPT {
1170  return assign(data, std::strlen(data));
1171  }
1172 
1173  /**
1174  * Assigns the value.
1175  */
1177  return assign(data.data(), data.size());
1178  }
1179 
1180  /**
1181  * Assigns the value.
1182  */
1183  val& assign(const std::string::const_iterator& data,
1184  const std::size_t len) LMDB_NOEXCEPT {
1185  return assign(&*data, len);
1186  }
1187 
1188  /**
1189  * Convert value to T
1190  */
1191  template<typename T>
1192  void assign_to(T& t) {
1193  t = *data<const T>();
1194  }
1195 
1196  /**
1197  * Convert value to string
1198  */
1200  str.assign(data(), size());
1201  }
1202 
1203 };
1204 
1205 #if !(defined(__COVERITY__) || defined(_MSC_VER) || defined(__INTEL_COMPILER))
1206 static_assert(std::is_standard_layout<lmdb::val>::value, "lmdb::val must be a standard-layout type");
1207 static_assert(std::is_trivial<lmdb::val>::value, "lmdb::val must be a trivial type");
1208 static_assert(sizeof(lmdb::val) == sizeof(MDB_val), "sizeof(lmdb::val) != sizeof(MDB_val)");
1209 #endif
1210 
1211 ////////////////////////////////////////////////////////////////////////////////
1212 /* Resource Interface: Environment */
1213 
1214 namespace lmdb {
1215  class env;
1216 }
1217 
1218 /**
1219  * Resource class for `MDB_env*` handles.
1220  *
1221  * @note Instances of this class are movable, but not copyable.
1222  * @see http://symas.com/mdb/doc/group__internal.html#structMDB__env
1223  */
1224 class lmdb::env {
1225 protected:
1226  MDB_env* _handle{nullptr};
1227 
1228 public:
1229  static LMDB_CONSTEXPR unsigned int default_flags = 0;
1230  static LMDB_CONSTEXPR mode default_mode = 0644; /* -rw-r--r-- */
1231 
1232  /**
1233  * Creates a new LMDB environment.
1234  *
1235  * @param flags
1236  * @throws lmdb::error on failure
1237  */
1238  static env create(const unsigned int flags = default_flags) {
1239  MDB_env* handle{nullptr};
1241 #ifdef LMDBXX_DEBUG
1242  assert(handle != nullptr);
1243 #endif
1244  if (flags) {
1245  try {
1247  }
1248  catch (const lmdb::error&) {
1250  throw;
1251  }
1252  }
1253  return env{handle};
1254  }
1255 
1256  /**
1257  * Constructor.
1258  *
1259  * @param handle a valid `MDB_env*` handle
1260  */
1262  : _handle{handle} {}
1263 
1264  /**
1265  * Move constructor.
1266  */
1267  env(env&& other) LMDB_NOEXCEPT {
1268  std::swap(_handle, other._handle);
1269  }
1270 
1271  /**
1272  * Move assignment operator.
1273  */
1275  if (this != &other) {
1276  std::swap(_handle, other._handle);
1277  }
1278  return *this;
1279  }
1280 
1281  /**
1282  * Destructor.
1283  */
1285  try { close(); } catch (...) {}
1286  }
1287 
1288  /**
1289  * Returns the underlying `MDB_env*` handle.
1290  */
1291  operator MDB_env*() const LMDB_NOEXCEPT {
1292  return _handle;
1293  }
1294 
1295  /**
1296  * Returns the underlying `MDB_env*` handle.
1297  */
1299  return _handle;
1300  }
1301 
1302  /**
1303  * Flushes data buffers to disk.
1304  *
1305  * @param force
1306  * @throws lmdb::error on failure
1307  */
1308  void sync(const bool force = true) {
1309  lmdb::env_sync(handle(), force);
1310  }
1311 
1312  /**
1313  * Closes this environment, releasing the memory map.
1314  *
1315  * @note this method is idempotent
1316  * @post `handle() == nullptr`
1317  */
1319  if (handle()) {
1321  _handle = nullptr;
1322  }
1323  }
1324 
1325  /**
1326  * Opens this environment.
1327  *
1328  * @param path
1329  * @param flags
1330  * @param mode
1331  * @throws lmdb::error on failure
1332  */
1333  env& open(const char* const path,
1334  const unsigned int flags = default_flags,
1335  const mode mode = default_mode) {
1336  lmdb::env_open(handle(), path, flags, mode);
1337  return *this;
1338  }
1339 
1340  /**
1341  * @param flags
1342  * @param onoff
1343  * @throws lmdb::error on failure
1344  */
1345  env& set_flags(const unsigned int flags,
1346  const bool onoff = true) {
1347  lmdb::env_set_flags(handle(), flags, onoff);
1348  return *this;
1349  }
1350 
1351  /**
1352  * @param size
1353  * @throws lmdb::error on failure
1354  */
1355  env& set_mapsize(const std::size_t size) {
1357  return *this;
1358  }
1359 
1360  /**
1361  * @param count
1362  * @throws lmdb::error on failure
1363  */
1364  env& set_max_readers(const unsigned int count) {
1366  return *this;
1367  }
1368 
1369  /**
1370  * @param count
1371  * @throws lmdb::error on failure
1372  */
1373  env& set_max_dbs(const MDB_dbi count) {
1374  lmdb::env_set_max_dbs(handle(), count);
1375  return *this;
1376  }
1377 };
1378 
1379 ////////////////////////////////////////////////////////////////////////////////
1380 /* Resource Interface: Transactions */
1381 
1382 namespace lmdb {
1383  class txn;
1384 }
1385 
1386 /**
1387  * Resource class for `MDB_txn*` handles.
1388  *
1389  * @note Instances of this class are movable, but not copyable.
1390  * @see http://symas.com/mdb/doc/group__internal.html#structMDB__txn
1391  */
1392 class lmdb::txn {
1393 protected:
1394  MDB_txn* _handle{nullptr};
1395 
1396 public:
1397  static LMDB_CONSTEXPR unsigned int default_flags = 0;
1398 
1399  /**
1400  * Creates a new LMDB transaction.
1401  *
1402  * @param env the environment handle
1403  * @param parent
1404  * @param flags
1405  * @throws lmdb::error on failure
1406  */
1407  static txn begin(MDB_env* const env,
1408  MDB_txn* const parent = nullptr,
1409  const unsigned int flags = default_flags) {
1410  MDB_txn* handle{nullptr};
1411  lmdb::txn_begin(env, parent, flags, &handle);
1412 #ifdef LMDBXX_DEBUG
1413  assert(handle != nullptr);
1414 #endif
1415  return txn{handle};
1416  }
1417 
1418  /**
1419  * Constructor.
1420  *
1421  * @param handle a valid `MDB_txn*` handle
1422  */
1424  : _handle{handle} {}
1425 
1426  /**
1427  * Move constructor.
1428  */
1429  txn(txn&& other) LMDB_NOEXCEPT {
1430  std::swap(_handle, other._handle);
1431  }
1432 
1433  /**
1434  * Move assignment operator.
1435  */
1437  if (this != &other) {
1438  std::swap(_handle, other._handle);
1439  }
1440  return *this;
1441  }
1442 
1443  /**
1444  * Destructor.
1445  */
1447  if (_handle) {
1448  try { abort(); } catch (...) {}
1449  _handle = nullptr;
1450  }
1451  }
1452 
1453  /**
1454  * Returns the underlying `MDB_txn*` handle.
1455  */
1456  operator MDB_txn*() const LMDB_NOEXCEPT {
1457  return _handle;
1458  }
1459 
1460  /**
1461  * Returns the underlying `MDB_txn*` handle.
1462  */
1464  return _handle;
1465  }
1466 
1467  /**
1468  * Returns the transaction's `MDB_env*` handle.
1469  */
1471  return lmdb::txn_env(handle());
1472  }
1473 
1474  /**
1475  * Commits this transaction.
1476  *
1477  * @throws lmdb::error on failure
1478  * @post `handle() == nullptr`
1479  */
1480  void commit() {
1482  _handle = nullptr;
1483  }
1484 
1485  /**
1486  * Aborts this transaction.
1487  *
1488  * @post `handle() == nullptr`
1489  */
1492  _handle = nullptr;
1493  }
1494 
1495  /**
1496  * Resets this read-only transaction.
1497  */
1500  }
1501 
1502  /**
1503  * Renews this read-only transaction.
1504  *
1505  * @throws lmdb::error on failure
1506  */
1507  void renew() {
1509  }
1510 };
1511 
1512 ////////////////////////////////////////////////////////////////////////////////
1513 /* Resource Interface: Databases */
1514 
1515 namespace lmdb {
1516  class dbi;
1517 }
1518 
1519 /**
1520  * Resource class for `MDB_dbi` handles.
1521  *
1522  * @note Instances of this class are movable, but not copyable.
1523  * @see http://symas.com/mdb/doc/group__mdb.html#gadbe68a06c448dfb62da16443d251a78b
1524  */
1525 class lmdb::dbi {
1526 protected:
1527  MDB_dbi _handle{0};
1528 
1529 public:
1530  static LMDB_CONSTEXPR unsigned int default_flags = 0;
1531  static LMDB_CONSTEXPR unsigned int default_put_flags = 0;
1532 
1533  /**
1534  * Opens a database handle.
1535  *
1536  * @param txn the transaction handle
1537  * @param name
1538  * @param flags
1539  * @throws lmdb::error on failure
1540  */
1541  static dbi
1542  open(MDB_txn* const txn,
1543  const char* const name = nullptr,
1544  const unsigned int flags = default_flags) {
1545  MDB_dbi handle{};
1546  lmdb::dbi_open(txn, name, flags, &handle);
1547  return dbi{handle};
1548  }
1549 
1550  /**
1551  * Constructor.
1552  *
1553  * @param handle a valid `MDB_dbi` handle
1554  */
1556  : _handle{handle} {}
1557 
1558  /**
1559  * Move constructor.
1560  */
1561  dbi(dbi&& other) LMDB_NOEXCEPT {
1562  std::swap(_handle, other._handle);
1563  }
1564 
1565  /**
1566  * Move assignment operator.
1567  */
1569  if (this != &other) {
1570  std::swap(_handle, other._handle);
1571  }
1572  return *this;
1573  }
1574 
1575  /**
1576  * Destructor.
1577  */
1579  if (_handle) {
1580  /* No need to call close() here. */
1581  }
1582  }
1583 
1584  /**
1585  * Closes DB handle
1586  */
1587  void close(MDB_env* const env) {
1588  if (_handle) {
1590  _handle = 0;
1591  }
1592  }
1593 
1594  /**
1595  * Returns the underlying `MDB_dbi` handle.
1596  */
1598  return _handle;
1599  }
1600 
1601  /**
1602  * Returns the underlying `MDB_dbi` handle.
1603  */
1605  return _handle;
1606  }
1607 
1608  /**
1609  * Returns statistics for this database.
1610  *
1611  * @param txn a transaction handle
1612  * @throws lmdb::error on failure
1613  */
1614  MDB_stat stat(MDB_txn* const txn) const {
1615  MDB_stat result;
1617  return result;
1618  }
1619 
1620  /**
1621  * Retrieves the flags for this database handle.
1622  *
1623  * @param txn a transaction handle
1624  * @throws lmdb::error on failure
1625  */
1626  unsigned int flags(MDB_txn* const txn) const {
1627  unsigned int result{};
1629  return result;
1630  }
1631 
1632  /**
1633  * Returns the number of records in this database.
1634  *
1635  * @param txn a transaction handle
1636  * @throws lmdb::error on failure
1637  */
1638  std::size_t size(MDB_txn* const txn) const {
1639  return stat(txn).ms_entries;
1640  }
1641 
1642  /**
1643  * @param txn a transaction handle
1644  * @param del
1645  * @throws lmdb::error on failure
1646  */
1647  void drop(MDB_txn* const txn,
1648  const bool del = false) {
1650  }
1651 
1652  /**
1653  * Sets a custom key comparison function for this database.
1654  *
1655  * @param txn a transaction handle
1656  * @param cmp the comparison function
1657  * @throws lmdb::error on failure
1658  */
1660  MDB_cmp_func* const cmp = nullptr) {
1662  return *this;
1663  }
1664 
1665  /**
1666  * Retrieves a key/value pair from this database.
1667  *
1668  * @param txn a transaction handle
1669  * @param key
1670  * @param data
1671  * @throws lmdb::error on failure
1672  */
1673  bool get(MDB_txn* const txn,
1674  const val& key,
1675  val& data) const {
1676  return lmdb::dbi_get(txn, handle(), key, data);
1677  }
1678 
1679  /**
1680  * Retrieves a key from this database.
1681  *
1682  * @param txn a transaction handle
1683  * @param key
1684  * @throws lmdb::error on failure
1685  */
1686  template<typename K>
1687  bool get(MDB_txn* const txn,
1688  const K& key) const {
1689  const lmdb::val k{key};
1690  lmdb::val v{};
1691  return lmdb::dbi_get(txn, handle(), k, v);
1692  }
1693 
1694  /**
1695  * Retrieves a key/value pair from this database.
1696  *
1697  * @param txn a transaction handle
1698  * @param key
1699  * @param val
1700  * @throws lmdb::error on failure
1701  */
1702  template<typename K, typename V>
1703  bool get(MDB_txn* const txn,
1704  const K& key,
1705  V& val) const {
1706  const lmdb::val k{key};
1707  lmdb::val v{};
1708  const bool result = lmdb::dbi_get(txn, handle(), k, v);
1709  if (result)
1710  v.assign_to(val);
1711  return result;
1712  }
1713 
1714  /**
1715  * Retrieves a key/value pair from this database.
1716  *
1717  * @param txn a transaction handle
1718  * @param key a NUL-terminated string key
1719  * @param val
1720  * @throws lmdb::error on failure
1721  */
1722  template<typename V>
1723  bool get(MDB_txn* const txn,
1724  const char* const key,
1725  V& val) const {
1726  const lmdb::val k{key};
1727  lmdb::val v{};
1728  const bool result = lmdb::dbi_get(txn, handle(), k, v);
1729  if (result)
1730  v.assign_to(val);
1731  return result;
1732  }
1733 
1734  /**
1735  * Stores a key/value pair into this database.
1736  *
1737  * @param txn a transaction handle
1738  * @param key
1739  * @param data
1740  * @param flags
1741  * @throws lmdb::error on failure
1742  */
1743  bool put(MDB_txn* const txn,
1744  const val& key,
1745  const val& data,
1746  const unsigned int flags = default_put_flags) {
1747  return lmdb::dbi_put(txn, handle(), key, data, flags);
1748  }
1749 
1750  /**
1751  * Stores a key into this database.
1752  *
1753  * @param txn a transaction handle
1754  * @param key
1755  * @param flags
1756  * @throws lmdb::error on failure
1757  */
1758  template<typename K>
1759  bool put(MDB_txn* const txn,
1760  const K& key,
1761  const unsigned int flags = default_put_flags) {
1762  const lmdb::val k{key};
1763  lmdb::val v{};
1764  return lmdb::dbi_put(txn, handle(), k, v, flags);
1765  }
1766 
1767  /**
1768  * Stores a key/value pair into this database.
1769  *
1770  * @param txn a transaction handle
1771  * @param key
1772  * @param val
1773  * @param flags
1774  * @throws lmdb::error on failure
1775  */
1776  template<typename K, typename V>
1777  bool put(MDB_txn* const txn,
1778  const K& key,
1779  const V& val,
1780  const unsigned int flags = default_put_flags) {
1781  const lmdb::val k{key};
1782  lmdb::val v{val};
1783  return lmdb::dbi_put(txn, handle(), k, v, flags);
1784  }
1785 
1786  /**
1787  * Stores a key/value pair into this database.
1788  *
1789  * @param txn a transaction handle
1790  * @param key a NUL-terminated string key
1791  * @param val
1792  * @param flags
1793  * @throws lmdb::error on failure
1794  */
1795  template<typename V>
1796  bool put(MDB_txn* const txn,
1797  const char* const key,
1798  const V& val,
1799  const unsigned int flags = default_put_flags) {
1800  const lmdb::val k{key};
1801  lmdb::val v{val};
1802  return lmdb::dbi_put(txn, handle(), k, v, flags);
1803  }
1804 
1805  /**
1806  * Stores a key/value pair into this database.
1807  *
1808  * @param txn a transaction handle
1809  * @param key a NUL-terminated string key
1810  * @param val a NUL-terminated string key
1811  * @param flags
1812  * @throws lmdb::error on failure
1813  */
1814  bool put(MDB_txn* const txn,
1815  const char* const key,
1816  const char* const val,
1817  const unsigned int flags = default_put_flags) {
1818  const lmdb::val k{key};
1819  lmdb::val v{val};
1820  return lmdb::dbi_put(txn, handle(), k, v, flags);
1821  }
1822 
1823  /**
1824  * Removes a key/value pair from this database.
1825  *
1826  * @param txn a transaction handle
1827  * @param key
1828  * @throws lmdb::error on failure
1829  */
1830  bool del(MDB_txn* const txn,
1831  const val& key) {
1832  return lmdb::dbi_del(txn, handle(), key);
1833  }
1834 
1835  /**
1836  * Removes a key/value pair from this database.
1837  *
1838  * @param txn a transaction handle
1839  * @param key
1840  * @throws lmdb::error on failure
1841  */
1842  template<typename K>
1843  bool del(MDB_txn* const txn,
1844  const K& key) {
1845  const lmdb::val k{key};
1846  return lmdb::dbi_del(txn, handle(), k);
1847  }
1848 };
1849 
1850 ////////////////////////////////////////////////////////////////////////////////
1851 /* Resource Interface: Cursors */
1852 
1853 namespace lmdb {
1854  class cursor;
1855 }
1856 
1857 /**
1858  * Resource class for `MDB_cursor*` handles.
1859  *
1860  * @note Instances of this class are movable, but not copyable.
1861  * @see http://symas.com/mdb/doc/group__internal.html#structMDB__cursor
1862  */
1863 class lmdb::cursor {
1864 protected:
1865  MDB_cursor* _handle{nullptr};
1866 
1867 public:
1868  static LMDB_CONSTEXPR unsigned int default_flags = 0;
1869 
1870  /**
1871  * Creates an LMDB cursor.
1872  *
1873  * @param txn the transaction handle
1874  * @param dbi the database handle
1875  * @throws lmdb::error on failure
1876  */
1877  static cursor
1878  open(MDB_txn* const txn,
1879  const MDB_dbi dbi) {
1880  MDB_cursor* handle{};
1882 #ifdef LMDBXX_DEBUG
1883  assert(handle != nullptr);
1884 #endif
1885  return cursor{handle};
1886  }
1887 
1888  /**
1889  * Constructor.
1890  *
1891  * @param handle a valid `MDB_cursor*` handle
1892  */
1894  : _handle{handle} {}
1895 
1896  /**
1897  * Move constructor.
1898  */
1900  std::swap(_handle, other._handle);
1901  }
1902 
1903  /**
1904  * Move assignment operator.
1905  */
1907  if (this != &other) {
1908  std::swap(_handle, other._handle);
1909  }
1910  return *this;
1911  }
1912 
1913  /**
1914  * Destructor.
1915  */
1917  try { close(); } catch (...) {}
1918  }
1919 
1920  /**
1921  * Returns the underlying `MDB_cursor*` handle.
1922  */
1923  operator MDB_cursor*() const LMDB_NOEXCEPT {
1924  return _handle;
1925  }
1926 
1927  /**
1928  * Returns the underlying `MDB_cursor*` handle.
1929  */
1931  return _handle;
1932  }
1933 
1934  /**
1935  * Closes this cursor.
1936  *
1937  * @note this method is idempotent
1938  * @post `handle() == nullptr`
1939  */
1941  if (_handle) {
1943  _handle = nullptr;
1944  }
1945  }
1946 
1947  /**
1948  * Renews this cursor.
1949  *
1950  * @param txn the transaction scope
1951  * @throws lmdb::error on failure
1952  */
1953  void renew(MDB_txn* const txn) {
1955  }
1956 
1957  /**
1958  * Returns the cursor's transaction handle.
1959  */
1961  return lmdb::cursor_txn(handle());
1962  }
1963 
1964  /**
1965  * Returns the cursor's database handle.
1966  */
1968  return lmdb::cursor_dbi(handle());
1969  }
1970 
1971  /**
1972  * Retrieves a key from the database.
1973  *
1974  * @param key
1975  * @param op
1976  * @throws lmdb::error on failure
1977  */
1978  bool get(MDB_val* const key,
1979  const MDB_cursor_op op) {
1980  return get(key, nullptr, op);
1981  }
1982 
1983  /**
1984  * Retrieves a key from the database.
1985  *
1986  * @param key
1987  * @param op
1988  * @throws lmdb::error on failure
1989  */
1991  const MDB_cursor_op op) {
1992  return get(key, nullptr, op);
1993  }
1994 
1995  /**
1996  * Retrieves a key/value pair from the database.
1997  *
1998  * @param key
1999  * @param val (may be `nullptr`)
2000  * @param op
2001  * @throws lmdb::error on failure
2002  */
2003  bool get(MDB_val* const key,
2004  MDB_val* const val,
2005  const MDB_cursor_op op) {
2006  return lmdb::cursor_get(handle(), key, val, op);
2007  }
2008 
2009  /**
2010  * Retrieves a key/value pair from the database.
2011  *
2012  * @param key
2013  * @param val
2014  * @param op
2015  * @throws lmdb::error on failure
2016  */
2018  lmdb::val& val,
2019  const MDB_cursor_op op) {
2020  return lmdb::cursor_get(handle(), key, val, op);
2021  }
2022 
2023  /**
2024  * Retrieves a key/value pair from the database.
2025  *
2026  * @param key
2027  * @param val
2028  * @param op
2029  * @throws lmdb::error on failure
2030  */
2031  template<typename K, typename V>
2032  bool get(K& key,
2033  V& val,
2034  const MDB_cursor_op op) {
2035  lmdb::val k{key}, v{val};
2036  const bool found = get(k, v, op);
2037  if (found) {
2038  k.assign_to(key);
2039  v.assign_to(val);
2040  }
2041  return found;
2042  }
2043 
2044  /**
2045  * Positions this cursor at the given key.
2046  *
2047  * @param key
2048  * @param op
2049  * @throws lmdb::error on failure
2050  */
2051  template<typename K>
2052  bool find(const K& key,
2053  const MDB_cursor_op op = MDB_SET) {
2054  lmdb::val k{key};
2055  return get(k, nullptr, op);
2056  }
2057 };
2058 
2059 ////////////////////////////////////////////////////////////////////////////////
2060 
2061 #undef LMDB_NOEXCEPT
2062 #undef LMDB_CONSTEXPR
2063 #undef LMDB_SNPRINTF
2064 
2065 
2066 #endif /* LMDBXX_H */
Exception class for `MDB_BAD_DBI` errors.
Definition: lmdb++.h:205
Exception class for `MDB_CORRUPTED` errors.
Definition: lmdb++.h:164
Resource class for `MDB_cursor*` handles.
Definition: lmdb++.h:1725
bool get(lmdb::val &key, const MDB_cursor_op op)
Retrieves a key from the database.
Definition: lmdb++.h:1990
MDB_cursor * handle() const noexcept
Returns the underlying `MDB_cursor*` handle.
Definition: lmdb++.h:1792
bool get(K &key, V &val, const MDB_cursor_op op)
Retrieves a key/value pair from the database.
Definition: lmdb++.h:2032
MDB_txn * txn() const noexcept
Returns the cursor's transaction handle.
Definition: lmdb++.h:1960
bool get(lmdb::val &key, lmdb::val &val, const MDB_cursor_op op)
Retrieves a key/value pair from the database.
Definition: lmdb++.h:2017
void close() noexcept
Closes this cursor.
Definition: lmdb++.h:1802
~cursor() noexcept
Destructor.
Definition: lmdb++.h:1916
bool get(MDB_val *const key, const MDB_cursor_op op)
Retrieves a key from the database.
Definition: lmdb++.h:1978
bool find(const K &key, const MDB_cursor_op op=MDB_SET)
Positions this cursor at the given key.
Definition: lmdb++.h:2052
cursor(cursor &&other) noexcept
Move constructor.
Definition: lmdb++.h:1899
MDB_dbi dbi() const noexcept
Returns the cursor's database handle.
Definition: lmdb++.h:1967
static cursor open(MDB_txn *const txn, const MDB_dbi dbi)
Creates an LMDB cursor.
Definition: lmdb++.h:1878
MDB_cursor * _handle
Definition: lmdb++.h:1727
cursor(MDB_cursor *const handle) noexcept
Constructor.
Definition: lmdb++.h:1755
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:2003
cursor & operator=(cursor &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1906
static constexpr unsigned int default_flags
Definition: lmdb++.h:1730
void renew(MDB_txn *const txn)
Renews this cursor.
Definition: lmdb++.h:1953
Resource class for `MDB_dbi` handles.
Definition: lmdb++.h:1395
std::size_t size(MDB_txn *const txn) const
Returns the number of records in this database.
Definition: lmdb++.h:1638
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:1777
dbi(const MDB_dbi handle) noexcept
Constructor.
Definition: lmdb++.h:1425
bool del(MDB_txn *const txn, const val &key)
Removes a key/value pair from this database.
Definition: lmdb++.h:1692
dbi & operator=(dbi &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1568
~dbi() noexcept
Destructor.
Definition: lmdb++.h:1578
void close(MDB_env *const env)
Closes DB handle.
Definition: lmdb++.h:1587
bool get(MDB_txn *const txn, const val &key, val &data) const
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1673
MDB_stat stat(MDB_txn *const txn) const
Returns statistics for this database.
Definition: lmdb++.h:1614
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:1796
unsigned int flags(MDB_txn *const txn) const
Retrieves the flags for this database handle.
Definition: lmdb++.h:1486
bool del(MDB_txn *const txn, const K &key)
Removes a key/value pair from this database.
Definition: lmdb++.h:1843
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:1542
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:1659
static constexpr unsigned int default_flags
Definition: lmdb++.h:1400
static constexpr unsigned int default_put_flags
Definition: lmdb++.h:1401
bool get(MDB_txn *const txn, const K &key, V &val) const
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1703
bool put(MDB_txn *const txn, const val &key, const val &data, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1743
void drop(MDB_txn *const txn, const bool del=false)
Definition: lmdb++.h:1647
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:1814
bool get(MDB_txn *const txn, const char *const key, V &val) const
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1723
dbi(dbi &&other) noexcept
Move constructor.
Definition: lmdb++.h:1561
MDB_dbi _handle
Definition: lmdb++.h:1397
bool get(MDB_txn *const txn, const K &key) const
Retrieves a key from this database.
Definition: lmdb++.h:1687
MDB_dbi handle() const noexcept
Returns the underlying `MDB_dbi` handle.
Definition: lmdb++.h:1464
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:1759
Resource class for `MDB_env*` handles.
Definition: lmdb++.h:1094
MDB_env * _handle
Definition: lmdb++.h:1096
void close() noexcept
Closes this environment, releasing the memory map.
Definition: lmdb++.h:1188
env & set_flags(const unsigned int flags, const bool onoff=true)
Definition: lmdb++.h:1345
~env() noexcept
Destructor.
Definition: lmdb++.h:1284
MDB_env * handle() const noexcept
Returns the underlying `MDB_env*` handle.
Definition: lmdb++.h:1168
env(MDB_env *const handle) noexcept
Constructor.
Definition: lmdb++.h:1261
static constexpr mode default_mode
Definition: lmdb++.h:1100
env(env &&other) noexcept
Move constructor.
Definition: lmdb++.h:1267
env & operator=(env &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1274
env & open(const char *const path, const unsigned int flags=default_flags, const mode mode=default_mode)
Opens this environment.
Definition: lmdb++.h:1333
void sync(const bool force=true)
Flushes data buffers to disk.
Definition: lmdb++.h:1308
static env create(const unsigned int flags=default_flags)
Creates a new LMDB environment.
Definition: lmdb++.h:1238
static constexpr unsigned int default_flags
Definition: lmdb++.h:1099
env & set_max_readers(const unsigned int count)
Definition: lmdb++.h:1364
env & set_max_dbs(const MDB_dbi count)
Definition: lmdb++.h:1373
env & set_mapsize(const std::size_t size)
Definition: lmdb++.h:1355
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
int code() const noexcept
Returns the underlying LMDB error code.
Definition: lmdb++.h:116
static void raise(const char *origin, int rc)
Throws an error based on the given LMDB return code.
Definition: lmdb++.h:211
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:126
Exception class for `MDB_KEYEXIST` errors.
Definition: lmdb++.h:144
Base class for logic error conditions.
Definition: lmdb++.h:118
Exception class for `MDB_MAP_FULL` errors.
Definition: lmdb++.h:194
Exception class for `MDB_NOTFOUND` errors.
Definition: lmdb++.h:154
Exception class for `MDB_PANIC` errors.
Definition: lmdb++.h:174
Base class for runtime error conditions.
Definition: lmdb++.h:134
Resource class for `MDB_txn*` handles.
Definition: lmdb++.h:1262
void commit()
Commits this transaction.
Definition: lmdb++.h:1480
MDB_env * env() const noexcept
Returns the transaction's `MDB_env*` handle.
Definition: lmdb++.h:1470
txn & operator=(txn &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1436
void abort() noexcept
Aborts this transaction.
Definition: lmdb++.h:1360
void reset() noexcept
Resets this read-only transaction.
Definition: lmdb++.h:1498
MDB_txn * _handle
Definition: lmdb++.h:1264
~txn() noexcept
Destructor.
Definition: lmdb++.h:1446
void renew()
Renews this read-only transaction.
Definition: lmdb++.h:1507
static constexpr unsigned int default_flags
Definition: lmdb++.h:1267
txn(txn &&other) noexcept
Move constructor.
Definition: lmdb++.h:1429
txn(MDB_txn *const handle) noexcept
Constructor.
Definition: lmdb++.h:1423
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:1407
MDB_txn * handle() const noexcept
Returns the underlying `MDB_txn*` handle.
Definition: lmdb++.h:1333
Wrapper class for `MDB_val` structures.
Definition: lmdb++.h:948
val & assign(const T &data) noexcept
Assigns the value.
Definition: lmdb++.h:1160
val(const char *const data) noexcept
Constructor.
Definition: lmdb++.h:1049
val & assign(const T *const data, const std::size_t size) noexcept
Assigns the value.
Definition: lmdb++.h:1149
val(const T &t) noexcept
Template Constructor.
Definition: lmdb++.h:1043
MDB_val _val
Definition: lmdb++.h:950
val(const void *const data, const std::size_t size) noexcept
Constructor.
Definition: lmdb++.h:1055
const T * data() const noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1127
val & assign(const std::string::const_iterator &data, const std::size_t len) noexcept
Assigns the value.
Definition: lmdb++.h:1183
bool empty() const noexcept
Determines whether this value is empty.
Definition: lmdb++.h:1104
const char * data() const noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1141
void assign_to(std::string &str)
Convert value to string.
Definition: lmdb++.h:1199
void assign_to(T &t)
Convert value to T.
Definition: lmdb++.h:1192
val(val &&other) noexcept=default
Move constructor.
T * data() noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1024
val() noexcept=default
Default constructor.
val(const std::string::const_iterator &data, std::size_t len) noexcept
Constructor.
Definition: lmdb++.h:1036
char * data() noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1134
val & assign(const char *const data) noexcept
Assigns the value.
Definition: lmdb++.h:1169
~val() noexcept=default
Destructor.
std::size_t size() const noexcept
Returns the size of the data.
Definition: lmdb++.h:1016
val(const val &other) noexcept=default
Copy constructor.
val & operator=(val &&other) noexcept=default
Move assignment operator.
val & assign(const std::string &data) noexcept
Assigns the value.
Definition: lmdb++.h:1176
Exception class for `MDB_VERSION_MISMATCH` errors.
Definition: lmdb++.h:184
char value[7]
Definition: config.c:431
static uch flags
CS_CONTEXT * ctx
Definition: t0006.c:12
#define T(s)
Definition: common.h:230
static void fatal_error(const char *msg)
Definition: dynamic1.c:26
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
string
Definition: cgiapp.hpp:687
#define MDB_VERINT(a, b, c)
Combine args a,b,c into a single integer for easy version comparisons.
Definition: lmdb.h:206
#define MDB_VERSION_FULL
The full library version as a single integer.
Definition: lmdb.h:209
#define MDB_KEYEXIST
key/data pair already exists
Definition: lmdb.h:405
#define MDB_MAP_FULL
Environment mapsize reached.
Definition: lmdb.h:419
#define MDB_VERSION_MISMATCH
Environment version mismatch.
Definition: lmdb.h:415
#define MDB_BAD_DBI
The specified DBI was changed unexpectedly.
Definition: lmdb.h:450
#define MDB_NOTFOUND
key/data pair not found (EOF)
Definition: lmdb.h:407
#define MDB_SUCCESS
Successful result.
Definition: lmdb.h:403
#define MDB_PANIC
Update of meta page failed or environment had fatal error.
Definition: lmdb.h:413
#define MDB_CORRUPTED
Located page was wrong type.
Definition: lmdb.h:411
void mdb_txn_reset(MDB_txn *txn)
Reset a read-only transaction.
Definition: mdb.c:3048
int mdb_env_info(MDB_env *env, MDB_envinfo *stat)
Return information about the LMDB environment.
Definition: mdb.c:9689
int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Store by cursor.
Definition: mdb.c:6540
int mdb_cursor_del(MDB_cursor *cursor, unsigned int flags)
Delete current key/data pair.
Definition: mdb.c:7069
int mdb_env_get_flags(MDB_env *env, unsigned int *flags)
Get environment flags.
Definition: mdb.c:9601
MDB_dbi mdb_cursor_dbi(MDB_cursor *cursor)
Return the cursor's database handle.
Definition: mdb.c:7745
int mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
Open an environment handle.
Definition: mdb.c:4959
int mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags)
Copy an LMDB environment to the specified path, with options.
Definition: mdb.c:9563
int mdb_cursor_count(MDB_cursor *cursor, size_t *countp)
Return count of duplicates for current key.
Definition: mdb.c:7685
void mdb_env_close(MDB_env *env)
Close the environment and release the memory map.
Definition: mdb.c:5156
int mdb_env_copyfd(MDB_env *env, mdb_filehandle_t fd)
Copy an LMDB environment to the specified file descriptor.
Definition: mdb.c:9557
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Definition: mdb.c:6319
int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned int flags)
Store items into a database.
Definition: mdb.c:9009
int mdb_env_copyfd2(MDB_env *env, mdb_filehandle_t fd, unsigned int flags)
Copy an LMDB environment to the specified file descriptor, with options.
Definition: mdb.c:9548
void mdb_dbi_close(MDB_env *env, MDB_dbi dbi)
Close a database handle.
Definition: mdb.c:9867
int mdb_env_copy(MDB_env *env, const char *path)
Copy an LMDB environment to the specified path.
Definition: mdb.c:9583
int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Set a custom key comparison function for a database.
Definition: mdb.c:10042
int mdb_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
Set a relocation function for a MDB_FIXEDMAP database.
Definition: mdb.c:10060
int mdb_txn_renew(MDB_txn *txn)
Renew a read-only transaction.
Definition: mdb.c:2812
void * mdb_env_get_userctx(MDB_env *env)
Get the application information associated with the MDB_env.
Definition: mdb.c:9620
int mdb_env_get_maxreaders(MDB_env *env, unsigned int *readers)
Get the maximum number of threads/reader slots for the environment.
Definition: mdb.c:4112
void mdb_txn_abort(MDB_txn *txn)
Abandon all the operations of the transaction instead of saving them.
Definition: mdb.c:3061
int mdb_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
Set a context pointer for a MDB_FIXEDMAP database's relocation function.
Definition: mdb.c:10069
int mdb_env_set_flags(MDB_env *env, unsigned int flags, int onoff)
Set environment flags.
Definition: mdb.c:9589
int mdb_txn_commit(MDB_txn *txn)
Commit all the operations of a transaction into the database.
Definition: mdb.c:3448
int mdb_env_sync(MDB_env *env, int force)
Flush the data buffers to disk.
Definition: mdb.c:2513
int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data)
Get items from a database.
Definition: mdb.c:5782
int mdb_dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
Retrieve the DB flags for a database handle.
Definition: mdb.c:9883
char * mdb_strerror(int err)
Return a string describing a given error code.
Definition: mdb.c:1479
int mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Create a cursor handle.
Definition: mdb.c:7634
int mdb_env_set_mapsize(MDB_env *env, size_t size)
Set the size of the memory map to use for this environment.
Definition: mdb.c:4060
int mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs)
Set the maximum number of named databases for the environment.
Definition: mdb.c:4094
int mdb_env_create(MDB_env **env)
Create an LMDB environment handle.
Definition: mdb.c:3951
int mdb_env_get_maxkeysize(MDB_env *env)
Get the maximum size of keys and MDB_DUPSORT data we can write.
Definition: mdb.c:10079
int mdb_del(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data)
Delete items from a database.
Definition: mdb.c:8523
int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
Empty or delete+close a database.
Definition: mdb.c:9991
int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
Open a database in the environment.
Definition: mdb.c:9730
int mdb_env_get_path(MDB_env *env, const char **path)
Return the path that was used in mdb_env_open().
Definition: mdb.c:9637
int mdb_cursor_renew(MDB_txn *txn, MDB_cursor *cursor)
Renew a cursor handle.
Definition: mdb.c:7668
int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Set a custom data comparison function for a MDB_DUPSORT database.
Definition: mdb.c:10051
void mdb_cursor_close(MDB_cursor *cursor)
Close a cursor handle.
Definition: mdb.c:7723
int mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Create a transaction for use with the environment.
Definition: mdb.c:2829
size_t mdb_txn_id(MDB_txn *txn)
Return the transaction's ID.
Definition: mdb.c:2937
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:366
int mdb_env_set_maxreaders(MDB_env *env, unsigned int readers)
Set the maximum number of threads/reader slots for the environment.
Definition: mdb.c:4103
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Retrieve statistics for a database.
Definition: mdb.c:9850
MDB_txn * mdb_cursor_txn(MDB_cursor *cursor)
Return the cursor's transaction handle.
Definition: mdb.c:7738
int mdb_env_get_fd(MDB_env *env, mdb_filehandle_t *fd)
Return the filedescriptor for the given environment.
Definition: mdb.c:9647
int mdb_env_set_userctx(MDB_env *env, void *ctx)
Set application information associated with the MDB_env.
Definition: mdb.c:9611
int mdb_env_stat(MDB_env *env, MDB_stat *stat)
Return statistics about the LMDB environment.
Definition: mdb.c:9676
MDB_env * mdb_txn_env(MDB_txn *txn)
Returns the transaction's MDB_env.
Definition: mdb.c:2930
@ MDB_SET
Position at specified key.
Definition: lmdb.h:390
size_t ms_entries
Number of data items.
Definition: lmdb.h:463
size_t mv_size
size of the data item
Definition: lmdb.h:258
void * mv_data
address of the data item
Definition: lmdb.h:259
void() MDB_rel_func(MDB_val *item, void *oldptr, void *newptr, void *relctx)
A callback function used to relocate a position-dependent data item in a fixed-address database.
Definition: lmdb.h:279
int() MDB_cmp_func(const MDB_val *a, const MDB_val *b)
A callback function used to compare two keys in a database.
Definition: lmdb.h:263
unsigned int MDB_dbi
A handle for an individual database in the DB environment.
Definition: lmdb.h:241
int len
<lmdb++.h> - C++11 wrapper for LMDB.
Definition: lmdb++.h:37
static void env_info(MDB_env *env, MDB_envinfo *stat)
Definition: lmdb++.h:356
static void * env_get_userctx(MDB_env *env)
Definition: lmdb++.h:524
static void dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
Definition: lmdb++.h:673
static void cursor_renew(MDB_txn *txn, MDB_cursor *cursor)
Definition: lmdb++.h:854
static void env_copy_fd(MDB_env *env, mdb_filehandle_t fd, unsigned int flags)
Definition: lmdb++.h:324
static void txn_commit(MDB_txn *txn)
Definition: lmdb++.h:583
static void env_open(MDB_env *env, const char *path, unsigned int flags, mode mode)
Definition: lmdb++.h:288
static MDB_txn * cursor_txn(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:866
static void dbi_drop(MDB_txn *txn, MDB_dbi dbi, bool del)
Definition: lmdb++.h:695
static bool dbi_put(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:783
static void env_create(MDB_env **env)
Definition: lmdb++.h:276
static unsigned int env_get_max_keysize(MDB_env *env)
Definition: lmdb++.h:494
static void cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Definition: lmdb++.h:832
static void cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:899
static void env_get_fd(MDB_env *env, mdb_filehandle_t *fd)
Definition: lmdb++.h:430
static void cursor_del(MDB_cursor *cursor, unsigned int flags)
Definition: lmdb++.h:914
static void dbi_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
Definition: lmdb++.h:737
static void dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
Definition: lmdb++.h:644
static void dbi_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:709
static void env_set_max_readers(MDB_env *env, unsigned int count)
Definition: lmdb++.h:456
static MDB_env * txn_env(MDB_txn *txn) noexcept
Definition: lmdb++.h:564
static void env_set_mapsize(MDB_env *env, std::size_t size)
Definition: lmdb++.h:443
static void env_set_max_dbs(MDB_env *env, MDB_dbi count)
Definition: lmdb++.h:482
static void env_close(MDB_env *env) noexcept
Definition: lmdb++.h:381
static void env_set_flags(MDB_env *env, unsigned int flags, bool onoff)
Definition: lmdb++.h:390
static void txn_renew(MDB_txn *txn)
Definition: lmdb++.h:611
static void cursor_close(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:845
static bool cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Definition: lmdb++.h:883
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:469
static MDB_dbi cursor_dbi(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:874
static void txn_abort(MDB_txn *txn) noexcept
Definition: lmdb++.h:594
static void env_get_path(MDB_env *env, const char **path)
Definition: lmdb++.h:417
static void dbi_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Definition: lmdb++.h:659
static bool dbi_del(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, const MDB_val *data)
Definition: lmdb++.h:801
static bool dbi_get(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, MDB_val *data)
Definition: lmdb++.h:766
static void env_copy(MDB_env *env, const char *path, unsigned int flags)
Definition: lmdb++.h:304
static void txn_reset(MDB_txn *txn) noexcept
Definition: lmdb++.h:602
static void env_set_userctx(MDB_env *env, void *ctx)
Definition: lmdb++.h:509
static void dbi_close(MDB_env *env, MDB_dbi dbi) noexcept
Definition: lmdb++.h:686
static void env_stat(MDB_env *env, MDB_stat *stat)
Definition: lmdb++.h:343
static void env_sync(MDB_env *env, bool force)
Definition: lmdb++.h:369
static void dbi_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:723
mdb_mode_t mode
Definition: lmdb++.h:38
static void env_get_flags(MDB_env *env, unsigned int *flags)
Definition: lmdb++.h:404
static void txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Definition: lmdb++.h:550
static void dbi_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
Definition: lmdb++.h:751
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::KEY key
EIPRangeType t
Definition: ncbi_localip.c:101
static const GLdouble origin[]
static pcre_uint8 * buffer
Definition: pcretest.c:1051
#define K
int mdb_filehandle_t
An abstraction for a file handle.
Definition: lmdb.h:188
mode_t mdb_mode_t
Unix permissions for creating files, or dummy definition for Windows.
Definition: lmdb.h:178
#define assert(x)
Definition: srv_diag.hpp:58
static const char * str(char *buf, int n)
Definition: stats.c:84
Cursors are used for all DB operations.
Definition: mdb.c:1184
The database environment.
Definition: mdb.c:1259
Information about the environment.
Definition: lmdb.h:467
Statistics for a database in the environment.
Definition: lmdb.h:456
A database transaction.
Definition: mdb.c:1084
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:257
else result
Definition: token2.c:20
static HENV env
Definition: transaction2.c:38
#define LMDB_NOEXCEPT
<lmdb++.h> - C++11 wrapper for LMDB.
Definition: lmdb++.h:56
#define LMDB_SNPRINTF
Definition: lmdb++.h:58
#define LMDB_CONSTEXPR
Definition: lmdb++.h:57
#define const
Definition: zconf.h:230
Modified on Fri Dec 01 04:46:32 2023 by modify_doxy.py rev. 669887