pub trait NodeDb: Send + Sync {
Show 20 methods
// Required methods
fn vector_search<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
collection: &'life1 str,
query: &'life2 [f32],
k: usize,
filter: Option<&'life3 MetadataFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<SearchResult>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn vector_insert<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
embedding: &'life3 [f32],
metadata: Option<Document>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn vector_delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn graph_traverse<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
start: &'life1 NodeId,
depth: u8,
edge_filter: Option<&'life2 EdgeFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<SubGraph>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn graph_insert_edge<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
from: &'life1 NodeId,
to: &'life2 NodeId,
edge_type: &'life3 str,
properties: Option<Document>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<EdgeId>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn graph_delete_edge<'life0, 'life1, 'async_trait>(
&'life0 self,
edge_id: &'life1 EdgeId,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn document_get<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Option<Document>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn document_put<'life0, 'life1, 'async_trait>(
&'life0 self,
collection: &'life1 str,
doc: Document,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn document_delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn execute_sql<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
query: &'life1 str,
params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = NodeDbResult<QueryResult>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
// Provided methods
fn vector_insert_field<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
collection: &'life1 str,
field_name: &'life2 str,
id: &'life3 str,
embedding: &'life4 [f32],
metadata: Option<Document>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait { ... }
fn vector_search_field<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
collection: &'life1 str,
field_name: &'life2 str,
query: &'life3 [f32],
k: usize,
filter: Option<&'life4 MetadataFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<SearchResult>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait { ... }
fn graph_shortest_path<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
from: &'life1 NodeId,
to: &'life2 NodeId,
max_depth: u8,
edge_filter: Option<&'life3 EdgeFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Option<Vec<NodeId>>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait { ... }
fn text_search<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
query: &'life2 str,
top_k: usize,
params: TextSearchParams,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<SearchResult>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn batch_vector_insert<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
collection: &'life1 str,
vectors: &'life2 [(&'life3 str, &'life4 [f32])],
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait { ... }
fn batch_graph_insert_edges<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
edges: &'life1 [(&'life2 str, &'life3 str, &'life4 str)],
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait { ... }
fn undrop_collection<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn drop_collection_purge<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn list_dropped_collections<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<DroppedCollection>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn on_collection_purged<'life0, 'async_trait>(
&'life0 self,
_handler: CollectionPurgedHandler,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
}Expand description
Unified database interface for NodeDB.
Two implementations:
NodeDbLite: executes queries against in-memory HNSW/CSR/Loro engines on the edge device. Writes produce CRDT deltas synced to Origin in background.NodeDbRemote: translates trait calls into parameterized SQL and sends them over pgwire to the Origin cluster.
The developer writes agent logic once. Switching between local and cloud is a one-line configuration change.
Required Methods§
Sourcefn vector_search<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
collection: &'life1 str,
query: &'life2 [f32],
k: usize,
filter: Option<&'life3 MetadataFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<SearchResult>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn vector_search<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
collection: &'life1 str,
query: &'life2 [f32],
k: usize,
filter: Option<&'life3 MetadataFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<SearchResult>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Search for the k nearest vectors to query in collection.
Returns results ordered by ascending distance. Optional metadata filter constrains which vectors are considered.
On Lite: direct in-memory HNSW search. Sub-millisecond.
On Remote: translated to SELECT ... ORDER BY embedding <-> $1 LIMIT $2.
Sourcefn vector_insert<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
embedding: &'life3 [f32],
metadata: Option<Document>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn vector_insert<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
embedding: &'life3 [f32],
metadata: Option<Document>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Insert a vector with optional metadata into collection.
On Lite: inserts into in-memory HNSW + emits CRDT delta + persists to SQLite.
On Remote: translated to INSERT INTO collection (id, embedding, metadata) VALUES (...).
Sourcefn vector_delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn vector_delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Delete a vector by ID from collection.
On Lite: marks deleted in HNSW + emits CRDT tombstone.
On Remote: DELETE FROM collection WHERE id = $1.
Sourcefn graph_traverse<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
start: &'life1 NodeId,
depth: u8,
edge_filter: Option<&'life2 EdgeFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<SubGraph>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn graph_traverse<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
start: &'life1 NodeId,
depth: u8,
edge_filter: Option<&'life2 EdgeFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<SubGraph>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Traverse the graph from start up to depth hops.
Returns the discovered subgraph (nodes + edges). Optional edge filter constrains which edges are followed during traversal.
On Lite: direct CSR pointer-chasing in contiguous memory. Microseconds.
On Remote: SELECT * FROM graph_traverse($1, $2, $3).
Sourcefn graph_insert_edge<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
from: &'life1 NodeId,
to: &'life2 NodeId,
edge_type: &'life3 str,
properties: Option<Document>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<EdgeId>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn graph_insert_edge<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
from: &'life1 NodeId,
to: &'life2 NodeId,
edge_type: &'life3 str,
properties: Option<Document>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<EdgeId>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Insert a directed edge from from to to with the given label.
Returns the generated edge ID.
On Lite: appends to mutable adjacency buffer + CRDT delta + SQLite.
On Remote: INSERT INTO edges (src, dst, label, properties) VALUES (...).
Sourcefn graph_delete_edge<'life0, 'life1, 'async_trait>(
&'life0 self,
edge_id: &'life1 EdgeId,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn graph_delete_edge<'life0, 'life1, 'async_trait>(
&'life0 self,
edge_id: &'life1 EdgeId,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Delete a graph edge by ID.
On Lite: marks deleted + CRDT tombstone.
On Remote: DELETE FROM edges WHERE id = $1.
Sourcefn document_get<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Option<Document>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn document_get<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Option<Document>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Get a document by ID from collection.
On Lite: direct Loro state read. Sub-millisecond.
On Remote: SELECT * FROM collection WHERE id = $1.
Sourcefn document_put<'life0, 'life1, 'async_trait>(
&'life0 self,
collection: &'life1 str,
doc: Document,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn document_put<'life0, 'life1, 'async_trait>(
&'life0 self,
collection: &'life1 str,
doc: Document,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Put (insert or update) a document into collection.
The document’s id field determines the key. If a document with that
ID already exists, it is overwritten (last-writer-wins locally; CRDT
merge on sync).
On Lite: Loro apply + CRDT delta + SQLite persist.
On Remote: INSERT ... ON CONFLICT (id) DO UPDATE SET ....
Sourcefn document_delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn document_delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
id: &'life2 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Delete a document by ID from collection.
On Lite: Loro delete + CRDT tombstone.
On Remote: DELETE FROM collection WHERE id = $1.
Sourcefn execute_sql<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
query: &'life1 str,
params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = NodeDbResult<QueryResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn execute_sql<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
query: &'life1 str,
params: &'life2 [Value],
) -> Pin<Box<dyn Future<Output = NodeDbResult<QueryResult>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Execute a raw SQL query with parameters.
On Lite: requires the sql feature flag (compiles in DataFusion parser).
Returns NodeDbError::SqlNotEnabled if the feature is not compiled in.
On Remote: pass-through to Origin via pgwire.
For most AI agent workloads, the typed methods above are sufficient and faster. Use this for BI tools, existing ORMs, or ad-hoc queries.
Provided Methods§
Sourcefn vector_insert_field<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
collection: &'life1 str,
field_name: &'life2 str,
id: &'life3 str,
embedding: &'life4 [f32],
metadata: Option<Document>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
fn vector_insert_field<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
collection: &'life1 str,
field_name: &'life2 str,
id: &'life3 str,
embedding: &'life4 [f32],
metadata: Option<Document>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
Insert a vector into a named field within a collection.
Enables multiple embeddings per collection (e.g., “title_embedding”,
“body_embedding”) with independent HNSW indexes.
Default: delegates to vector_insert() ignoring field_name.
Sourcefn vector_search_field<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
collection: &'life1 str,
field_name: &'life2 str,
query: &'life3 [f32],
k: usize,
filter: Option<&'life4 MetadataFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<SearchResult>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
fn vector_search_field<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
collection: &'life1 str,
field_name: &'life2 str,
query: &'life3 [f32],
k: usize,
filter: Option<&'life4 MetadataFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<SearchResult>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
Search a named vector field.
Default: delegates to vector_search() ignoring field_name.
Sourcefn graph_shortest_path<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
from: &'life1 NodeId,
to: &'life2 NodeId,
max_depth: u8,
edge_filter: Option<&'life3 EdgeFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Option<Vec<NodeId>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn graph_shortest_path<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
from: &'life1 NodeId,
to: &'life2 NodeId,
max_depth: u8,
edge_filter: Option<&'life3 EdgeFilter>,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Option<Vec<NodeId>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Find the shortest path between two nodes.
Returns the path as a list of node IDs, or None if no path exists
within max_depth hops. Uses bidirectional BFS.
Sourcefn text_search<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
query: &'life2 str,
top_k: usize,
params: TextSearchParams,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<SearchResult>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn text_search<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
collection: &'life1 str,
query: &'life2 str,
top_k: usize,
params: TextSearchParams,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<SearchResult>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Full-text search with BM25 scoring.
Returns document IDs with relevance scores, ordered by descending score.
Pass TextSearchParams::default() for standard OR-mode non-fuzzy search.
Sourcefn batch_vector_insert<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
collection: &'life1 str,
vectors: &'life2 [(&'life3 str, &'life4 [f32])],
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
fn batch_vector_insert<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
collection: &'life1 str,
vectors: &'life2 [(&'life3 str, &'life4 [f32])],
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
Batch insert vectors — amortizes CRDT delta export to O(1) per batch.
Sourcefn batch_graph_insert_edges<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
edges: &'life1 [(&'life2 str, &'life3 str, &'life4 str)],
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
fn batch_graph_insert_edges<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
edges: &'life1 [(&'life2 str, &'life3 str, &'life4 str)],
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
Batch insert graph edges — amortizes CRDT delta export to O(1) per batch.
Sourcefn undrop_collection<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn undrop_collection<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Restore a soft-deleted collection within its retention window.
Equivalent to UNDROP COLLECTION <name>. Fails with 42P01 if
the retention window has elapsed and the row is gone, or with
42501 if the caller is neither preserved owner nor admin.
Default impl routes through execute_sql so any implementation
that can execute SQL inherits the correct behavior for free.
Sourcefn drop_collection_purge<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn drop_collection_purge<'life0, 'life1, 'async_trait>(
&'life0 self,
name: &'life1 str,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Hard-delete a collection, skipping soft-delete and retention.
Equivalent to DROP COLLECTION <name> PURGE. Admin-only on the
server; the server rejects non-admin callers with 42501.
Bypasses the retention safety net — data is unrecoverable.
Sourcefn list_dropped_collections<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<DroppedCollection>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_dropped_collections<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = NodeDbResult<Vec<DroppedCollection>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List every soft-deleted collection in the current tenant that is still within its retention window.
Equivalent to SELECT tenant_id, name, owner, deactivated_at_ns, retention_expires_at_ns FROM _system.dropped_collections.
Returns Vec<DroppedCollection> — empty if no soft-deleted rows
exist for the caller’s tenant.
Sourcefn on_collection_purged<'life0, 'async_trait>(
&'life0 self,
_handler: CollectionPurgedHandler,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn on_collection_purged<'life0, 'async_trait>(
&'life0 self,
_handler: CollectionPurgedHandler,
) -> Pin<Box<dyn Future<Output = NodeDbResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Register a handler fired when a collection the caller has synced is purged on Origin and the local copy is removed.
Default impl returns NodeDbError::storage with a
"not supported" detail — implementations that maintain a
sync client (Lite, any future push-capable remote client)
override with registration into their internal handler list.
Stateless clients (pgwire-only NodeDbRemote) have nothing
to push, so the default rejection is the correct behavior.