pub struct Connection { /* private fields */ }Expand description
A connection to a Hyper database.
This struct represents an active connection to a Hyper server and optionally an attached database. The connection is automatically closed when dropped.
§Transport Auto-Detection
The transport is automatically detected from the endpoint URL:
https://orhttp://→ gRPC transport (read-only until server supports writes)- Otherwise → TCP transport (full read/write support)
§CSV / Text Import & Export
For CSV, TSV, and other delimited-text formats, see the copy
module which provides export_csv(),
import_csv(), and related methods on this struct.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
// TCP connection (full read/write)
let conn = Connection::connect("localhost:7483", "example.hyper", CreateMode::CreateIfNotExists)?;
// Execute SQL commands
conn.execute_command("CREATE TABLE test (id INT, name TEXT)")?;
conn.execute_command("INSERT INTO test VALUES (1, 'Hello')")?;
Ok(())
}// gRPC connection (read-only, auto-detected from URL)
let conn = Connection::connect(
"https://hyper-server.example.com:443",
"example.hyper",
CreateMode::DoNotCreate, // Must be DoNotCreate for gRPC
)?;Implementations§
Source§impl Connection
impl Connection
Sourcepub fn new(
instance: &HyperProcess,
database_path: impl AsRef<Path>,
create_mode: CreateMode,
) -> Result<Self>
pub fn new( instance: &HyperProcess, database_path: impl AsRef<Path>, create_mode: CreateMode, ) -> Result<Self>
Creates a new connection to a Hyper instance with a database.
This is the primary way to connect to a running HyperProcess.
§Arguments
instance- The Hyper server instance to connect to.database_path- Path to the database file.create_mode- How to handle database creation.
§Errors
Returns an error if the connection could not be established.
§Example
use hyperdb_api::{HyperProcess, Connection, CreateMode, Result};
fn main() -> Result<()> {
let hyper = HyperProcess::new(None, None)?;
let conn = Connection::new(&hyper, "database.hyper", CreateMode::CreateIfNotExists)?;
Ok(())
}Sourcepub fn connect(
endpoint: &str,
database_path: &str,
create_mode: CreateMode,
) -> Result<Self>
pub fn connect( endpoint: &str, database_path: &str, create_mode: CreateMode, ) -> Result<Self>
Sourcepub fn builder(endpoint: &str) -> ConnectionBuilder
pub fn builder(endpoint: &str) -> ConnectionBuilder
Returns a connection builder for advanced configuration.
This is useful when you need to set authentication, timeouts, or other advanced options before connecting.
Sourcepub fn transport_type(&self) -> &'static str
pub fn transport_type(&self) -> &'static str
Returns the transport type name (e.g., “TCP”, “gRPC”, “Unix Socket”).
Sourcepub fn supports_writes(&self) -> bool
pub fn supports_writes(&self) -> bool
Returns true if this connection supports write operations.
Currently, only TCP connections support writes. gRPC connections are read-only until the server supports write operations over gRPC.
Sourcepub fn connect_with_auth(
endpoint: &str,
database_path: &str,
create_mode: CreateMode,
user: &str,
password: &str,
) -> Result<Self>
pub fn connect_with_auth( endpoint: &str, database_path: &str, create_mode: CreateMode, user: &str, password: &str, ) -> Result<Self>
Connects to a Hyper server with authentication.
§Arguments
endpoint- The server endpoint (host:port).database_path- Path to the database file.create_mode- How to handle database creation.user- Username for authentication.password- Password for authentication.
§Errors
Returns an error if the connection or authentication fails.
Sourcepub fn without_database(endpoint: &str) -> Result<Self>
pub fn without_database(endpoint: &str) -> Result<Self>
Creates a connection to a Hyper server without attaching a database.
§Errors
Returns Error::Client if the TCP or gRPC handshake fails, and
Error::Io if the endpoint cannot be reached.
Sourcepub fn execute_command(&self, command: &str) -> Result<u64>
pub fn execute_command(&self, command: &str) -> Result<u64>
Executes a SQL command that doesn’t return results.
Use this for DDL statements (CREATE, ALTER, DROP) and DML statements (INSERT, UPDATE, DELETE).
§Arguments
command- The SQL command to execute.
§Returns
The number of affected rows, or 0 if not applicable.
§Errors
Returns an error if:
- The connection is using gRPC transport (write operations not yet supported)
- The command fails to execute
Sourcepub fn execute_query(&self, query: &str) -> Result<Rowset<'_>>
pub fn execute_query(&self, query: &str) -> Result<Rowset<'_>>
Executes a SQL query and returns a streaming result set.
Results are streamed in chunks (default 64K rows), keeping memory usage constant regardless of result set size. This makes it safe for any result size, from a single row to billions of rows.
§Example
let mut result = conn.execute_query("SELECT id, value FROM measurements")?;
while let Some(chunk) = result.next_chunk()? {
for row in &chunk {
// Generic typed access (like C++ row.get<T>())
let id: Option<i32> = row.get(0);
let value: Option<f64> = row.get(1);
// Or direct accessors
let id = row.get_i32(0);
let value = row.get_f64(1);
}
}§Memory Behavior
- Only one chunk is held in memory at a time (~few MB for 64K rows)
- Safe for result sets of any size (millions/billions of rows)
- Memory usage is
O(chunk_size), notO(total_rows)
§Errors
- Returns
Error::Clientwrapping ahyperdb_api_core::client::Errorif the SQL fails to parse, execute, or if the server reports an error while streaming. - Returns
Error::Ioon transport-level I/O failures.
Sourcepub fn execute_query_to_arrow(&self, select_query: &str) -> Result<Bytes>
pub fn execute_query_to_arrow(&self, select_query: &str) -> Result<Bytes>
Executes a SELECT query and returns results as Arrow IPC stream bytes.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::CreateIfNotExists)?;
// Create and populate a table
conn.execute_command("CREATE TABLE data (id INT, value DOUBLE PRECISION)")?;
conn.execute_command("INSERT INTO data VALUES (1, 1.5), (2, 2.5)")?;
// Get results as Arrow IPC stream
let arrow_data = conn.execute_query_to_arrow("SELECT * FROM data")?;
println!("Got {} bytes of Arrow IPC data", arrow_data.len());
Ok(())
}§Errors
Propagates any Error::Client from the TCP or gRPC transport when
the query fails or the server cannot produce Arrow IPC output.
Sourcepub fn export_table_to_arrow(&self, table_name: &str) -> Result<Bytes>
pub fn export_table_to_arrow(&self, table_name: &str) -> Result<Bytes>
Exports an entire table to Arrow IPC stream format.
This is a convenience method equivalent to
execute_query_to_arrow("SELECT * FROM table_name").
§Arguments
table_name- The table name
§Returns
Raw Arrow IPC stream bytes containing all rows from the table.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::CreateIfNotExists)?;
let arrow_data = conn.export_table_to_arrow("my_table")?;
Ok(())
}§Errors
Returns whatever execute_query_to_arrow
would return for SELECT * FROM <table_name> — typically
Error::Client if the table does not exist or the query is rejected.
Sourcepub fn execute_query_to_batches(
&self,
select_query: &str,
) -> Result<Vec<RecordBatch>>
pub fn execute_query_to_batches( &self, select_query: &str, ) -> Result<Vec<RecordBatch>>
Executes a SELECT query and returns results as Arrow RecordBatches.
This is the recommended method for Arrow-native workflows (DataFusion,
Polars, etc.) where you want direct RecordBatch access without going
through the Row abstraction.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
use arrow::record_batch::RecordBatch;
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let batches: Vec<RecordBatch> = conn.execute_query_to_batches("SELECT * FROM data")?;
for batch in &batches {
println!("batch: {} rows x {} cols", batch.num_rows(), batch.num_columns());
}
Ok(())
}§Errors
- Returns
Error::Clientif the query itself fails. - Returns
Error::Otherif the Arrow IPC payload returned by the server is malformed and cannot be decoded into record batches.
Sourcepub fn fetch_one<Q>(&self, query: Q) -> Result<Row>
pub fn fetch_one<Q>(&self, query: Q) -> Result<Row>
Fetches a single row from a query.
Returns an error if the query returns no rows.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let row = conn.fetch_one("SELECT * FROM users WHERE id = 1")?;
let id: Option<i32> = row.get(0);
let name: Option<String> = row.get(1);
Ok(())
}§Errors
- Returns the error from
execute_queryif the query itself fails. - Returns
Error::Otherwith message"Query returned no rows"if the query produced zero rows.
Sourcepub fn fetch_optional<Q>(&self, query: Q) -> Result<Option<Row>>
pub fn fetch_optional<Q>(&self, query: Q) -> Result<Option<Row>>
Fetches an optional single row from a query.
Returns None if the query returns no rows.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
if let Some(row) = conn.fetch_optional("SELECT * FROM users WHERE id = 999")? {
let name: Option<String> = row.get(1);
println!("Found user: {:?}", name);
}
Ok(())
}§Errors
Returns the error from execute_query if the
query itself fails. An empty result set is not an error — it yields
Ok(None).
Sourcepub fn fetch_all<Q>(&self, query: Q) -> Result<Vec<Row>>
pub fn fetch_all<Q>(&self, query: Q) -> Result<Vec<Row>>
Fetches all rows from a query.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let rows = conn.fetch_all("SELECT * FROM users WHERE active = true ORDER BY name")?;
for row in rows {
let id: Option<i32> = row.get(0);
let name: Option<String> = row.get(1);
println!("User {}: {:?}", id.unwrap_or(-1), name);
}
Ok(())
}§Errors
Returns the error from execute_query, or a
transport error produced while draining every chunk of the streamed
result set.
Sourcepub fn fetch_one_as<T: FromRow>(&self, query: &str) -> Result<T>
pub fn fetch_one_as<T: FromRow>(&self, query: &str) -> Result<T>
Fetches a single row and maps it to a struct using FromRow.
Returns an error if the query returns no rows or if mapping fails.
§Example
use hyperdb_api::{Connection, CreateMode, Row, FromRow, Result};
struct User { id: i32, name: String }
impl FromRow for User {
fn from_row(row: &Row) -> Result<Self> {
Ok(User {
id: row.get::<i32>(0).ok_or_else(|| hyperdb_api::Error::new("NULL id"))?,
name: row.get::<String>(1).unwrap_or_default(),
})
}
}
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let user: User = conn.fetch_one_as("SELECT id, name FROM users WHERE id = 1")?;
Ok(())
}§Errors
- Returns the error from
fetch_oneif the query fails or returns no rows. - Returns whatever error
FromRow::from_rowproduces when the row cannot be mapped intoT.
Sourcepub fn fetch_all_as<T: FromRow>(&self, query: &str) -> Result<Vec<T>>
pub fn fetch_all_as<T: FromRow>(&self, query: &str) -> Result<Vec<T>>
Fetches all rows and maps them to structs using FromRow.
§Example
let users: Vec<User> = conn.fetch_all_as("SELECT id, name FROM users")?;§Errors
- Returns the error from
fetch_allif the query fails. - Returns the first error produced by
FromRow::from_rowon any of the rows.
Sourcepub fn fetch_scalar<T, Q>(&self, query: Q) -> Result<T>
pub fn fetch_scalar<T, Q>(&self, query: Q) -> Result<T>
Fetches a single scalar value from a query.
Returns an error if the query returns no rows or NULL.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let count: i64 = conn.fetch_scalar("SELECT COUNT(*) FROM users")?;
println!("User count: {}", count);
Ok(())
}§Errors
- Returns the error from
execute_queryif the query itself fails. - Returns
Error::Otherwith message"Query returned no rows"if the query produced zero rows. - Returns
Error::Otherwith message"Scalar query returned NULL"if the single cell is SQLNULL.
Sourcepub fn fetch_optional_scalar<T, Q>(&self, query: Q) -> Result<Option<T>>
pub fn fetch_optional_scalar<T, Q>(&self, query: Q) -> Result<Option<T>>
Fetches an optional scalar value from a query.
Returns None if the query returns no rows or NULL.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let max_id: Option<i32> = conn.fetch_optional_scalar("SELECT MAX(id) FROM users")?;
println!("Max ID: {:?}", max_id);
Ok(())
}§Errors
- Returns the error from
execute_queryif the query itself fails. - Returns
Error::Otherwith message"Query returned no rows"if the query produced zero rows. (An empty result is treated as an error here because we need at least one row to inspect; SQLNULLin the single cell yieldsOk(None).)
Sourcepub fn execute_scalar_query<T>(&self, query: &str) -> Result<Option<T>>where
T: ScalarValue + RowValue,
pub fn execute_scalar_query<T>(&self, query: &str) -> Result<Option<T>>where
T: ScalarValue + RowValue,
Executes a scalar query and returns a single value of type T.
Alias for fetch_optional_scalar for C++ API compatibility.
§Errors
Sourcepub fn query_count(&self, query: &str) -> Result<i64>
pub fn query_count(&self, query: &str) -> Result<i64>
Queries for a count value, defaulting to 0 if NULL.
This is optimized for COUNT queries which typically return 0 instead of NULL when there are no matching rows.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let count = conn.query_count("SELECT COUNT(*) FROM users WHERE active = true")?;
println!("Active users: {}", count);
Ok(())
}§Errors
Returns the error from execute_query if the
query fails or produces no rows. SQL NULL is mapped to 0, not an
error.
Sourcepub fn query_params(
&self,
query: &str,
params: &[&dyn ToSqlParam],
) -> Result<Rowset<'_>>
pub fn query_params( &self, query: &str, params: &[&dyn ToSqlParam], ) -> Result<Rowset<'_>>
Executes a parameterized query, returning streaming results.
This is safe to use with untrusted user input: parameters travel
through the extended query protocol (Parse/Bind/Execute) as
binary HyperBinary values and are never interpolated into the
SQL string. For repeated executions of the same SQL with different
values, prefer the explicit prepare API — it
returns a reusable PreparedStatement
that skips the Parse round-trip on every call.
Under the hood, query_params is a one-shot
prepare+execute+close: it prepares an unnamed statement, binds
the parameters, starts streaming, and closes the statement when
the returned Rowset is dropped.
§Arguments
query- The SQL query with parameter placeholders ($1,$2, etc.)params- Parameter values matching the placeholders
§SQL Injection Prevention
use hyperdb_api::{Connection, CreateMode, Result};
fn search_users(conn: &Connection, user_input: &str) -> Result<()> {
// DANGEROUS - vulnerable to SQL injection:
// let query = format!("SELECT * FROM users WHERE name = '{}'", user_input);
// SAFE - parameterized query:
let mut result = conn.query_params(
"SELECT * FROM users WHERE name = $1",
&[&user_input],
)?;
while let Some(chunk) = result.next_chunk()? {
for row in &chunk {
let id: Option<i32> = row.get(0);
let name: Option<String> = row.get(1);
println!("Found: {:?} - {:?}", id, name);
}
}
Ok(())
}§Multiple Parameters
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
// Multiple parameters of different types
let result = conn.query_params(
"SELECT * FROM orders WHERE customer_id = $1 AND total > $2",
&[&42i32, &100.0f64],
)?;
Ok(())
}§Errors
- Returns
Error::Otherif the connection is using gRPC transport (prepared statements are TCP-only). - Returns
Error::Clientif the server rejects the statement atParse,Bind, orExecutetime, including on type-mismatch betweenparamsand the inferred OIDs. - Returns
Error::Ioon transport-level I/O failures.
Sourcepub fn command_params(
&self,
query: &str,
params: &[&dyn ToSqlParam],
) -> Result<u64>
pub fn command_params( &self, query: &str, params: &[&dyn ToSqlParam], ) -> Result<u64>
Executes a parameterized command that doesn’t return rows.
Use this for INSERT, UPDATE, DELETE, or DDL statements with parameters. Returns the number of affected rows.
See query_params for details on parameter
handling and SQL injection prevention.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn delete_user(conn: &Connection, user_id: i32) -> Result<u64> {
// Safe from SQL injection
conn.command_params("DELETE FROM users WHERE id = $1", &[&user_id])
}§Errors
- Returns
Error::Otherif the connection is using gRPC transport. - Returns
Error::Clientif the server rejects the statement atParse,Bind, orExecutetime. - Returns
Error::Ioon transport-level I/O failures.
Sourcepub fn execute_batch(&self, statements: &[&str]) -> Result<u64>
pub fn execute_batch(&self, statements: &[&str]) -> Result<u64>
Executes multiple SQL statements in a single call.
Each statement is executed sequentially. If any statement fails, execution stops and the error is returned. Returns the total number of affected rows across all statements.
This is more efficient than calling execute_command in a loop
because it reduces round-trips for DDL scripts and multi-statement setup.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let total = conn.execute_batch(&[
"CREATE TABLE users (id INT, name TEXT)",
"INSERT INTO users VALUES (1, 'Alice')",
"INSERT INTO users VALUES (2, 'Bob')",
])?;
println!("Total affected: {}", total);
Ok(())
}§Errors
Returns a wrapped Error::Other on the first statement that fails;
its source is the original Error::Client from
execute_command. The error message
includes the failing statement’s ordinal and an 80-character preview
of its SQL.
Sourcepub fn create_database(&self, path: &str) -> Result<()>
pub fn create_database(&self, path: &str) -> Result<()>
Creates a new database file.
§Example
use hyperdb_api::{Connection, Result};
fn main() -> Result<()> {
let conn = Connection::without_database("localhost:7483")?;
conn.create_database("new_database.hyper")?;
Ok(())
}§Errors
Returns Error::Client if the server rejects the
CREATE DATABASE IF NOT EXISTS statement (e.g. the path is not
writable on the server).
Sourcepub fn drop_database(&self, path: &str) -> Result<()>
pub fn drop_database(&self, path: &str) -> Result<()>
Drops (deletes) a database file.
§Example
use hyperdb_api::{Connection, Result};
fn main() -> Result<()> {
let conn = Connection::without_database("localhost:7483")?;
conn.drop_database("old_database.hyper")?;
Ok(())
}§Errors
Returns Error::Client if the server rejects the
DROP DATABASE IF EXISTS statement (e.g. the database is still
attached or permissions deny deletion).
Sourcepub fn attach_database(&self, path: &str, alias: Option<&str>) -> Result<()>
pub fn attach_database(&self, path: &str, alias: Option<&str>) -> Result<()>
Attaches a database file to the connection.
Once attached, the database can be queried and modified. The database is identified by its alias (or by its path if no alias is provided).
§Arguments
path- The path to the database file to attach.alias- Optional alias for the database. IfNone, the database is attached without an explicit alias (typically using its filename).
§Errors
Returns an error if the database file doesn’t exist or if attachment fails.
§Example
use hyperdb_api::{Connection, Result};
fn main() -> Result<()> {
let conn = Connection::without_database("localhost:7483")?;
// Attach with an alias
conn.attach_database("data.hyper", Some("mydata"))?;
// Attach without an alias
conn.attach_database("other.hyper", None)?;
Ok(())
}Sourcepub fn detach_database(&self, alias: &str) -> Result<()>
pub fn detach_database(&self, alias: &str) -> Result<()>
Detaches a database from this connection.
After detaching, the database file is released and can be accessed externally (e.g., copied, moved, etc.). All pending updates are written to disk before detaching.
§Arguments
alias- The alias of the database to detach.
§Errors
Returns an error if the database is not attached or if detachment fails.
§Example
use hyperdb_api::{Connection, Result};
fn main() -> Result<()> {
let conn = Connection::without_database("localhost:7483")?;
conn.attach_database("data.hyper", Some("mydata"))?;
// ... work with the database ...
conn.detach_database("mydata")?;
Ok(())
}Sourcepub fn detach_all_databases(&self) -> Result<()>
pub fn detach_all_databases(&self) -> Result<()>
Detaches all databases from this connection.
This is useful for cleanup before closing a connection or when you need to release all database files.
§Errors
Returns Error::Client if the server rejects the
DETACH ALL DATABASES statement (e.g. a database is still in use by
another session).
Sourcepub fn create_schema<T>(&self, schema_name: T) -> Result<()>
pub fn create_schema<T>(&self, schema_name: T) -> Result<()>
Creates a schema in the database.
§Errors
- Returns an error if
schema_namecannot be converted into aSchemaName(invalid identifier). - Returns
Error::Clientif the server rejects theCREATE SCHEMAstatement (e.g. the schema already exists).
Sourcepub fn has_schema<T>(&self, schema: T) -> Result<bool>
pub fn has_schema<T>(&self, schema: T) -> Result<bool>
Checks whether a schema exists.
§Arguments
schema- The schema name (can include database qualifier).
§Example
use hyperdb_api::{Connection, Result};
fn main() -> Result<()> {
let conn = Connection::without_database("localhost:7483")?;
if conn.has_schema("public")? {
println!("Schema 'public' exists");
}
Ok(())
}§Errors
- Returns an error if
schemacannot be converted into aSchemaName. - Returns
Error::Clientif the catalog lookup query fails.
Sourcepub fn has_table<T>(&self, table_name: T) -> Result<bool>
pub fn has_table<T>(&self, table_name: T) -> Result<bool>
Checks whether a table exists.
§Arguments
table_name- The table name (can include database and schema qualifiers).
§Example
use hyperdb_api::{Connection, Result};
fn main() -> Result<()> {
let conn = Connection::without_database("localhost:7483")?;
if conn.has_table("public.users")? {
println!("Table 'users' exists");
}
Ok(())
}§Errors
- Returns an error if
table_namecannot be converted into aTableName. - Returns
Error::Clientif the catalog lookup query fails.
Sourcepub fn server_version(&self) -> Option<ServerVersion>
pub fn server_version(&self) -> Option<ServerVersion>
Returns the server version as a parsed struct.
Returns None if the version cannot be determined (e.g., gRPC connection).
§Example
use hyperdb_api::{Connection, CreateMode, HyperProcess, ServerVersion, Result};
fn main() -> Result<()> {
let hyper = HyperProcess::new(None, None)?;
let conn = Connection::new(&hyper, "test.hyper", CreateMode::CreateIfNotExists)?;
if let Some(version) = conn.server_version() {
println!("Hyper {}", version);
if version >= ServerVersion::new(0, 1, 0) {
println!("Has feature X");
}
}
Ok(())
}Sourcepub fn copy_database(&self, source: &str, destination: &str) -> Result<()>
pub fn copy_database(&self, source: &str, destination: &str) -> Result<()>
Copies a database file to a new path.
The source database must be attached to this connection.
§Example
use hyperdb_api::{Connection, CreateMode, HyperProcess, Result};
fn main() -> Result<()> {
let hyper = HyperProcess::new(None, None)?;
let conn = Connection::new(&hyper, "source.hyper", CreateMode::DoNotCreate)?;
conn.copy_database("source.hyper", "backup.hyper")?;
Ok(())
}§Errors
Returns Error::Client if the server rejects the
COPY DATABASE statement — e.g. the source is not attached, the
destination path is not writable, or it already exists.
Sourcepub fn explain(&self, query: &str) -> Result<String>
pub fn explain(&self, query: &str) -> Result<String>
Executes EXPLAIN on a query and returns the plan as a string.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let plan = conn.explain("SELECT * FROM users WHERE id = 1")?;
println!("{}", plan);
Ok(())
}§Errors
Returns Error::Client if EXPLAIN <query> fails to parse or
plan, or if the streamed result cannot be consumed.
Sourcepub fn explain_analyze(&self, query: &str) -> Result<String>
pub fn explain_analyze(&self, query: &str) -> Result<String>
Executes EXPLAIN ANALYZE on a query and returns the plan with timing info.
Note: This actually executes the query to collect timing information.
§Errors
Returns Error::Client if EXPLAIN ANALYZE <query> fails — this
includes any runtime error raised by actually executing query.
Sourcepub fn tcp_client(&self) -> Option<&Client>
pub fn tcp_client(&self) -> Option<&Client>
Returns a reference to the underlying TCP client.
§Panics
This method returns None if the connection is using gRPC transport.
Sourcepub fn prepare(&self, query: &str) -> Result<PreparedStatement<'_>>
pub fn prepare(&self, query: &str) -> Result<PreparedStatement<'_>>
Prepares a SQL statement with automatic parameter type inference.
The returned PreparedStatement can
be executed many times with different parameter values; the
server caches the parsed plan. This is the preferred way to
execute a statement repeatedly inside a loop.
For explicit parameter types (necessary when $N placeholders
would otherwise be ambiguous), use
prepare_typed.
§Example
let stmt = conn.prepare("SELECT name FROM users WHERE id = $1")?;
for id in [1_i32, 2, 3] {
let name: String = stmt.fetch_scalar(&[&id])?;
println!("{id}: {name}");
}§Errors
See prepare_typed — this method delegates
to it with an empty OID list.
Sourcepub fn prepare_typed(
&self,
query: &str,
param_types: &[Oid],
) -> Result<PreparedStatement<'_>>
pub fn prepare_typed( &self, query: &str, param_types: &[Oid], ) -> Result<PreparedStatement<'_>>
Prepares a SQL statement with explicit parameter type OIDs.
Use this when the server cannot infer parameter types from the
SQL alone (e.g. a bare $1 in a WHERE v > $1 clause with no
other context). Constants for common types live in
hyperdb_api_core::types::oids.
§Errors
- Returns
Error::Otherif the connection is using gRPC transport (prepared statements are TCP-only). - Returns
Error::Clientif the server rejects theParsemessage, e.g. SQL syntax error or unknown OID. - Returns
Error::Ioon transport-level I/O failures.
Sourcepub fn is_alive(&self) -> bool
pub fn is_alive(&self) -> bool
Returns true if the connection is alive (passive check).
This is a lightweight check that does not send any data to the server.
For an active health check, use ping.
Sourcepub fn ping(&self) -> Result<()>
pub fn ping(&self) -> Result<()>
Actively checks that the connection is healthy by executing a trivial query.
Unlike is_alive which only checks local state,
this method sends SELECT 1 to the server and verifies a response.
§Example
if conn.ping().is_ok() {
println!("Connection is healthy");
}§Errors
Returns Error::Client or Error::Io if the SELECT 1
round-trip fails — i.e. the connection is no longer usable.
Sourcepub fn process_id(&self) -> i32
pub fn process_id(&self) -> i32
Returns the process ID of the backend server connection.
Returns 0 for gRPC connections (not applicable).
Sourcepub fn secret_key(&self) -> i32
pub fn secret_key(&self) -> i32
Returns the secret key for the backend server connection.
This is used for cancellation requests. Returns 0 for gRPC connections (not applicable).
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 encodingDateStyle- Date display formatTimeZone- Server timezonesession_identifier- Session ID for connection migration (if routing enabled)
Returns None if the parameter is not known.
§Example
use hyperdb_api::{Connection, CreateMode, HyperProcess, Result};
fn main() -> Result<()> {
let hyper = HyperProcess::new(None, None)?;
let conn = Connection::new(&hyper, "test.hyper", CreateMode::CreateIfNotExists)?;
if let Some(version) = conn.parameter_status("server_version") {
println!("Connected to Hyper version: {}", version);
}
Ok(())
}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.
Server notices and warnings are passed to this callback instead of being
logged. Pass None to restore default logging behavior.
Sourcepub fn cancel(&self) -> Result<()>
pub fn cancel(&self) -> Result<()>
Cancels the currently executing query (thread-safe).
§Errors
- Returns
Error::Otheron gRPC connections — cancellation is not yet implemented for gRPC transport. - Returns
Error::ClientorError::Ioif the separate cancel-request connection to the server fails.
Sourcepub fn close(self) -> Result<()>
pub fn close(self) -> Result<()>
Closes the connection, detaching all databases first.
§Errors
- Returns
Error::Otherwrapping the underlying close failure (itssourceis the transport error) if the client cannot be shut down cleanly. - Returns
Error::Otherwrapping the detach failure if the attached database could not be detached but close itself succeeded.
Sourcepub fn unload_database(&self) -> Result<()>
pub fn unload_database(&self) -> Result<()>
Unloads the database from memory while keeping the connection active.
This executes the UNLOAD DATABASE command, which releases the database
from memory but keeps the session and connection open. The database can
be accessed again by subsequent queries that will automatically reload it.
This is useful for releasing memory locks when switching between databases or when working with multiple database files.
§Example
use hyperdb_api::{Connection, CreateMode, HyperProcess, Result};
fn main() -> Result<()> {
let hyper = HyperProcess::new(None, None)?;
let conn = Connection::new(&hyper, "test.hyper", CreateMode::Create)?;
// Do some work with the database
conn.execute_command("CREATE TABLE test (id INT)")?;
// Unload from memory (but keep connection)
conn.unload_database()?;
// Database can still be accessed (will be reloaded automatically)
let count: i64 = conn.fetch_scalar("SELECT COUNT(*) FROM test")?;
println!("Count: {}", count);
Ok(())
}§Errors
Returns Error::Client if the server rejects the UNLOAD DATABASE
command (e.g. the database is still in use by another session).
Sourcepub fn unload_release(&self) -> Result<()>
pub fn unload_release(&self) -> Result<()>
Releases the database completely from the session.
This executes the UNLOAD RELEASE command, which completely releases
the database from the session. After this call, the database cannot
be accessed until a new connection is established.
This is useful for completely freeing database resources when you’re done with a database and want to ensure no locks are held.
Note: This should only be used when the session has exactly one
database attached. Hyper does not support UNLOAD RELEASE with
multiple databases attached to the same session.
§Example
use hyperdb_api::{Connection, CreateMode, HyperProcess, Result};
fn main() -> Result<()> {
let hyper = HyperProcess::new(None, None)?;
let conn = Connection::new(&hyper, "test.hyper", CreateMode::Create)?;
// Do some work with the database
conn.execute_command("CREATE TABLE test (id INT)")?;
// Release database completely from session
conn.unload_release()?;
// Database cannot be accessed after this point without new connection
// conn.execute_command("SELECT * FROM test")?; // This would fail
Ok(())
}§Errors
Returns Error::Client if the server rejects UNLOAD RELEASE, most
commonly because multiple databases are attached to the same session
(Hyper only supports UNLOAD RELEASE with exactly one attached DB).
Sourcepub fn enable_query_stats(
&mut self,
provider: impl QueryStatsProvider + 'static,
)
pub fn enable_query_stats( &mut self, provider: impl QueryStatsProvider + 'static, )
Enables query statistics collection for this connection.
After enabling, each execute_command() or execute_query() call will
capture detailed performance metrics from Hyper. Retrieve them via
last_query_stats().
The provider determines how stats are collected. Use
LogFileStatsProvider to parse Hyper’s log file (requires local
hyperd.log), or implement a custom QueryStatsProvider.
§Example
use hyperdb_api::LogFileStatsProvider;
// Auto-detect log path from HyperProcess
conn.enable_query_stats(LogFileStatsProvider::from_process(&hyper));
// Or specify an explicit log path
// conn.enable_query_stats(LogFileStatsProvider::new("/path/to/hyperd.log"));Sourcepub fn disable_query_stats(&mut self)
pub fn disable_query_stats(&mut self)
Disables query statistics collection.
After calling this, last_query_stats() will return None.
Sourcepub fn last_query_stats(&self) -> Option<QueryStats>
pub fn last_query_stats(&self) -> Option<QueryStats>
Returns the query statistics from the most recent query execution.
Stats are resolved lazily — the log file is read when this method
is called, not when the query executes. This is important for streaming
queries (execute_query), where Hyper writes the execution stats only
after the result set is fully consumed.
Call this after consuming the result set (e.g., after collect_rows(),
iterating all chunks, or dropping the Rowset).
Returns None if:
- Query stats collection is not enabled
- No query has been executed yet
- Stats could not be found for the last query (e.g., log entry not matched)
§Example
conn.execute_command("CREATE TABLE t (id INT)")?;
if let Some(stats) = conn.last_query_stats() {
println!("Total: {}s", stats.elapsed_s);
if let Some(ref pre) = stats.pre_execution {
println!(" Parse: {:?}s", pre.parsing_time_s);
println!(" Compile: {:?}s", pre.compilation_time_s);
}
if let Some(ref exec) = stats.execution {
println!(" Execute: {:?}s", exec.elapsed_s);
println!(" Peak mem: {:?} MB", exec.peak_memory_mb);
}
}Source§impl Connection
impl Connection
Sourcepub fn begin_transaction(&self) -> Result<()>
pub fn begin_transaction(&self) -> Result<()>
Begins an explicit transaction.
For an RAII guard that auto-rolls back on drop, use transaction() instead.
§Example
conn.begin_transaction()?;
conn.execute_command("INSERT INTO users VALUES (1, 'Alice')")?;
conn.commit()?;§Errors
Returns Error::Client if the server rejects BEGIN TRANSACTION
(e.g. a transaction is already open on this session).
Sourcepub fn commit(&self) -> Result<()>
pub fn commit(&self) -> Result<()>
Commits the current transaction.
§Errors
Returns Error::Client if the server rejects COMMIT — most
commonly because no transaction is currently open.
Sourcepub fn rollback(&self) -> Result<()>
pub fn rollback(&self) -> Result<()>
Rolls back the current transaction.
§Errors
Returns Error::Client if the server rejects ROLLBACK — most
commonly because no transaction is currently open.
Sourcepub fn transaction(&mut self) -> Result<Transaction<'_>>
pub fn transaction(&mut self) -> Result<Transaction<'_>>
Starts a transaction and returns an RAII guard that auto-rolls back on drop.
The returned Transaction exclusively borrows this connection,
preventing any other use of the connection while the transaction is active.
This is enforced at compile time by Rust’s borrow checker. The guard provides
commit() and rollback() methods. If dropped without calling either, the
transaction is automatically rolled back.
§Example
let txn = conn.transaction()?;
txn.execute_command("INSERT INTO users VALUES (1, 'Alice')")?;
txn.commit()?; // or drop `txn` to auto-rollback§Errors
Returns Error::Client if the server rejects the BEGIN
statement issued internally by
Transaction::new.
Source§impl Connection
impl Connection
Sourcepub fn export_csv(
&self,
select_query: &str,
writer: &mut dyn Write,
) -> Result<u64>
pub fn export_csv( &self, select_query: &str, writer: &mut dyn Write, ) -> Result<u64>
Exports query results as CSV to a writer.
Uses default CSV options (comma-separated, with header row).
For custom options, use export_text.
This method streams data directly to the writer without buffering the entire result set in memory, making it safe for large exports.
Returns the number of bytes written.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
// Export to file
let mut file = std::fs::File::create("output.csv")?;
conn.export_csv("SELECT * FROM users", &mut file)?;
// Export to string
let mut buf = Vec::new();
conn.export_csv("SELECT * FROM users", &mut buf)?;
let csv_string = String::from_utf8(buf).unwrap();
Ok(())
}§Errors
- Returns
Error::Otherif the connection is using gRPC transport (COPY is TCP-only). - Returns
Error::Clientif the server rejects theCOPY (<select_query>) TO STDOUTstatement. - Returns
Error::Ioif writing towriterfails.
Sourcepub fn export_text(
&self,
select_query: &str,
options: &CopyOptions,
writer: &mut dyn Write,
) -> Result<u64>
pub fn export_text( &self, select_query: &str, options: &CopyOptions, writer: &mut dyn Write, ) -> Result<u64>
Exports query results as text (CSV/TSV/custom) to a writer.
This method streams data directly to the writer without buffering the entire result set in memory.
Returns the number of bytes written.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
use hyperdb_api::copy::CopyOptions;
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
// TSV export
let opts = CopyOptions::tsv().with_header(true);
let mut buf = Vec::new();
conn.export_text("SELECT * FROM users", &opts, &mut buf)?;
// Pipe-separated with custom NULL
let opts = CopyOptions::csv()
.with_delimiter(b'|')
.with_null("\\N".to_string())
.with_header(true);
conn.export_text("SELECT * FROM users", &opts, &mut std::io::stdout())?;
Ok(())
}§Errors
- Returns
Error::Otherifoptionsfail validation (e.g. an illegal delimiter/quote combination) or the connection is on gRPC. - Returns
Error::Clientif the server rejects theCOPY TO STDOUTstatement. - Returns
Error::Ioif writing towriterfails.
Sourcepub fn export_csv_string(&self, select_query: &str) -> Result<String>
pub fn export_csv_string(&self, select_query: &str) -> Result<String>
Exports query results as CSV to a String.
Convenience method that collects the CSV output into a String.
For large datasets, prefer export_csv with a file writer.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
let csv = conn.export_csv_string("SELECT id, name FROM users")?;
println!("{}", csv);
Ok(())
}§Errors
- Returns whatever
export_csvreturns. - Returns
Error::Otherwith message"CSV output is not valid UTF-8"if the server emitted bytes that are not valid UTF-8 (a Hyper server only emits UTF-8, so this indicates a non-UTF-8CLIENT_ENCODINGsetting).
Sourcepub fn import_csv(&self, table_name: &str, reader: impl Read) -> Result<u64>
pub fn import_csv(&self, table_name: &str, reader: impl Read) -> Result<u64>
Imports CSV data from a reader into a table.
Uses default CSV options (comma-separated, no header).
For custom options, use import_text.
Returns the number of rows imported.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
// Import from a string
let csv = "1,Alice\n2,Bob\n";
let rows = conn.import_csv("users", csv.as_bytes())?;
// Import from a file
let file = std::fs::File::open("data.csv")?;
let rows = conn.import_csv("users", file)?;
Ok(())
}§Errors
See import_text.
Sourcepub fn import_csv_with_header(
&self,
table_name: &str,
reader: impl Read,
) -> Result<u64>
pub fn import_csv_with_header( &self, table_name: &str, reader: impl Read, ) -> Result<u64>
Imports CSV data with header from a reader into a table.
The first line is treated as a header row and skipped.
Returns the number of rows imported.
§Errors
See import_text.
Sourcepub fn import_text(
&self,
table_name: &str,
options: &CopyOptions,
reader: impl Read,
) -> Result<u64>
pub fn import_text( &self, table_name: &str, options: &CopyOptions, reader: impl Read, ) -> Result<u64>
Imports text-format data (CSV/TSV/custom) from a reader into a table.
Streams data in chunks to the server via COPY FROM STDIN, keeping memory usage constant regardless of input size.
Returns the number of rows imported.
§Example
use hyperdb_api::{Connection, CreateMode, Result};
use hyperdb_api::copy::CopyOptions;
fn main() -> Result<()> {
let conn = Connection::connect("localhost:7483", "test.hyper", CreateMode::DoNotCreate)?;
// Import TSV data
let opts = CopyOptions::tsv();
let tsv = "1\tAlice\n2\tBob\n";
let rows = conn.import_text("users", &opts, tsv.as_bytes())?;
// Import pipe-delimited with header
let opts = CopyOptions::csv().with_delimiter(b'|').with_header(true);
let data = "id|name\n1|Alice\n2|Bob\n";
let rows = conn.import_text("users", &opts, data.as_bytes())?;
Ok(())
}§Errors
- Returns
Error::Otherifoptionsfail validation or the connection is on gRPC. - Returns
Error::Clientif the server rejects theCOPY <table> FROM STDINstatement or a row during import. - Returns
Error::Ioif reading fromreaderfails.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Connection
impl !RefUnwindSafe for Connection
impl Send for Connection
impl Sync for Connection
impl Unpin for Connection
impl UnsafeUnpin for Connection
impl !UnwindSafe for Connection
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