use std::collections::HashMap;
use crate::{storage::Storage, Database, Datom, Fact, TransactionError, Value, EID};
pub trait Transactable {
fn tx(&self) -> Transaction;
}
#[derive(Clone, Debug)]
pub struct Transaction {
facts: Vec<Fact>,
}
impl Transaction {
pub const fn new() -> Self {
Self { facts: vec![] }
}
pub fn push_fact(&mut self, fact: Fact) {
self.facts.push(fact)
}
pub fn add(&mut self, entity: EID, attribute: EID, value: Value) {
self.push_fact(Fact::Add(entity, attribute, value));
}
pub fn add_many(&mut self, entity: EID, attr_value_pairs: HashMap<EID, Value>) {
for (attr, val) in attr_value_pairs {
self.push_fact(Fact::Add(entity.clone(), attr, val));
}
}
pub fn retract_value(&mut self, entity: EID, attribute: EID, value: Value) {
self.push_fact(Fact::RetractValue(entity, attribute, value));
}
pub fn retract(&mut self, entity: EID, attribute: EID) {
self.push_fact(Fact::Retract(entity, attribute))
}
pub fn append<T: Transactable>(&mut self, txable: T) {
self.facts.append(&mut txable.tx().facts);
}
pub fn datoms<'c, S: Storage>(
&self,
t: u64,
db: &Database<'c, S>,
) -> Result<Vec<Datom>, TransactionError> {
self.facts
.iter()
.map(|f| f.to_owned().datom(t, db))
.collect()
}
}
impl Default for Transaction {
fn default() -> Self {
Self::new()
}
}
impl Transactable for Transaction {
fn tx(&self) -> Transaction {
self.to_owned()
}
}