C语言封装LMDB数据库接口示例
#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的数据库,并插入了一个键值对。然后我们读取了这个键对应的值并打印出来,最后删除了这个键值对并关闭了数据库。
原文地址: https://www.cveoy.top/t/topic/mj6z 著作权归作者所有。请勿转载和采集!