Skip to content

wlaur/monetdb-rust

 
 

Repository files navigation

MonetDB bindings for Rust

Rust client for the MonetDB analytics database.

The crate follows semantic versioning. Its synchronous SQL/MAPI API includes typed result conversion, TLS, binary result windows, and client-side binary uploads.

Examples

use std::error::Error;
use monetdb::Connection;

fn main() -> Result<(), Box<dyn Error>> {
    let url = "monetdb:///demo?user=monetdb&password=monetdb";
    let conn = Connection::connect_url(url)?;
    let mut cursor = conn.cursor();

    cursor.execute("SELECT hostname, clientpid, client, remark FROM sys.sessions")?;
    while cursor.next_row()? {
        // getters return Option< >, None means NULL
        let hostname: Option<&str> = cursor.get_str(0)?;
        let clientpid: Option<u32> = cursor.get_u32(1)?;
        let client: Option<&str> = cursor.get_str(2)?;
        let remark: Option<&str> = cursor.get_str(3)?; // usually NULL
        println!("host={hostname:?} clientpid={clientpid:?} client={client:?} remark={remark:?}",);
    }
    Ok(())
}

// Example output:
// host=Some("totoro") clientpid=Some(1895691) client=Some("libmapi 11.51.4") remark=None
// host=Some("totoro") clientpid=Some(1914127) client=Some("monetdb-rust 0.1.1") remark=None

You can also use a Parameters object to fine-tune the connection parameters:

# use std::error::Error;
use monetdb::{Parameters, Connection};
# fn main() -> Result<(), Box<dyn Error>> {
let parms = Parameters::basic("demo", "monetdb", "monetdb")? // database / user / password
    .with_autocommit(false)?;
let conn = Connection::new(parms)?;
# Ok(())
# }

When the server advertises client information, connections report the host, process, application, and monetdb-rust library version by default. Use client_application, client_remark, and client_prefix connection parameters to customize those values, or client_info=false to disable them.

Current status

  • The client is tested against current MonetDB and selected older releases. Compatibility outside the tested matrix is not guaranteed.

  • Rust 2024 edition; Rust 1.85 is the minimum supported version, and CI also tests current stable, beta, and nightly.

  • The full monetdb:// connection URL syntax is supported, though not all features have been implemented.

  • Most data types can be retrieved in string form using get_str(), with typed conversions for primitive, decimal, temporal, UUID, and BLOB values.

  • The primitive types bool, i8/u8, i16/u16, i32/u32, i64/u64, i128/u128, isize/usize, f32/f64 have typed getters, for example get_i8().

  • A single call to Cursor::execute() can return multiple result sets.

  • Optional TLS 1.3 (monetdbs://) support includes platform verification, custom certificate authorities, SHA-256 certificate pins, and mutual TLS. Certificate pins require at least 16 hexadecimal digits (64 bits).

  • Binary result windows are available through Cursor::fetch_binary() and Cursor::fetch_binary_into().

  • COPY BINARY ... ON CLIENT can upload eager or lazily produced in-memory files, with configurable message sizes.

  • PREPARE result metadata and statement ids are exposed for clients that implement parameter binding.

Not implemented yet but planned:

  • A high-level parameter-binding API. PREPARE metadata and statement ids are already exposed for clients that implement binding.

  • Scanning /tmp for Unix Domain sockets

  • Non-SQL, for example language=mal for MonetDB's tracing / profiling API

  • Async, seems to be needed for sqlx

  • Integration with database frameworks such as sqlx and Diesel. There does not seem to be a JDBC equivalent for Rust.

Optional features

The monetdb crate defines these optional features:

  • rustls Enable TLS connections using rustls. URL parameters select system verification, a custom CA (cert=), a SHA-256 certificate pin (certhash=), and optional client certificates (clientkey= and clientcert=). To enable it, pass it on the command line like this:

    cargo run --features=rustls --example testconnect -- monetdbs://my.tls.host/demo
    

    or enable it in your application's Cargo.toml like this:

    [dependencies]
    monetdb = { version="0.2", features=["rustls"]}
    
  • uuid Enable UUID conversion (enabled by default).

  • time Enable local-time-zone discovery for connections whose timezone parameter is not set.

  • rust_decimal and decimal-rs enable conversions to the corresponding decimal crates.

Result windows

The first replysize rows are included in the query response. Subsequent text-protocol windows double in size until they reach the maxprefetch limit, which defaults to 2,500 rows beyond the row currently requested. Set maxprefetch=0 to disable read-ahead or maxprefetch=-1 to allow unbounded window growth. Binary clients can use BinaryResult and Cursor::fetch_binary_into() to choose their own window sizes directly.

Testing

cargo test runs the serverless unit and documentation suites. The internal ci-tests feature enables the live integration target, so cargo test --all-features requires CI_SERVER_URL to name a running MonetDB server. Run cargo test --all-features --lib and cargo test --all-features --doc when checking every library feature without a server.

About

No description, website, or topics provided.

Resources

Contributing

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages