#![cfg(feature = "sqlite")]
use sql_middleware::middleware::ConfigAndPool;
use sql_middleware::pool::MiddlewarePoolConnection;
use sql_middleware::sqlite::transaction::{
begin_transaction, set_rewrap_on_rollback_failure_for_tests,
};
use sql_middleware::SqlMiddlewareDbError;
#[tokio::test(flavor = "current_thread")]
async fn sqlite_evicts_connection_when_rollback_busy() -> Result<(), SqlMiddlewareDbError> {
let cap = ConfigAndPool::sqlite_builder("file::memory:?cache=shared".into())
.build()
.await?;
let mut conn_slot = cap.get_connection().await?;
set_force_rollback_busy(&mut conn_slot, true);
set_rewrap_on_rollback_failure_for_tests(false);
{
let _tx = begin_transaction(&mut conn_slot).await?;
}
if let MiddlewarePoolConnection::Sqlite { ref conn, .. } = conn_slot {
assert!(
conn.is_none(),
"rollback failure should evict the connection instead of rewrapping it"
);
} else {
panic!("expected sqlite connection");
}
set_rewrap_on_rollback_failure_for_tests(true);
let mut legacy_slot = cap.get_connection().await?;
set_force_rollback_busy(&mut legacy_slot, true);
{
let _tx = begin_transaction(&mut legacy_slot).await?;
}
match legacy_slot {
MiddlewarePoolConnection::Sqlite { ref conn, .. } => {
if let Some(conn) = conn {
conn.set_force_rollback_busy_for_tests(false);
}
assert!(
conn.is_some(),
"legacy path would have returned the connection to the pool"
);
}
_ => panic!("expected sqlite connection"),
}
set_rewrap_on_rollback_failure_for_tests(false);
Ok(())
}
fn set_force_rollback_busy(conn_slot: &mut MiddlewarePoolConnection, force: bool) {
match conn_slot {
MiddlewarePoolConnection::Sqlite { conn: Some(conn), .. } => {
conn.set_force_rollback_busy_for_tests(force);
}
_ => panic!("expected sqlite connection"),
}
}