Rust数据库绑定库leveldb-sys的使用,支持高效LevelDB键值存储引擎的原生接口调用

leveldb-sys

LevelDB C库的低级绑定。

依赖

  • 您平台的C++编译器(在Linux和Unix上通常是gccclang,在Windows上是Visual Studio构建环境)
  • cmake

用法

如果您的项目使用Cargo,请在Cargo.toml中添加以下行:

[dependencies]
leveldb-sys = "*"

特性

levelbd-sys提供了一个snappy特性来构建snappy库。

许可证

MIT

BSD支持

要构建leveldb-sys,您需要安装gmake(GNU Make)

安装

在您的项目目录中运行以下Cargo命令:

cargo add leveldb-sys

或在您的Cargo.toml中添加以下行:

leveldb-sys = "2.0.9"

完整示例代码

// Cargo.toml
[dependencies]
leveldb-sys = "2.0.9"
// main.rs
extern crate leveldb_sys;

use std::ptr;
use std::ffi::CString;

fn main() {
    // 创建数据库选项
    let mut options = leveldb_sys::leveldb_options_create();
    leveldb_sys::leveldb_options_set_create_if_missing(options, 1);
    
    // 打开数据库
    let db_path = CString::new("./test_db").unwrap();
    let mut error: *mut i8 = ptr::null_mut();
    let db = unsafe {
        leveldb_sys::leveldb_open(
            options,
            db_path.as_ptr(),
            &mut error
        )
    };
    
    if !error.is_null() {
        println!("Error opening database");
        return;
    }
    
    // 创建写入选项
    let write_options = leveldb_sys::leveldb_writeoptions_create();
    
    // 写入数据
    let key = CString::new("test_key").unwrap();
    let value = CString::new("test_value").unwrap();
    
    unsafe {
        leveldb_sys::leveldb_put(
            db,
            write_options,
            key.as_ptr(),
            key.as_bytes().len(),
            value.as_ptr(),
            value.as_bytes().len(),
            &mut error
        );
    }
    
    if !error.is_null() {
        println!("Error writing to database");
        return;
    }
    
    // 创建读取选项
    let read_options = leveldb_sys::leveldb_readoptions_create();
    
    // 读取数据
    let mut value_len: usize = 0;
    let value_ptr = unsafe {
        leveldb_sys::leveldb_get(
            db,
            read_options,
            key.as_ptr(),
            key.as_bytes().len(),
            &mut value_len,
            &mut error
        )
    };
    
    if !error.is_null() {
        println!("Error reading from database");
        return;
    }
    
    if !value_ptr.is_null() {
        let value_slice = unsafe {
            std::slice::from_raw_parts(value_ptr as *const u8, value_len)
        };
        let value_str = std::str::from_utf8(value_slice).unwrap();
        println!("Read value: {}", value_str);
        
        // 释放内存
        unsafe {
            leveldb_sys::leveldb_free(value_ptr as *mut std::ffi::c_void);
        }
    }
    
    // 清理资源
    unsafe {
        leveldb_sys::leveldb_writeoptions_destroy(write_options);
        leveldb_sys::leveldb_readoptions_destroy(read_options);
        leveldb_sys::leveldb_options_destroy(options);
        leveldb_sys::leveldb_close(db);
    }
    
    println!("Database operations completed successfully");
}

1 回复

Rust数据库绑定库leveldb-sys使用指南

概述

leveldb-sys是Rust语言对LevelDB键值存储引擎的原始系统绑定库,提供对LevelDB C++库的直接接口调用。该库为需要高性能键值存储的Rust应用程序提供底层原生支持。

主要特性

  • 提供LevelDB C++ API的原始Rust绑定
  • 支持高效的键值存储和检索操作
  • 支持原子批处理操作
  • 提供迭代器功能用于范围查询
  • 支持自定义比较器和压缩器

安装方法

在Cargo.toml中添加依赖:

[dependencies]
leveldb-sys = "0.8"
libc = "0.2"

基本使用方法

1. 打开数据库

use leveldb_sys::*;
use std::ptr;
use std::ffi::CString;

let mut options = leveldb_options_create();
leveldb_options_set_create_if_missing(options, 1);

let mut error: *mut i8 = ptr::null_mut();
let db_name = CString::new("test_db").unwrap();
let db = leveldb_open(options, db_name.as_ptr(), &mut error);

if !error.is_null() {
    // 错误处理
    let error_msg = unsafe { CStr::from_ptr(error) };
    eprintln!("打开数据库失败: {:?}", error_msg);
    leveldb_free(error as *mut std::ffi::c_void);
}

2. 写入数据

let write_options = leveldb_writeoptions_create();
let key = CString::new("my_key").unwrap();
let value = CString::new("my_value").unwrap();

let mut error: *mut i8 = ptr::null_mut();
leveldb_put(
    db,
    write_options,
    key.as_ptr() as *const i8,
    key.as_bytes().len(),
    value.as_ptr() as *const i8,
    value.as_bytes().len(),
    &mut error,
);

leveldb_writeoptions_destroy(write_options);

3. 读取数据

let read_options = leveldb_readoptions_create();
let mut value_len: usize = 0;
let mut error: *mut i8 = ptr::null_mut();

let value_ptr = leveldb_get(
    db,
    read_options,
    key.as_ptr() as *const i8,
    key.as_bytes().len(),
    &mut value_len,
    &mut error,
);

if !value_ptr.is_null() {
    let value_slice = unsafe {
        std::slice::from_raw_parts(value_ptr as *const u8, value_len)
    };
    let value_str = std::str::from_utf8(value_slice).unwrap();
    println!("读取的值: {}", value_str);
    leveldb_free(value_ptr as *mut std::ffi::c_void);
}

leveldb_readoptions_destroy(read_options);

4. 删除数据

let write_options = leveldb_writeoptions_create();
let mut error: *mut i8 = ptr::null_mut();

leveldb_delete(
    db,
    write_options,
    key.as_ptr() as *const i8,
    key.as_bytes().len(),
    &mut error,
);

leveldb_writeoptions_destroy(write_options);

5. 批量操作

let write_options = leveldb_writeoptions_create();
let batch = leveldb_writebatch_create();

// 添加多个操作到批处理
leveldb_writebatch_put(
    batch,
    key1.as_ptr() as *const i8,
    key1.as_bytes().len(),
    value1.as_ptr() as *const i8,
    value1.as_bytes().len(),
);

leveldb_writebatch_delete(
    batch,
    key2.as_ptr() as *const i8,
    key2.as_bytes().len(),
);

let mut error: *mut i8 = ptr::null_mut();
leveldb_write(db, write_options, batch, &mut error);

leveldb_writebatch_destroy(batch);
leveldb_writeoptions_destroy(write_options);

注意事项

  1. leveldb-sys是底层绑定库,使用时需要手动管理内存和错误处理
  2. 所有字符串参数都需要转换为C字符串格式
  3. 使用后需要正确释放资源,避免内存泄漏
  4. 建议在生产环境中使用更高级的Rust LevelDB封装库

资源清理

// 关闭数据库
leveldb_close(db);

// 销毁选项对象
leveldb_options_destroy(options);

完整示例代码

use leveldb_sys::*;
use std::ffi::{CStr, CString};
use std::ptr;

fn main() {
    // 创建数据库选项
    let mut options = leveldb_options_create();
    leveldb_options_set_create_if_missing(options, 1); // 如果数据库不存在则创建

    // 打开数据库
    let mut error: *mut i8 = ptr::null_mut();
    let db_name = CString::new("example_db").unwrap();
    let db = leveldb_open(options, db_name.as_ptr(), &mut error);
    
    if !error.is_null() {
        let error_msg = unsafe { CStr::from_ptr(error) };
        eprintln!("打开数据库失败: {:?}", error_msg);
        leveldb_free(error as *mut std::ffi::c_void);
        return;
    }

    // 写入数据
    let write_options = leveldb_writeoptions_create();
    let key = CString::new("test_key").unwrap();
    let value = CString::new("test_value").unwrap();
    
    let mut error: *mut i8 = ptr::null_mut();
    leveldb_put(
        db,
        write_options,
        key.as_ptr() as *const i8,
        key.as_bytes().len(),
        value.as_ptr() as *const i8,
        value.as_bytes().len(),
        &mut error,
    );
    
    if !error.is_null() {
        let error_msg = unsafe { CStr::from_ptr(error) };
        eprintln!("写入数据失败: {:?}", error_msg);
        leveldb_free(error as *mut std::ffi::c_void);
    }

    // 读取数据
    let read_options = leveldb_readoptions_create();
    let mut value_len: usize = 0;
    let mut error: *mut i8 = ptr::null_mut();
    
    let value_ptr = leveldb_get(
        db,
        read_options,
        key.as_ptr() as *const i8,
        key.as_bytes().len(),
        &mut value_len,
        &mut error,
    );
    
    if !error.is_null() {
        let error_msg = unsafe { CStr::from_ptr(error) };
        eprintln!("读取数据失败: {:?}", error_msg);
        leveldb_free(error as *mut std::ffi::c_void);
    } else if !value_ptr.is_null() {
        let value_slice = unsafe {
            std::slice::from_raw_parts(value_ptr as *const u8, value_len)
        };
        let value_str = std::str::from_utf8(value_slice).unwrap();
        println!("成功读取值: {}", value_str);
        leveldb_free(value_ptr as *mut std::ffi::c_void);
    }

    // 删除数据
    let mut error: *mut i8 = ptr::null_mut();
    leveldb_delete(
        db,
        write_options,
        key.as_ptr() as *const i8,
        key.as_bytes().len(),
        &mut error,
    );
    
    if !error.is_null() {
        let error_msg = unsafe { CStr::from_ptr(error) };
        eprintln!("删除数据失败: {:?}", error_msg);
        leveldb_free(error as *mut std::ffi::c_void);
    }

    // 资源清理
    leveldb_writeoptions_destroy(write_options);
    leveldb_readoptions_destroy(read_options);
    leveldb_close(db);
    leveldb_options_destroy(options);
    
    println!("示例程序执行完成");
}

这个基础指南展示了leveldb-sys库的核心功能和使用方法,开发者可以根据具体需求进一步探索更高级的功能。

回到顶部