#[cfg(all(not(target_arch = "wasm32"), feature = "fs_persist"))]
#[cfg(test)]
mod transaction_sync_tests {
use absurder_sql::{DatabaseConfig, SqliteIndexedDB};
use serial_test::serial;
use std::time::Instant;
#[tokio::test]
#[serial]
async fn test_transaction_should_defer_sync_operations() {
let config = DatabaseConfig {
name: "test_transaction_sync.db".to_string(),
..Default::default()
};
let mut db = SqliteIndexedDB::new(config).await.unwrap();
db.execute("DROP TABLE IF EXISTS test").await.unwrap();
db.execute("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)")
.await
.unwrap();
db.execute("BEGIN TRANSACTION").await.unwrap();
let start = Instant::now();
for i in 1..=100 {
db.execute(&format!("INSERT INTO test VALUES ({}, 'value_{}')", i, i))
.await
.unwrap();
}
let insert_duration = start.elapsed();
db.execute("COMMIT").await.unwrap();
println!("100 inserts in transaction took: {:?}", insert_duration);
assert!(
insert_duration.as_millis() < 50,
"Transaction with 100 inserts took {}ms - sync operations are NOT being deferred! \
Expected < 50ms if sync only happens on COMMIT.",
insert_duration.as_millis()
);
}
#[tokio::test]
#[serial]
async fn test_sync_happens_outside_transaction() {
let config = DatabaseConfig {
name: "test_sync_outside_tx.db".to_string(),
..Default::default()
};
let mut db = SqliteIndexedDB::new(config).await.unwrap();
db.execute("DROP TABLE IF EXISTS test").await.unwrap();
db.execute("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)")
.await
.unwrap();
db.execute("INSERT INTO test VALUES (1, 'test')")
.await
.unwrap();
let result = db.execute("SELECT * FROM test").await.unwrap();
assert_eq!(result.rows.len(), 1);
}
#[tokio::test]
#[serial]
async fn test_nested_transactions_defer_sync() {
let config = DatabaseConfig {
name: "test_nested_tx_sync.db".to_string(),
..Default::default()
};
let mut db = SqliteIndexedDB::new(config).await.unwrap();
db.execute("DROP TABLE IF EXISTS test").await.unwrap();
db.execute("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)")
.await
.unwrap();
db.execute("BEGIN TRANSACTION").await.unwrap();
let start = Instant::now();
for i in 1..=50 {
db.execute(&format!("INSERT INTO test VALUES ({}, 'value_{}')", i, i))
.await
.unwrap();
}
db.execute("SAVEPOINT sp1").await.unwrap();
for i in 51..=100 {
db.execute(&format!("INSERT INTO test VALUES ({}, 'value_{}')", i, i))
.await
.unwrap();
}
db.execute("RELEASE SAVEPOINT sp1").await.unwrap();
let duration = start.elapsed();
db.execute("COMMIT").await.unwrap();
assert!(
duration.as_millis() < 50,
"Nested transaction inserts took {}ms - sync not properly deferred",
duration.as_millis()
);
}
}