1use crate::error::GraphError;
6use std::collections::HashMap;
7
8#[derive(Debug, Clone)]
10pub struct CypherQuery {
11 pub cypher: String,
12 pub parameters: HashMap<String, serde_json::Value>,
13}
14
15impl CypherQuery {
16 pub fn new(cypher: &str) -> Self {
17 Self {
18 cypher: cypher.to_string(),
19 parameters: HashMap::new(),
20 }
21 }
22
23 pub fn with_params(cypher: &str, params: HashMap<String, serde_json::Value>) -> Self {
24 Self {
25 cypher: cypher.to_string(),
26 parameters: params,
27 }
28 }
29
30 pub fn add_param(&mut self, key: &str, value: serde_json::Value) {
31 self.parameters.insert(key.to_string(), value);
32 }
33}
34
35pub struct CypherQueryBuilder {
37 query: CypherQuery,
38}
39
40impl CypherQueryBuilder {
41 pub fn new(cypher: &str) -> Self {
42 Self {
43 query: CypherQuery::new(cypher),
44 }
45 }
46
47 pub fn param(mut self, key: &str, value: impl Into<serde_json::Value>) -> Self {
48 self.query.add_param(key, value.into());
49 self
50 }
51
52 pub fn build(self) -> CypherQuery {
53 self.query
54 }
55}
56
57#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
59pub struct GraphNode {
60 pub id: String,
61 pub labels: Vec<String>,
62 pub properties: serde_json::Value,
63}
64
65#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
67pub struct GraphRelationship {
68 pub id: String,
69 pub rel_type: String,
70 pub start_node_id: String,
71 pub end_node_id: String,
72 pub properties: serde_json::Value,
73}
74
75#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
77pub struct GraphPath {
78 pub nodes: Vec<GraphNode>,
79 pub relationships: Vec<GraphRelationship>,
80}
81
82#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
84#[serde(tag = "type")]
85pub enum GraphResult {
86 Node { node: GraphNode },
87 Relationship { relationship: GraphRelationship },
88 Path { path: GraphPath },
89 Scalar { value: serde_json::Value },
90}
91
92impl GraphResult {
93 pub fn as_node(&self) -> Option<&GraphNode> {
94 match self {
95 GraphResult::Node { node } => Some(node),
96 _ => None,
97 }
98 }
99
100 pub fn as_relationship(&self) -> Option<&GraphRelationship> {
101 match self {
102 GraphResult::Relationship { relationship } => Some(relationship),
103 _ => None,
104 }
105 }
106
107 pub fn as_scalar(&self) -> Option<&serde_json::Value> {
108 match self {
109 GraphResult::Scalar { value } => Some(value),
110 _ => None,
111 }
112 }
113}
114
115pub async fn execute_query(
117 conn: &crate::connection::GraphConnection,
118 query: &CypherQuery,
119) -> Result<Vec<GraphResult>, GraphError> {
120 if !conn.is_connected() {
121 return Err(GraphError::ConnectionError("not connected".into()));
122 }
123 if query.cypher.is_empty() {
124 return Err(GraphError::QueryError("empty query".into()));
125 }
126 Ok(vec![])
127}