pub struct Client { /* private fields */ }Expand description
A synchronous client for Hyper database.
The client handles connection management and query execution.
It is thread-safe and can be shared between threads using Arc.
§Thread Safety
The Client is thread-safe and can be shared between threads using Arc<Client>.
All methods use internal mutexes to synchronize access to the underlying connection.
§Example
use hyperdb_api_core::client::{Client, Config};
let config = Config::new()
.with_host("localhost")
.with_port(7483)
.with_database("test.hyper");
let client = Client::connect(&config)?;
let rows = client.query("SELECT 1")?;
client.close()?;Implementations§
Source§impl Client
impl Client
Sourcepub fn connect(config: &Config) -> Result<Self>
pub fn connect(config: &Config) -> Result<Self>
Connects to a Hyper server using the given configuration.
Establishes a TCP connection, performs authentication, and initializes the client. Returns an error if the connection fails or authentication is rejected.
§Arguments
config- Connection configuration (host, port, credentials, etc.)
§Errors
Returns Error if:
- Connection to the server fails
- Authentication fails
- Protocol handshake fails
§Example
let config = Config::new()
.with_host("localhost")
.with_port(7483)
.with_user("myuser")
.with_password("mypass")
.with_database("test.hyper");
let client = Client::connect(&config)?;Sourcepub fn connect_unix(
socket_path: impl AsRef<Path>,
config: &Config,
) -> Result<Self>
pub fn connect_unix( socket_path: impl AsRef<Path>, config: &Config, ) -> Result<Self>
Sourcepub fn connect_endpoint(
endpoint: &ConnectionEndpoint,
config: &Config,
) -> Result<Self>
pub fn connect_endpoint( endpoint: &ConnectionEndpoint, config: &Config, ) -> Result<Self>
Connects to a Hyper server using a ConnectionEndpoint.
This is a lower-level method that accepts a pre-parsed endpoint.
§Errors
Delegates to Client::connect, Client::connect_unix, or
Client::connect_named_pipe depending on the endpoint variant,
and propagates their errors unchanged.
Sourcepub fn endpoint(&self) -> &ConnectionEndpoint
pub fn endpoint(&self) -> &ConnectionEndpoint
Returns the connection endpoint.
Sourcepub fn process_id(&self) -> i32
pub fn process_id(&self) -> i32
Returns the server process ID for this connection.
Sourcepub fn secret_key(&self) -> i32
pub fn secret_key(&self) -> i32
Returns the secret key for cancel requests.
Sourcepub fn cancel(&self) -> Result<()>
pub fn cancel(&self) -> Result<()>
Cancels the currently executing query on this connection.
This method is thread-safe and can be called from any thread while a query is running on another thread. It works by opening a separate TCP connection to the server and sending a cancel request.
§How It Works
- Opens a new TCP connection to the same server
- Sends a cancel request containing the process ID and secret key
- The server receives this and cancels the running query
- The original query will fail with error code 57014 (
query_canceled)
§Thread Safety
This method does NOT acquire the connection mutex, so it can be called while another thread is blocked waiting for query results.
§Relation to the Cancellable trait
This is the fallible user-facing cancel API: it returns a
Result<()> so explicit callers can observe transport-level
failures (network errors, socket issues) and react accordingly —
e.g. record a metric, show “cancel failed” UX, or retry.
For Drop-path and other internal cleanup contexts where error
propagation is impossible, the separate
impl Cancellable for Client wraps
this method and swallows errors (logged via tracing::warn!).
The two coexist by design — each serves a different consumer.
§Example
use std::thread;
use std::sync::Arc;
use std::time::Duration;
use hyperdb_api_core::client::{Client, Config};
let client = Arc::new(Client::connect(&config)?);
let client_clone = Arc::clone(&client);
// Start a long query in another thread
let handle = thread::spawn(move || {
client_clone.query("SELECT pg_sleep(60)")
});
// Cancel from the main thread
thread::sleep(Duration::from_millis(100));
client.cancel()?;
// The query thread will get a cancellation error
let result = handle.join().unwrap();
assert!(result.is_err());§Errors
- Returns
Error(connection) if the fresh cancel-side socket cannot be opened (TCP / UDS / named-pipe, depending onSelf::endpoint). - Returns
Error(I/O) if writing or flushing the cancel request fails.
Sourcepub fn parameter_status(&self, name: &str) -> Option<String>
pub fn parameter_status(&self, name: &str) -> Option<String>
Returns a server parameter value by name.
Server parameters are sent by the server during connection startup. Common parameters include:
server_version- The server version stringserver_encoding- The server’s character encodingclient_encoding- The client’s character encoding
§Example
if let Some(version) = client.parameter_status("server_version") {
println!("Connected to Hyper version: {}", version);
}Sourcepub fn set_notice_receiver(&mut self, receiver: Option<NoticeReceiver>)
pub fn set_notice_receiver(&mut self, receiver: Option<NoticeReceiver>)
Sets the notice receiver for this connection.
Notice and warning messages generated by the server are not returned by query execution functions since they don’t indicate failure. Instead, they are passed to a notice handling function.
The default behavior is to log notices at the warn level.
§Arguments
receiver- The callback function that will be called with each notice. PassNoneto restore default logging behavior.
§Example
client.set_notice_receiver(Some(Box::new(|notice| {
println!("Server notice: {}", notice);
})));
// Or capture notices in a Vec
let notices = Arc::new(Mutex::new(Vec::new()));
let notices_clone = notices.clone();
client.set_notice_receiver(Some(Box::new(move |notice| {
notices_clone.lock().unwrap().push(notice);
})));Sourcepub fn query(&self, query: &str) -> Result<Vec<Row>>
pub fn query(&self, query: &str) -> Result<Vec<Row>>
Executes a simple query and returns the rows.
§Errors
- Returns
Error(connection) if the connection mutex is poisoned. - Returns
Error(server) for any SQL error the server reports (syntax error, constraint violation, type mismatch). - Returns
Error(I/O) on wire-protocol I/O failure. - Propagates any
Errorfrom row construction (invalid row description or data row bytes).
Sourcepub fn query_fast(&self, query: &str) -> Result<Vec<StreamRow>>
pub fn query_fast(&self, query: &str) -> Result<Vec<StreamRow>>
Executes a query using HyperBinary format for maximum performance.
Returns StreamRows which compute offsets on-demand without pre-allocation,
making them faster for large result sets where each row is processed once.
Uses the extended query protocol with HyperBinary format (format code 2)
for direct binary access without text parsing overhead.
§Errors
Same as Self::query: connection-mutex poisoning, SQL errors
from the server, and wire-protocol I/O failures all surface as
Error.
Sourcepub fn query_streaming<'a>(
&'a self,
query: &str,
chunk_size: usize,
) -> Result<QueryStream<'a>>
pub fn query_streaming<'a>( &'a self, query: &str, chunk_size: usize, ) -> Result<QueryStream<'a>>
Executes a query with streaming results for minimum memory usage.
Combines HyperBinary format with incremental row fetching.
§Errors
Sourcepub fn exec(&self, query: &str) -> Result<u64>
pub fn exec(&self, query: &str) -> Result<u64>
Executes a SQL command that doesn’t return rows (e.g., INSERT, UPDATE).
§Errors
Same error modes as Self::query — connection-mutex poisoning,
server-side SQL errors, and wire-protocol I/O failures all
surface as Error.
Sourcepub fn batch_execute(&self, query: &str) -> Result<()>
pub fn batch_execute(&self, query: &str) -> Result<()>
Executes a batch of statements separated by semicolons.
§Errors
Same error modes as Self::query — connection-mutex poisoning,
server-side SQL errors, and wire-protocol I/O failures.
Sourcepub fn prepare(&self, query: &str) -> Result<OwnedPreparedStatement>
pub fn prepare(&self, query: &str) -> Result<OwnedPreparedStatement>
Prepares a statement for execution with the [params!] macro.
Returns an prepare::OwnedPreparedStatement that automatically closes when dropped.
§Example
let stmt = client.prepare("SELECT * FROM users WHERE id = $1")?;
let rows = client.execute(&stmt, params![42_i32])?;§Errors
Propagates any Error from prepare::prepare_owned —
connection-mutex poisoning, server-side Parse failures (SQL
syntax, type resolution), and wire-protocol I/O failures.
Sourcepub fn prepare_typed(
&self,
query: &str,
param_types: &[Oid],
) -> Result<OwnedPreparedStatement>
pub fn prepare_typed( &self, query: &str, param_types: &[Oid], ) -> Result<OwnedPreparedStatement>
Sourcepub fn execute<P: AsRef<[Option<Vec<u8>>]>>(
&self,
statement: &OwnedPreparedStatement,
params: P,
) -> Result<Vec<Row>>
pub fn execute<P: AsRef<[Option<Vec<u8>>]>>( &self, statement: &OwnedPreparedStatement, params: P, ) -> Result<Vec<Row>>
Executes a prepared statement with parameters.
Use the [params!] macro for ergonomic parameter encoding:
let stmt = client.prepare("SELECT * FROM users WHERE id = $1 AND name = $2")?;
let rows = client.execute(&stmt, params![42_i32, "Alice"])?;§Errors
Propagates any Error from prepare::execute_prepared —
parameter-count or type mismatch, server-side SQL errors, and
wire-protocol I/O failures.
Sourcepub fn execute_no_result<P: AsRef<[Option<Vec<u8>>]>>(
&self,
statement: &OwnedPreparedStatement,
params: P,
) -> Result<u64>
pub fn execute_no_result<P: AsRef<[Option<Vec<u8>>]>>( &self, statement: &OwnedPreparedStatement, params: P, ) -> Result<u64>
Executes a prepared statement that doesn’t return rows.
§Errors
Same failure modes as Self::execute.
Sourcepub fn execute_streaming<'a, P: AsRef<[Option<Vec<u8>>]>>(
&'a self,
statement: &OwnedPreparedStatement,
params: P,
chunk_size: usize,
) -> Result<PreparedQueryStream<'a>>
pub fn execute_streaming<'a, P: AsRef<[Option<Vec<u8>>]>>( &'a self, statement: &OwnedPreparedStatement, params: P, chunk_size: usize, ) -> Result<PreparedQueryStream<'a>>
Executes a prepared statement with streaming results.
Returns a PreparedQueryStream
that yields rows in chunks, keeping memory bounded regardless of
result size. This is the prepared-statement analog of
query_streaming.
The connection mutex is held for the duration of iteration; dropping the stream before completion issues a best-effort cancel.
§Errors
Sourcepub fn copy_in(
&self,
table_name: &str,
columns: &[&str],
) -> Result<CopyInWriter<'_>>
pub fn copy_in( &self, table_name: &str, columns: &[&str], ) -> Result<CopyInWriter<'_>>
Starts a COPY IN operation for bulk data insertion.
Returns a CopyInWriter that can be used to send data in HyperBinary format.
§Example
let mut writer = client.copy_in("\"my_table\"", &["col1", "col2"])?;
writer.send(binary_data)?;
let rows = writer.finish()?;§Errors
Delegates to Self::copy_in_with_format; see that method
for the concrete failure modes.
Sourcepub fn copy_in_with_format(
&self,
table_name: &str,
columns: &[&str],
format: &str,
) -> Result<CopyInWriter<'_>>
pub fn copy_in_with_format( &self, table_name: &str, columns: &[&str], format: &str, ) -> Result<CopyInWriter<'_>>
Starts a COPY IN operation with a specified data format.
Returns a CopyInWriter that can be used to send data in the specified format.
§Arguments
table_name- The target table name (should be properly quoted if needed)columns- Column names to insert intoformat- The data format string: “HYPERBINARY” or “ARROWSTREAM”
§Example
// For Arrow IPC stream format
let mut writer = client.copy_in_with_format("\"my_table\"", &["col1", "col2"], "ARROWSTREAM")?;
writer.send(arrow_ipc_data)?;
let rows = writer.finish()?;§Errors
Sourcepub fn copy_in_raw(&self, query: &str) -> Result<CopyInWriter<'_>>
pub fn copy_in_raw(&self, query: &str) -> Result<CopyInWriter<'_>>
Starts a COPY IN operation from a raw SQL query string.
The query must be a complete COPY ... FROM STDIN ... statement.
This is useful for text-format imports (CSV, TSV) where you need
full control over the COPY options.
§Security
The query is validated to start with COPY (case-insensitive) as a
defense-in-depth measure. Callers are still responsible for proper
escaping of table names and other identifiers within the query.
Prefer copy_in() or
copy_in_with_format() when possible,
as they handle escaping automatically.
§Example
let mut writer = client.copy_in_raw(
"COPY \"my_table\" FROM STDIN WITH (FORMAT csv, HEADER true)"
)?;
writer.send(b"1,Alice\n2,Bob\n")?;
let rows = writer.finish()?;§Errors
- Returns
ErrorKind::Queryifquery(trimmed) does not start withCOPY(defense-in-depth check against non-COPY statements). - Returns
Error(connection) if the connection mutex is poisoned. - Returns
Error(server) orError(I/O) if the server rejects the COPY statement or the wire write fails.
Sourcepub fn is_alive(&self) -> bool
pub fn is_alive(&self) -> bool
Returns true if the connection is alive (no error has occurred).
Sourcepub fn copy_out(&self, query: &str) -> Result<Vec<u8>>
pub fn copy_out(&self, query: &str) -> Result<Vec<u8>>
Executes a COPY … TO STDOUT query and returns all output data.
This is used for queries like:
COPY (SELECT ...) TO STDOUT WITH (format arrowstream)
§Arguments
query- The COPY TO STDOUT query to execute
§Returns
The raw bytes from all CopyData messages concatenated together.
§Example
let arrow_data = client.copy_out(
"COPY (SELECT * FROM my_table) TO STDOUT WITH (format arrowstream)"
)?;§Errors
Sourcepub fn copy_out_to_writer(
&self,
query: &str,
writer: &mut dyn Write,
) -> Result<u64>
pub fn copy_out_to_writer( &self, query: &str, writer: &mut dyn Write, ) -> Result<u64>
Executes a COPY … TO STDOUT query and streams output to a writer.
Unlike copy_out which collects all data into memory,
this method streams each CopyData chunk directly to the provided writer,
keeping memory usage constant regardless of result size.
Returns the total number of bytes written.
§Example
let mut file = std::fs::File::create("output.csv")?;
let bytes_written = client.copy_out_to_writer(
"COPY (SELECT * FROM my_table) TO STDOUT WITH (FORMAT csv, HEADER true)",
&mut file,
)?;
println!("Wrote {} bytes", bytes_written);§Errors
Same failure modes as Self::copy_out, plus Error (I/O)
when the supplied writer returns an error while receiving
COPY chunks.
Trait Implementations§
Source§impl Cancellable for Client
impl Cancellable for Client
Auto Trait Implementations§
impl Freeze for Client
impl !RefUnwindSafe for Client
impl Send for Client
impl Sync for Client
impl Unpin for Client
impl UnsafeUnpin for Client
impl !UnwindSafe 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> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request