use std::{error::Error, sync::Arc};
use musq::{Connection, Musq, Pool, query, query::QueryExecutor, query_as};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let pool = Arc::new(Musq::new().open_in_memory().await?);
let standalone_conn = Connection::connect_with(&Musq::new()).await?;
setup_schema(&*pool).await?;
setup_schema(&standalone_conn).await?;
println!("✅ All executor types work interchangeably with query.execute()!");
insert_user(&*pool, 1, "Alice").await?;
println!("📊 Inserted user via Pool");
let pool_conn = pool.acquire().await?;
insert_user(&pool_conn, 2, "Bob").await?;
println!("📊 Inserted user via PoolConnection");
insert_user(&standalone_conn, 1, "Charlie").await?;
println!("📊 Inserted user via standalone Connection");
let mut tx = pool.begin().await?;
insert_user(&tx, 3, "Diana").await?;
tx.commit().await?;
println!("📊 Inserted user via Transaction");
let pool_users = get_users(&*pool).await?;
println!("👥 Pool users: {pool_users:?}");
let standalone_users = get_users(&standalone_conn).await?;
println!("👥 Standalone users: {standalone_users:?}");
println!("🚀 Testing concurrent pool usage...");
test_concurrent_pool_usage(&pool).await?;
Ok(())
}
async fn setup_schema<E: QueryExecutor>(executor: E) -> musq::Result<()> {
query("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)")
.execute(executor)
.await?;
Ok(())
}
async fn insert_user<E: QueryExecutor>(executor: E, id: i32, name: &str) -> musq::Result<()> {
query("INSERT INTO users (id, name) VALUES (?, ?)")
.bind(id)
.bind(name)
.execute(executor)
.await?;
Ok(())
}
async fn get_users<E: QueryExecutor>(executor: E) -> musq::Result<Vec<(i32, String)>> {
query_as("SELECT id, name FROM users ORDER BY id")
.fetch_all(executor)
.await
}
async fn test_concurrent_pool_usage(pool: &Arc<Pool>) -> musq::Result<()> {
let mut handles = vec![];
for i in 10..15 {
let pool_clone = Arc::clone(pool);
let handle = tokio::spawn(async move {
let name = format!("User{i}");
insert_user(&*pool_clone, i, &name).await
});
handles.push(handle);
}
for handle in handles {
handle.await.unwrap()?;
}
let count: (i64,) = query_as("SELECT COUNT(*) FROM users")
.fetch_one(&**pool)
.await?;
println!("🎯 Total users after concurrent operations: {}", count.0);
Ok(())
}