#![cfg(any(feature = "sqlite", feature = "postgresql", feature = "mysql"))]
pub mod _test_common;
define_test_user_direct!(TestDistinctUser, "test_distinct_users_1");
#[test]
fn test_distinct_full_select_sql() {
let sql = ormer::Select::<TestDistinctUser>::new().distinct().to_sql();
println!("DISTINCT full select SQL: {}", sql);
assert!(
sql.starts_with("SELECT DISTINCT "),
"Expected SQL to start with 'SELECT DISTINCT ', got: {}",
sql
);
assert!(
sql.contains("FROM test_distinct_users_1"),
"Expected SQL to contain table name, got: {}",
sql
);
}
#[test]
fn test_normal_select_sql_no_distinct() {
let sql = ormer::Select::<TestDistinctUser>::new().to_sql();
println!("Normal select SQL: {}", sql);
assert!(
sql.starts_with("SELECT ") && !sql.starts_with("SELECT DISTINCT "),
"Expected normal SELECT, got: {}",
sql
);
}
#[test]
fn test_distinct_map_to_sql() {
let sql = ormer::Select::<TestDistinctUser>::new()
.distinct()
.map_to(|p| p.name)
.to_sql();
println!("DISTINCT map_to SQL: {}", sql);
assert!(
sql.starts_with("SELECT DISTINCT name FROM test_distinct_users_1"),
"Expected 'SELECT DISTINCT name FROM ...', got: {}",
sql
);
}
#[test]
fn test_distinct_with_filter_map_to_sql() {
let sql = ormer::Select::<TestDistinctUser>::new()
.distinct()
.filter(|p| p.age.ge(18))
.map_to(|p| p.name)
.to_sql();
println!("DISTINCT + filter + map_to SQL: {}", sql);
assert!(
sql.starts_with("SELECT DISTINCT name FROM test_distinct_users_1"),
"Expected DISTINCT, got: {}",
sql
);
assert!(
sql.contains("WHERE age >="),
"Expected WHERE clause, got: {}",
sql
);
}
#[test]
fn test_distinct_map_to_tuple_sql() {
let sql = ormer::Select::<TestDistinctUser>::new()
.distinct()
.map_to(|p| (p.name, p.age))
.to_sql();
println!("DISTINCT map_to tuple SQL: {}", sql);
assert!(
sql.starts_with("SELECT DISTINCT name, age FROM test_distinct_users_1"),
"Expected 'SELECT DISTINCT name, age FROM ...', got: {}",
sql
);
}
#[test]
fn test_distinct_with_order_and_range_sql() {
let sql = ormer::Select::<TestDistinctUser>::new()
.distinct()
.order_by(|p| p.name)
.range(..10)
.to_sql();
println!("DISTINCT + order + range SQL: {}", sql);
assert!(
sql.starts_with("SELECT DISTINCT "),
"Expected DISTINCT, got: {}",
sql
);
assert!(
sql.contains("ORDER BY name"),
"Expected ORDER BY, got: {}",
sql
);
assert!(sql.contains("LIMIT 10"), "Expected LIMIT, got: {}", sql);
}
async fn test_distinct_e2e_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let db = _test_common::create_db_connection(config).await?;
db.create_table::<TestDistinctUser>().execute().await?;
db.insert(&TestDistinctUser {
id: 1,
name: "Alice".to_string(),
age: 25,
})
.execute()
.await?;
db.insert(&TestDistinctUser {
id: 2,
name: "Alice".to_string(),
age: 30,
})
.execute()
.await?;
db.insert(&TestDistinctUser {
id: 3,
name: "Bob".to_string(),
age: 25,
})
.execute()
.await?;
db.insert(&TestDistinctUser {
id: 4,
name: "Charlie".to_string(),
age: 35,
})
.execute()
.await?;
let distinct_names: Vec<String> = db
.select::<TestDistinctUser>()
.distinct()
.map_to(|p| p.name)
.collect::<Vec<_>>()
.await?;
println!("Distinct names: {:?}", distinct_names);
assert_eq!(distinct_names.len(), 3, "Expected 3 distinct names");
let all_names: Vec<String> = db
.select::<TestDistinctUser>()
.map_to(|p| p.name)
.collect::<Vec<_>>()
.await?;
println!("All names: {:?}", all_names);
assert_eq!(all_names.len(), 4, "Expected 4 names without DISTINCT");
let distinct_ages: Vec<i32> = db
.select::<TestDistinctUser>()
.distinct()
.map_to(|p| p.age)
.collect::<Vec<_>>()
.await?;
println!("Distinct ages: {:?}", distinct_ages);
assert_eq!(distinct_ages.len(), 3, "Expected 3 distinct ages");
let distinct_users: Vec<TestDistinctUser> = db
.select::<TestDistinctUser>()
.distinct()
.collect::<Vec<_>>()
.await?;
println!("Distinct users count: {}", distinct_users.len());
assert_eq!(
distinct_users.len(),
4,
"All rows are distinct on full columns"
);
db.drop_table::<TestDistinctUser>().execute().await?;
Ok(())
}
test_on_all_dbs_result!(test_distinct_e2e_impl);