use std::env;
use zero_postgres::sync::Conn;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let url = env::var("DATABASE_URL")?;
let mut conn = Conn::new(url.as_str())?;
conn.query_drop(
"CREATE TEMP TABLE test_bench (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
age INT,
email VARCHAR(100),
score REAL,
description VARCHAR(100)
)",
)?;
let insert_stmt = conn.prepare(
"INSERT INTO test_bench (name, age, email, score, description) VALUES ($1, $2, $3, $4, $5)",
)?;
const N: usize = 10000;
let mut rows = Vec::with_capacity(N);
for i in 0..N {
rows.push((
format!("user_{}", i),
(20 + (i % 50)) as i32,
format!("user{}@example.com", i),
(i % 100) as f32 / 10.0,
format!("Description for user {}", i),
));
}
for iteration in 0..10 {
let iteration_start = std::time::Instant::now();
const BATCH_SIZE: usize = 1000;
for chunk in rows.chunks(BATCH_SIZE) {
conn.pipeline(|p| {
let mut tickets = Vec::with_capacity(chunk.len());
for (username, age, email, score, description) in chunk.iter() {
let ticket = p.exec(
&insert_stmt,
(
username.as_str(),
*age,
email.as_str(),
*score,
description.as_str(),
),
)?;
tickets.push(ticket);
}
p.sync()?;
for ticket in tickets {
p.claim_drop(ticket)?;
}
Ok(())
})?;
}
let elapsed = iteration_start.elapsed();
let count: Vec<(i64,)> = conn.query_collect("SELECT COUNT(*) FROM test_bench")?;
println!(
"Iteration {}: Inserted {} rows (took {:.2}ms)",
iteration,
count[0].0,
elapsed.as_secs_f64() * 1000.0
);
conn.query_drop("TRUNCATE TABLE test_bench")?;
}
conn.close_statement(&insert_stmt)?;
conn.close()?;
Ok(())
}