Ecto schema for the sourced events table, and every query the adapter runs against it.
Queries live here rather than beside the repo calls that run them, so
Ecto.Query is imported in one place and the read path and the append
condition cannot drift apart on what counts as a match.
Summary
Functions
Query asking whether anything matching query has arrived past
expected_sequence.
Query returning the sequence of the last event matching query past
expected_sequence, or 0 when nothing is past it.
Query returning the sequence of the last event matching query, or 0 when
nothing matches.
Functions
Query asking whether anything matching query has arrived past
expected_sequence.
This is the DCB check, and under SERIALIZABLE it needs no help to be
race-free: the read takes SIREAD predicate locks over the range it touched, a
concurrent insert into that range creates an rw-conflict, and the dangerous
structure detector aborts one side. It needs no ordering against the insert
that follows it, and so runs as an ordinary statement of its own.
Phrased as an existence check over the tail rather than as max(sequence)
over everything matching, because under SSI the read set is the lock set: this
reads only past expected_sequence and can stop at the first row, which is a
strictly narrower predicate-lock footprint for an equivalent question.
Query returning the sequence of the last event matching query past
expected_sequence, or 0 when nothing is past it.
Reports what a rejected append conflicted with. Bounded to the same tail as
conflict_query/2, so it is only meaningful where something is already known
to be in that tail — the 0 it returns otherwise would misreport an empty
tail as an empty stream. Where that is not known, use last_sequence/1.
Worth the narrowing because this runs inside the append's own transaction,
where a read of the whole matched range would take the wide predicate locks
that conflict_query/2 exists to avoid.
Query returning the sequence of the last event matching query, or 0 when
nothing matches.