C++11 wrapper for the LMDB embedded B+ tree database library.

Related tags

Database cxx lmdb
Overview

lmdb++: a C++11 wrapper for LMDB

Travis CI build status Coverity Scan build status

This is a comprehensive C++ wrapper for the LMDB embedded database library, offering both an error-checked procedural interface and an object-oriented resource interface with RAII semantics.

Example

Here follows a simple motivating example demonstrating basic use of the object-oriented resource interface:

#include <cstdio>
#include <cstdlib>
#include <lmdb++.h>

int main() {
  /* Create and open the LMDB environment: */
  auto env = lmdb::env::create();
  env.set_mapsize(1UL * 1024UL * 1024UL * 1024UL); /* 1 GiB */
  env.open("./example.mdb", 0, 0664);

  /* Insert some key/value pairs in a write transaction: */
  auto wtxn = lmdb::txn::begin(env);
  auto dbi = lmdb::dbi::open(wtxn, nullptr);
  dbi.put(wtxn, "username", "jhacker");
  dbi.put(wtxn, "email", "[email protected]");
  dbi.put(wtxn, "fullname", "J. Random Hacker");
  wtxn.commit();

  /* Fetch key/value pairs in a read-only transaction: */
  auto rtxn = lmdb::txn::begin(env, nullptr, MDB_RDONLY);
  auto cursor = lmdb::cursor::open(rtxn, dbi);
  std::string key, value;
  while (cursor.get(key, value, MDB_NEXT)) {
    std::printf("key: '%s', value: '%s'\n", key.c_str(), value.c_str());
  }
  cursor.close();
  rtxn.abort();

  /* The enviroment is closed automatically. */

  return EXIT_SUCCESS;
}

Should any operation in the above fail, an lmdb::error exception will be thrown and terminate the program since we don't specify an exception handler. All resources will regardless get automatically cleaned up due to RAII semantics.

Note

In order to run this example, you must first manually create the ./example.mdb directory. This is a basic characteristic of LMDB: the given environment path must already exist, as LMDB will not attempt to automatically create it.

Features

  • Designed to be entirely self-contained as a single <lmdb++.h> header file that can be dropped into a project.
  • Implements a straightforward mapping from C to C++, with consistent naming.
  • Provides both a procedural interface and an object-oriented RAII interface.
  • Simplifies error handling by translating error codes into C++ exceptions.
  • Carefully differentiates logic errors, runtime errors, and fatal errors.
  • Exception strings include the name of the LMDB function that failed.
  • Plays nice with others: all symbols are placed into the lmdb namespace.
  • 100% free and unencumbered public domain software, usable in any context and for any purpose.

Requirements

The <lmdb++.h> header file requires a C++11 compiler and standard library. Recent releases of Clang or GCC will work fine.

In addition, for your application to build and run, the underlying <lmdb.h> header file shipped with LMDB must be available in the preprocessor's include path, and you must link with the liblmdb native library. On Ubuntu Linux 14.04 and newer, these prerequisites can be satisfied by installing the liblmdb-dev package.

Overview

This wrapper offers both an error-checked procedural interface and an object-oriented resource interface with RAII semantics. The former will be useful for easily retrofitting existing projects that currently use the raw C interface, but we recommend the latter for all new projects due to the exception safety afforded by RAII semantics.

Resource Interface

The high-level resource interface wraps LMDB handles in a loving RAII embrace. This way, you can ensure e.g. that a transaction will get automatically aborted when exiting a lexical scope, regardless of whether the escape happened normally or by throwing an exception.

C handle C++ wrapper class
MDB_env* lmdb::env
MDB_txn* lmdb::txn
MDB_dbi lmdb::dbi
MDB_cursor* lmdb::cursor
MDB_val lmdb::val

The methods available on these C++ classes are named consistently with the procedural interface, below, with the obvious difference of omitting the handle type prefix which is already implied by the class in question.

Procedural Interface

The low-level procedural interface wraps LMDB functions with error-checking code that will throw an instance of a corresponding C++ exception class in case of failure. This interface doesn't offer any convenience overloads as does the resource interface; the parameter types are exactly the same as for the raw C interface offered by LMDB itself. The return type is generally void for these functions since the wrapper eats the error code returned by the underlying C function, throwing an exception in case of failure and otherwise returning values in the same output parameters as the C interface.

This interface is implemented entirely using static inline functions, so there are no hidden extra costs to using these wrapper functions so long as you have a decent compiler capable of basic inlining optimization.

C function C++ wrapper function
mdb_version() N/A
mdb_strerror() N/A
mdb_env_create() lmdb::env_create()
mdb_env_open() lmdb::env_open()
mdb_env_copy() lmdb::env_copy() [1]
mdb_env_copyfd() lmdb::env_copy_fd() [1]
mdb_env_copy2() lmdb::env_copy() [1]
mdb_env_copyfd2() lmdb::env_copy_fd() [1]
mdb_env_stat() lmdb::env_stat()
mdb_env_info() lmdb::env_info()
mdb_env_sync() lmdb::env_sync()
mdb_env_close() lmdb::env_close()
mdb_env_set_flags() lmdb::env_set_flags()
mdb_env_get_flags() lmdb::env_get_flags()
mdb_env_get_path() lmdb::env_get_path()
mdb_env_get_fd() lmdb::env_get_fd()
mdb_env_set_mapsize() lmdb::env_set_mapsize()
mdb_env_set_maxreaders() lmdb::env_set_max_readers()
mdb_env_get_maxreaders() lmdb::env_get_max_readers()
mdb_env_set_maxdbs() lmdb::env_set_max_dbs()
mdb_env_get_maxkeysize() lmdb::env_get_max_keysize()
mdb_env_set_userctx() lmdb::env_set_userctx() [2]
mdb_env_get_userctx() lmdb::env_get_userctx() [2]
mdb_env_set_assert() N/A
mdb_txn_begin() lmdb::txn_begin()
mdb_txn_env() lmdb::txn_env()
mdb_txn_id() lmdb::txn_id() [3]
mdb_txn_commit() lmdb::txn_commit()
mdb_txn_abort() lmdb::txn_abort()
mdb_txn_reset() lmdb::txn_reset()
mdb_txn_renew() lmdb::txn_renew()
mdb_dbi_open() lmdb::dbi_open()
mdb_stat() lmdb::dbi_stat() [4]_
mdb_dbi_flags() lmdb::dbi_flags()
mdb_dbi_close() lmdb::dbi_close()
mdb_drop() lmdb::dbi_drop() [4]_
mdb_set_compare() lmdb::dbi_set_compare() [4]_
mdb_set_dupsort() lmdb::dbi_set_dupsort() [4]_
mdb_set_relfunc() lmdb::dbi_set_relfunc() [4]_
mdb_set_relctx() lmdb::dbi_set_relctx() [4]_
mdb_get() lmdb::dbi_get() [4]_
mdb_put() lmdb::dbi_put() [4]_
mdb_del() lmdb::dbi_del() [4]_
mdb_cursor_open() lmdb::cursor_open()
mdb_cursor_close() lmdb::cursor_close()
mdb_cursor_renew() lmdb::cursor_renew()
mdb_cursor_txn() lmdb::cursor_txn()
mdb_cursor_dbi() lmdb::cursor_dbi()
mdb_cursor_get() lmdb::cursor_get()
mdb_cursor_put() lmdb::cursor_put()
mdb_cursor_del() lmdb::cursor_del()
mdb_cursor_count() lmdb::cursor_count()
mdb_cmp() N/A
mdb_dcmp() N/A
mdb_reader_list() TODO
mdb_reader_check() TODO

Footnotes

[1] (1, 2, 3, 4) Three-parameter signature available since LMDB 0.9.14 (2014/09/20).
[2] (1, 2) Only available since LMDB 0.9.11 (2014/01/15).
[3] Only available in LMDB HEAD, not yet in any 0.9.x release (as of 0.9.16). Define the LMDBXX_TXN_ID preprocessor symbol to unhide this.
[4] Note the difference in naming. (See below.)

Caveats

  • The C++ procedural interface is more strictly and consistently grouped by handle type than is the LMDB native interface. For instance, mdb_put() is wrapped as the C++ function lmdb::dbi_put(), not lmdb::put(). These differences--a handful in number--all concern operations on database handles.
  • The C++ interface takes some care to be const-correct for input-only parameters, something the original C interface largely ignores. Hence occasional use of const_cast in the wrapper code base.
  • lmdb::dbi_put() does not throw an exception if LMDB returns the MDB_KEYEXIST error code; it instead just returns false. This is intended to simplify common usage patterns.
  • lmdb::dbi_get(), lmdb::dbi_del(), and lmdb::cursor_get() do not throw an exception if LMDB returns the MDB_NOTFOUND error code; they instead just return false. This is intended to simplify common usage patterns.
  • lmdb::env_get_max_keysize() returns an unsigned integer, instead of a signed integer as the underlying mdb_env_get_maxkeysize() function does. This conversion is done since the return value cannot in fact be negative.

Error Handling

This wrapper draws a careful distinction between three different classes of possible LMDB error conditions:

  • Logic errors, represented by lmdb::logic_error. Errors of this class are thrown due to programming errors where the function interfaces are used in violation of documented preconditions. A common strategy for handling this class of error conditions is to abort the program with a core dump, facilitating introspection to locate and remedy the bug.
  • Fatal errors, represented by lmdb::fatal_error. Errors of this class are thrown due to the exhaustion of critical system resources, in particular available memory (ENOMEM), or due to attempts to exceed applicable system resource limits. A typical strategy for handling this class of error conditions is to terminate the program with a descriptive error message. More robust programs and shared libraries may wish to implement another strategy, such as retrying the operation after first letting most of the call stack unwind in order to free up scarce resources.
  • Runtime errors, represented by lmdb::runtime_error. Errors of this class are thrown as a matter of course to indicate various exceptional conditions. These conditions are generally recoverable, and robust programs will take care to correctly handle them.

Note

The distinction between logic errors and runtime errors mirrors that found in the C++11 standard library, where the <stdexcept> header defines the standard exception base classes std::logic_error and std::runtime_error. The standard exception class std::bad_alloc, on the other hand, is a representative example of a fatal error.

Error code Exception class Exception type
MDB_KEYEXIST lmdb::key_exist_error runtime
MDB_NOTFOUND lmdb::not_found_error runtime
MDB_CORRUPTED lmdb::corrupted_error fatal
MDB_PANIC lmdb::panic_error fatal
MDB_VERSION_MISMATCH lmdb::version_mismatch_error fatal
MDB_MAP_FULL lmdb::map_full_error runtime
MDB_BAD_DBI lmdb::bad_dbi_error runtime [4]_
(others) lmdb::runtime_error runtime

Footnotes

[4] Available since LMDB 0.9.14 (2014/09/20).

Note

MDB_KEYEXIST and MDB_NOTFOUND are handled specially by some functions.

Versioning Policy

The lmdb++ version tracks the upstream LMDB release (x.y.z) that it is compatible with, and appends a sub-patch-level version (x.y.z.N) to indicate changes to the wrapper itself.

For example, an lmdb++ release of 0.9.14.2 would indicate that it is designed for compatibility with LMDB 0.9.14, and is the third wrapper release (the first being .0, and the second .1) for that upstream target.

Note

To the extent that LMDB will preserve API and ABI compatibility going forward, older versions of the wrapper should work with newer versions of LMDB; and newer versions of the wrapper will generally work with older versions of LMDB by using the preprocessor to conditionalize the visibility of newer symbols--see, for example, the preprocessor guards around the definition of lmdb::env_set_userctx().

Installation

lmdb++ is currently available as a package/port in the following operating system distributions and package management systems:

Distribution Package Name Installation Hint
Arch Linux AUR liblmdb++ yaourt -Sa liblmdb++
Fink [5] lmdb++ sudo fink install lmdb++
MacPorts lmdbxx sudo port install lmdbxx
Portage [6] lmdb++ sudo emerge --ask lmdb++

Footnotes

[5] Still pending review.
[6] Compatible with Gentoo Linux, Funtoo Linux, and Sabayon Linux.

Support

To report a bug or submit a patch for lmdb++, please file an issue in the issue tracker on GitHub.

Questions and discussions about LMDB itself should be directed to the OpenLDAP mailing lists.

Elsewhere

Find this project at: GitHub, Bitbucket, Open Hub, SourceForge, Travis CI, and Coverity Scan.

The API documentation is published at: http://lmdbxx.sourceforge.net/

Author

Arto Bendiken - http://ar.to/

License

This is free and unencumbered public domain software. For more information, see http://unlicense.org/ or the accompanying UNLICENSE file.

Comments
  • Help needed cursor_put and MDB_MULTIPLE

    Help needed cursor_put and MDB_MULTIPLE

    Hi, I am trying yo use lmdb++ to work with LMDB. I have it working via the example you provided. I have a problem when trying to use cursor_put with MDB_MULTIPLE. I cant seem to get it to work right. Here is the code:

    `std::vector rawData(1000000, std::rand()); MDB_val value1, value2, key; value1.mv_size = sizeof(int); value1.mv_data = const_cast<void*> (static_cast<const void*> (&rawData[0]));; value2.mv_size = 1000000; MDB_val mData[2] = { value1, value2 }; int i = 0;

    auto env = lmdb::env::create(); env.set_mapsize(1UL * 1024UL * 1024UL * 1024UL); /* 1 GiB */ env.open(path.c_str(), 0, 0664); auto wtxn = lmdb::txn::begin(env); auto dbi = lmdb::dbi::open(wtxn, nullptr, MDB_DUPSORT | MDB_DUPFIXED | MDB_INTEGERDUP | MDB_CREATE); auto cursor = lmdb::cursor::open(wtxn, dbi); key.mv_size = sizeof(i); key.mv_data = &i; cursor_put(cursor, &key, mData, MDB_MULTIPLE);`

    I think I am probably misusing the lib or some part of it. So any advice would be good.

    opened by matija-kovacek-1995 5
  • Feature Request: remove dependency on pthreads?

    Feature Request: remove dependency on pthreads?

    I'd like to use lmdb++ but as it stands I cannot because of it's dependency on pthreads... The real problem is that on Windows it looks like the current code requires pthread_t from mingw and I am using Visual Studio on Windows. Since it requires a modern implementation of C++ anyway, might it be possible to use only standard features?

    invalid 
    opened by dicroce 4
  • Modify cursor_put so it matches dbi_put.

    Modify cursor_put so it matches dbi_put.

    dbi_put return false if it cannot insert a duplicate value because of MDB_NODUPDATA or MDB_NOOVERWRITE, while cursor_put will raise an exception.

    This patch modifies cursor_put so it has the same behavior as dbi_put.

    opened by suspend0 4
  • Example uses the same dbi instance with a different transaction

    Example uses the same dbi instance with a different transaction

    In the example code provided in your Readme.MD, the second transaction uses the "dbi" instance that was opened using the first transaction:

    auto dbi = lmdb::dbi::open(wtxn, nullptr);
    ...
    auto cursor = lmdb::cursor::open(rtxn, dbi);
    

    Is this recommended? Or should one open a new database for every transaction?

    help wanted question 
    opened by varung 2
  • Symbol mdb_env_create() doesn't resolve

    Symbol mdb_env_create() doesn't resolve

    I tried to compile your example.cc using the latest lmdb++.h in /usr/include like so:

    g++ example.cc
    

    But I get the followin error:

    /tmp/ccUhugbK.o: In function `lmdb::env_create(MDB_env**)':
    example.cc:(.text+0x14): undefined reference to `mdb_env_create'
    /tmp/ccUhugbK.o: In function `lmdb::env_open(MDB_env*, char const*, unsigned int, unsigned int)':
    example.cc:(.text+0x5b): undefined reference to `mdb_env_open'
    /tmp/ccUhugbK.o: In function `lmdb::env_close(MDB_env*)':
    example.cc:(.text+0x8e): undefined reference to `mdb_env_close'
    /tmp/ccUhugbK.o: In function `lmdb::env_set_flags(MDB_env*, unsigned int, bool)':
    example.cc:(.text+0xc8): undefined reference to `mdb_env_set_flags'
    /tmp/ccUhugbK.o: In function `lmdb::env_set_mapsize(MDB_env*, unsigned long)':
    example.cc:(.text+0x106): undefined reference to `mdb_env_set_mapsize'
    /tmp/ccUhugbK.o: In function `lmdb::txn_begin(MDB_env*, MDB_txn*, unsigned int, MDB_txn**)':
    example.cc:(.text+0x14f): undefined reference to `mdb_txn_begin'
    /tmp/ccUhugbK.o: In function `lmdb::txn_commit(MDB_txn*)':
    example.cc:(.text+0x182): undefined reference to `mdb_txn_commit'
    /tmp/ccUhugbK.o: In function `lmdb::txn_abort(MDB_txn*)':
    example.cc:(.text+0x1b5): undefined reference to `mdb_txn_abort'
    /tmp/ccUhugbK.o: In function `lmdb::dbi_open(MDB_txn*, char const*, unsigned int, unsigned int*)':
    example.cc:(.text+0x1e6): undefined reference to `mdb_dbi_open'
    /tmp/ccUhugbK.o: In function `lmdb::dbi_put(MDB_txn*, unsigned int, MDB_val const*, MDB_val*, unsigned int)':
    example.cc:(.text+0x239): undefined reference to `mdb_put'
    /tmp/ccUhugbK.o: In function `lmdb::cursor_open(MDB_txn*, unsigned int, MDB_cursor**)':
    example.cc:(.text+0x28b): undefined reference to `mdb_cursor_open'
    /tmp/ccUhugbK.o: In function `lmdb::cursor_close(MDB_cursor*)':
    example.cc:(.text+0x2be): undefined reference to `mdb_cursor_close'
    /tmp/ccUhugbK.o: In function `lmdb::cursor_get(MDB_cursor*, MDB_val*, MDB_val*, MDB_cursor_op)':
    example.cc:(.text+0x2ef): undefined reference to `mdb_cursor_get'
    /tmp/ccUhugbK.o: In function `lmdb::error::what() const':
    example.cc:(.text._ZNK4lmdb5error4whatEv[_ZNK4lmdb5error4whatEv]+0x1c): undefined reference to `mdb_strerror'
    collect2: error: ld returned 1 exit status
    

    Looking inside lmdb++.h it seems that mdb_env_create hasn't been defined anywhere, but it IS referenced.

    PS: Thanks for this great library, I hope to make use of it.

    invalid 
    opened by dbedrenko 1
  • thread-local storage is not supported for clang7

    thread-local storage is not supported for clang7

    Error is "lmdb++.h:97:12: error: thread-local storage is not supported for the current target static thread_local char buffer[1024];"

    Apple LLVM version 7.0.2 (clang-700.1.81) Target: x86_64-apple-darwin15.2.0 Thread model: posix

    help wanted 
    opened by sroycode 1
  • Querying for different types in key/value pair

    Querying for different types in key/value pair

    In my case, I'm storing key/value pairs as int/string.

    The problem arises when I wan't to check if given pair exists in database. Currently I'm only able to check if given key exists via lmdb::cursor::find. Is it somehow possible to do this for key/value pair?

    help wanted 
    opened by Thazz 1
  • MSVC support

    MSVC support

    Hello,

    while trying to compile on windows I ran into a few minor issues.

    Mainly because Microsoft has not updated __cplusplus for years.

    For some odd reason it does not think lmdb::val is a POD. Given the info on PODTypes on CppReference I'd guess it's still doing pre-11 checks or the default-declared dtor confuses him.

    My testings were done with VS2015, which afaik is fully compliant with c++11.

    enhancement 
    opened by gregoire-astruc 1
  • problem in lmdb++.h line 1654

    problem in lmdb++.h line 1654

    in lmdb::dbi_put there is no way to put an element like : int data[10] lmdb::val lmdbData((void*)data, sizeof(int)*10 ); ... dbi.put(wtxn, "data", lmdbData))

    bug 
    opened by vivipac 1
  • Adding code to run on Powersystem

    Adding code to run on Powersystem

    Hi Here is my contribution to your code, its working good on powersystems.

    Thanks for the code, its working good.

    What do these changes do?

    Added Architecture "ppc64le"

    Are there changes in behavior for the user?

    No

    opened by genisysram 1
  • Double-free when txn.commit() throws

    Double-free when txn.commit() throws

    @core-process noticed and fixed this issue in our C++17 fork of lmdbxx:

    If an exception was throw by txn.commit() (ie MDB_MAP_FULL), and this transaction was later aborted (because it went out of scope while unwinding the stack), then a double-free would occur.

    You can use the following test to observe this (address sanitizer should be enabled, as it is by default in our Makefile):

    https://github.com/hoytech/lmdbxx/blob/5223582ebf92a9b14608ce6768535aef0c65910f/check.cc#L329

    bug 
    opened by hoytech 0
  • Cursor.get returns key and value concatenated into key variable

    Cursor.get returns key and value concatenated into key variable

    Weird output from cursor get: I would get both key and value inside the key variable, then the value inside the value variable :

    #include <cstdio>
    #include <cstdlib>
    #include <lmdb++.h>
    using namespace lmdb;
    int getsize(const lmdb::env& e){
        auto t = lmdb::txn::begin(e.handle(), nullptr, MDB_RDONLY);
        auto d = lmdb::dbi::open(t, nullptr);
        int r=d.size(t);
        t.abort();
        return r;
    }
    
    
    int main() {
      auto env = lmdb::env::create();
      env.set_mapsize(1UL * 1024UL * 1024UL * 1024UL); /* 1 GiB */
      env.open("./example.mdb", 0, 0664);
      {
        auto wtxn = lmdb::txn::begin(env);
        auto dbi = lmdb::dbi::open(wtxn, nullptr);
        char a[6] = "hello";
        dbi.put(wtxn, "email", "hello");
        dbi.put(wtxn, "key", "value");
        dbi.put(wtxn, "user", "johndoe");
        wtxn.commit();
      }
      {
          auto rtxn = lmdb::txn::begin(env);
          auto dbi = lmdb::dbi::open(rtxn, nullptr);
          auto cursor = lmdb::cursor::open(rtxn, dbi);
          lmdb::val k, v;
          while(cursor.get(k, v, MDB_NEXT)){
            printf("We got '%s'\nValue '%s'\n", k.data(), v.data());
          }
      }
      {
        std::printf("size is %d\n", getsize(env));
      }
    return EXIT_SUCCESS;
    }
    
    

    Expected Output:

    We got 'email'
    Value 'hello'
    We got 'key'
    Value 'value'
    We got 'user'
    Value 'johndoe'
    size is 3
    
    

    Output :

    We got 'emailhello'
    Value 'hello'
    We got 'keyvalue'
    Value 'value'
    We got 'userjohndoe'
    Value 'johndoe'
    size is 3
    
    
    opened by DrissiReda 10
  • mdb_del : Invalid argument for simple deletion

    mdb_del : Invalid argument for simple deletion

    I tried to simply delete an entry, and can't really know if I'm wrong or if this is a bug, the only documentation I could find was the api reference, if anyone has better material I'd be glad to take it.

    #include <cstdio>
    #include <cstdlib>
    #include <lmdb++.h>
    using namespace lmdb;
    int main() {
      auto env = lmdb::env::create();
      env.set_mapsize(1UL * 1024UL * 1024UL); 
      env.open("./example.mdb", 0, 0664);
    
      auto wtxn = lmdb::txn::begin(env);
      auto dbi = lmdb::dbi::open(wtxn, nullptr);
      dbi.put(wtxn, "key_entry", "value_entry");
      wtxn.commit();
      dbi.del(wtxn, "key_entry");
    
      return EXIT_SUCCESS;
    }
    

    This yields the following error :

    terminate called after throwing an instance of 'lmdb::runtime_error'
      what():  mdb_del: Invalid argument
    
    
    opened by DrissiReda 9
Releases(0.9.14.0)
Owner
D.R.Y. C++
Public domain libraries for the C++ programming language.
D.R.Y. C++
MySQL Server, the world's most popular open source database, and MySQL Cluster, a real-time, open source transactional database.

Copyright (c) 2000, 2021, Oracle and/or its affiliates. This is a release of MySQL, an SQL database server. License information can be found in the

MySQL 8.6k Dec 26, 2022
A mini database for learning database

A mini database for learning database

Chuckie Tan 4 Nov 14, 2022
ESE is an embedded / ISAM-based database engine, that provides rudimentary table and indexed access.

Extensible-Storage-Engine A Non-SQL Database Engine The Extensible Storage Engine (ESE) is one of those rare codebases having proven to have a more th

Microsoft 792 Dec 22, 2022
A very fast lightweight embedded database engine with a built-in query language.

upscaledb 2.2.1 Fr 10. Mär 21:33:03 CET 2017 (C) Christoph Rupp, [email protected]; http://www.upscaledb.com This is t

Christoph Rupp 542 Dec 30, 2022
libmdbx is an extremely fast, compact, powerful, embedded, transactional key-value database, with permissive license

One of the fastest embeddable key-value ACID database without WAL. libmdbx surpasses the legendary LMDB in terms of reliability, features and performance.

Леонид Юрьев (Leonid Yuriev) 1.1k Dec 19, 2022
An Embedded NoSQL, Transactional Database Engine

UnQLite - Transactional Embedded Database Engine

PixLab | Symisc Systems 1.8k Dec 24, 2022
C++ embedded memory database

ShadowDB 一个C++嵌入式内存数据库 语法极简风 支持自定义索引、复合条件查询('<','<=','==','>=','>','!=',&&,||) 能够快速fork出一份数据副本 // ShadowDB简单示例 // ShadowDB是一个可以创建索引、能够快速fork出一份数据分支的C+

null 13 Nov 10, 2022
SOCI - The C++ Database Access Library

Originally, SOCI was developed by Maciej Sobczak at CERN as abstraction layer for Oracle, a Simple Oracle Call Interface. Later, several database backends have been developed for SOCI, thus the long name has lost its practicality. Currently, if you like, SOCI may stand for Simple Open (Database) Call Interface or something similar.

SOCI 1.2k Jan 9, 2023
Velox is a new C++ vectorized database acceleration library aimed to optimizing query engines and data processing systems.

Velox is a C++ database acceleration library which provides reusable, extensible, and high-performance data processing components

Facebook Incubator 2k Jan 8, 2023
The fastest database-library on Android OS.

Android SQLite3 NDK 封装 Demo下载 (操作:按钮新增 按钮查询 点按编辑 长按删除) 写在前面 sqlite3 开源、集成简单(现在的版本只有2个文件 sqlite3.h sqlite3.c) 这个库抽离自 Telegram 的开源代码、作者:DrKLO 我个人感觉 Tele

水银灯、 2 Dec 27, 2021
A friendly and lightweight C++ database library for MySQL, PostgreSQL, SQLite and ODBC.

QTL QTL is a C ++ library for accessing SQL databases and currently supports MySQL, SQLite, PostgreSQL and ODBC. QTL is a lightweight library that con

null 173 Dec 12, 2022
Trilogy is a client library for MySQL-compatible database servers, designed for performance, flexibility, and ease of embedding.

Trilogy is a client library for MySQL-compatible database servers, designed for performance, flexibility, and ease of embedding.

GitHub 482 Dec 31, 2022
dqlite is a C library that implements an embeddable and replicated SQL database engine with high-availability and automatic failover

dqlite dqlite is a C library that implements an embeddable and replicated SQL database engine with high-availability and automatic failover. The acron

Canonical 3.3k Jan 9, 2023
The C++14 wrapper around sqlite library

sqlite modern cpp wrapper This library is a lightweight modern wrapper around sqlite C api . #include<iostream> #include <sqlite_modern_cpp.h> using n

null 720 Dec 29, 2022
Nebula Graph is a distributed, fast open-source graph database featuring horizontal scalability and high availability

Nebula Graph is an open-source graph database capable of hosting super large scale graphs with dozens of billions of vertices (nodes) and trillions of edges, with milliseconds of latency.

vesoft inc. 834 Dec 24, 2022
DuckDB is an in-process SQL OLAP Database Management System

DuckDB is an in-process SQL OLAP Database Management System

DuckDB 7.8k Jan 3, 2023
YugabyteDB is a high-performance, cloud-native distributed SQL database that aims to support all PostgreSQL features

YugabyteDB is a high-performance, cloud-native distributed SQL database that aims to support all PostgreSQL features. It is best to fit for cloud-native OLTP (i.e. real-time, business-critical) applications that need absolute data correctness and require at least one of the following: scalability, high tolerance to failures, or globally-distributed deployments.

yugabyte 7.4k Jan 7, 2023
TimescaleDB is an open-source database designed to make SQL scalable for time-series data.

An open-source time-series SQL database optimized for fast ingest and complex queries. Packaged as a PostgreSQL extension.

Timescale 14.3k Jan 2, 2023
Beryl-cli is a client for the BerylDB database server

Beryl-cli is a client for the BerylDB database server. It offers multiple commands and is designed to be fast and user-friendly.

BerylDB 11 Oct 9, 2022