use sqlx::postgres::PgPoolOptions;
use sqlx_pool_router::{DbPools, PoolProvider};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let primary_url = std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgresql://postgres:password@localhost/test".to_string());
let replica_url = std::env::var("REPLICA_DATABASE_URL").unwrap_or_else(|_| primary_url.clone());
println!("๐ Connecting to databases:");
println!(" Primary: {}", primary_url);
println!(" Replica: {}", replica_url);
println!();
let primary = PgPoolOptions::new()
.max_connections(5)
.connect(&primary_url)
.await?;
let replica = PgPoolOptions::new()
.max_connections(10) .connect(&replica_url)
.await?;
let pools = if primary_url == replica_url {
println!("โ ๏ธ Using single pool (primary and replica are the same)");
DbPools::new(primary)
} else {
println!("โ Using separate pools for read/write separation");
DbPools::with_replica(primary, replica)
};
println!();
println!("๐ Creating example table...");
sqlx::query(
r#"
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
)
"#,
)
.execute(pools.write())
.await?;
println!("โ Table created");
println!();
println!("๐ Inserting users...");
for name in &["Alice", "Bob", "Charlie"] {
sqlx::query("INSERT INTO users (name) VALUES ($1)")
.bind(name)
.execute(pools.write())
.await?;
println!(" โ Inserted {}", name);
}
println!();
println!("๐ Reading users from replica...");
let users: Vec<(i32, String)> = sqlx::query_as("SELECT id, name FROM users ORDER BY id")
.fetch_all(pools.read())
.await?;
println!(" Found {} users:", users.len());
for (id, name) in users {
println!(" - ID {}: {}", id, name);
}
println!();
let count: (i64,) = sqlx::query_as("SELECT COUNT(*) FROM users")
.fetch_one(pools.read())
.await?;
println!("๐ Total users (from replica): {}", count.0);
println!();
println!("โ๏ธ Updating user...");
sqlx::query("UPDATE users SET name = $1 WHERE id = $2")
.bind("Alice Smith")
.bind(1)
.execute(pools.write())
.await?;
println!(" โ Updated user 1");
println!();
let updated_name: (String,) = sqlx::query_as("SELECT name FROM users WHERE id = $1")
.bind(1)
.fetch_one(pools.read())
.await?;
println!("๐ Updated name (from replica): {}", updated_name.0);
println!();
println!("๐งน Cleaning up...");
sqlx::query("DROP TABLE users")
.execute(pools.write())
.await?;
println!(" โ Table dropped");
println!();
println!("โ
Example completed successfully!");
println!();
println!("๐ก Key takeaways:");
println!(" - Write operations (INSERT, UPDATE, DELETE) use .write()");
println!(" - Read operations (SELECT) use .read()");
println!(" - Reads route to replica for load distribution");
println!(" - Writes always route to primary for consistency");
Ok(())
}