use microrm::prelude::*;
use test_log::test;
mod common;
#[derive(Entity)]
struct KV {
key: usize,
value: usize,
}
#[derive(Schema)]
struct KVStore {
kvs: microrm::IDMap<KV>,
}
#[test]
#[should_panic]
fn txn_should_abort() {
let (pool, db): (_, KVStore) = common::open_test_db!();
let mut txn1 = pool.start().unwrap();
let mut txn2 = pool.start().unwrap();
db.kvs.insert(&mut txn2, KV { key: 0, value: 0 }).unwrap();
let _err = db.kvs.insert(&mut txn1, KV { key: 0, value: 1 });
unreachable!()
}
#[test]
fn txn_read_old_data_rollback() {
let (pool, db): (_, KVStore) = common::open_test_db!();
let mut itxn = pool.start().unwrap();
let mut k0 = db
.kvs
.insert_and_return(&mut itxn, KV { key: 0, value: 0 })
.unwrap();
itxn.commit().unwrap();
let mut txn1 = pool.start().unwrap();
let mut txn2 = pool.start().unwrap();
k0.value = 1;
k0.sync(&mut txn2).unwrap();
let nk0 = db.kvs.by_id(&mut txn1, k0.id()).unwrap().unwrap();
assert_eq!(nk0.value, 0);
let Err(microrm::Error::TransactionAbort) = txn2.commit() else {
panic!("Transaction was successful when it should not have been");
};
}
#[test]
fn txn_read_old_data_wal() {
let (pool, db): (_, KVStore) = microrm::ConnectionPool::open(
microrm::db::ConnectionPoolConfig::new(common::test_db_path("txn_read_old_data_wal"))
.with_wal(),
)
.unwrap();
let mut itxn = pool.start().unwrap();
let mut k0 = db
.kvs
.insert_and_return(&mut itxn, KV { key: 0, value: 0 })
.unwrap();
itxn.commit().unwrap();
let mut txn1 = pool.start().unwrap();
let mut txn2 = pool.start().unwrap();
k0.value = 1;
k0.sync(&mut txn2).unwrap();
let nk0 = db.kvs.by_id(&mut txn1, k0.id()).unwrap().unwrap();
assert_eq!(nk0.value, 0);
txn2.commit().unwrap();
let nk0 = db.kvs.by_id(&mut txn1, k0.id()).unwrap().unwrap();
assert_eq!(nk0.value, 0);
let mut txn1 = pool.start().unwrap();
let nk0 = db.kvs.by_id(&mut txn1, k0.id()).unwrap().unwrap();
assert_eq!(nk0.value, 1);
}