Skip to content

Commit

Permalink
feat(rust): add integration tests and some improvements (apache#1883)
Browse files Browse the repository at this point in the history
This should be the last PR for the initial Rust implementation.

It includes:
- An integration test for the driver manager against the official SQLite
driver
- An integration test for the dummy driver against itself (comparing
output when using the Rust API and when using its exported version
through the driver manager)
- New info codes and options which have been added recently
- An enum for identifying statistics

Note that I also have an integration test for the driver manager against
the official PostgreSQL driver but it needs a running PostgreSQL
instance to be executed, so it cannot be easily integrated into the CI.
This test proved useful during development as it allowed me to catch
some bugs. The existence of this test is the reason why there is a
common module. Maybe we can add it in a follow-up PR?
  • Loading branch information
alexandreyc authored Jun 22, 2024
1 parent ab567df commit aec0e8d
Show file tree
Hide file tree
Showing 9 changed files with 1,501 additions and 46 deletions.
74 changes: 36 additions & 38 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 28 additions & 1 deletion rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,31 @@

This is a Rust implementation of [Arrow Database Connectivity (ADBC)](https://arrow.apache.org/adbc).

It's still work in progress and should not be used in production.
It currently provides:

- An abstract Rust API to be implemented by vendor-specific drivers.
- A driver manager which implements this same API, but dynamically loads
drivers internally and forwards calls appropriately using the C API.
- A driver exporter that takes an implementation of the abstract API and
turns it into an object file that implements the C API.
- A dummy driver implementation for testing and documentation purposes.

## Development

To run the integration tests you must:

1. Install [SQLite](https://www.sqlite.org/) and have its dynamic library in path.
1. Build the official ADBC SQLite driver by following the [documentation](../CONTRIBUTING.md).
1. Place the resulting object file into your dynamic loader path or set
`LD_LIBRARY_PATH/DYLD_LIBRARY_PATH` appropriately.
1. Run `cargo test --all-features --workspace`

## Writing Drivers

To write an ADBC driver in Rust you have to:

1. Create a new library crate with `crate-type = ["lib", "cdylib"]`.
1. Implement the abstract API which consists of the traits `Driver`, `Database`, `Connection` and `Statement`.
1. Export your driver to C with the macro `adbc_core::export_driver!`.

The resulting object file can then be loaded by other languages trough their own driver manager.
9 changes: 8 additions & 1 deletion rust/core/src/ffi/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub const ADBC_VERSION_1_1_0: c_int = 1_001_000;
pub const ADBC_INFO_VENDOR_NAME: u32 = 0;
pub const ADBC_INFO_VENDOR_VERSION: u32 = 1;
pub const ADBC_INFO_VENDOR_ARROW_VERSION: u32 = 2;
pub const ADBC_INFO_VENDOR_SQL: u32 = 3;
pub const ADBC_INFO_VENDOR_SUBSTRAIT: u32 = 4;
pub const ADBC_INFO_VENDOR_SUBSTRAIT_MIN_VERSION: u32 = 5;
pub const ADBC_INFO_VENDOR_SUBSTRAIT_MAX_VERSION: u32 = 6;
pub const ADBC_INFO_DRIVER_NAME: u32 = 100;
pub const ADBC_INFO_DRIVER_VERSION: u32 = 101;
pub const ADBC_INFO_DRIVER_ARROW_VERSION: u32 = 102;
Expand All @@ -55,8 +59,11 @@ pub const ADBC_OBJECT_DEPTH_COLUMNS: c_int = ADBC_OBJECT_DEPTH_ALL;
pub const ADBC_ERROR_VENDOR_CODE_PRIVATE_DATA: i32 = i32::MIN;

pub const ADBC_INGEST_OPTION_TARGET_TABLE: &str = "adbc.ingest.target_table";
pub const ADBC_INGEST_OPTION_MODE: &str = "adbc.ingest.mode";
pub const ADBC_INGEST_OPTION_TARGET_CATALOG: &str = "adbc.ingest.target_catalog";
pub const ADBC_INGEST_OPTION_TARGET_DB_SCHEMA: &str = "adbc.ingest.target_db_schema";
pub const ADBC_INGEST_OPTION_TEMPORARY: &str = "adbc.ingest.temporary";

pub const ADBC_INGEST_OPTION_MODE: &str = "adbc.ingest.mode";
pub const ADBC_INGEST_OPTION_MODE_CREATE: &str = "adbc.ingest.mode.create";
pub const ADBC_INGEST_OPTION_MODE_APPEND: &str = "adbc.ingest.mode.append";
pub const ADBC_INGEST_OPTION_MODE_REPLACE: &str = "adbc.ingest.mode.replace";
Expand Down
3 changes: 1 addition & 2 deletions rust/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,7 @@ pub trait Connection: Optionable<Option = OptionConnection> {
/// 2. A dictionary-encoded statistic name (although we do not use the Arrow
/// dictionary type). Values in [0, 1024) are reserved for ADBC. Other
/// values are for implementation-specific statistics. For the definitions
/// of predefined statistic types, TODO (change this when statistics enum is added )
/// see \ref adbc-table-statistics. To get
/// of predefined statistic types, see [options::Statistics]. To get
/// driver-specific statistic names, use [Connection::get_statistic_names].
/// 3. If true, then the value is approximate or best-effort.
///
Expand Down
Loading

0 comments on commit aec0e8d

Please sign in to comment.