Skip to main content

CardsProjection

Struct CardsProjection 

Source
pub struct CardsProjection { /* private fields */ }
Expand description

The read model over a card’s seven kinds and an alias’s two.

Stateless apart from the name it answers to: everything it knows is in the tables, which is what makes a rebuild a replay rather than a reconstruction of anything held here.

Implementations§

Source§

impl CardsProjection

Source

pub const NAME: &'static str = "cards_v4"

The consumer name, and so the identity of the cursor. See the module doc for what the _v4 is for.

Source

pub const KINDS: [&'static str; 10]

The kinds these streams carry. Naming them is not only a filter: it is what lets the runner read through the (kind, position) index instead of walking the whole log, and it is the reason apply may treat an unknown kind as a bug.

Source

pub fn new() -> CardsProjection

The projection this build folds under.

Trait Implementations§

Source§

impl Default for CardsProjection

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Projection for CardsProjection

Source§

fn init(&mut self, tx: &Transaction<'_>) -> Result<()>

Create the tables — after dropping them, when the ones there predate this shape.

CREATE TABLE IF NOT EXISTS leaves an existing table as it is, so a cb_cards written by an older build has no params_json, and the CREATE INDEX on model that follows would fail on every open — which is what cardbox version did on a store a cards_v3 build had created. The tables are a fold of the log and nothing else, so an outdated one is dropped and folded again; crate::Store::open runs the rebuild, having asked shape_outdated the same question before this ran.

Source§

fn tolerates_truncation(&self) -> bool

One event, folded.

The card’s id comes from the stream name rather than from meta: the stream is what the store’s own decisions fold over, so it is the identity the invariants are already stated in terms of, and a meta that disagreed with it would describe a card that no append_if was ever protecting. An event of one of these kinds on a stream that is not a card’s is a bug in whatever wrote it, and is reported rather than skipped.

An unknown kind is likewise an error. kinds() is what the runner filters on, so one arriving here means the filter and this match have drifted apart, and a fold that quietly ignored it would leave a read model missing rows with nothing saying so. Yes — and only because every removal announces itself first.

The default is false, and for an accumulating model the default is the right answer: sample_rows, eval_count and cb_blobs.refs are running totals, and a replay over a log missing part of its input produces a smaller number with nothing about it saying so. What makes this model different is the shape of the only removal it allows.

A prune is retain(Plan::Streams, ..) over whole card-<id> streams, and a cards_pruned event on PRUNE_STREAM is appended before it — that stream is never itself retained, so the journal survives what it describes. On a rebuild the pruned cards’ events are gone, so no row is ever created for them and no counter ever incremented; the journal event then replays over an absent card and [purge] returns without touching anything. The totals come out the same as they were, because the events that would have moved them and the event that moved them back are both absent.

That is the whole of the claim, and it is narrow on purpose: it holds for a removal of whole card streams that a journal event announced, and it would not hold for a bare eventsdb::sqlite::Plan::Before or OlderThan over this log. Neither is reachable — crate::Store exposes retain_streams and nothing else.

Source§

fn name(&self) -> &str

The consumer name the cursor is stored under. Stable across restarts, because it is the identity of the cursor.
Source§

fn kinds(&self) -> Option<Vec<String>>

Which kinds this projection folds. None sees every kind. Read more
Source§

fn reset(&mut self, tx: &Transaction<'_>) -> Result<()>

Empty the read model, for a rebuild. Whatever init created, this returns to its initial state.
Source§

fn apply(&mut self, tx: &Transaction<'_>, event: &Recorded) -> Result<()>

Fold one event into the read model.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> MaybeSend for T

Source§

impl<T> MaybeSync for T

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.