use std::collections::HashMap;
use wasm_dbms_api::prelude::{DbmsError, DbmsResult, QueryError, TransactionId};
use super::Transaction;
#[derive(Default, Debug)]
pub struct TransactionSession {
transactions: HashMap<TransactionId, Transaction>,
next_transaction_id: TransactionId,
}
impl TransactionSession {
pub fn begin_transaction(&mut self) -> TransactionId {
let transaction_id = self.next_transaction_id;
self.next_transaction_id += 1;
self.transactions
.insert(transaction_id, Transaction::default());
transaction_id
}
pub fn has_transaction(&self, transaction_id: &TransactionId) -> bool {
self.transactions.contains_key(transaction_id)
}
pub fn get_transaction(&self, transaction_id: &TransactionId) -> DbmsResult<&Transaction> {
self.transactions
.get(transaction_id)
.ok_or(DbmsError::Query(QueryError::TransactionNotFound))
}
pub fn take_transaction(&mut self, transaction_id: &TransactionId) -> DbmsResult<Transaction> {
self.transactions
.remove(transaction_id)
.ok_or(DbmsError::Query(QueryError::TransactionNotFound))
}
pub fn close_transaction(&mut self, transaction_id: &TransactionId) {
self.transactions.remove(transaction_id);
}
pub fn get_transaction_mut(
&mut self,
transaction_id: &TransactionId,
) -> DbmsResult<&mut Transaction> {
self.transactions
.get_mut(transaction_id)
.ok_or(DbmsError::Query(QueryError::TransactionNotFound))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_should_begin_transaction() {
let mut session = TransactionSession::default();
let first = session.begin_transaction();
let second = session.begin_transaction();
assert_ne!(first, second);
assert!(session.has_transaction(&first));
assert!(session.has_transaction(&second));
assert!(!session.has_transaction(&(second + 1)));
assert!(session.get_transaction_mut(&first).is_ok());
}
#[test]
fn test_should_close_transaction() {
let mut session = TransactionSession::default();
let transaction_id = session.begin_transaction();
assert!(session.has_transaction(&transaction_id));
session.close_transaction(&transaction_id);
assert!(!session.has_transaction(&transaction_id));
assert!(session.get_transaction_mut(&transaction_id).is_err());
assert!(!session.transactions.contains_key(&transaction_id));
}
#[test]
fn test_should_take_transaction() {
let mut session = TransactionSession::default();
let transaction_id = session.begin_transaction();
let _transaction = session
.take_transaction(&transaction_id)
.expect("failed to take tx");
assert!(!session.has_transaction(&transaction_id));
assert!(session.get_transaction(&transaction_id).is_err());
assert!(!session.transactions.contains_key(&transaction_id));
}
#[test]
fn test_should_get_transaction() {
let mut session = TransactionSession::default();
let transaction_id = session.begin_transaction();
let _tx = session
.get_transaction(&transaction_id)
.expect("failed to get tx");
}
}