rbatis_codegen/codegen/syntax_tree_pysql/
mod.rs

1/// this the py_sql syntax tree
2pub mod bind_node;
3pub mod break_node;
4pub mod choose_node;
5pub mod continue_node;
6pub mod error;
7pub mod foreach_node;
8pub mod if_node;
9pub mod otherwise_node;
10pub mod set_node;
11pub mod sql_node;
12pub mod string_node;
13pub mod trim_node;
14pub mod when_node;
15pub mod where_node;
16pub mod to_html;
17
18use crate::codegen::syntax_tree_pysql::bind_node::BindNode;
19use crate::codegen::syntax_tree_pysql::break_node::BreakNode;
20use crate::codegen::syntax_tree_pysql::choose_node::ChooseNode;
21use crate::codegen::syntax_tree_pysql::continue_node::ContinueNode;
22use crate::codegen::syntax_tree_pysql::foreach_node::ForEachNode;
23use crate::codegen::syntax_tree_pysql::if_node::IfNode;
24use crate::codegen::syntax_tree_pysql::otherwise_node::OtherwiseNode;
25use crate::codegen::syntax_tree_pysql::set_node::SetNode;
26use crate::codegen::syntax_tree_pysql::sql_node::SqlNode;
27use crate::codegen::syntax_tree_pysql::string_node::StringNode;
28use crate::codegen::syntax_tree_pysql::trim_node::TrimNode;
29use crate::codegen::syntax_tree_pysql::when_node::WhenNode;
30use crate::codegen::syntax_tree_pysql::where_node::WhereNode;
31
32/// PySQL Syntax Tree
33/// 
34/// The syntax of PySQL is based on Python-like indentation and line structure.
35/// Each node type below represents a different structure in the PySQL language.
36/// 
37/// Syntax Rules:
38/// 
39/// 1. Nodes that define a block end with a colon ':' and their children are indented.
40/// 
41/// 2. `NString` - Plain text or SQL fragments. Can preserve whitespace with backticks:
42/// ```sql
43/// SELECT * FROM users
44/// `  SELECT   column1,    column2   FROM table  `
45/// ```
46/// 
47/// 3. `NIf` - Conditional execution, similar to Python's if statement:
48/// ```pysql
49/// if condition:
50///   SQL fragment
51/// ```
52/// 
53/// 4. `NTrim` - Removes specified characters from start/end of the content:
54/// ```pysql
55/// trim ',':                   # Removes ',' from both start and end
56/// trim start=',',end=')':     # Removes ',' from start and ')' from end
57/// ```
58/// 
59/// 5. `NForEach` - Iterates over collections:
60/// ```pysql
61/// for item in items:          # Simple iteration
62///   #{item}
63/// for key,item in items:      # With key/index
64///   #{key}: #{item}
65/// ```
66/// 
67/// 6. `NChoose`/`NWhen`/`NOtherwise` - Switch-like structure:
68/// ```pysql
69/// choose:
70///   when condition1:
71///     SQL fragment 1
72///   when condition2:
73///     SQL fragment 2
74///   otherwise:                # Or use '_:'
75///     Default SQL fragment
76/// ```
77/// 
78/// 7. `NBind` - Variable binding:
79/// ```pysql
80/// bind name = 'value':        # Or use 'let name = value:'
81///   SQL using #{name}
82/// ```
83/// 
84/// 8. `NSet` - For UPDATE statements, handles comma separation.
85///    It can also define a collection to iterate over for generating SET clauses.
86/// ```pysql
87/// // Simple set for direct updates
88/// set:
89///   if name != null:
90///     name = #{name},
91///   if age != null:
92///     age = #{age}
93///
94/// // Set with collection to iterate (e.g., from a map or struct)
95/// // Assuming 'user_updates' is a map like {'name': 'new_name', 'status': 'active'}
96/// set collection="user_updates" skips="id,created_at" skip_null="true":
97///   // This will generate: name = #{user_updates.name}, status = #{user_updates.status}
98///   // 'id' and 'created_at' fields from 'user_updates' will be skipped.
99///   // If a value in 'user_updates' is null and skip_null is true, it will be skipped.
100/// ```
101/// 
102/// 9. `NWhere` - For WHERE clauses, handles AND/OR prefixes:
103/// ```pysql
104/// where:
105///   if id != null:
106///     AND id = #{id}
107///   if name != null:
108///     AND name = #{name}
109/// ```
110/// 
111/// 10. `NContinue`/`NBreak` - Loop control, must be inside a for loop:
112/// ```pysql
113/// for item in items:
114///   if item == null:
115///     break:
116///   if item == 0:
117///     continue:
118/// ```
119/// 
120/// 11. `NSql` - Reusable SQL fragments with an ID:
121/// ```pysql
122/// sql id='userColumns':
123///   id, name, age
124/// ```
125///     
126/// Note: All control nodes require a colon at the end, and their child content
127/// must be indented with more spaces than the parent node.
128#[derive(Clone, Debug, Eq, PartialEq)]
129pub enum NodeType {
130    NString(StringNode),
131    NIf(IfNode),
132    NTrim(TrimNode),
133    NForEach(ForEachNode),
134    NChoose(ChooseNode),
135    NOtherwise(OtherwiseNode),
136    NWhen(WhenNode),
137    NBind(BindNode),
138    NSet(SetNode),
139    NWhere(WhereNode),
140    NContinue(ContinueNode),
141    NBreak(BreakNode),
142    NSql(SqlNode),
143}
144
145/// the node name
146pub trait Name {
147    fn name() -> &'static str;
148}
149
150/// node default name
151pub trait DefaultName {
152    fn default_name() -> &'static str;
153}
154
155/// Convert syntax tree to HTML deconstruction
156pub trait ToHtml {
157    fn as_html(&self) -> String;
158}