Skip to content

Commit

Permalink
update README
Browse files Browse the repository at this point in the history
Change-Id: I24fe97e063d00ec99de2d95033560b581b212b6f
  • Loading branch information
wangfenjin committed Jun 30, 2021
1 parent 37c1e15 commit 8aef6a3
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 31 deletions.
10 changes: 10 additions & 0 deletions .github/.codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ignore:
- "libsduckdb-sys/duckdb"
coverage:
status:
project:
default:
informational: true
patch:
default:
informational: true
137 changes: 110 additions & 27 deletions .github/workflows/rust.yaml
Original file line number Diff line number Diff line change
@@ -1,33 +1,116 @@
name: Rust build

on: push
name: CI

on:
push:
branches:
- master
pull_request:
branches:
- master
env:
CARGO_TERM_COLOR: always

RUST_BACKTRACE: 1
jobs:
build:
test:
name: Test ${{ matrix.target }}

strategy:
fail-fast: true

matrix:
include:
#- { target: x86_64-pc-windows-msvc, os: windows-latest }
- { target: x86_64-unknown-linux-gnu, os: ubuntu-latest }
#- { target: x86_64-apple-darwin, os: macos-latest }
#- {
#target: x86_64-pc-windows-gnu,
#os: windows-latest,
#host: -x86_64-pc-windows-gnu,
#}

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
# This has a matcher for test panics, so we use it even though elsewhere
# we use actions-rs/toolchain.
- uses: hecrj/setup-rust-action@v1
with:
rust-version: stable${{ matrix.host }}
targets: ${{ matrix.target }}

# - run: cargo build --features bundled --workspace --all-targets --verbose
- run: cargo test --features bundled --workspace --all-targets --verbose
# - run: cargo test --features bundled --workspace --doc --verbose

sanitizer:
name: Address Sanitizer
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Need nightly rust.
- uses: hecrj/setup-rust-action@v1
with:
rust-version: nightly
components: rust-src
- name: Tests with asan
env:
RUSTFLAGS: -Zsanitizer=address
RUSTDOCFLAGS: -Zsanitizer=address
ASAN_OPTIONS: "detect_stack_use_after_return=1:detect_leaks=0"
# Work around https://github.com/rust-lang/rust/issues/59125 by
# disabling backtraces. In an ideal world we'd probably suppress the
# leak sanitization, but we don't care about backtraces here, so long
# as the other tests have them.
RUST_BACKTRACE: "0"
run: cargo -Z build-std test --features 'bundled' --target x86_64-unknown-linux-gnu

# Ensure clippy doesn't complain.
clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install latest nightly
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt, clippy
- name: Cache .cargo
id: cache-cargo
uses: actions/cache@v2
with:
path: ~/.cargo
key: ${{ runner.os }}-${{ hashFiles('Cargo**') }}
- name: cargo test
uses: actions-rs/cargo@v1
with:
command: test
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
- uses: actions/checkout@v2
- uses: hecrj/setup-rust-action@v1
with:
components: clippy
- run: cargo clippy --all-targets --workspace --features bundled -- -D warnings

# Ensure patch is formatted.
fmt:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: hecrj/setup-rust-action@v1
with:
components: rustfmt
- run: cargo fmt --all -- --check

# Detect cases where documentation links don't resolve and such.
# doc:
# name: Docs
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v2
# - uses: hecrj/setup-rust-action@v1
# with:
# rust-version: nightly
# # Need to use `cargo rustdoc` to actually get it to respect -D
# # warnings... Note: this also requires nightly.
# - run: cargo rustdoc --features 'bundled' -- -D warnings

codecov:
name: Generate code coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: hecrj/setup-rust-action@v1
- name: Run cargo-tarpaulin
uses: actions-rs/[email protected]
with:
# Intentionally omit time feature until we're on time 0.3, at which
# point it should be added to `bundled-full`.
args: '--features "bundled"'

- name: Upload to codecov.io
uses: codecov/codecov-action@v1
129 changes: 125 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,133 @@
# duckdb-rs (WIP)
Ergonomic bindings to duckdb for Rust
# duckdb-rs

# TODO
[![Build Status](https://github.com/wangfenjin/duckdb-rs/workflows/CI/badge.svg)](https://github.com/wangfenjin/duckdb-rs/actions)
[![dependency status](https://deps.rs/repo/github/wangfenjin/duckdb-rs/status.svg)](https://deps.rs/repo/github/wangfenjin/duckdb-rs)
[comment]: <> ([![Latest Version](https://img.shields.io/crates/v/duckdb.svg)](https://crates.io/crates/duckdb))
[comment]: <> ([![Docs](https://docs.rs/rusqlite/badge.svg)](https://docs.rs/rusqlite))
[![codecov](https://codecov.io/gh/wangfenjin/duckdb-rs/branch/master/graph/badge.svg)](https://codecov.io/gh/wangfenjin/duckdb-rs)

duckdb-rs is an ergonomic wrapper for using [duckdb](https://github.com/duckdb/duckdb) from Rust. It attempts to expose
an interface similar to [rusqlite](https://github.com/rusqlite/rusqlite). Acctually the initial code and even this README is
forked from rusqlite as duckdb also tries to expose a sqlite3 compatible API.

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

#[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],
)?;

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 {
println!("Found person {:?}", person.unwrap());
}
Ok(())
}
```

## Notes on building rusqlite and libduckdb-sys

`libduckdb-sys` is a separate crate from `duckdb-rs` that provides the Rust
declarations for DuckDB's C API. By default, `libduckdb-sys` attempts to find a DuckDB library that already exists on your system using pkg-config, or a
[Vcpkg](https://github.com/Microsoft/vcpkg) installation for MSVC ABI builds.

You can adjust this behavior in a number of ways:

* If you use the `bundled` feature, `libsqlite3-sys` will use the
[cc](https://crates.io/crates/cc) crate to compile DuckDB from source and
link against that. This source is embedded in the `libsqlite3-sys` crate and
as we are still in development, we will update it regularly. After we are more stable,
we will use the stable released version from [duckdb](https://github.com/duckdb/duckdb/releases).
This is probably the simplest solution to any build problems. You can enable this by adding the following in your `Cargo.toml` file:
```toml
[dependencies.duckdb]
version = "0.1"
features = ["bundled"]
```
* When linking against a DuckDB library already on the system (so *not* using any of the `bundled` features), you can set the `DUCKDB_LIB_DIR` environment variable to point to a directory containing the library. You can also set the `DUCKDB_INCLUDE_DIR` variable to point to the directory containing `duckdb.h`.
* Installing the duckdb development packages will usually be all that is required, but
the build helpers for [pkg-config](https://github.com/alexcrichton/pkg-config-rs)
and [vcpkg](https://github.com/mcgoo/vcpkg-rs) have some additional configuration
options. The default when using vcpkg is to dynamically link,
which must be enabled by setting `VCPKGRS_DYNAMIC=1` environment variable before build.


### Binding generation

We use [bindgen](https://crates.io/crates/bindgen) to generate the Rust
declarations from DuckDB's C header file. `bindgen`
[recommends](https://github.com/servo/rust-bindgen#library-usage-with-buildrs)
running this as part of the build process of libraries that used this. We tried
this briefly (`duckdb` 0.10.0, specifically), but it had some annoyances:

* The build time for `libduckdb-sys` (and therefore `duckdb`) increased
dramatically.
* Running `bindgen` requires a relatively-recent version of Clang, which many
systems do not have installed by default.
* Running `bindgen` also requires the DuckDB header file to be present.

So we try to avoid running `bindgen` at build-time by shipping
pregenerated bindings for DuckDB.

If you use the `bundled` features, you will get pregenerated bindings for the
bundled version of DuckDB. If you want to run `bindgen` at buildtime to
produce your own bindings, use the `buildtime_bindgen` Cargo feature.

## Contributing

If running bindgen is problematic for you, `--features bundled` enables
bundled and all features which don't require binding generation, and can be used
instead.

### Checklist

- Run `cargo fmt` to ensure your Rust code is correctly formatted.
- Ensure `cargo clippy --all-targets --workspace --features bundled` passes without warnings.
- Ensure `cargo test --all-targets --workspace --features bundled` reports no failures.

### TODOs

- [x] Refactor the ErrorCode part, it's borrowed from rusqlite, we should have our own
- [ ] Support more type
- [ ] Update duckdb.h
- [x] Update duckdb.h
- [ ] Adjust the code examples and documentation
- [x] Delete unused code / functions
- [x] Add CI
- [ ] Publish to crate

## License

DuckDB and libduckdb-sys are available under the MIT license. See the LICENSE file for more info.

0 comments on commit 8aef6a3

Please sign in to comment.