@@ -14,29 +14,67 @@ use xml::reader::*;
1414/// 回车
1515const CRLF : [ u8 ; 1 ] = [ 0x0a ] ;
1616
17+ pub enum Mode {
18+ Statement ,
19+ Select ,
20+ Insert ,
21+ Update ,
22+ Delete ,
23+ SqlPart ,
24+ }
25+
26+ impl Mode {
27+ pub fn from ( name : & str ) -> Self {
28+ match name {
29+ "statement" => Mode :: Statement ,
30+ "select" => Mode :: Select ,
31+ "insert" => Mode :: Insert ,
32+ "update" => Mode :: Update ,
33+ "delete" => Mode :: Delete ,
34+ "sql" => Mode :: SqlPart ,
35+ _ => panic ! ( "unkown mode" ) ,
36+ }
37+ }
38+ }
39+
40+ pub struct SqlStatement {
41+ pub mode : Mode ,
42+ pub id : String ,
43+ pub sql : String ,
44+ }
45+
46+ impl SqlStatement {
47+ pub fn new ( mode : Mode , id : String , sql : String ) -> Self {
48+ return SqlStatement { mode, id, sql } ;
49+ }
50+ }
51+
1752/// 解析过程中数据
1853pub struct XmlParsedState {
54+ /// 过程中变化
1955 /// 是否在语句中
2056 pub in_statement : bool ,
21- /// 是否在 `sql` 块中
22- pub in_sql : bool ,
23- /// `sql` 索引
24- pub sql_idx : i32 ,
25- /// `sql` 临时存储,以索引为键,`sql` 为值
26- pub include_temp_sqls : HashMap < i32 , String > ,
27- /// `sql` 临时存储,以 `sql` 的 `id` 为键,索引为值
28- pub include_temp_sqls_ids : HashMap < String , i32 > ,
57+ /// 当前ID
58+ pub current_id : String ,
59+ /// 过程中累计
60+ /// 语句集
61+ pub statements : Vec < SqlStatement > ,
62+ /// 语句集
63+ pub sql_part_map : HashMap < String , SqlStatement > ,
64+ /// 过程中不再变化
65+ /// 文件名
66+ pub filename : String ,
2967}
3068
3169impl XmlParsedState {
3270 /// 构建器,构造工厂
3371 pub fn new ( ) -> Self {
3472 return XmlParsedState {
3573 in_statement : false ,
36- in_sql : false ,
37- sql_idx : 0 ,
38- include_temp_sqls : HashMap :: new ( ) ,
39- include_temp_sqls_ids : HashMap :: new ( ) ,
74+ current_id : String :: from ( "" ) ,
75+ statements : Vec :: new ( ) ,
76+ sql_part_map : HashMap :: new ( ) ,
77+ filename : String :: from ( "" ) ,
4078 } ;
4179 }
4280}
@@ -81,23 +119,24 @@ pub trait Parser {
81119 let parser = EventReader :: new ( buf) ;
82120 let mut builder = StringBuilder :: new ( ) ;
83121 let mut state = XmlParsedState :: new ( ) ;
122+ state. filename = filename. clone ( ) ;
84123 for e in parser {
85124 match e {
86125 Ok ( XmlEvent :: StartElement {
87126 name, attributes, ..
88127 } ) => {
89- self . parse_start_element ( name, attributes, & mut builder, & mut state, sql_store ) ;
128+ self . parse_start_element ( name, attributes, & mut builder, & mut state) ;
90129 }
91130 Ok ( XmlEvent :: EndElement { name } ) => {
92- self . parse_end_element ( name, & mut builder, & mut state, sql_store ) ;
131+ self . parse_end_element ( name, & mut builder, & mut state) ;
93132 }
94133 Ok ( XmlEvent :: CData ( s) ) => {
95- if state. in_statement || state . in_sql {
134+ if state. in_statement {
96135 builder. append ( s) ;
97136 }
98137 }
99138 Ok ( XmlEvent :: Characters ( s) ) => {
100- if state. in_statement || state . in_sql {
139+ if state. in_statement {
101140 builder. append ( s) ;
102141 }
103142 }
@@ -108,6 +147,8 @@ pub trait Parser {
108147 _ => { }
109148 }
110149 }
150+ info ! ( "{}" , state. filename) ;
151+ self . replace_and_fill ( sql_store, & state. statements , & state. sql_part_map ) ;
111152 }
112153
113154 fn parse_start_element (
@@ -116,34 +157,54 @@ pub trait Parser {
116157 attributes : Vec < OwnedAttribute > ,
117158 builder : & mut StringBuilder ,
118159 state : & mut XmlParsedState ,
119- sql_store : & mut Vec < String > ,
120160 ) ;
121161
122162 fn parse_end_element (
123163 & self ,
124164 name : OwnedName ,
125165 builder : & mut StringBuilder ,
126166 state : & mut XmlParsedState ,
127- sql_store : & mut Vec < String > ,
128167 ) {
129168 let element_name = name. local_name . as_str ( ) . to_ascii_lowercase ( ) ;
130169 if parse_helper:: match_statement ( & element_name) {
131- let sql = parse_helper:: replace_included_sql (
132- builder,
133- & state. include_temp_sqls ,
134- & state. include_temp_sqls_ids ,
135- ) ;
136- self . clear_and_push ( & sql, sql_store) ;
170+ let mode = Mode :: from ( element_name. as_str ( ) ) ;
171+ match mode {
172+ Mode :: SqlPart => {
173+ let sql_stat =
174+ SqlStatement :: new ( mode, state. current_id . clone ( ) , builder. to_string ( ) ) ;
175+ state
176+ . sql_part_map
177+ . insert ( state. current_id . clone ( ) , sql_stat) ;
178+ }
179+ _ => {
180+ let sql_stat =
181+ SqlStatement :: new ( mode, state. current_id . clone ( ) , builder. to_string ( ) ) ;
182+ state. statements . push ( sql_stat) ;
183+ }
184+ }
137185 state. in_statement = false ;
138- } else if element_name == "sql" {
139- state
140- . include_temp_sqls
141- . insert ( state. sql_idx , builder. to_string ( ) ) ;
142- state. sql_idx += 1 ;
186+ state. current_id = String :: from ( "" ) ;
143187 builder. clear ( ) ;
144- state. in_sql = false ;
145188 }
146189 }
190+
191+ fn replace_and_fill (
192+ & self ,
193+ sql_store : & mut Vec < String > ,
194+ statements : & Vec < SqlStatement > ,
195+ sql_part_map : & HashMap < String , SqlStatement > ,
196+ ) {
197+ for sql in statements {
198+ sql_store. push ( "--- " . to_string ( ) + & sql. id ) ;
199+ let mut sql_stat = sql. sql . clone ( ) ;
200+ for sql_part in sql_part_map {
201+ sql_stat =
202+ parse_helper:: replace_included_sql ( & sql_stat, & sql_part. 0 , & sql_part. 1 . sql ) ;
203+ }
204+ self . clear_and_push ( & sql_stat, sql_store) ;
205+ }
206+ }
207+
147208 fn clear_and_push ( & self , origin_sql : & String , sql_store : & mut Vec < String > ) ;
148209
149210 fn save ( & self , output_dir : & String , sql_store : Vec < String > ) {
0 commit comments