pub struct SqlGraphStore { /* private fields */ }Expand description
A GraphStore backed by SQLite tables.
Implementations§
Source§impl SqlGraphStore
impl SqlGraphStore
Sourcepub fn new_scoped(
pool: Arc<ConnectionPool>,
is_file_backed: bool,
namespace: impl Into<String>,
) -> Self
pub fn new_scoped( pool: Arc<ConnectionPool>, is_file_backed: bool, namespace: impl Into<String>, ) -> Self
Create a new store with a default namespace for multi-record query filtering.
The namespace is a PARAM-ONLY hint (ADR-007 rule 4) — it is used as a
WHERE filter in multi-record queries and as the write namespace stamped on
upserted edges, but it does NOT enforce isolation: upsert_edge accepts
edges from any namespace, and by-ID ops (get_edge, delete_edge) ignore
the namespace entirely.
Trait Implementations§
Source§impl GraphStore for SqlGraphStore
impl GraphStore for SqlGraphStore
Source§fn neighbors_both_directions<'life0, 'async_trait>(
&'life0 self,
node_id: Uuid,
query: NeighborQuery,
) -> Pin<Box<dyn Future<Output = Result<Vec<DirectedNeighborHit>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn neighbors_both_directions<'life0, 'async_trait>(
&'life0 self,
node_id: Uuid,
query: NeighborQuery,
) -> Pin<Box<dyn Future<Output = Result<Vec<DirectedNeighborHit>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Single-query both-direction neighbor fetch (ADR-089 context-verb
optimization): projects a 'out'/'in' literal from each UNION ALL
arm so the caller gets direction labels without a second direction-
scoped round trip. query.direction is ignored — always both.
Source§fn latest_annotating_note<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
node_id: Uuid,
kind: &'life1 str,
tag: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<(Uuid, i64)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn latest_annotating_note<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
node_id: Uuid,
kind: &'life1 str,
tag: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<(Uuid, i64)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Return the newest live note of
kind carrying the exact string tag
in its properties.tags array and connected to node_id by a live
incoming annotates edge in this store’s namespace. Returns its UUID
and creation timestamp; equal timestamps choose the smallest UUID. Read moreSource§fn upsert_edge<'life0, 'async_trait>(
&'life0 self,
edge: Edge,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_edge<'life0, 'async_trait>(
&'life0 self,
edge: Edge,
) -> Pin<Box<dyn Future<Output = Result<(), StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert or update a single edge.
Source§fn upsert_edge_observed<'life0, 'async_trait>(
&'life0 self,
request: EdgeUpsertRequest,
) -> Pin<Box<dyn Future<Output = Result<EdgeUpsertResult, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_edge_observed<'life0, 'async_trait>(
&'life0 self,
request: EdgeUpsertRequest,
) -> Pin<Box<dyn Future<Output = Result<EdgeUpsertResult, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert or replace one edge and return the transaction-observed
disposition plus preimage. Tombstone restoration is controlled by the
request rather than being an implicit side effect of every upsert.
Source§fn insert_edge_if_absent<'life0, 'async_trait>(
&'life0 self,
edge: Edge,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn insert_edge_if_absent<'life0, 'async_trait>(
&'life0 self,
edge: Edge,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert an edge only when neither its id nor natural key already
exists. Returns
true when this call inserted the row and false
when an existing row won the race. The existing row is never updated. Read moreSource§fn replace_edge_if_unchanged<'life0, 'async_trait>(
&'life0 self,
edge: Edge,
expected_updated_at: DateTime<Utc>,
expected_deleted_at: Option<DateTime<Utc>>,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn replace_edge_if_unchanged<'life0, 'async_trait>(
&'life0 self,
edge: Edge,
expected_updated_at: DateTime<Utc>,
expected_deleted_at: Option<DateTime<Utc>>,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Replace an edge only when the persisted row still matches the
caller’s read snapshot. Read more
Source§fn upsert_edges<'life0, 'async_trait>(
&'life0 self,
edges: Vec<Edge>,
) -> Pin<Box<dyn Future<Output = Result<BatchWriteSummary, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_edges<'life0, 'async_trait>(
&'life0 self,
edges: Vec<Edge>,
) -> Pin<Box<dyn Future<Output = Result<BatchWriteSummary, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert or update a batch of edges.
Source§fn upsert_edge_guarded<'life0, 'async_trait>(
&'life0 self,
edge: Edge,
) -> Pin<Box<dyn Future<Output = Result<GuardedWriteOutcome, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_edge_guarded<'life0, 'async_trait>(
&'life0 self,
edge: Edge,
) -> Pin<Box<dyn Future<Output = Result<GuardedWriteOutcome, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Insert or update a single edge, re-checking that both endpoints still
exist (and are not soft-deleted) as part of the same write, not a
separate prior read. Closes the TOCTOU window between an async
prepare-time existence check and a later, unconditional write: a
concurrent hard-delete of an endpoint that lands between the two can
otherwise leave a durably dangling edge (#769). Read more
Source§fn upsert_edge_guarded_observed<'life0, 'async_trait>(
&'life0 self,
request: EdgeUpsertRequest,
) -> Pin<Box<dyn Future<Output = Result<GuardedEdgeUpsertOutcome, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_edge_guarded_observed<'life0, 'async_trait>(
&'life0 self,
request: EdgeUpsertRequest,
) -> Pin<Box<dyn Future<Output = Result<GuardedEdgeUpsertOutcome, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Observed form of
GraphStore::upsert_edge_guarded. In addition to
the endpoint guard, it distinguishes create, live replacement, and
explicit resurrection without a caller-side read/write race.Source§fn upsert_edges_guarded<'life0, 'async_trait>(
&'life0 self,
edges: Vec<Edge>,
) -> Pin<Box<dyn Future<Output = Result<GuardedBatchOutcome, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_edges_guarded<'life0, 'async_trait>(
&'life0 self,
edges: Vec<Edge>,
) -> Pin<Box<dyn Future<Output = Result<GuardedBatchOutcome, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Batch form of
GraphStore::upsert_edge_guarded. All-or-nothing:
if any edge’s endpoints are missing at write time, no edge from the
batch is persisted, BatchWriteSummary::affected is 0, and
GuardedBatchOutcome::refused names the first failing batch entry and
its missing endpoint(s) — determined by the same in-transaction
pre-check that aborted the batch, not a post-hoc re-read.
Retain the original ordered input to enumerate every aborted write via
GuardedBatchOutcome::refusal_page beyond the default bounded sample. Read moreSource§fn upsert_edges_guarded_observed<'life0, 'async_trait>(
&'life0 self,
requests: Vec<EdgeUpsertRequest>,
) -> Pin<Box<dyn Future<Output = Result<GuardedEdgeBatchUpsertOutcome, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert_edges_guarded_observed<'life0, 'async_trait>(
&'life0 self,
requests: Vec<EdgeUpsertRequest>,
) -> Pin<Box<dyn Future<Output = Result<GuardedEdgeBatchUpsertOutcome, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
All-or-nothing observed batch form. Implementations must perform
endpoint and tombstone-policy preflight in the same write transaction
before applying any row.
Source§fn get_edge<'life0, 'async_trait>(
&'life0 self,
id: LinkId,
) -> Pin<Box<dyn Future<Output = Result<Option<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_edge<'life0, 'async_trait>(
&'life0 self,
id: LinkId,
) -> Pin<Box<dyn Future<Output = Result<Option<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Fetch an edge by link ID, returning
None if absent. Filters soft-deleted rows.Source§fn get_edge_including_deleted<'life0, 'async_trait>(
&'life0 self,
id: LinkId,
) -> Pin<Box<dyn Future<Output = Result<Option<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_edge_including_deleted<'life0, 'async_trait>(
&'life0 self,
id: LinkId,
) -> Pin<Box<dyn Future<Output = Result<Option<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Fetch an edge by link ID including soft-deleted rows. Used by the runtime hard-delete path
to locate and namespace-check an already-soft-deleted edge before purging it.
Source§fn edge_sequence<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<i64>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn edge_sequence<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<i64>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Resolve an edge id to its immutable insertion sequence.
Source§fn edge_sequences<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [Uuid],
) -> Pin<Box<dyn Future<Output = Result<Vec<(Uuid, i64)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn edge_sequences<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [Uuid],
) -> Pin<Box<dyn Future<Output = Result<Vec<(Uuid, i64)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Resolve edge ids to immutable insertion sequences. Implementations may
override this to batch the lookup; the default preserves correctness.
Source§fn get_edge_by_natural_key_including_deleted<'life0, 'life1, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
source_id: Uuid,
target_id: Uuid,
relation: EdgeRelation,
) -> Pin<Box<dyn Future<Output = Result<Option<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_edge_by_natural_key_including_deleted<'life0, 'life1, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
source_id: Uuid,
target_id: Uuid,
relation: EdgeRelation,
) -> Pin<Box<dyn Future<Output = Result<Option<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch an edge by natural key (namespace, source, target, relation) including
soft-deleted rows. Used by the atomic-apply result renderer for a symmetric-relation
update whose surviving canonical row may be tombstoned (ADR-039 DO NOTHING) — the
normal
query_edges/list_edges path filters deleted_at IS NULL and would report
“not found” for exactly that row. Read moreSource§fn get_edges<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [LinkId],
) -> Pin<Box<dyn Future<Output = Result<Vec<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_edges<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [LinkId],
) -> Pin<Box<dyn Future<Output = Result<Vec<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch multiple edges by their link IDs in a single round-trip. Read more
Source§fn batch_neighbors<'life0, 'life1, 'async_trait>(
&'life0 self,
sources: &'life1 [Uuid],
query: NeighborQuery,
) -> Pin<Box<dyn Future<Output = Result<Vec<(Uuid, NeighborHit)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn batch_neighbors<'life0, 'life1, 'async_trait>(
&'life0 self,
sources: &'life1 [Uuid],
query: NeighborQuery,
) -> Pin<Box<dyn Future<Output = Result<Vec<(Uuid, NeighborHit)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Return neighbors for multiple source nodes in a single round-trip,
yielding
(source_id, hit) pairs. Read moreSource§fn delete_edge<'life0, 'async_trait>(
&'life0 self,
id: LinkId,
mode: DeleteMode,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn delete_edge<'life0, 'async_trait>(
&'life0 self,
id: LinkId,
mode: DeleteMode,
) -> Pin<Box<dyn Future<Output = Result<bool, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Delete an edge by link ID using the specified delete mode.
Source§fn query_edges<'life0, 'async_trait>(
&'life0 self,
filter: EdgeFilter,
sort: Vec<SortOrder<EdgeSortField>>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn query_edges<'life0, 'async_trait>(
&'life0 self,
filter: EdgeFilter,
sort: Vec<SortOrder<EdgeSortField>>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Query edges with filter, sort, and pagination without an implicit
exact count. Implementations should return
total: None; callers that
need a count use Self::count_edges explicitly.Source§fn count_edges<'life0, 'async_trait>(
&'life0 self,
filter: EdgeFilter,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn count_edges<'life0, 'async_trait>(
&'life0 self,
filter: EdgeFilter,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Count edges matching the given filter.
Source§fn count_edges_in_namespaces<'life0, 'life1, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
filter: EdgeFilter,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn count_edges_in_namespaces<'life0, 'life1, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
filter: EdgeFilter,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Count edges across the given namespaces in one aggregate query.
Backends without batched namespace support retain the single-namespace
path and reject multi-namespace requests explicitly.
Source§fn query_edges_in_namespaces<'life0, 'life1, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
filter: EdgeFilter,
sort: Vec<SortOrder<EdgeSortField>>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn query_edges_in_namespaces<'life0, 'life1, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
filter: EdgeFilter,
sort: Vec<SortOrder<EdgeSortField>>,
page: PageRequest,
) -> Pin<Box<dyn Future<Output = Result<Page<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Query edges across the given namespaces in one deterministic query
with real SQL paging. The multi-namespace analogue of
Self::query_edges: a single statement with namespace IN (...)
keeps offset continuation coherent, where fetching per-namespace
prefixes and slicing a client-side merge floats the window between
calls (silent duplicate/skip enumeration). Backends without batched
namespace support retain the single-namespace path and reject
multi-namespace requests explicitly. Implementations should return
total: None; callers that need a count use
Self::count_edges_in_namespaces explicitly.Source§fn count_edges_by_relation<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<(EdgeRelation, u64)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn count_edges_by_relation<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<(EdgeRelation, u64)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Count edges grouped by relation, ignoring soft-deleted rows. Cheap
aggregate (
GROUP BY relation) used to report the true per-relation
population for full-graph audits (#702.3).Source§fn count_edges_by_relation_in_namespaces<'life0, 'life1, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<Vec<(EdgeRelation, u64)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn count_edges_by_relation_in_namespaces<'life0, 'life1, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<Vec<(EdgeRelation, u64)>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Count edges grouped by relation across the given namespaces in one
aggregate query.
Source§fn count_edges_by_endpoint_base<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<EdgeEndpointBaseCounts, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn count_edges_by_endpoint_base<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<EdgeEndpointBaseCounts, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Count live edges grouped by the base each endpoint resolves against. Read more
Source§fn count_edges_by_endpoint_base_in_namespaces<'life0, 'life1, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<EdgeEndpointBaseCounts, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn count_edges_by_endpoint_base_in_namespaces<'life0, 'life1, 'async_trait>(
&'life0 self,
namespaces: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<EdgeEndpointBaseCounts, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Count live edges by endpoint base across the given namespaces in one
aggregate query.
Source§fn query_edges_after<'life0, 'async_trait>(
&'life0 self,
filter: EdgeFilter,
after: Option<Uuid>,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<EdgeSeekPage, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn query_edges_after<'life0, 'async_trait>(
&'life0 self,
filter: EdgeFilter,
after: Option<Uuid>,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<EdgeSeekPage, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Seek-pagination page of edges ordered by
id ascending, using an
indexed range scan (id > after) against the (namespace, id)
primary key instead of OFFSET. after is exclusive; None starts
from the beginning of the set. This remains an efficient compatibility
path for a fixed edge set, but random UUIDs inserted concurrently may
sort behind an issued boundary. Public concurrent walks use
Self::query_edges_sequence_after instead (#1424).Source§fn query_edges_sequence_after<'life0, 'async_trait>(
&'life0 self,
filter: EdgeFilter,
after: Option<SeekCursor>,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<SeekPage<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn query_edges_sequence_after<'life0, 'async_trait>(
&'life0 self,
filter: EdgeFilter,
after: Option<SeekCursor>,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<SeekPage<Edge>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Seek-pagination page ordered by immutable insertion sequence. This is
the stable public-list contract for walks overlapping inserts (#1424).
Source§fn neighbors<'life0, 'async_trait>(
&'life0 self,
node_id: Uuid,
query: NeighborQuery,
) -> Pin<Box<dyn Future<Output = Result<Vec<NeighborHit>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn neighbors<'life0, 'async_trait>(
&'life0 self,
node_id: Uuid,
query: NeighborQuery,
) -> Pin<Box<dyn Future<Output = Result<Vec<NeighborHit>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Return immediate neighbors of a graph node.
Source§fn neighbors_page<'life0, 'async_trait>(
&'life0 self,
node_id: Uuid,
query: NeighborQuery,
after: Option<NeighborCursor>,
neighbor_kinds: Option<Vec<String>>,
) -> Pin<Box<dyn Future<Output = Result<Vec<NeighborHit>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn neighbors_page<'life0, 'async_trait>(
&'life0 self,
node_id: Uuid,
query: NeighborQuery,
after: Option<NeighborCursor>,
neighbor_kinds: Option<Vec<String>>,
) -> Pin<Box<dyn Future<Output = Result<Vec<NeighborHit>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Return one deterministic neighbor page.
after is exclusive and
neighbor_kinds, when present, filters entity and note kinds before
the limit is applied. Backends that do not implement kind-aware paging
retain an explicit unsupported result rather than silently returning a
misleading page.Source§fn traverse<'life0, 'async_trait>(
&'life0 self,
request: TraversalRequest,
) -> Pin<Box<dyn Future<Output = Result<Vec<GraphPath>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn traverse<'life0, 'async_trait>(
&'life0 self,
request: TraversalRequest,
) -> Pin<Box<dyn Future<Output = Result<Vec<GraphPath>, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Bounded multi-hop BFS traversal from the given roots. Read more
Source§fn purge_incident_edges<'life0, 'async_trait>(
&'life0 self,
node_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn purge_incident_edges<'life0, 'async_trait>(
&'life0 self,
node_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<u64, StorageError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Hard-delete every incident edge (source or target) for
node_id, regardless of soft-delete
state. Used during endpoint hard-delete to prevent dangling graph_edges rows (ADR-002
no-dangling-references contract).Auto Trait Implementations§
impl !RefUnwindSafe for SqlGraphStore
impl !UnwindSafe for SqlGraphStore
impl Freeze for SqlGraphStore
impl Send for SqlGraphStore
impl Sync for SqlGraphStore
impl Unpin for SqlGraphStore
impl UnsafeUnpin for SqlGraphStore
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
Mutably borrows from an owned value. Read more
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> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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