Skip to main content

GraphBackend

Trait GraphBackend 

Source
pub trait GraphBackend {
Show 21 methods // Required methods fn insert_node(&self, node: NodeSpec) -> Result<i64, SqliteGraphError>; fn insert_edge(&self, edge: EdgeSpec) -> Result<i64, SqliteGraphError>; fn update_node( &self, node_id: i64, node: NodeSpec, ) -> Result<i64, SqliteGraphError>; fn delete_entity(&self, id: i64) -> Result<(), SqliteGraphError>; fn entity_ids(&self) -> Result<Vec<i64>, SqliteGraphError>; fn get_node( &self, snapshot_id: SnapshotId, id: i64, ) -> Result<GraphEntity, SqliteGraphError>; fn neighbors( &self, snapshot_id: SnapshotId, node: i64, query: NeighborQuery, ) -> Result<Vec<i64>, SqliteGraphError>; fn bfs( &self, snapshot_id: SnapshotId, start: i64, depth: u32, ) -> Result<Vec<i64>, SqliteGraphError>; fn shortest_path( &self, snapshot_id: SnapshotId, start: i64, end: i64, ) -> Result<Option<Vec<i64>>, SqliteGraphError>; fn node_degree( &self, snapshot_id: SnapshotId, node: i64, ) -> Result<(usize, usize), SqliteGraphError>; fn k_hop( &self, snapshot_id: SnapshotId, start: i64, depth: u32, direction: BackendDirection, ) -> Result<Vec<i64>, SqliteGraphError>; fn k_hop_filtered( &self, snapshot_id: SnapshotId, start: i64, depth: u32, direction: BackendDirection, allowed_edge_types: &[&str], ) -> Result<Vec<i64>, SqliteGraphError>; fn chain_query( &self, snapshot_id: SnapshotId, start: i64, chain: &[ChainStep], ) -> Result<Vec<i64>, SqliteGraphError>; fn pattern_search( &self, snapshot_id: SnapshotId, start: i64, pattern: &PatternQuery, ) -> Result<Vec<PatternMatch>, SqliteGraphError>; fn checkpoint(&self) -> Result<(), SqliteGraphError>; fn flush(&self) -> Result<(), SqliteGraphError>; fn backup( &self, backup_dir: &Path, ) -> Result<BackupResult, SqliteGraphError>; fn snapshot_export( &self, export_dir: &Path, ) -> Result<SnapshotMetadata, SqliteGraphError>; fn snapshot_import( &self, import_dir: &Path, ) -> Result<ImportMetadata, SqliteGraphError>; fn query_nodes_by_kind( &self, snapshot_id: SnapshotId, kind: &str, ) -> Result<Vec<i64>, SqliteGraphError>; fn query_nodes_by_name_pattern( &self, snapshot_id: SnapshotId, pattern: &str, ) -> Result<Vec<i64>, SqliteGraphError>;
}
Expand description

Backend trait defining the interface for graph database backends.

Each trait method delegates to backend-specific primitives while ensuring deterministic behavior and a single integration surface for consumers.

§Snapshot Isolation

All read operations require a snapshot_id: SnapshotId parameter to enforce ACID compliance. Reads only observe data committed at or before the snapshot.

Required Methods§

Source

fn insert_node(&self, node: NodeSpec) -> Result<i64, SqliteGraphError>

Source

fn insert_edge(&self, edge: EdgeSpec) -> Result<i64, SqliteGraphError>

Source

fn update_node( &self, node_id: i64, node: NodeSpec, ) -> Result<i64, SqliteGraphError>

Update an existing node in place without allocating a new node ID

This modifies the data associated with an existing node while preserving its node_id. This is critical for avoiding node region exhaustion in the Native V2 backend, which has a hard limit of 2048 nodes.

§Arguments
  • node_id - The ID of the node to update (must exist)
  • node - New node specification (kind, name, file_path, data)
§Returns

The same node_id that was passed in, if update succeeded

§Errors

Returns SqliteGraphError if:

  • The node_id doesn’t exist
  • The update operation fails
  • The backend doesn’t support in-place updates
§Behavior by Backend
  • Native V2: Uses WAL to update node data in place, preserving node_id
  • SQLite: Uses UPDATE SQL query on entities table
§Example
// Create a node
let node_id = backend.insert_node(NodeSpec {
    kind: "File".to_string(),
    name: "main.rs".to_string(),
    file_path: Some("main.rs".to_string()),
    data: serde_json::json!({"hash": "abc123"}),
})?;

// Update it - this does NOT allocate a new node_id
let updated_id = backend.update_node(node_id, NodeSpec {
    kind: "File".to_string(),
    name: "main.rs".to_string(),
    file_path: Some("main.rs".to_string()),
    data: serde_json::json!({"hash": "def456", "modified": true}),
})?;

assert_eq!(updated_id, node_id); // Same ID!
Source

fn delete_entity(&self, id: i64) -> Result<(), SqliteGraphError>

Delete an entity (node) from the graph by ID

This removes the entity and all associated edges from the graph. For SQLite backend: deletes from entities table and cascades to edges For Native backend: marks node as deleted and updates adjacency indexes

Source

fn entity_ids(&self) -> Result<Vec<i64>, SqliteGraphError>

Get all entity IDs from the graph

Returns a vector of all node IDs currently stored in the graph. For SQLite backend: queries all IDs from entities table For Native backend: iterates over node store

Source

fn get_node( &self, snapshot_id: SnapshotId, id: i64, ) -> Result<GraphEntity, SqliteGraphError>

Source

fn neighbors( &self, snapshot_id: SnapshotId, node: i64, query: NeighborQuery, ) -> Result<Vec<i64>, SqliteGraphError>

Source

fn bfs( &self, snapshot_id: SnapshotId, start: i64, depth: u32, ) -> Result<Vec<i64>, SqliteGraphError>

Source

fn shortest_path( &self, snapshot_id: SnapshotId, start: i64, end: i64, ) -> Result<Option<Vec<i64>>, SqliteGraphError>

Source

fn node_degree( &self, snapshot_id: SnapshotId, node: i64, ) -> Result<(usize, usize), SqliteGraphError>

Source

fn k_hop( &self, snapshot_id: SnapshotId, start: i64, depth: u32, direction: BackendDirection, ) -> Result<Vec<i64>, SqliteGraphError>

Source

fn k_hop_filtered( &self, snapshot_id: SnapshotId, start: i64, depth: u32, direction: BackendDirection, allowed_edge_types: &[&str], ) -> Result<Vec<i64>, SqliteGraphError>

Source

fn chain_query( &self, snapshot_id: SnapshotId, start: i64, chain: &[ChainStep], ) -> Result<Vec<i64>, SqliteGraphError>

Source

fn checkpoint(&self) -> Result<(), SqliteGraphError>

Trigger WAL checkpoint for backends that support write-ahead logging

For Native backend with WAL: flushes WAL to graph file For SQLite backend: executes PRAGMA wal_checkpoint(TRUNCATE) For backends without WAL: returns Ok(()) as no-op

Source

fn flush(&self) -> Result<(), SqliteGraphError>

Force immediate flush of WAL buffer to disk

Ensures all buffered WAL records (including KV writes) are persisted immediately, making them visible to other processes.

For Native V2 backend with WAL: flushes WAL buffer to disk For SQLite backend: returns Ok(()) as no-op (SQLite handles sync) For backends without WAL: returns Ok(()) as no-op

Source

fn backup(&self, backup_dir: &Path) -> Result<BackupResult, SqliteGraphError>

Create a backup of the database

Creates a consistent snapshot of the database including all data pages. For Native V2 backend, optionally checkpoints before backup to ensure WAL is applied and snapshot is consistent.

§Arguments
  • backup_dir - Destination directory for backup files
§Returns

Backup result with paths, checksum, and metadata

Source

fn snapshot_export( &self, export_dir: &Path, ) -> Result<SnapshotMetadata, SqliteGraphError>

Export database snapshot to the specified directory

Creates a consistent snapshot of the current database state. For Native backend: uses V2 snapshot format For SQLite backend: uses JSON dump format

§Arguments
  • export_dir - Directory path where snapshot will be written
§Returns

Snapshot metadata including file paths and size information

Source

fn snapshot_import( &self, import_dir: &Path, ) -> Result<ImportMetadata, SqliteGraphError>

Import database snapshot from the specified directory

Restores database state from a previously created snapshot. For Native backend: loads V2 snapshot format For SQLite backend: loads JSON dump format

§Arguments
  • import_dir - Directory path containing snapshot files
§Returns

Import metadata including number of records imported

Source

fn query_nodes_by_kind( &self, snapshot_id: SnapshotId, kind: &str, ) -> Result<Vec<i64>, SqliteGraphError>

Query all nodes with a given kind

Returns all node IDs where the node’s kind equals the given string. Results are sorted by node ID for deterministic output.

§Arguments
  • snapshot_id - Only return data committed at or before this snapshot
  • kind - Kind string to match (case-sensitive)
§Returns

Vector of node IDs with matching kind

Source

fn query_nodes_by_name_pattern( &self, snapshot_id: SnapshotId, pattern: &str, ) -> Result<Vec<i64>, SqliteGraphError>

Query nodes by name pattern using glob matching

Returns all node IDs where the node’s label matches the glob pattern. Pattern syntax:

  • * matches any sequence of characters
  • ? matches exactly one character
§Arguments
  • snapshot_id - Only return data committed at or before this snapshot
  • pattern - Glob pattern to match against node labels
§Returns

Vector of node IDs with matching labels

Implementations on Foreign Types§

Source§

impl<B> GraphBackend for &B
where B: GraphBackend + ?Sized,

Reference implementation for GraphBackend trait that works with references.

Source§

fn insert_node(&self, node: NodeSpec) -> Result<i64, SqliteGraphError>

Source§

fn get_node( &self, snapshot_id: SnapshotId, id: i64, ) -> Result<GraphEntity, SqliteGraphError>

Source§

fn insert_edge(&self, edge: EdgeSpec) -> Result<i64, SqliteGraphError>

Source§

fn update_node( &self, node_id: i64, node: NodeSpec, ) -> Result<i64, SqliteGraphError>

Source§

fn delete_entity(&self, id: i64) -> Result<(), SqliteGraphError>

Source§

fn entity_ids(&self) -> Result<Vec<i64>, SqliteGraphError>

Source§

fn neighbors( &self, snapshot_id: SnapshotId, node: i64, query: NeighborQuery, ) -> Result<Vec<i64>, SqliteGraphError>

Source§

fn bfs( &self, snapshot_id: SnapshotId, start: i64, depth: u32, ) -> Result<Vec<i64>, SqliteGraphError>

Source§

fn shortest_path( &self, snapshot_id: SnapshotId, start: i64, end: i64, ) -> Result<Option<Vec<i64>>, SqliteGraphError>

Source§

fn node_degree( &self, snapshot_id: SnapshotId, node: i64, ) -> Result<(usize, usize), SqliteGraphError>

Source§

fn k_hop( &self, snapshot_id: SnapshotId, start: i64, depth: u32, direction: BackendDirection, ) -> Result<Vec<i64>, SqliteGraphError>

Source§

fn k_hop_filtered( &self, snapshot_id: SnapshotId, start: i64, depth: u32, direction: BackendDirection, allowed_edge_types: &[&str], ) -> Result<Vec<i64>, SqliteGraphError>

Source§

fn chain_query( &self, snapshot_id: SnapshotId, start: i64, chain: &[ChainStep], ) -> Result<Vec<i64>, SqliteGraphError>

Source§

fn checkpoint(&self) -> Result<(), SqliteGraphError>

Source§

fn flush(&self) -> Result<(), SqliteGraphError>

Source§

fn backup(&self, backup_dir: &Path) -> Result<BackupResult, SqliteGraphError>

Source§

fn snapshot_export( &self, export_dir: &Path, ) -> Result<SnapshotMetadata, SqliteGraphError>

Source§

fn snapshot_import( &self, import_dir: &Path, ) -> Result<ImportMetadata, SqliteGraphError>

Source§

fn query_nodes_by_kind( &self, snapshot_id: SnapshotId, kind: &str, ) -> Result<Vec<i64>, SqliteGraphError>

Source§

fn query_nodes_by_name_pattern( &self, snapshot_id: SnapshotId, pattern: &str, ) -> Result<Vec<i64>, SqliteGraphError>

Implementors§