#![cfg(any(feature = "sqlite", feature = "postgresql", feature = "mysql"))]
use ormer::Database;
mod _test_common;
define_test_user_for_pool!(PoolTestUser, "pool_test_users_1");
#[cfg(any(feature = "sqlite", feature = "postgresql", feature = "mysql"))]
mod connection_pool_tests {
use super::Database;
use super::PoolTestUser;
use crate::_test_common;
use crate::_test_common::DbConfig;
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_creation_turso() -> Result<(), Box<dyn std::error::Error>> {
let config: DbConfig = (ormer::DbType::Sqlite, ":memory:");
let _ = _test_common::create_db_connection(&config).await?;
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
let conn = pool.get().await?;
conn.create_table::<PoolTestUser>().execute().await?;
conn.drop_table::<PoolTestUser>().execute().await?;
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_insert_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
let conn = pool.get().await?;
conn.create_table::<PoolTestUser>().execute().await?;
conn.insert(&PoolTestUser {
id: 1,
name: "Alice".to_string(),
age: 25,
email: Some("alice@example.com".to_string()),
})
.execute()
.await?;
conn.insert(&vec![
PoolTestUser {
id: 2,
name: "Bob".to_string(),
age: 30,
email: Some("bob@example.com".to_string()),
},
PoolTestUser {
id: 3,
name: "Charlie".to_string(),
age: 35,
email: None,
},
])
.execute()
.await?;
conn.drop_table::<PoolTestUser>().execute().await?;
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_select_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
{
let conn = pool.get().await?;
conn.create_table::<PoolTestUser>().execute().await?;
conn.insert(&PoolTestUser {
id: 1,
name: "Alice".to_string(),
age: 25,
email: Some("alice@example.com".to_string()),
})
.execute()
.await?;
conn.insert(&PoolTestUser {
id: 2,
name: "Bob".to_string(),
age: 30,
email: Some("bob@example.com".to_string()),
})
.execute()
.await?;
let users = conn.select::<PoolTestUser>().collect::<Vec<_>>().await?;
assert_eq!(users.len(), 2);
assert_eq!(users[0].name, "Alice");
assert_eq!(users[1].name, "Bob");
conn.drop_table::<PoolTestUser>().execute().await?;
}
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_filter_select_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
{
let conn = pool.get().await?;
conn.create_table::<PoolTestUser>().execute().await?;
for i in 1..=5 {
conn.insert(&PoolTestUser {
id: i,
name: format!("User{}", i),
age: 20 + i * 5,
email: Some(format!("user{}@example.com", i)),
})
.execute()
.await?;
}
let users = conn
.select::<PoolTestUser>()
.filter(|p| p.age.ge(35))
.collect::<Vec<_>>()
.await?;
assert_eq!(users.len(), 3);
conn.drop_table::<PoolTestUser>().execute().await?;
}
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_update_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
{
let conn = pool.get().await?;
conn.create_table::<PoolTestUser>().execute().await?;
conn.insert(&PoolTestUser {
id: 1,
name: "Alice".to_string(),
age: 25,
email: Some("alice@example.com".to_string()),
})
.execute()
.await?;
let count = conn
.update::<PoolTestUser>()
.filter(|p| p.name.eq("Alice".to_string()))
.set(|p| p.age, 30)
.execute()
.await?;
assert_eq!(count, 1);
let users = conn
.select::<PoolTestUser>()
.filter(|p| p.name.eq("Alice".to_string()))
.collect::<Vec<_>>()
.await?;
assert_eq!(users.len(), 1);
assert_eq!(users[0].age, 30);
conn.drop_table::<PoolTestUser>().execute().await?;
}
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_delete_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
{
let conn = pool.get().await?;
conn.create_table::<PoolTestUser>().execute().await?;
conn.insert(&PoolTestUser {
id: 1,
name: "Alice".to_string(),
age: 25,
email: None,
})
.execute()
.await?;
conn.insert(&PoolTestUser {
id: 2,
name: "Bob".to_string(),
age: 30,
email: None,
})
.execute()
.await?;
let count = conn
.delete::<PoolTestUser>()
.filter(|p| p.age.lt(28))
.execute()
.await?;
assert_eq!(count, 1);
let users = conn.select::<PoolTestUser>().collect::<Vec<_>>().await?;
assert_eq!(users.len(), 1);
assert_eq!(users[0].name, "Bob");
conn.drop_table::<PoolTestUser>().execute().await?;
}
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_transaction_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
let conn = pool.get().await?;
conn.create_table::<PoolTestUser>().execute().await?;
let mut txn = conn.begin().await?;
txn.insert(&PoolTestUser {
id: 1,
name: "Alice".to_string(),
age: 25,
email: Some("alice@example.com".to_string()),
})
.execute()
.await?;
txn.insert(&PoolTestUser {
id: 2,
name: "Bob".to_string(),
age: 30,
email: Some("bob@example.com".to_string()),
})
.execute()
.await?;
txn.commit().await?;
let users = conn.select::<PoolTestUser>().collect::<Vec<_>>().await?;
assert_eq!(users.len(), 2);
conn.drop_table::<PoolTestUser>().execute().await?;
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_aggregate_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
{
let conn = pool.get().await?;
conn.create_table::<PoolTestUser>().execute().await?;
for i in 1..=5 {
conn.insert(&PoolTestUser {
id: i,
name: format!("User{}", i),
age: 20 + i * 5,
email: None,
})
.execute()
.await?;
}
let count: usize = conn.select::<PoolTestUser>().count(|p| p.id).await?;
assert_eq!(count, 5);
let sum: Option<i32> = conn.select::<PoolTestUser>().sum(|p| p.age).await?;
assert_eq!(sum, Some(175));
let avg: Option<f64> = conn.select::<PoolTestUser>().avg(|p| p.age).await?;
assert!((avg.unwrap() - 35.0).abs() < 0.01);
let min: Option<i32> = conn.select::<PoolTestUser>().min(|p| p.age).await?;
assert_eq!(min, Some(25));
let max: Option<i32> = conn.select::<PoolTestUser>().max(|p| p.age).await?;
assert_eq!(max, Some(45));
conn.drop_table::<PoolTestUser>().execute().await?;
}
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_multiple_get_return_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
{
let conn = pool.get().await?;
conn.create_table::<PoolTestUser>().execute().await?;
conn.insert(&PoolTestUser {
id: 1,
name: "Alice".to_string(),
age: 25,
email: None,
})
.execute()
.await?;
let users = conn.select::<PoolTestUser>().collect::<Vec<_>>().await?;
assert_eq!(users.len(), 1);
conn.drop_table::<PoolTestUser>().execute().await?;
}
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_exec_sql_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
let conn = pool.get().await?;
let _ = conn.drop_table::<PoolTestUser>().execute().await;
conn.create_table::<PoolTestUser>().execute().await?;
conn.exec_non_query(
"INSERT INTO pool_test_users_1 (id, name, age, email) VALUES (1, 'Alice', 25, 'alice@example.com')",
)
.await?;
let users = conn
.execute::<PoolTestUser>("SELECT * FROM pool_test_users_1")
.await?;
assert_eq!(users.len(), 1);
assert_eq!(users[0].name, "Alice");
conn.drop_table::<PoolTestUser>().execute().await?;
Ok(())
}
#[cfg(feature = "sqlite")]
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pool_range_config_turso() -> Result<(), Box<dyn std::error::Error>> {
let pool1 = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
let pool2 = Database::create_pool(ormer::DbType::Sqlite, ":memory:")
.range(0..1)
.build()
.await?;
let conn1 = pool1.get().await?;
conn1.create_table::<PoolTestUser>().execute().await?;
let conn2 = pool2.get().await?;
conn2.create_table::<PoolTestUser>().execute().await?;
conn1.drop_table::<PoolTestUser>().execute().await?;
conn2.drop_table::<PoolTestUser>().execute().await?;
Ok(())
}
}