#![cfg(any(feature = "sqlite", feature = "postgresql", feature = "mysql"))]
pub mod _test_common;
define_test_user_for_range!(StreamCleanupUserPollution, "stream_cleanup_pollution");
define_test_user_for_range!(StreamCleanupUserEt, "stream_cleanup_et");
define_test_user_for_range!(StreamCleanupUserMc, "stream_cleanup_mc");
define_test_user_for_range!(StreamCleanupUserPool, "stream_cleanup_pool");
async fn test_stream_pollution_on_error_impl(config: &_test_common::DbConfig) {
let db = _test_common::create_db_connection(config).await.unwrap();
let _ = db
.execute_sql("DROP TABLE IF EXISTS stream_cleanup_pollution")
.await;
db.create_table::<StreamCleanupUserPollution>()
.execute()
.await
.unwrap();
for i in 0..5 {
let user = StreamCleanupUserPollution {
id: i + 1,
name: format!("user{}", i),
age: 20 + i,
};
db.insert(&user).execute().await.unwrap();
}
let mut stream = db
.select::<StreamCleanupUserPollution>()
.stream()
.into_iter()
.await
.unwrap();
let mut count = 0;
while let Some(result) = stream.next().await {
assert!(result.is_ok(), "Expected Ok result, got Err");
count += 1;
}
assert_eq!(count, 5);
println!("✓ test_stream_pollution_on_error passed - normal iteration works");
}
async fn test_stream_early_termination_cleanup_impl(config: &_test_common::DbConfig) {
let db = _test_common::create_db_connection(config).await.unwrap();
let _ = db
.execute_sql("DROP TABLE IF EXISTS stream_cleanup_et")
.await;
db.create_table::<StreamCleanupUserEt>()
.execute()
.await
.unwrap();
for i in 0..100 {
let user = StreamCleanupUserEt {
id: i + 1,
name: format!("user{}", i),
age: 18 + (i % 50),
};
db.insert(&user).execute().await.unwrap();
}
for _iteration in 0..10 {
let mut stream = db
.select::<StreamCleanupUserEt>()
.stream()
.into_iter()
.await
.unwrap();
let mut count = 0;
while let Some(result) = stream.next().await {
result.unwrap();
count += 1;
if count >= 5 {
break; }
}
}
let all_users: Vec<StreamCleanupUserEt> =
db.select::<StreamCleanupUserEt>().collect().await.unwrap();
assert_eq!(all_users.len(), 100);
println!(
"✓ test_stream_early_termination_cleanup passed - connection reused after early termination"
);
}
async fn test_multiple_consecutive_streams_impl(config: &_test_common::DbConfig) {
let db = _test_common::create_db_connection(config).await.unwrap();
let _ = db
.execute_sql("DROP TABLE IF EXISTS stream_cleanup_mc")
.await;
db.create_table::<StreamCleanupUserMc>()
.execute()
.await
.unwrap();
for i in 0..10 {
let user = StreamCleanupUserMc {
id: i + 1,
name: format!("user{}", i),
age: 20 + i,
};
db.insert(&user).execute().await.unwrap();
}
for _iteration in 0..5 {
let mut stream = db
.select::<StreamCleanupUserMc>()
.stream()
.into_iter()
.await
.unwrap();
let mut count = 0;
while let Some(result) = stream.next().await {
let user = result.unwrap();
assert!(user.id >= 1 && user.id <= 10);
count += 1;
}
assert_eq!(count, 10);
}
println!(
"✓ test_multiple_consecutive_streams passed - {} iterations completed",
5
);
}
async fn test_stream_with_pool_cleanup_impl(config: &_test_common::DbConfig) {
#[cfg(feature = "sqlite")]
let pool = if config.0 == ormer::DbType::Sqlite {
ormer::Database::create_pool(config.0, config.1)
.range(1..1)
.build()
.await
.unwrap()
} else {
ormer::Database::create_pool(config.0, config.1)
.range(1..3)
.build()
.await
.unwrap()
};
#[cfg(not(feature = "sqlite"))]
let pool = ormer::Database::create_pool(config.0, config.1)
.range(1..3)
.build()
.await
.unwrap();
let pooled_conn = pool.get().await.unwrap();
let _ = pooled_conn
.execute_sql("DROP TABLE IF EXISTS stream_cleanup_pool")
.await;
pooled_conn
.create_table::<StreamCleanupUserPool>()
.execute()
.await
.unwrap();
for i in 0..10 {
let user = StreamCleanupUserPool {
id: i + 1,
name: format!("pool_user{}", i),
age: 18 + i,
};
pooled_conn.insert(&user).execute().await.unwrap();
}
for _iteration in 0..3 {
let mut stream = pooled_conn
.stream::<StreamCleanupUserPool>()
.into_iter()
.await
.unwrap();
let mut count = 0;
while let Some(result) = stream.next().await {
result.unwrap();
count += 1;
}
assert_eq!(count, 10);
}
drop(pooled_conn);
println!("✓ test_stream_with_pool_cleanup passed - pool connections managed correctly");
}
#[cfg(feature = "sqlite")]
#[tokio::test]
async fn test_stream_pollution_on_error_sqlite() {
let config = (ormer::DbType::Sqlite, ":memory:");
test_stream_pollution_on_error_impl(&config).await;
}
#[cfg(feature = "sqlite")]
#[tokio::test]
async fn test_stream_early_termination_cleanup_sqlite() {
let config = (ormer::DbType::Sqlite, ":memory:");
test_stream_early_termination_cleanup_impl(&config).await;
}
#[cfg(feature = "sqlite")]
#[tokio::test]
async fn test_multiple_consecutive_streams_sqlite() {
let config = (ormer::DbType::Sqlite, ":memory:");
test_multiple_consecutive_streams_impl(&config).await;
}
#[cfg(feature = "sqlite")]
#[tokio::test]
async fn test_stream_with_pool_cleanup_sqlite() {
let config = (ormer::DbType::Sqlite, ":memory:");
test_stream_with_pool_cleanup_impl(&config).await;
}
#[cfg(feature = "postgresql")]
#[tokio::test]
async fn test_stream_pollution_on_error_postgresql() {
let config = _test_common::postgresql_config();
test_stream_pollution_on_error_impl(&config).await;
}
#[cfg(feature = "postgresql")]
#[tokio::test]
async fn test_stream_early_termination_cleanup_postgresql() {
let config = _test_common::postgresql_config();
test_stream_early_termination_cleanup_impl(&config).await;
}
#[cfg(feature = "postgresql")]
#[tokio::test]
async fn test_multiple_consecutive_streams_postgresql() {
let config = _test_common::postgresql_config();
test_multiple_consecutive_streams_impl(&config).await;
}
#[cfg(feature = "postgresql")]
#[tokio::test]
async fn test_stream_with_pool_cleanup_postgresql() {
let config = _test_common::postgresql_config();
test_stream_with_pool_cleanup_impl(&config).await;
}
#[cfg(feature = "mysql")]
#[tokio::test]
async fn test_stream_pollution_on_error_mysql() {
let config = _test_common::mysql_config();
test_stream_pollution_on_error_impl(&config).await;
}
#[cfg(feature = "mysql")]
#[tokio::test]
async fn test_stream_early_termination_cleanup_mysql() {
let config = _test_common::mysql_config();
test_stream_early_termination_cleanup_impl(&config).await;
}
#[cfg(feature = "mysql")]
#[tokio::test]
async fn test_multiple_consecutive_streams_mysql() {
let config = _test_common::mysql_config();
test_multiple_consecutive_streams_impl(&config).await;
}
#[cfg(feature = "mysql")]
#[tokio::test]
async fn test_stream_with_pool_cleanup_mysql() {
let config = _test_common::mysql_config();
test_stream_with_pool_cleanup_impl(&config).await;
}