use corium_core::{
AttrId, Attribute, Cardinality, Datom, EntityId, Keyword, Partition, Schema, Value, ValueType,
};
use crate::Idents;
pub const TX_INSTANT: AttrId = EntityId::new(Partition::Db as u32, 50);
#[must_use]
pub fn tx_instant_ident() -> Keyword {
Keyword::new(Some("db"), "txInstant")
}
#[must_use]
pub const fn tx_instant_attribute() -> Attribute {
Attribute {
id: TX_INSTANT,
value_type: ValueType::Instant,
cardinality: Cardinality::One,
unique: None,
is_component: false,
indexed: true,
no_history: false,
}
}
pub fn install(schema: &mut Schema, idents: &mut Idents) {
schema.insert(tx_instant_attribute());
idents.insert(tx_instant_ident(), TX_INSTANT);
}
pub fn install_schema(schema: &mut Schema) {
schema.insert(tx_instant_attribute());
}
#[must_use]
pub fn tx_instant_datom(t: u64, instant: i64) -> Datom {
let tx = EntityId::new(Partition::Tx as u32, t);
Datom {
e: tx,
a: TX_INSTANT,
v: Value::Instant(instant),
tx,
added: true,
}
}
#[must_use]
pub fn asserted_instant(t: u64, datoms: &[Datom]) -> Option<i64> {
let tx = EntityId::new(Partition::Tx as u32, t);
let mut asserted = None;
for datom in datoms {
if let Datom {
e,
a,
v: Value::Instant(instant),
added,
..
} = datom
&& *e == tx
&& *a == TX_INSTANT
{
if *added {
asserted = Some(*instant);
} else if asserted == Some(*instant) {
asserted = None;
}
}
}
asserted
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn install_is_idempotent() {
let mut schema = Schema::default();
let mut idents = Idents::default();
install(&mut schema, &mut idents);
install(&mut schema, &mut idents);
assert_eq!(schema.iter().count(), 1);
assert_eq!(idents.iter().count(), 1);
assert_eq!(idents.entid(&tx_instant_ident()), Some(TX_INSTANT));
}
#[test]
fn asserted_instant_finds_transaction_metadata() {
let datoms = vec![tx_instant_datom(7, 1_700_000_000_000)];
assert_eq!(asserted_instant(7, &datoms), Some(1_700_000_000_000));
assert_eq!(asserted_instant(8, &datoms), None);
}
#[test]
fn asserted_instant_uses_the_final_cardinality_one_value() {
let mut datoms = vec![tx_instant_datom(7, 2_000)];
let mut retract = tx_instant_datom(7, 2_000);
retract.added = false;
datoms.push(retract);
datoms.push(tx_instant_datom(7, 1_000));
assert_eq!(asserted_instant(7, &datoms), Some(1_000));
}
}