Skip to main content

sz_orm_graph/
query.rs

1//! # Query — Cypher 查询构造与执行
2//!
3//! CypherQuery + CypherQueryBuilder + GraphResult
4
5use crate::error::GraphError;
6use std::collections::HashMap;
7
8/// Cypher 查询
9#[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
35/// Cypher 查询构造器(链式)
36pub 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/// 图节点
58#[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/// 图关系
66#[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/// 图路径
76#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
77pub struct GraphPath {
78    pub nodes: Vec<GraphNode>,
79    pub relationships: Vec<GraphRelationship>,
80}
81
82/// 图查询结果
83#[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
115/// 查询执行器
116pub 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}