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}