use ormer::Model;
#[derive(Debug, Model, Clone)]
#[table = "test_users_join"]
struct TestUserJoin {
#[primary(auto)]
id: i32,
#[unique]
name: String,
age: i32,
}
#[derive(Debug, Model, Clone)]
#[table = "test_roles_join"]
struct TestRoleJoin {
#[primary]
id: i32,
#[index]
uid: i32,
role_name: String,
}
#[tokio::test]
async fn test_inner_join() -> Result<(), Box<dyn std::error::Error>> {
let db = ormer::Database::connect(ormer::DbType::Turso, ":memory:").await?;
db.create_table::<TestUserJoin>().await?;
db.create_table::<TestRoleJoin>().await?;
db.insert(&TestUserJoin {
id: 1,
name: "Alice".to_string(),
age: 25,
})
.await?;
db.insert(&TestUserJoin {
id: 2,
name: "Bob".to_string(),
age: 30,
})
.await?;
db.insert(&TestRoleJoin {
id: 1,
uid: 1,
role_name: "admin".to_string(),
})
.await?;
let user_roles: Vec<(TestUserJoin, TestRoleJoin)> = db
.select::<TestUserJoin>()
.inner_join::<TestRoleJoin>(|u, r| u.id.eq(r.uid))
.collect::<Vec<_>>()
.await?;
assert_eq!(user_roles.len(), 1);
assert_eq!(user_roles[0].0.name, "Alice");
assert_eq!(user_roles[0].1.role_name, "admin");
println!("✓ Inner join test passed: {} records", user_roles.len());
Ok(())
}
#[tokio::test]
#[ignore] async fn test_right_join() -> Result<(), Box<dyn std::error::Error>> {
let db = ormer::Database::connect(ormer::DbType::Turso, ":memory:").await?;
db.create_table::<TestUserJoin>().await?;
db.create_table::<TestRoleJoin>().await?;
db.insert(&TestUserJoin {
id: 1,
name: "Alice".to_string(),
age: 25,
})
.await?;
db.insert(&TestRoleJoin {
id: 1,
uid: 1,
role_name: "admin".to_string(),
})
.await?;
db.insert(&TestRoleJoin {
id: 2,
uid: 99, role_name: "orphan_role".to_string(),
})
.await?;
let user_roles: Vec<(Option<TestUserJoin>, TestRoleJoin)> = db
.select::<TestUserJoin>()
.right_join::<TestRoleJoin>(|u, r| u.id.eq(r.uid))
.collect::<Vec<_>>()
.await?;
assert_eq!(user_roles.len(), 2);
let admin_role = user_roles
.iter()
.find(|(_, role)| role.role_name == "admin")
.expect("Should find admin role");
assert!(admin_role.0.is_some());
assert_eq!(admin_role.0.as_ref().unwrap().name, "Alice");
let orphan_role = user_roles
.iter()
.find(|(_, role)| role.role_name == "orphan_role")
.expect("Should find orphan role");
assert!(orphan_role.0.is_none());
println!("✓ Right join test passed: {} records", user_roles.len());
Ok(())
}
#[tokio::test]
async fn test_left_join() -> Result<(), Box<dyn std::error::Error>> {
let db = ormer::Database::connect(ormer::DbType::Turso, ":memory:").await?;
db.create_table::<TestUserJoin>().await?;
db.create_table::<TestRoleJoin>().await?;
db.insert(&TestUserJoin {
id: 1,
name: "Alice".to_string(),
age: 25,
})
.await?;
db.insert(&TestUserJoin {
id: 2,
name: "Bob".to_string(),
age: 30,
})
.await?;
db.insert(&TestRoleJoin {
id: 1,
uid: 1,
role_name: "admin".to_string(),
})
.await?;
let user_roles: Vec<(TestUserJoin, Option<TestRoleJoin>)> = db
.select::<TestUserJoin>()
.left_join::<TestRoleJoin>(|u, r| u.id.eq(r.uid))
.collect::<Vec<_>>()
.await?;
println!("Left join results: {:?}", user_roles);
assert_eq!(user_roles.len(), 2);
let alice = user_roles
.iter()
.find(|(user, _)| user.name == "Alice")
.expect("Should find Alice");
assert!(alice.1.is_some());
assert_eq!(alice.1.as_ref().unwrap().role_name, "admin");
let bob = user_roles
.iter()
.find(|(user, _)| user.name == "Bob")
.expect("Should find Bob");
assert!(bob.1.is_none());
println!("✓ Left join test passed: {} records", user_roles.len());
Ok(())
}
#[tokio::test]
async fn test_inner_join_with_filter() -> Result<(), Box<dyn std::error::Error>> {
let db = ormer::Database::connect(ormer::DbType::Turso, ":memory:").await?;
db.create_table::<TestUserJoin>().await?;
db.create_table::<TestRoleJoin>().await?;
db.insert(&TestUserJoin {
id: 1,
name: "Alice".to_string(),
age: 25,
})
.await?;
db.insert(&TestUserJoin {
id: 2,
name: "Bob".to_string(),
age: 30,
})
.await?;
db.insert(&TestRoleJoin {
id: 1,
uid: 1,
role_name: "admin".to_string(),
})
.await?;
db.insert(&TestRoleJoin {
id: 2,
uid: 2,
role_name: "user".to_string(),
})
.await?;
let user_roles: Vec<(TestUserJoin, TestRoleJoin)> = db
.select::<TestUserJoin>()
.inner_join::<TestRoleJoin>(|u, r| u.id.eq(r.uid))
.range(..1)
.collect::<Vec<_>>()
.await?;
assert_eq!(user_roles.len(), 1);
println!(
"✓ Inner join with range test passed: {} records",
user_roles.len()
);
Ok(())
}