py_sql/node/
foreach_node.rs1use crate::ast::RbatisAST;
2use crate::node::node::do_child_nodes;
3use crate::node::node_type::NodeType;
4use rexpr::ast::Node;
5use rexpr::runtime::RExprRuntime;
6use serde_json::{json, Value};
7#[derive(Clone, Debug)]
8pub struct ForEachNode {
9 pub childs: Vec<NodeType>,
10 pub collection: String,
11 pub index: String,
12 pub item: String,
13 pub get_collection_func: Node,
14}
15
16impl ForEachNode {
17 pub fn from(
18 runtime: &RExprRuntime,
19 source: &str,
20 express: &str,
21 childs: Vec<NodeType>,
22 ) -> Result<Self, crate::error::Error> {
23 if !express.contains("in ") {
24 return Err(crate::error::Error::from(
25 "[rbatis] parser express fail:".to_string() + source,
26 ));
27 }
28 let express = express[Self::name().len()..].trim();
29 let in_index = express.find("in ").unwrap();
30 let col = express[in_index + "in ".len()..].trim();
31 let mut item = express[..in_index].trim();
32 let mut index = "";
33 if item.contains(",") {
34 let items: Vec<&str> = item.split(",").collect();
35 if items.len() != 2 {
36 return Err(crate::error::Error::from(format!(
37 "[rbatis][py] parse fail 'for ,' must be 'for arg1,arg2 in ...',value:'{}'",
38 source
39 )));
40 }
41 index = items[0];
42 item = items[1];
43 }
44 return Ok(ForEachNode {
45 childs: childs,
46 collection: col.to_string(),
47 index: index.to_string(),
48 item: item.to_string(),
49 get_collection_func: runtime.parse(col)?,
50 });
51 }
52}
53
54impl RbatisAST for ForEachNode {
55 fn name() -> &'static str {
56 "for"
57 }
58 fn eval(
59 &self,
60 convert: &dyn crate::StringConvert,
61 env: &mut Value,
62 engine: &RExprRuntime,
63 arg_array: &mut Vec<Value>,
64 arg_sql: &mut String,
65 ) -> Result<serde_json::Value, crate::error::Error> {
66 let collection_value = self.get_collection_func.eval(env)?;
67 if collection_value.is_null() {
68 return Result::Ok(serde_json::Value::Null);
69 }
70 if collection_value.is_array() {
71 let collection = collection_value.as_array().unwrap();
72 let mut index = -1;
73 for item in collection {
74 index = index + 1;
75 env[&self.item] = item.clone();
76 env[&self.index] = serde_json::Value::Number(serde_json::Number::from(index));
77 do_child_nodes(convert, &self.childs, env, engine, arg_array, arg_sql)?;
78 match env {
79 serde_json::Value::Object(obj) => {
80 obj.remove(&self.item);
81 obj.remove(&self.index);
82 }
83 _ => {}
84 }
85 }
86 return Result::Ok(serde_json::Value::Null);
87 } else if collection_value.is_object() {
88 let collection = collection_value.as_object().unwrap();
89 let mut index = -1;
90 for (key, item) in collection {
91 index = index + 1;
92 env[&self.item] = item.clone();
93 env[&self.index] = serde_json::Value::String(key.to_string());
94 do_child_nodes(convert, &self.childs, env, engine, arg_array, arg_sql)?;
95 match env {
96 serde_json::Value::Object(obj) => {
97 obj.remove(&self.item);
98 obj.remove(&self.index);
99 }
100 _ => {}
101 }
102 }
103 return Result::Ok(serde_json::Value::Null);
104 } else {
105 return Result::Err(crate::error::Error::from(
106 "[rbatis] collection name:".to_owned()
107 + self.collection.as_str()
108 + " is not a array or object/map value!",
109 ));
110 }
111 }
112}