无法从LMDB获取价值

时间:2019-04-16 16:02:32

标签: c++ c lmdb

我正在尝试存储和从LMDB获取一些数据。数据似乎已经存储了,我可以在数据库中看到键,但是当我尝试使用与我刚刚存储在其中的ID相同的值来获取值时,它会给我MDB_NOTFOUND

数据库打开

    MDB_env* environment;
    MDB_dbi main;
    MDB_dbi order;
    mdb_env_create(&environment);
    mdb_env_set_maxdbs(environment, 2);
    mdb_env_open(environment, path.toStdString().c_str(), 0, 0664);

    int rc;
    MDB_txn *txn;
    mdb_txn_begin(environment, NULL, 0, &txn);
    mdb_dbi_open(txn, "main", MDB_CREATE, &main);
    mdb_dbi_open(txn, "order", MDB_CREATE | MDB_INTEGERKEY, &order);
    mdb_txn_commit(txn);

插入

void Core::Archive::addElement(const Shared::Message& message) {
    QByteArray ba;
    QDataStream ds(&ba, QIODevice::WriteOnly);
    message.serialize(ds);
    uint64_t stamp = message.getTime().toMSecsSinceEpoch();
    const std::string& id = message.getId().toStdString();

    MDB_val lmdbKey, lmdbData;
    lmdbKey.mv_size = id.size();
    lmdbKey.mv_data = (uint8_t*)id.c_str();
    lmdbData.mv_size = ba.size();
    lmdbData.mv_data = (uint8_t*)ba.data();
    MDB_txn *txn;
    mdb_txn_begin(environment, NULL, 0, &txn);
    int rc;
    rc = mdb_put(txn, main, &lmdbKey, &lmdbData, 0);
    if (rc == 0) {
        MDB_val orderKey;
        orderKey.mv_size = 8;
        orderKey.mv_data = (uint8_t*) &stamp;

        rc = mdb_put(txn, order, &orderKey, &lmdbKey, 0);
        if (rc) {
            mdb_txn_abort(txn);
        } else {
            rc = mdb_txn_commit(txn);
            if (rc) {
                qDebug() << "A transaction error: " << mdb_strerror(rc);
            }
        }
    } else {
        qDebug() << "An element couldn't been added to the archive, skipping" << mdb_strerror(rc);
        mdb_txn_abort(txn);
    }
}

正在获取

Shared::Message Core::Archive::getElement(const QString& id) {
    MDB_val lmdbKey, lmdbData;
    lmdbKey.mv_size = id.toStdString().size();
    lmdbKey.mv_data = (uint8_t*)id.toStdString().c_str();

    MDB_txn *txn;
    int rc;
    mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
    rc = mdb_get(txn, main, &lmdbKey, &lmdbData);
    if (rc) {
        qDebug() <<"Get error: " << mdb_strerror(rc);
        mdb_txn_abort(txn);
        throw NotFound(id.toStdString(), jid.toStdString());
    } else {
        //it never comes here
    }
}

测试代码

Core::Archive ar();
ar.open("Test");
Shared::Message msg1;
msg1.generateRandomId();
msg1.setBody("oldest");
msg1.setTime(QDateTime::currentDateTime().addDays(-7));
Shared::Message msg2;
msg2.generateRandomId();
msg2.setBody("Middle");
msg2.setTime(QDateTime::currentDateTime().addDays(-4));
Shared::Message msg3;
msg3.generateRandomId();
msg3.setBody("newest");
msg3.setTime(QDateTime::currentDateTime());

ar.addElement(msg2);
ar.addElement(msg3);
ar.addElement(msg1);

Shared::Message d0 = ar.getElement(msg1.getId());

我的日志显示存储的密钥。我可以看到所需的键,如果我使用光标在整个存储空间上滚动,我什至可以将其与请求的键进行比较,它甚至表明它们是相等的,但是mdb_cursor_getmdb_get经常给我{ {1}}。我在做什么错了?

1 个答案:

答案 0 :(得分:0)

我明白了。不管我把什么放在数据库中,我都必须将其读取为字符*

必须修改获取代码

lmdbKey.mv_data = (uint8_t*)id.toStdString().c_str();

我不得不将其更改为

lmdbKey.mv_data = (char*)id.toStdString().c_str();

成功了