use std::env;
use zero_postgres::sync::Conn;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let url = env::var("DATABASE_URL")?;
println!("Connecting...");
let mut conn = Conn::new(url.as_str())?;
println!("Connected!\n");
conn.query_drop("DROP TABLE IF EXISTS users")?;
conn.query_drop(
"CREATE TABLE users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
active BOOLEAN NOT NULL DEFAULT TRUE
)",
)?;
println!("Created test table.\n");
conn.query_drop("INSERT INTO users (name, active) VALUES ('Alice', true)")?;
conn.query_drop("INSERT INTO users (name, active) VALUES ('Bob', false)")?;
conn.query_drop("INSERT INTO users (name, active) VALUES ('Charlie', true)")?;
conn.query_drop("INSERT INTO users (name, active) VALUES ('Diana', false)")?;
println!("Inserted test data.\n");
println!("=== Pipeline with Prepared Statements ===\n");
{
let stmts = conn.prepare_batch(&[
"SELECT id, name FROM users WHERE active = $1",
"SELECT COUNT(*) FROM users",
])?;
let (active, inactive, count) = conn.pipeline(|p| {
let t1 = p.exec(&stmts[0], (true,))?;
let t2 = p.exec(&stmts[0], (false,))?;
let t3 = p.exec(&stmts[1], ())?;
p.sync()?;
let active: Vec<(i32, String)> = p.claim_collect(t1)?;
let inactive: Vec<(i32, String)> = p.claim_collect(t2)?;
let count: Vec<(i64,)> = p.claim_collect(t3)?;
Ok((active, inactive, count))
})?;
println!("Active users:");
for (id, name) in &active {
println!(" id={}, name={}", id, name);
}
println!("\nInactive users:");
for (id, name) in &inactive {
println!(" id={}, name={}", id, name);
}
println!("\nTotal count: {}", count[0].0);
}
println!();
println!("=== Pipeline with Raw SQL ===\n");
{
let (names, alice, bob) = conn.pipeline(|p| {
let t1 = p.exec("SELECT name FROM users ORDER BY name", ())?;
let t2 = p.exec("SELECT name FROM users WHERE id = $1", (1_i32,))?;
let t3 = p.exec("SELECT name FROM users WHERE id = $1", (2_i32,))?;
p.sync()?;
let names: Vec<(String,)> = p.claim_collect(t1)?;
let alice: Option<(String,)> = p.claim_one(t2)?;
let bob: Option<(String,)> = p.claim_one(t3)?;
Ok((names, alice, bob))
})?;
println!(
"All names: {:?}",
names.iter().map(|r| &r.0).collect::<Vec<_>>()
);
println!("User 1: {:?}", alice.map(|r| r.0));
println!("User 2: {:?}", bob.map(|r| r.0));
}
println!();
println!("=== Mixed Pipeline ===\n");
{
let stmt = conn.prepare("SELECT id, name FROM users WHERE id > $1")?;
let (all, active_count) = conn.pipeline(|p| {
let t1 = p.exec(&stmt, (0_i32,))?;
let t2 = p.exec("SELECT COUNT(*) FROM users WHERE active = $1", (true,))?;
let t3 = p.exec(&stmt, (2_i32,))?;
p.sync()?;
let all: Vec<(i32, String)> = p.claim_collect(t1)?;
let active_count: Option<(i64,)> = p.claim_one(t2)?;
p.claim_drop(t3)?;
Ok((all, active_count))
})?;
println!("All users (id > 0): {} rows", all.len());
println!("Active user count: {}", active_count.map_or(0, |r| r.0));
}
println!();
conn.query_drop("DROP TABLE users")?;
println!("Cleaned up test table.");
conn.close()?;
println!("Connection closed.");
Ok(())
}