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.
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=NoneYou 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.
-
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()andCursor::fetch_binary_into(). -
COPY BINARY ... ON CLIENTcan 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.
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=andclientcert=). To enable it, pass it on the command line like this:cargo run --features=rustls --example testconnect -- monetdbs://my.tls.host/demoor 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
timezoneparameter is not set. -
rust_decimal and decimal-rs enable conversions to the corresponding decimal crates.
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.
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.