use std::sync::Arc;
use sqry_core::graph::unified::node::NodeId;
use sqry_db::QueryDb;
use sqry_db::queries::RelationKey;
pub(crate) use sqry_db::queries::dispatch::{mcp_callees_query, mcp_callers_query};
#[allow(unused_imports)]
pub(crate) use sqry_db::queries::dispatch::{
mcp_exports_query, mcp_imports_query, mcp_references_query,
};
#[cfg(test)]
use sqry_db::queries::dispatch::make_query_db;
use crate::tools::RelationType;
#[must_use]
#[allow(dead_code)]
pub(crate) fn relation_endpoints_for_mcp(
db: &QueryDb,
relation: RelationType,
symbol: &str,
) -> Arc<Vec<NodeId>> {
let key = RelationKey::exact(symbol);
match relation {
RelationType::Callers => mcp_callers_query(db, &key),
RelationType::Callees => mcp_callees_query(db, &key),
RelationType::Imports => mcp_imports_query(db, &key),
RelationType::Exports => mcp_exports_query(db, &key),
RelationType::Returns => Arc::new(Vec::new()),
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::Path;
use std::sync::Arc;
use sqry_core::graph::unified::concurrent::{CodeGraph, GraphSnapshot};
use sqry_core::graph::unified::edge::EdgeKind;
use sqry_core::graph::unified::node::NodeKind;
use sqry_core::graph::unified::storage::NodeEntry;
fn build_caller_graph() -> (Arc<GraphSnapshot>, NodeId, NodeId, NodeId) {
let mut graph = CodeGraph::new();
let file_id = graph.files_mut().register(Path::new("lib.rs")).unwrap();
let main_name = graph.strings_mut().intern("main").unwrap();
let helper_name = graph.strings_mut().intern("helper").unwrap();
let isolated_name = graph.strings_mut().intern("isolated").unwrap();
let main_id = graph
.nodes_mut()
.alloc(
NodeEntry::new(NodeKind::Function, main_name, file_id)
.with_qualified_name(main_name),
)
.unwrap();
let helper_id = graph
.nodes_mut()
.alloc(
NodeEntry::new(NodeKind::Function, helper_name, file_id)
.with_qualified_name(helper_name),
)
.unwrap();
let isolated_id = graph
.nodes_mut()
.alloc(
NodeEntry::new(NodeKind::Function, isolated_name, file_id)
.with_qualified_name(isolated_name),
)
.unwrap();
graph.edges_mut().add_edge(
main_id,
helper_id,
EdgeKind::Calls {
argument_count: 0,
is_async: false,
},
file_id,
);
(Arc::new(graph.snapshot()), main_id, helper_id, isolated_id)
}
#[test]
fn mcp_dispatch_routes_relation_type_to_correct_query() {
let (snapshot, main_id, helper_id, _isolated_id) = build_caller_graph();
let db = make_query_db(snapshot);
let callers_set = relation_endpoints_for_mcp(&db, RelationType::Callers, "helper");
assert!(callers_set.contains(&main_id));
let callees_set = relation_endpoints_for_mcp(&db, RelationType::Callees, "main");
assert!(callees_set.contains(&helper_id));
let returns_set = relation_endpoints_for_mcp(&db, RelationType::Returns, "anything");
assert!(returns_set.is_empty(), "Returns is not modelled as an edge");
}
}