pub struct Client { /* private fields */ }Expand description
A configured Trino client.
Created with ClientBuilder. Cheap to share: it wraps a connection-pooled
HTTP client, so build one and reuse it for all queries. The main entry
points are get_all (buffer the result),
stream (stream it lazily) and execute
(run a statement).
Implementations§
Source§impl Client
impl Client
Sourcepub async fn stream<'a, T>(
&'a self,
sql: impl Into<String>,
) -> Result<RowStream<'a, T>>
pub async fn stream<'a, T>( &'a self, sql: impl Into<String>, ) -> Result<RowStream<'a, T>>
Execute sql and stream the resulting rows lazily, page by page, without
buffering the whole result set in memory.
Trino returns results as a chain of pages linked by nextUri. This method
first drives the query far enough to resolve the result schema (so
RowStream::columns is available up front), then hands back a
RowStream that follows the remaining pages on demand, yielding each
row as it is decoded. Prefer it over Client::get_all for large result
sets.
Both the Direct and (with the spooling feature) Spooled protocols are
supported. With spooling, rows are still materialized one segment at a
time rather than for the entire query, keeping peak memory bounded.
Unlike Client::get_all, this does not reject a query that mixes the
Direct and Spooled protocols across pages; each page is decoded according
to its own protocol.
The returned stream borrows self, so it must not outlive the Client.
§Example
use futures::StreamExt;
let client = ClientBuilder::new("user", "localhost").port(8080).build()?;
let mut rows = client.stream::<Row>("SELECT 1").await?;
println!("columns: {:?}", rows.columns());
while let Some(row) = rows.next().await {
let row = row?;
// use row
}Sourcepub async fn execute(&self, sql: impl Into<String>) -> Result<ExecuteResult>
pub async fn execute(&self, sql: impl Into<String>) -> Result<ExecuteResult>
- Execute a SQL statement and return the result.
- If the TRINO query returns an error, the method returns an error of type
Error::Query - @param sql The SQL statement to execute
- @return
Result<ExecuteResult>` The result of the execution
Sourcepub async fn transaction_id(&self) -> TransactionId
pub async fn transaction_id(&self) -> TransactionId
The transaction this client’s session is currently bound to.
Sourcepub async fn set_transaction_id(&self, id: TransactionId)
pub async fn set_transaction_id(&self, id: TransactionId)
Bind the session to a transaction.
Normally unnecessary — begin_transaction
captures the identifier Trino issues. Use this to adopt a transaction
started elsewhere.
Sourcepub async fn begin_transaction(&self) -> Result<()>
pub async fn begin_transaction(&self) -> Result<()>
Start a transaction.
Issues START TRANSACTION and captures the identifier Trino returns, so
statements issued afterwards on this client run inside the transaction
until commit or rollback.
§Concurrency
A transaction is a property of the whole client, so treat a client as single-threaded for as long as one is open. Statements already in flight when the transaction starts do not join it, and statements issued concurrently from another task will run inside it whether or not that was intended.
The nesting check below is best-effort, not atomic: the session lock is
released before START TRANSACTION is sent (holding it would deadlock
against the write lock taken when the response is processed). Two tasks
calling this concurrently can therefore both pass the check and open two
transactions, of which only the last is retained — the other is orphaned
on the coordinator until it times out. Use a separate client per
transaction if you need concurrency.
§Errors
Returns Error::Transaction if a transaction is already active —
Trino does not support nested transactions.
Also returns Error::Transaction if the statement succeeded but no
usable identifier came back in X-Trino-Started-Transaction-Id. A
healthy coordinator always sends it, so this signals something between
client and coordinator dropping or rewriting the header. The
transaction may be open on the coordinator, and because its identifier
never reached the client it cannot be committed or rolled back — it
stays open until the coordinator times it out. Surfacing that as an
error is what lets Ok(()) mean a transaction is genuinely active.
When the statement itself fails the transaction may nevertheless have
been started, since the identifier is captured before the statement
finishes. Call rollback to discard it; that also
clears an identifier the coordinator has already expired.
Sourcepub async fn get<T>(&self, sql: impl Into<String>) -> Result<QueryResult<T>>where
for<'de> T: Trino + 'static + Deserialize<'de>,
pub async fn get<T>(&self, sql: impl Into<String>) -> Result<QueryResult<T>>where
for<'de> T: Trino + 'static + Deserialize<'de>,
Submit sql and return the first result page.
Low-level building block: the returned QueryResult may carry a
next_uri that you must follow with get_next to
retrieve the rest. Most callers should use get_all
or stream, which handle pagination.
Sourcepub async fn get_next<T>(&self, url: &str) -> Result<QueryResult<T>>where
for<'de> T: Trino + 'static + Deserialize<'de>,
pub async fn get_next<T>(&self, url: &str) -> Result<QueryResult<T>>where
for<'de> T: Trino + 'static + Deserialize<'de>,
Fetch the next result page from a next_uri returned by a previous
get / get_next call.
Auto Trait Implementations§
impl !Freeze for Client
impl !RefUnwindSafe for Client
impl !UnwindSafe for Client
impl Send for Client
impl Sync for Client
impl Unpin for Client
impl UnsafeUnpin for Client
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more