#![cfg(any(feature = "sqlite", feature = "postgresql", feature = "mysql"))]
mod _test_common;
define_test_user!(ExecTestUser1, "exec_test_users_1");
define_test_user!(ExecTestUser2, "exec_test_users_2");
define_test_user!(ExecTestUser3, "exec_test_users_3");
define_test_user!(ExecTestUser4, "exec_test_users_4");
async fn test_execute_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let db = _test_common::create_db_connection(config).await?;
let _ = db.drop_table::<ExecTestUser1>().execute().await;
db.create_table::<ExecTestUser1>().execute().await?;
db.insert(&ExecTestUser1 {
id: 1,
name: "Alice".to_string(),
age: 25,
email: Some("alice@example.com".to_string()),
})
.execute()
.await?;
db.insert(&ExecTestUser1 {
id: 2,
name: "Bob".to_string(),
age: 30,
email: Some("bob@example.com".to_string()),
})
.execute()
.await?;
db.insert(&ExecTestUser1 {
id: 3,
name: "Charlie".to_string(),
age: 35,
email: None,
})
.execute()
.await?;
let users = db
.execute::<ExecTestUser1>("SELECT * FROM exec_test_users_1;")
.await?;
assert_eq!(users.len(), 3);
assert_eq!(users[0].name, "Alice");
assert_eq!(users[1].name, "Bob");
assert_eq!(users[2].name, "Charlie");
let young_users = db
.execute::<ExecTestUser1>("SELECT * FROM exec_test_users_1 WHERE age < 30;")
.await?;
assert_eq!(young_users.len(), 1);
assert_eq!(young_users[0].name, "Alice");
assert_eq!(young_users[0].age, 25);
let old_users = db
.execute::<ExecTestUser1>("SELECT * FROM exec_test_users_1 WHERE age > 100;")
.await?;
assert_eq!(old_users.len(), 0);
let sorted_users = db
.execute::<ExecTestUser1>("SELECT * FROM exec_test_users_1 ORDER BY age DESC;")
.await?;
assert_eq!(sorted_users.len(), 3);
assert_eq!(sorted_users[0].name, "Charlie");
assert_eq!(sorted_users[0].age, 35);
assert_eq!(sorted_users[1].name, "Bob");
assert_eq!(sorted_users[1].age, 30);
assert_eq!(sorted_users[2].name, "Alice");
assert_eq!(sorted_users[2].age, 25);
db.drop_table::<ExecTestUser1>().execute().await?;
Ok(())
}
async fn test_exec_non_query_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let db = _test_common::create_db_connection(config).await?;
let _ = db.drop_table::<ExecTestUser2>().execute().await;
db.create_table::<ExecTestUser2>().execute().await?;
db.insert(&ExecTestUser2 {
id: 1,
name: "Alice".to_string(),
age: 25,
email: Some("alice@example.com".to_string()),
})
.execute()
.await?;
db.insert(&ExecTestUser2 {
id: 2,
name: "Bob".to_string(),
age: 30,
email: Some("bob@example.com".to_string()),
})
.execute()
.await?;
db.insert(&ExecTestUser2 {
id: 3,
name: "Charlie".to_string(),
age: 35,
email: None,
})
.execute()
.await?;
let updated_rows = db
.exec_non_query("UPDATE exec_test_users_2 SET age = 40 WHERE age >= 30;")
.await?;
assert_eq!(updated_rows, 2);
let users = db
.execute::<ExecTestUser2>("SELECT * FROM exec_test_users_2 ORDER BY id;")
.await?;
assert_eq!(users[0].age, 25); assert_eq!(users[1].age, 40); assert_eq!(users[2].age, 40);
let deleted_rows = db
.exec_non_query("DELETE FROM exec_test_users_2 WHERE age < 30;")
.await?;
println!("Deleted rows: {}", deleted_rows);
assert!(deleted_rows >= 1);
let users = db
.execute::<ExecTestUser2>("SELECT * FROM exec_test_users_2;")
.await?;
assert_eq!(users.len(), 2);
let inserted_rows = db
.exec_non_query(
"INSERT INTO exec_test_users_2 (id, name, age, email) VALUES (4, 'David', 28, 'david@example.com');",
)
.await?;
assert_eq!(inserted_rows, 1);
let users = db
.execute::<ExecTestUser2>("SELECT * FROM exec_test_users_2;")
.await?;
assert_eq!(users.len(), 3);
let updated_rows = db
.exec_non_query("UPDATE exec_test_users_2 SET age = 99 WHERE age > 200;")
.await?;
assert_eq!(updated_rows, 0);
db.drop_table::<ExecTestUser2>().execute().await?;
Ok(())
}
async fn test_execute_and_non_query_combined_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let db = _test_common::create_db_connection(config).await?;
let _ = db.drop_table::<ExecTestUser3>().execute().await;
db.create_table::<ExecTestUser3>().execute().await?;
db.exec_non_query(
"INSERT INTO exec_test_users_3 (id, name, age, email) VALUES
(1, 'Alice', 25, 'alice@example.com'),
(2, 'Bob', 30, 'bob@example.com'),
(3, 'Charlie', 35, NULL);",
)
.await?;
let users = db
.execute::<ExecTestUser3>("SELECT * FROM exec_test_users_3 ORDER BY age;")
.await?;
assert_eq!(users.len(), 3);
assert_eq!(users[0].name, "Alice");
assert_eq!(users[0].age, 25);
assert_eq!(users[1].name, "Bob");
assert_eq!(users[1].age, 30);
assert_eq!(users[2].name, "Charlie");
assert_eq!(users[2].age, 35);
db.exec_non_query("UPDATE exec_test_users_3 SET age = age + 5;")
.await?;
let users = db
.execute::<ExecTestUser3>("SELECT * FROM exec_test_users_3 ORDER BY age;")
.await?;
assert_eq!(users[0].age, 30);
assert_eq!(users[1].age, 35);
assert_eq!(users[2].age, 40);
let deleted = db.exec_non_query("DELETE FROM exec_test_users_3;").await?;
println!("Deleted all rows: {}", deleted);
assert!(deleted >= 3);
let users = db
.execute::<ExecTestUser3>("SELECT * FROM exec_test_users_3;")
.await?;
assert_eq!(users.len(), 0);
db.drop_table::<ExecTestUser3>().execute().await?;
Ok(())
}
async fn test_execute_with_null_values_impl(
config: &_test_common::DbConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let db = _test_common::create_db_connection(config).await?;
let _ = db.drop_table::<ExecTestUser4>().execute().await;
db.create_table::<ExecTestUser4>().execute().await?;
db.exec_non_query(
"INSERT INTO exec_test_users_4 (id, name, age, email) VALUES
(1, 'Alice', 25, NULL),
(2, 'Bob', 30, 'bob@example.com');",
)
.await?;
let users = db
.execute::<ExecTestUser4>("SELECT * FROM exec_test_users_4 ORDER BY id;")
.await?;
assert_eq!(users.len(), 2);
assert_eq!(users[0].name, "Alice");
assert_eq!(users[0].email, None); assert_eq!(users[1].name, "Bob");
assert_eq!(users[1].email, Some("bob@example.com".to_string()));
db.drop_table::<ExecTestUser4>().execute().await?;
Ok(())
}
test_on_all_dbs_result!(test_execute_impl);
test_on_all_dbs_result!(test_exec_non_query_impl);
test_on_all_dbs_result!(test_execute_and_non_query_combined_impl);
test_on_all_dbs_result!(test_execute_with_null_values_impl);