Skip to main content

nova_boot_graphdb/
wrapper.rs

1use crate::{error::GraphDbError, traits::GraphStore, types::*};
2use serde_json::Value as JsonValue;
3use std::sync::Arc;
4
5/// Convert a `GraphSubgraph` into JSON.
6pub fn graph_to_json(subgraph: &GraphSubgraph) -> Result<JsonValue, GraphDbError> {
7    serde_json::to_value(subgraph).map_err(|e| GraphDbError::Serialization(e.to_string()))
8}
9
10/// High-level graph database wrapper used by application handlers.
11///
12/// `NovaGraphDb` composes a backend `GraphStore` implementation and exposes a
13/// small, ergonomic API for executing queries, upserting nodes/edges, and
14/// traversing subgraphs. The struct is `Clone` and intended to be injected into
15/// request extensions by the plugin.
16#[derive(Clone)]
17pub struct NovaGraphDb {
18    store: Arc<dyn GraphStore>,
19}
20
21impl NovaGraphDb {
22    /// Construct a new wrapper around the provided store adapter.
23    pub fn new(store: Arc<dyn GraphStore>) -> Self {
24        Self { store }
25    }
26
27    /// Create an in-memory instance useful for testing and examples.
28    pub fn in_memory() -> Self {
29        Self::new(Arc::new(crate::memory::InMemoryGraphStore::default()))
30    }
31
32    /// Create a Neo4j-backed wrapper (adapter lives in `neo4j.rs`).
33    pub fn neo4j(
34        uri: impl Into<String>,
35        user: impl Into<String>,
36        password: impl Into<String>,
37    ) -> Self {
38        Self::new(Arc::new(crate::neo4j::Neo4jGraphStore::new(
39            uri, user, password,
40        )))
41    }
42
43    /// Create a SurrealDB-backed wrapper.
44    pub fn surreal(
45        endpoint: impl Into<String>,
46        namespace: impl Into<String>,
47        database: impl Into<String>,
48    ) -> Self {
49        Self::new(Arc::new(crate::surreal::SurrealGraphStore::new(
50            endpoint, namespace, database,
51        )))
52    }
53
54    /// Create a SurrealDB-backed wrapper with basic auth credentials.
55    pub fn surreal_with_auth(
56        endpoint: impl Into<String>,
57        namespace: impl Into<String>,
58        database: impl Into<String>,
59        username: impl Into<String>,
60        password: impl Into<String>,
61    ) -> Self {
62        Self::new(Arc::new(crate::surreal::SurrealGraphStore::new_with_auth(
63            endpoint, namespace, database, username, password,
64        )))
65    }
66
67    /// Execute a `GraphQuery` against the backend.
68    pub async fn execute(&self, query: GraphQuery) -> Result<JsonValue, GraphDbError> {
69        self.store.execute(query).await
70    }
71
72    /// Upsert a node.
73    pub async fn upsert_node(&self, node: GraphNode) -> Result<(), GraphDbError> {
74        self.store.upsert_node(node).await
75    }
76
77    /// Upsert an edge.
78    pub async fn upsert_edge(&self, edge: GraphEdge) -> Result<(), GraphDbError> {
79        self.store.upsert_edge(edge).await
80    }
81
82    /// Traverse the graph and return JSON representing the subgraph.
83    pub async fn traverse_json(
84        &self,
85        start: &str,
86        max_depth: usize,
87    ) -> Result<JsonValue, GraphDbError> {
88        let graph = self.store.traverse(start, max_depth).await?;
89        graph_to_json(&graph)
90    }
91}