MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / graph_traverse_impl

Method graph_traverse_impl

nodedb-client/src/remote/client/graph.rs:20–92  ·  view source on GitHub ↗
(
        &self,
        collection: &str,
        start: &NodeId,
        depth: u8,
        edge_filter: Option<&EdgeFilter>,
    )

Source from the content-addressed store, hash-verified

18
19impl NodeDbRemote {
20 pub(super) async fn graph_traverse_impl(
21 &self,
22 collection: &str,
23 start: &NodeId,
24 depth: u8,
25 edge_filter: Option<&EdgeFilter>,
26 ) -> NodeDbResult<SubGraph> {
27 // Server-side DSL: `GRAPH TRAVERSE FROM '<start>' DEPTH <n>
28 // [LABEL '<l>']`. The Origin graph overlay is tenant-scoped
29 // (the dispatcher routes on `identity.tenant_id`), so the
30 // `collection` argument is accepted for trait symmetry with
31 // `graph_insert_edge` and Lite parity but is not threaded into
32 // the wire DSL — every edge in the tenant participates in the
33 // traversal regardless of which collection it was inserted
34 // into.
35 let _ = collection;
36 let label_clause = edge_filter
37 .and_then(|f| f.labels.first())
38 .map(|l| format!(" LABEL {}", quote_string_literal(l)))
39 .unwrap_or_default();
40 let start_lit = quote_string_literal(start.as_str());
41 let sql = format!("GRAPH TRAVERSE FROM {start_lit} DEPTH {depth}{label_clause}");
42
43 let (columns, rows) = self.simple_query_raw(&sql).await?;
44
45 if columns.len() == 1 && columns[0] == "result" {
46 if let Some(row) = rows.first()
47 && let Some(Value::String(json_text)) = row.first()
48 {
49 return parse_graph_traverse_json(json_text);
50 }
51 return Ok(SubGraph::empty());
52 }
53
54 // Structured: node_id, depth, edge_src, edge_dst, edge_label columns.
55 let mut nodes = Vec::new();
56 let mut edges = Vec::new();
57 let mut seen_nodes = std::collections::HashSet::new();
58
59 for row in &rows {
60 let node_id_str = row.first().and_then(|v| v.as_str()).unwrap_or("");
61 let d = row.get(1).and_then(|v| v.as_i64()).unwrap_or(0) as u8;
62
63 if seen_nodes.insert(node_id_str.to_string()) {
64 nodes.push(SubGraphNode {
65 id: NodeId::from_validated(node_id_str.to_owned()),
66 depth: d,
67 properties: HashMap::new(),
68 });
69 }
70
71 if let (Some(src), Some(dst), Some(label)) = (
72 row.get(2).and_then(|v| v.as_str()),
73 row.get(3).and_then(|v| v.as_str()),
74 row.get(4).and_then(|v| v.as_str()),
75 ) {
76 edges.push(SubGraphEdge {
77 id: EdgeId::try_first(

Callers 1

graph_traverseMethod · 0.45

Calls 13

quote_string_literalFunction · 0.85
firstMethod · 0.80
simple_query_rawMethod · 0.80
to_stringMethod · 0.80
emptyFunction · 0.50
as_strMethod · 0.45
lenMethod · 0.45
getMethod · 0.45
as_i64Method · 0.45
insertMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected