Skip to main content

coven_format/
write_sources.rs

1//! Authenticated identities of the data a row change replaced (D5).
2
3use crate::error::{require, Error, Rule};
4use crate::value::{name, positive, row};
5use crate::wire::wire_struct;
6use coven_merge::{RowId, WriteId, WritePast};
7use std::collections::BTreeMap;
8
9/// One original row change, independent of its received interpretation.
10#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
11pub struct ChangeId {
12    /// The write containing the source change.
13    pub write: WriteId,
14    /// Its original table, key and audience, before any conversion.
15    pub row: RowId,
16}
17wire_struct!(ChangeId, write, row);
18
19/// One cell as named in the original setter's authenticated record.
20#[derive(Clone, Debug, PartialEq, Eq)]
21pub struct CellSource {
22    /// The original change that set the cell.
23    pub change: ChangeId,
24    /// The column's name in that change, before renaming.
25    pub column: String,
26}
27wire_struct!(CellSource, change, column => crate::wire::get_name);
28
29/// The author's observed generation source and replaced cell setters.
30#[derive(Clone, Debug, Default, PartialEq, Eq)]
31pub struct WriteSources {
32    /// Absent exactly at generation zero.
33    pub generation: Option<ChangeId>,
34    /// Authored column order is increasing name order. A delete retains every
35    /// replaced setter even when its old scalar map is empty. Columns which
36    /// have never been set have no setter; inserts replace no cells.
37    pub setters: BTreeMap<String, CellSource>,
38}
39wire_struct!(WriteSources, generation, setters => crate::wire::get_name_map);
40
41impl WriteSources {
42    /// Generation first, then setters in authored column order. Repeated
43    /// identities in different roles remain separate entries.
44    pub fn changes(&self) -> impl Iterator<Item = &ChangeId> {
45        self.generation.iter().chain(self.setters.values().map(|s| &s.change))
46    }
47
48    pub(crate) fn validate(&self, generation: u64) -> Result<(), Error> {
49        require(
50            self.generation.is_none() == (generation == 0),
51            "generation source",
52            Rule::Generation,
53        )?;
54        for source in self.changes() {
55            positive(source.write.number)?;
56            row(&source.row)?;
57        }
58        for (column, source) in &self.setters {
59            name(column)?;
60            name(&source.column)?;
61        }
62        Ok(())
63    }
64
65    /// Source identities must have been read, including implicit own predecessors.
66    /// Timestamps and original row/cell evidence are checked by the database.
67    pub fn validate_past(&self, past: &impl WritePast) -> Result<(), Error> {
68        require(self.changes().all(|s| past.contains(&s.write)), "source read", Rule::Coverage)
69    }
70}