0

How can I get the data from LMDB database? Here is the library - github.com/LMDB/lmdb/tree/mdb.master/libraries/liblmdb, and here is the lmdb file - github.com/LMDB/lmdb/blob/mdb.master/libraries/liblmdb/lmdb.h

Here is my code, but it is not working, I get segmentation error:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lmdb.h"

#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
    "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))

#define DBDIR "./testdb"

/* Put to db */
int putdb(char *, char *);

/* Get from db */
int getdb(char *);


int main()
{
    putdb("key", "value");
    getdb("key");

    return 0;
}

/* Put to db */
int putdb(char *keyvalue, char *value) {

    int rc;
    MDB_env *env;
    MDB_dbi dbi;
    MDB_txn *txn;
    MDB_val key, data, rdata;
    MDB_cursor *cursor;
    char sval[32];

    printf("put %s %s\n",keyvalue, value);

    E(mdb_env_create(&env));
    E(mdb_env_open(env, DBDIR, 0, 0664));

    /* Put some data */
    E(mdb_txn_begin(env, NULL, 0, &txn));
    E(mdb_dbi_open(txn, NULL, 0, &dbi));

    key.mv_data = keyvalue;
    key.mv_size = strlen(keyvalue);
    data.mv_data = value;
    data.mv_size = strlen(value);

    E(mdb_put(txn, dbi, &key, &data, 0));

    E(mdb_txn_commit(txn));

    mdb_dbi_close(env, dbi);
    mdb_env_close(env);

    return 0;
}

/* Get from lmdb */
int getdb(char *thekey) {

    int rc;
    MDB_env *env;
    MDB_dbi dbi;
    MDB_txn *txn;
    MDB_val key, data, rdata;
    MDB_cursor *cursor;

    printf("get %s\n", thekey);

    E(mdb_env_create(&env));
    //E(mdb_env_open(env, DBDIR, 0, 0664));

    /* Get some data */
    E(mdb_txn_begin(env, NULL, 0, &txn));
    E(mdb_dbi_open(txn, NULL, 0, &dbi));

    key.mv_data = thekey;
    key.mv_size = strlen(thekey);

    //data.mv_data = &somedata;
    //data.mv_size = sizeof(somedata);

    mdb_get(txn, dbi, &key, &data);

    printf("%s %d, %s %d\n", (char *) key.mv_data, key.mv_size, (char *)data.mv_data, data.mv_size);

    E(mdb_txn_commit(txn));


    mdb_dbi_close(env, dbi);
    mdb_env_close(env);

    return 0;
}

What is wrong? Maybe I need to initialize the data.mv_data and data.mv_size but how can I know the size before getting the value.

I could not find any examples with such code.

  • the posted code is trying to #include a file named `lmdb.h`, which seems to be something you created. For us to debug this, you need to post that file. – user3629249 Mar 29 '16 at 23:21
  • for ease of readability and understanding by us humans, please follow the axiom: *only one statement per line and (at most) one variable declaration per statement.* – user3629249 Mar 29 '16 at 23:24
  • Here is the library - https://github.com/LMDB/lmdb/tree/mdb.master/libraries/liblmdb, and here is the lmdb file - https://github.com/LMDB/lmdb/blob/mdb.master/libraries/liblmdb/lmdb.h – Sebastian Rockefeller Mar 30 '16 at 06:31

1 Answers1

1

This is at least strange:

key.mv_data = &keyvalue;
key.mv_size = strlen(keyvalue);
data.mv_data = value;
data.mv_size = strlen(value);

Both keyvalue and value are char * so data gets a char * in its mv_data member while key gets a char ** (one more indirection level).

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • Right, there should be key.mv_data = keyvalue; I corrected, but get is still not working – Sebastian Rockefeller Mar 30 '16 at 07:50
  • 1
    @SebastianRockefeller: there's is same extra `&` in `getdb`: `key.mv_data = &thekey;` But compiler should have issued warnings about that, and when you get segfaults you should really take care of warnings... – Serge Ballesta Mar 30 '16 at 07:54