A trino client library written in rust.
This project have been forked on 08/12/24 from the great : prusto made by @nooberfsh.
Fork rationale :
- Remove presto support
- Add advanced trino features.
- Rename things as "trino"
- Basic Auth
- Jwt Auth
- Interactive OAuth2 (browser-based)
- Spooling Protocol (for efficient large result set handling)
# Cargo.toml
[dependencies]
trino-rust-client = "0.12.0"
# For spooling protocol support
trino-rust-client = { version = "0.12.0", features = ["spooling"] }Breaking changes between releases are documented with before/after examples in the migration guide.
The client emits tracing events and wraps each
get_all / stream / execute call in a span carrying the query_id, so
logs correlate per query. Install any subscriber to see them, e.g.:
tracing_subscriber::fmt()
.with_env_filter("trino_rust_client=debug")
.init();use trino_rust_client::{ClientBuilder, Trino};
#[derive(Trino, Debug)]
struct Foo {
a: i64,
b: f64,
c: String,
}
#[tokio::main]
async fn main() {
let cli = ClientBuilder::new("user", "localhost")
.port(8090)
.catalog("catalog")
.build()
.unwrap();
let sql = "select 1 as a, cast(1.1 as double) as b, 'bar' as c ";
let data = cli.get_all::<Foo>(sql.into()).await.unwrap().into_vec();
for r in data {
println!("{:?}", r)
}
}use trino_rust_client::{ClientBuilder, Trino};
#[derive(Trino, Debug)]
struct Foo {
a: i64,
b: f64,
c: String,
}
#[tokio::main]
async fn main() {
let auth = Auth::Jwt("your access token");
let cli = ClientBuilder::new("user", "localhost")
.port(8443)
.secure(true)
.auth(auth)
.catalog("catalog")
.build()
.unwrap();
let sql = "select 1 as a, cast(1.1 as double) as b, 'bar' as c ";
let data = cli.get_all::<Foo>(sql.into()).await.unwrap().into_vec();
for r in data {
println!("{:?}", r)
}
}Trino's OAuth2 authentication makes the coordinator the OAuth client: on a
401 the client opens the coordinator-supplied login URL in a browser (and
prints it to stderr as a fallback), polls Trino's token endpoint until you finish
the IdP login, then retries with the bearer token. The token is cached in memory
for the life of the Client. Requires TLS to the coordinator.
use trino_rust_client::auth::Auth;
use trino_rust_client::{ClientBuilder, Row};
#[tokio::main]
async fn main() {
let cli = ClientBuilder::new("user", "coordinator.example.com")
.secure(true)
.auth(Auth::new_oauth2())
.catalog("catalog")
.build()
.unwrap();
let data = cli.get_all::<Row>("select 1").await.unwrap().into_vec();
for r in data {
println!("{:?}", r)
}
}Supply a custom presentation strategy (instead of opening a browser) with
Auth::new_oauth2_with_handler(Arc::new(my_handler)), and tune the token poll
loop with .with_poll(max_attempts, timeout).
use trino_rust_client::{ClientBuilder, Row, Trino};
#[tokio::main]
async fn main() {
let cli = ClientBuilder::new("user", "localhost")
.port(8080)
.catalog("catalog")
.build()
.unwrap();
let sql = "select first_name, last_name from users";
let rows = cli.get_all::<Row>(sql.into()).await.unwrap().into_vec();
for row in rows {
let first_name = row.value().get(0).unwrap();
let last_name = row.value().get(1).unwrap();
println!("{} : {}", first_name, last_name);
}
}use trino_rust_client::{ClientBuilder, Trino};
#[derive(Trino, Debug)]
struct User {
id: i64,
name: String,
email: String,
}
#[tokio::main]
async fn main() {
let cli = ClientBuilder::new("user", "localhost")
.port(8080)
.catalog("memory")
.schema("default")
.spooling_encoding("json+zstd") // Enable spooling with compression
.max_concurrent_segments(10) // Optional: control concurrent downloads
.build()
.unwrap();
let sql = "SELECT id, name, email FROM users LIMIT 1000";
let data = cli.get_all::<User>(sql.into()).await.unwrap();
println!("Retrieved {} rows", data.len());
for user in data.as_slice() {
println!("{:?}", user);
}
}MIT