Не могу получить значение из LMDB - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь сохранить и извлечь некоторые данные из LMDB. Кажется, что данные хранятся, я вижу ключи в моей базе данных, но при попытке извлечь значение с тем же идентификатором, под которым я только что его сохранил, выдается 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);

1010 * Вставка *

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);
    }
}

* Получение 1015 *

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_get или mdb_get постоянно дают мне MDB_NOTFOUND. Что я делаю не так?

1 Ответ

0 голосов
/ 17 апреля 2019

Я понял.Независимо от того, что я положил в базу данных, я должен читать его как символ *

Пришлось изменить код извлечения

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

Мне пришлось изменить его на

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

и все заработало

...