use stoolap::Database;
#[test]
fn test_isolation_level_session() {
let db = Database::open("memory://iso_session").expect("Failed to create database");
db.execute(
"CREATE TABLE test_iso (id INTEGER PRIMARY KEY, value TEXT)",
(),
)
.expect("Failed to create table");
db.execute("SET ISOLATIONLEVEL = 'SNAPSHOT'", ())
.expect("Failed to set session isolation level");
db.execute("BEGIN", ())
.expect("Failed to begin transaction");
db.execute(
"INSERT INTO test_iso (id, value) VALUES (1, 'tx1_data')",
(),
)
.expect("Failed to insert");
db.execute("COMMIT", ()).expect("Failed to commit");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM test_iso", ())
.expect("Failed to count");
assert_eq!(count, 1, "Expected 1 row after commit");
db.execute("SET ISOLATIONLEVEL = 'READ COMMITTED'", ())
.expect("Failed to reset session isolation level");
}
#[test]
fn test_isolation_level_transaction() {
let db = Database::open("memory://iso_tx").expect("Failed to create database");
db.execute(
"CREATE TABLE test_iso_tx (id INTEGER PRIMARY KEY, value TEXT)",
(),
)
.expect("Failed to create table");
db.execute("SET ISOLATIONLEVEL = 'READ COMMITTED'", ())
.expect("Failed to set session isolation level");
db.execute("BEGIN TRANSACTION ISOLATION LEVEL SNAPSHOT", ())
.expect("Failed to begin transaction with isolation level");
db.execute(
"INSERT INTO test_iso_tx (id, value) VALUES (1, 'tx1_snapshot')",
(),
)
.expect("Failed to insert");
db.execute("COMMIT", ()).expect("Failed to commit");
let result = db
.query("SELECT value FROM test_iso_tx WHERE id = 1", ())
.expect("Failed to query");
let mut found = false;
for row in result {
let row = row.expect("Failed to get row");
let value: String = row.get(0).unwrap();
assert_eq!(value, "tx1_snapshot");
found = true;
}
assert!(found, "Expected to find row with id=1");
}
#[test]
fn test_isolation_level_reset() {
let db = Database::open("memory://iso_reset").expect("Failed to create database");
db.execute(
"CREATE TABLE test_iso_reset (id INTEGER PRIMARY KEY, value TEXT)",
(),
)
.expect("Failed to create table");
db.execute("SET ISOLATIONLEVEL = 'READ COMMITTED'", ())
.expect("Failed to set session isolation level");
db.execute("BEGIN TRANSACTION ISOLATION LEVEL SNAPSHOT", ())
.expect("Failed to begin transaction");
db.execute("COMMIT", ()).expect("Failed to commit");
db.execute("BEGIN", ())
.expect("Failed to begin second transaction");
db.execute(
"INSERT INTO test_iso_reset (id, value) VALUES (1, 'test')",
(),
)
.expect("Failed to insert");
db.execute("COMMIT", ()).expect("Failed to commit");
let count: i64 = db
.query_one("SELECT COUNT(*) FROM test_iso_reset", ())
.expect("Failed to count");
assert_eq!(count, 1, "Expected 1 row");
}
#[test]
fn test_isolation_level_variants() {
let db = Database::open("memory://iso_variants").expect("Failed to create database");
db.execute("SET ISOLATIONLEVEL = 'SNAPSHOT'", ())
.expect("Failed to set SNAPSHOT isolation");
db.execute("SET ISOLATIONLEVEL = 'READ COMMITTED'", ())
.expect("Failed to set READ COMMITTED isolation");
let result = db.execute("SET ISOLATIONLEVEL = 'SERIALIZABLE'", ());
if result.is_err() {
println!("SERIALIZABLE isolation level not supported");
}
}
#[test]
fn test_isolation_visibility() {
let db = Database::open("memory://iso_visibility").expect("Failed to create database");
db.execute(
"CREATE TABLE visibility_test (id INTEGER PRIMARY KEY, value INTEGER)",
(),
)
.expect("Failed to create table");
db.execute(
"INSERT INTO visibility_test (id, value) VALUES (1, 100)",
(),
)
.expect("Failed to insert initial data");
db.execute("SET ISOLATIONLEVEL = 'SNAPSHOT'", ())
.expect("Failed to set isolation level");
db.execute("BEGIN", ()).expect("Failed to begin tx1");
let value1: i64 = db
.query_one("SELECT value FROM visibility_test WHERE id = 1", ())
.expect("Failed to read in tx1");
assert_eq!(value1, 100, "Expected initial value 100");
db.execute("UPDATE visibility_test SET value = 200 WHERE id = 1", ())
.expect("Failed to update");
let value2: i64 = db
.query_one("SELECT value FROM visibility_test WHERE id = 1", ())
.expect("Failed to read updated value");
assert_eq!(
value2, 200,
"Expected updated value 200 in same transaction"
);
db.execute("COMMIT", ()).expect("Failed to commit");
let final_value: i64 = db
.query_one("SELECT value FROM visibility_test WHERE id = 1", ())
.expect("Failed to read final value");
assert_eq!(final_value, 200, "Expected final value 200");
}
#[test]
fn test_isolation_rollback() {
let db = Database::open("memory://iso_rollback").expect("Failed to create database");
db.execute(
"CREATE TABLE rollback_test (id INTEGER PRIMARY KEY, value INTEGER)",
(),
)
.expect("Failed to create table");
db.execute("INSERT INTO rollback_test (id, value) VALUES (1, 100)", ())
.expect("Failed to insert");
db.execute("SET ISOLATIONLEVEL = 'SNAPSHOT'", ())
.expect("Failed to set isolation level");
db.execute("BEGIN", ()).expect("Failed to begin");
db.execute("UPDATE rollback_test SET value = 999 WHERE id = 1", ())
.expect("Failed to update");
db.execute("ROLLBACK", ()).expect("Failed to rollback");
let value: i64 = db
.query_one("SELECT value FROM rollback_test WHERE id = 1", ())
.expect("Failed to read value");
assert_eq!(value, 100, "Expected original value 100 after rollback");
}