#duck-db #ffi #api-bindings #native-bindings

sys libduckdb-sys

对 libduckdb 库的本地绑定,C API

25 个版本 (1 个稳定版)

1.0.0 2024年7月11日
0.10.2 2024年4月24日
0.10.1 2024年3月19日
0.9.2 2023年12月1日
0.1.2 2021年7月31日

#442 in 数据库接口

Download history 3453/week @ 2024-04-27 4050/week @ 2024-05-04 4531/week @ 2024-05-11 5140/week @ 2024-05-18 3537/week @ 2024-05-25 3846/week @ 2024-06-01 3913/week @ 2024-06-08 3892/week @ 2024-06-15 3947/week @ 2024-06-22 2489/week @ 2024-06-29 2902/week @ 2024-07-06 3042/week @ 2024-07-13 4128/week @ 2024-07-20 3713/week @ 2024-07-27 4956/week @ 2024-08-03 2793/week @ 2024-08-10

15,918 每月下载量
23 个crate中使用 (3个直接使用)

MIT 许可证

4MB
1.5K SLoC

Rust 1.5K SLoC // 0.1% comments C 94 SLoC Python 71 SLoC // 0.1% comments Shell 37 SLoC // 0.3% comments

duckdb-rs

Downloads Build Status dependency status codecov Latest Version Docs

duckdb-rs 是 Rust 使用 duckdb 的便捷封装。它试图提供一个类似于 rusqlite 的接口。实际上,最初的代码和这份 README 都是来自 rusqlite 的分支,因为 duckdb 也试图提供与 sqlite3 兼容的 API。

use duckdb::{params, Connection, Result};

// In your project, we need to keep the arrow version same as the version used in duckdb.
// Refer to https://github.com/wangfenjin/duckdb-rs/issues/92
// You can either:
use duckdb::arrow::record_batch::RecordBatch;
// Or in your Cargo.toml, use * as the version; features can be toggled according to your needs
// arrow = { version = "*", default-features = false, features = ["prettyprint"] }
// Then you can:
// use arrow::record_batch::RecordBatch;

use duckdb::arrow::util::pretty::print_batches;

#[derive(Debug)]
struct Person {
    id: i32,
    name: String,
    data: Option<Vec<u8>>,
}

fn main() -> Result<()> {
    let conn = Connection::open_in_memory()?;

    conn.execute_batch(
        r"CREATE SEQUENCE seq;
          CREATE TABLE person (
                  id              INTEGER PRIMARY KEY DEFAULT NEXTVAL('seq'),
                  name            TEXT NOT NULL,
                  data            BLOB
                  );
        ")?;

    let me = Person {
        id: 0,
        name: "Steven".to_string(),
        data: None,
    };
    conn.execute(
        "INSERT INTO person (name, data) VALUES (?, ?)",
        params![me.name, me.data],
    )?;

    // query table by rows
    let mut stmt = conn.prepare("SELECT id, name, data FROM person")?;
    let person_iter = stmt.query_map([], |row| {
        Ok(Person {
            id: row.get(0)?,
            name: row.get(1)?,
            data: row.get(2)?,
        })
    })?;

    for person in person_iter {
        let p = person.unwrap();
        println!("ID: {}", p.id);
        println!("Found person {:?}", p);
    }

    // query table by arrow
    let rbs: Vec<RecordBatch> = stmt.query_arrow([])?.collect();
    print_batches(&rbs).unwrap();
    Ok(())
}

关于构建 duckdb 和 libduckdb-sys 的注意事项

libduckdb-sys 是一个独立的crate,从 duckdb-rs 提供了 DuckDB 的 C API 的 Rust 声明。默认情况下,libduckdb-sys 会尝试使用 pkg-config 或 MSVC ABI 构建时的 Vcpkg 安装,在您的系统上找到已存在的 DuckDB 库。

您可以通过多种方式调整此行为

  • 如果您使用 bundled 功能,libduckdb-sys 将使用 cc crate 从源代码编译 DuckDB 并将其链接。此源代码嵌入在 libduckdb-sys crate 中,因为我们仍在开发中,我们将定期更新它。在更加稳定后,我们将使用来自 duckdb 的稳定发布版本。这可能是解决任何构建问题的最简单解决方案。您可以通过在您的 Cargo.toml 文件中添加以下内容来启用此功能:

    cargo add duckdb --features bundled
    

    Cargo.toml 将被更新。

    [dependencies]
    # Assume that version DuckDB version 0.9.2 is used.
    duckdb = { version = "0.9.2", features = ["bundled"] }
    
  • 当链接到系统上已有的 DuckDB 库(因此 使用任何 bundled 功能)时,您可以设置 DUCKDB_LIB_DIR 环境变量以指向包含库的目录。您还可以设置 DUCKDB_INCLUDE_DIR 变量以指向包含 duckdb.h 的目录。

  • 安装duckdb开发包通常就足够了,但对于pkg-configvcpkg的构建辅助工具,有一些额外的配置选项。使用vcpkg的默认选项是动态链接,需要在构建前设置环境变量VCPKGRS_DYNAMIC=1来启用。

绑定生成

我们使用bindgen从DuckDB的C头文件生成Rust声明。bindgen建议将此作为使用此库的库构建过程的组成部分运行。我们尝试了这种方法(具体是duckdb 0.10.0),但有一些不便之处。

  • libduckdb-sys(因此是duckdb)的构建时间显著增加。
  • 运行bindgen需要相对较新的Clang版本,而许多系统默认并未安装。
  • 运行bindgen还需要DuckDB头文件存在。

因此,我们尝试通过提供预生成的DuckDB绑定来避免在构建时运行bindgen

如果您使用bundled功能,您将获得捆绑版DuckDB的预生成绑定。如果您想在构建时运行bindgen以生成自己的绑定,请使用Cargo功能buildtime_bindgen

贡献

请参阅Contributing.md

清单

  • 运行cargo +nightly fmt以确保您的Rust代码格式正确。
  • 运行cargo clippy --fix --allow-dirty --all-targets --workspace --all-features -- -D warnings以修复所有clippy问题。
  • 确保cargo test --all-targets --workspace --features "modern-full extensions-full"没有失败报告。

TODOs

  • 重构ErrorCode部分,它是从rusqlite借用的,我们应该有自己的
  • 支持更多类型
  • 更新duckdb.h
  • 调整代码示例和文档
  • 删除未使用的代码/函数
  • 添加CI
  • 发布到crate

许可证

DuckDB和libduckdb-sys在MIT许可证下可用。有关更多信息,请参阅LICENSE文件。

无运行时依赖