pub struct BranchView { /* private fields */ }Expand description
One lineage’s handle on the ledger (§15.4, 0.14.9, D-226).
A Database plus a BranchId, so a caller who forked writes and reads
through the fork instead of naming it at every call. Every operation here
exists on Database already and takes a lineage there —
this type buys ergonomics and no capability, which is what makes it the
last piece of §15.4’s first bullet rather than a fifth release of it.
let alt = db.fork(BranchId::new("turn/17/alt/1")?, BranchId::main()).await?;
let view = db.view(alt.id);
view.assert_edge(EdgeAssertion::new("a", "b", "CITES").valid_from(ts())).await?;
let seen = view.traversal("a").execute_ids(view.read_conn(), ts()).await?;§It holds an Arc<Database> and cannot close it
Database::close takes self by value, and an
Arc cannot give that up while any clone survives. So the borrow is
structural rather than a documented request: a caller who forks a view,
reads it and drops it is not one call away from stopping the actor everyone
else is using. That is why the view is a separate type over an
Arc<Database> and not a Database with a field added, and it is the same
argument D-203 made when Database: Clone was declined — a handle that can
be cloned freely must not carry the right to end the thing it handles.
Clone is therefore free of that concern and is derived: the view owns no
lifecycle, so cloning it is cloning an Arc and a short string.
§What it does with an assertion that names a lineage
It stamps its own on one that names none, and refuses one that names a
different lineage with DbError::BranchMismatch.
Stamping over is the shape a caller building through the view produces and
costs nothing; relabelling a write that already named somewhere else would
discard a belief rather than contradict it. See that variant for the failure
it catches.
Implementations§
Source§impl BranchView
impl BranchView
Sourcepub fn new(db: Arc<Database>, branch: BranchId) -> Self
pub fn new(db: Arc<Database>, branch: BranchId) -> Self
Bind a lineage to a handle.
Infallible and does no I/O: the name is already validated by
BranchId, and whether it is registered is a question every
operation on this view asks for itself, answering
DbError::UnknownBranch by name. A
constructor that checked would buy one round trip’s worth of earlier
notice and cost the type its const-cheapness, and the check would be
stale by the next call anyway — branches is append-only, but the view
outlives the answer.
Sourcepub fn database(&self) -> &Arc<Database> ⓘ
pub fn database(&self) -> &Arc<Database> ⓘ
The handle underneath, for the operations that are not lineage-scoped.
archive, checkpoint, verify and the rest are properties of the
file rather than of a lineage, so they are reached through here rather
than duplicated onto a view that would answer the same thing for every
branch.
Sourcepub fn read_conn(&self) -> &Connection
pub fn read_conn(&self) -> &Connection
The read connection, so a TraversalBuilder from
Self::traversal can be executed without reaching for the handle.
Sourcepub fn traversal(&self, start_node: impl Into<String>) -> TraversalBuilder
pub fn traversal(&self, start_node: impl Into<String>) -> TraversalBuilder
A traversal already pointed at this lineage.
The one read this type needs to wrap, because everything downstream of
it — execute_ids, execute,
load_subgraph_with — takes the
lineage from the builder. Seeding it here is therefore the whole of
the read side rather than a first method of several.
Sourcepub async fn load_subgraph(
&self,
start_node: &str,
max_hops: u32,
now_ts: &str,
byte_budget: usize,
) -> Result<Subgraph>
pub async fn load_subgraph( &self, start_node: &str, max_hops: u32, now_ts: &str, byte_budget: usize, ) -> Result<Subgraph>
Database::load_subgraph on this
lineage.
The sugar form has no builder to carry the branch, so it is wrapped;
load_subgraph_with is not, because a builder from Self::traversal
already carries it.
Sourcepub async fn query_as_of_edges(
&self,
ts: &str,
) -> Result<Vec<(String, String, String, String, String)>>
pub async fn query_as_of_edges( &self, ts: &str, ) -> Result<Vec<(String, String, String, String, String)>>
Every edge this lineage believes in at ts.
Sourcepub async fn diff(&self, other: &BranchId) -> Result<Vec<Divergence>>
pub async fn diff(&self, other: &BranchId) -> Result<Vec<Divergence>>
Assert an edge on this lineage.
What this lineage believes that other does not.
Database::diff with this view’s lineage as
the first argument. The direction matters and is not symmetric: this
answers what did I conclude that they do not know, which is the
question the view’s holder is in a position to ask.
pub async fn assert_edge(&self, edge: EdgeAssertion) -> Result<()>
Sourcepub async fn retire_edge(
&self,
source: impl Into<String>,
target: impl Into<String>,
edge_type: impl Into<String>,
valid_from: &str,
valid_to: &str,
) -> Result<()>
pub async fn retire_edge( &self, source: impl Into<String>, target: impl Into<String>, edge_type: impl Into<String>, valid_from: &str, valid_to: &str, ) -> Result<()>
Retire an edge on this lineage — Database::retire_edge_on without
the argument.
An inherited edge is retired by writing this lineage’s own closed row at the ancestor’s key; the parent’s row is never touched.
Sourcepub async fn upsert_concept(&self, concept: ConceptUpsert) -> Result<()>
pub async fn upsert_concept(&self, concept: ConceptUpsert) -> Result<()>
Mint a concept on this lineage.
A branch inherits its parent’s concepts and may not restate one:
concepts is keyed by identity, so that is
DbError::CrossLineage.
Sourcepub async fn write_bulk_atomic(
&self,
edges: Vec<EdgeAssertion>,
) -> Result<usize>
pub async fn write_bulk_atomic( &self, edges: Vec<EdgeAssertion>, ) -> Result<usize>
Database::write_bulk_atomic with
every edge on this lineage.
Sourcepub async fn bulk_import(&self, edges: Vec<EdgeAssertion>) -> BulkResult<usize>
pub async fn bulk_import(&self, edges: Vec<EdgeAssertion>) -> BulkResult<usize>
Database::bulk_import with every edge
on this lineage.
Sourcepub async fn write_concepts(
&self,
concepts: Vec<ConceptUpsert>,
) -> BulkResult<usize>
pub async fn write_concepts( &self, concepts: Vec<ConceptUpsert>, ) -> BulkResult<usize>
Database::write_concepts with every
concept on this lineage.
Trait Implementations§
Source§impl Clone for BranchView
impl Clone for BranchView
Source§fn clone(&self) -> BranchView
fn clone(&self) -> BranchView
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for BranchView
Hand-written because Database is not Debug — it owns
a connection, a channel and a clock, none of which prints usefully. What a
reader of this type wants is which lineage against which file, so that is
what it prints.
impl Debug for BranchView
Hand-written because Database is not Debug — it owns
a connection, a channel and a clock, none of which prints usefully. What a
reader of this type wants is which lineage against which file, so that is
what it prints.
Auto Trait Implementations§
impl !RefUnwindSafe for BranchView
impl !UnwindSafe for BranchView
impl Freeze for BranchView
impl Send for BranchView
impl Sync for BranchView
impl Unpin for BranchView
impl UnsafeUnpin for BranchView
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request