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

typedef struct { MDB_env* env; MDB_dbi dbi; } lmdb_t;

int lmdb_open(lmdb_t* lmdb, const char* path, int flags, int mode) { int rc; rc = mdb_env_create(&lmdb->env); if (rc != 0) { fprintf(stderr, 'Failed to create LMDB environment: %s\n', mdb_strerror(rc)); return -1; }

rc = mdb_env_set_maxdbs(lmdb->env, 1);
if (rc != 0) {
    fprintf(stderr, 'Failed to set LMDB maxdbs: %s\n', mdb_strerror(rc));
    mdb_env_close(lmdb->env);
    return -1;
}

rc = mdb_env_open(lmdb->env, path, flags, mode);
if (rc != 0) {
    fprintf(stderr, 'Failed to open LMDB environment: %s\n', mdb_strerror(rc));
    mdb_env_close(lmdb->env);
    return -1;
}

rc = mdb_txn_begin(lmdb->env, NULL, 0, &lmdb->txn);
if (rc != 0) {
    fprintf(stderr, 'Failed to begin LMDB transaction: %s\n', mdb_strerror(rc));
    mdb_env_close(lmdb->env);
    return -1;
}

rc = mdb_dbi_open(lmdb->txn, NULL, 0, &lmdb->dbi);
if (rc != 0) {
    fprintf(stderr, 'Failed to open LMDB database: %s\n', mdb_strerror(rc));
    mdb_txn_abort(lmdb->txn);
    mdb_env_close(lmdb->env);
    return -1;
}

rc = mdb_txn_commit(lmdb->txn);
if (rc != 0) {
    fprintf(stderr, 'Failed to commit LMDB transaction: %s\n', mdb_strerror(rc));
    mdb_env_close(lmdb->env);
    return -1;
}

return 0;

}

int lmdb_close(lmdb_t* lmdb) { mdb_dbi_close(lmdb->env, lmdb->dbi); mdb_env_close(lmdb->env); return 0; }

int lmdb_put(lmdb_t* lmdb, const char* key, size_t key_size, const void* value, size_t value_size) { int rc; MDB_val k, v; MDB_txn* txn;

k.mv_size = key_size;
k.mv_data = (void*)key;

v.mv_size = value_size;
v.mv_data = (void*)value;

rc = mdb_txn_begin(lmdb->env, NULL, 0, &txn);
if (rc != 0) {
    fprintf(stderr, 'Failed to begin LMDB transaction: %s\n', mdb_strerror(rc));
    return -1;
}

rc = mdb_put(txn, lmdb->dbi, &k, &v, 0);
if (rc != 0) {
    fprintf(stderr, 'Failed to put value into LMDB: %s\n', mdb_strerror(rc));
    mdb_txn_abort(txn);
    return -1;
}

rc = mdb_txn_commit(txn);
if (rc != 0) {
    fprintf(stderr, 'Failed to commit LMDB transaction: %s\n', mdb_strerror(rc));
    return -1;
}

return 0;

}

int lmdb_get(lmdb_t* lmdb, const char* key, size_t key_size, void** value, size_t* value_size) { int rc; MDB_val k, v; MDB_txn* txn;

k.mv_size = key_size;
k.mv_data = (void*)key;

rc = mdb_txn_begin(lmdb->env, NULL, MDB_RDONLY, &txn);
if (rc != 0) {
    fprintf(stderr, 'Failed to begin LMDB transaction: %s\n', mdb_strerror(rc));
    return -1;
}

rc = mdb_get(txn, lmdb->dbi, &k, &v);
if (rc != 0) {
    fprintf(stderr, 'Failed to get value from LMDB: %s\n', mdb_strerror(rc));
    mdb_txn_abort(txn);
    return -1;
}

*value = malloc(v.mv_size);
memcpy(*value, v.mv_data, v.mv_size);
*value_size = v.mv_size;

rc = mdb_txn_commit(txn);
if (rc != 0) {
    fprintf(stderr, 'Failed to commit LMDB transaction: %s\n', mdb_strerror(rc));
    return -1;
}

return 0;

}

int lmdb_delete(lmdb_t* lmdb, const char* key, size_t key_size) { int rc; MDB_val k; MDB_txn* txn;

k.mv_size = key_size;
k.mv_data = (void*)key;

rc = mdb_txn_begin(lmdb->env, NULL, 0, &txn);
if (rc != 0) {
    fprintf(stderr, 'Failed to begin LMDB transaction: %s\n', mdb_strerror(rc));
    return -1;
}

rc = mdb_del(txn, lmdb->dbi, &k, NULL);
if (rc != 0) {
    fprintf(stderr, 'Failed to delete value from LMDB: %s\n', mdb_strerror(rc));
    mdb_txn_abort(txn);
    return -1;
}

rc = mdb_txn_commit(txn);
if (rc != 0) {
    fprintf(stderr, 'Failed to commit LMDB transaction: %s\n', mdb_strerror(rc));
    return -1;
}

return 0;

}

int main() { lmdb_t lmdb; char* value; size_t value_size;

if (lmdb_open(&lmdb, './test.lmdb', MDB_CREATE, 0664) != 0) {
    return -1;
}

if (lmdb_put(&lmdb, 'key', 3, 'value', 5) != 0) {
    lmdb_close(&lmdb);
    return -1;
}

if (lmdb_get(&lmdb, 'key', 3, (void**)&value, &value_size) != 0) {
    lmdb_close(&lmdb);
    return -1;
}

printf('Got value: %.*s\n', (int)value_size, value);

free(value);

if (lmdb_delete(&lmdb, 'key', 3) != 0) {
    lmdb_close(&lmdb);
    return -1;
}

lmdb_close(&lmdb);

return 0;

}

这个示例代码中,我们定义了一个lmdb_t结构体,它包含了一个MDB_env对象和一个MDB_dbi对象,分别表示LMDB环境和数据库句柄。我们定义了几个对LMDB数据库进行操作的函数,包括打开和关闭数据库、插入、读取和删除数据。

lmdb_open函数中,我们首先创建了一个LMDB环境,并设置最大数据库数量为1。然后我们打开了LMDB环境,并开始一个事务。接着我们打开了一个数据库,并提交了事务。在lmdb_close函数中,我们先关闭了数据库句柄,再关闭了LMDB环境。

lmdb_put函数中,我们将一个键值对插入到数据库中。在lmdb_get函数中,我们读取了一个键对应的值,并将其存储在一个动态分配的缓冲区中。在lmdb_delete函数中,我们删除了一个键值对。

在示例程序中,我们先打开了一个名为test.lmdb的数据库,并插入了一个键值对。然后我们读取了这个键对应的值并打印出来,最后删除了这个键值对并关闭了数据库。

C语言封装LMDB数据库接口示例

原文地址: https://www.cveoy.top/t/topic/mj6z 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录