use hyperdb_api::{
AsyncConnection, AsyncConnectionBuilder, CreateMode, FromRow, HyperProcess, Result, Row,
};
#[derive(Debug)]
#[expect(
dead_code,
reason = "fields are read only through the derived `Debug` impl in the example output"
)]
struct Order {
id: i32,
customer: String,
total: f64,
}
impl FromRow for Order {
fn from_row(row: &Row) -> Result<Self> {
Ok(Order {
id: row
.get::<i32>(0)
.ok_or_else(|| hyperdb_api::Error::new("NULL id"))?,
customer: row.get::<String>(1).unwrap_or_default(),
total: row.get::<f64>(2).unwrap_or(0.0),
})
}
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<()> {
let hyper = HyperProcess::new(None, None)?;
let endpoint = hyper.require_endpoint()?.to_string();
let db_path = std::env::temp_dir().join("async_parity_smoke.hyper");
let mut conn = AsyncConnectionBuilder::new(&endpoint)
.database(&db_path)
.create_mode(CreateMode::CreateAndReplace)
.build()
.await?;
conn.execute_command(
"CREATE TABLE orders (id INT NOT NULL, customer TEXT, total DOUBLE PRECISION)",
)
.await?;
for (id, customer, total) in [(1i32, "Alice", 99.5), (2, "Bob", 250.0), (3, "Carol", 12.0)] {
conn.command_params(
"INSERT INTO orders VALUES ($1, $2, $3)",
&[&id, &customer, &total],
)
.await?;
}
let count: i64 = conn.fetch_scalar("SELECT COUNT(*) FROM orders").await?;
println!("inserted {count} orders");
let rs = conn
.query_params(
"SELECT id, customer, total FROM orders WHERE total > $1 ORDER BY id",
&[&50.0_f64],
)
.await?;
let rows = rs.collect_rows().await?;
for row in &rows {
let order = Order::from_row(row)?;
println!(" high-value: {order:?}");
}
let all: Vec<Order> = conn
.fetch_all_as("SELECT id, customer, total FROM orders ORDER BY id")
.await?;
println!("all orders: {} entries", all.len());
{
let txn = conn.transaction().await?;
let current_total: f64 = txn.fetch_scalar("SELECT SUM(total) FROM orders").await?;
txn.command_params(
"INSERT INTO orders VALUES ($1, $2, $3)",
&[&999i32, &"AdjustmentBot", &-current_total],
)
.await?;
let new_total: f64 = txn.fetch_scalar("SELECT SUM(total) FROM orders").await?;
assert!(
new_total.abs() < 1e-6,
"balance should be zero after adjustment"
);
txn.commit().await?;
}
let arrow_bytes = conn.export_table_to_arrow("orders").await?;
println!("exported {} bytes of Arrow IPC", arrow_bytes.len());
let plan = conn
.explain("SELECT * FROM orders WHERE total > 100")
.await?;
println!(
"query plan (first line): {}",
plan.lines().next().unwrap_or("<empty>")
);
conn.ping().await?;
conn.close().await?;
let _ = AsyncConnection::builder; println!("async parity smoke: all 10 stages OK");
Ok(())
}