18
18
package com .dangdang .ddframe .rdb .sharding .parser .result .router ;
19
19
20
20
import com .google .common .base .Joiner ;
21
+ import lombok .AccessLevel ;
21
22
import lombok .Getter ;
22
23
23
24
import java .io .IOException ;
24
- import java .util .Collection ;
25
+ import java .util .ArrayList ;
25
26
import java .util .HashMap ;
26
- import java .util .HashSet ;
27
27
import java .util .LinkedList ;
28
28
import java .util .List ;
29
29
import java .util .Map ;
35
35
*/
36
36
public class SQLBuilder implements Appendable {
37
37
38
+ private final List <SQLBuilder > derivedSQLBuilders = new ArrayList <>();
39
+
38
40
private final List <Object > segments ;
39
41
40
42
private final Map <String , StringToken > tokenMap ;
@@ -46,6 +48,11 @@ public class SQLBuilder implements Appendable {
46
48
@ Getter
47
49
private boolean changed ;
48
50
51
+ @ Getter (AccessLevel .PRIVATE )
52
+ private boolean removeDerivedSQLToken ;
53
+
54
+ private boolean hasExistedDerivedSQLToken ;
55
+
49
56
public SQLBuilder () {
50
57
segments = new LinkedList <>();
51
58
tokenMap = new HashMap <>();
@@ -83,24 +90,41 @@ public void appendToken(final String label, final String token) {
83
90
stringToken .label = label ;
84
91
stringToken .value = token ;
85
92
tokenMap .put (label , stringToken );
86
- stringToken .listeners .add (this );
87
93
}
88
94
stringToken .indices .add (segments .size ());
89
95
segments .add (stringToken );
90
96
currentSegment = new StringBuilder ();
91
97
segments .add (currentSegment );
92
98
}
93
-
99
+
94
100
/**
95
101
* 用实际的值替代占位符.
96
102
*
97
103
* @param label 占位符
98
104
* @param token 实际的值
99
105
*/
100
106
public void buildSQL (final String label , final String token ) {
101
- if (tokenMap .containsKey (label )) {
102
- tokenMap .get (label ).setValue (token );
107
+ buildSQL (label , token , false );
108
+ }
109
+
110
+ /**
111
+ * 用实际的值替代占位符,并可以标记该SQL是否为派生SQL.
112
+ *
113
+ * @param label 占位符
114
+ * @param token 实际的值
115
+ * @param isDerived 是否是派生的SQL
116
+ */
117
+ public void buildSQL (final String label , final String token , final boolean isDerived ) {
118
+ if (!tokenMap .containsKey (label )) {
119
+ return ;
120
+ }
121
+ if (isDerived ) {
122
+ hasExistedDerivedSQLToken = true ;
103
123
}
124
+ StringToken labelSQL = tokenMap .get (label );
125
+ labelSQL .isDerived = isDerived ;
126
+ labelSQL .value = token ;
127
+ changeState ();
104
128
}
105
129
106
130
/**
@@ -134,9 +158,7 @@ public SQLBuilder buildSQLWithNewToken() {
134
158
result .segments .set (index , each );
135
159
}
136
160
}
137
- for (StringToken each : result .tokenMap .values ()) {
138
- each .listeners .add (result );
139
- }
161
+ derivedSQLBuilders .add (result );
140
162
newTokenList .clear ();
141
163
return result ;
142
164
}
@@ -173,15 +195,28 @@ public Appendable append(final char c) throws IOException {
173
195
changeState ();
174
196
return this ;
175
197
}
176
-
198
+
177
199
private void changeState () {
178
200
changed = true ;
201
+ for (SQLBuilder each : derivedSQLBuilders ) {
202
+ each .changeState ();
203
+ }
179
204
}
180
205
181
206
private void clearState () {
182
207
changed = false ;
183
208
}
184
209
210
+ /**
211
+ * 移除衍生的SQL片段.
212
+ */
213
+ public void removeDerivedSQL () {
214
+ if (hasExistedDerivedSQLToken ) {
215
+ removeDerivedSQLToken = true ;
216
+ changeState ();
217
+ }
218
+ }
219
+
185
220
@ Override
186
221
public String toString () {
187
222
StringBuilder result = new StringBuilder ();
@@ -200,29 +235,26 @@ private class StringToken {
200
235
private String label ;
201
236
202
237
private String value ;
238
+
239
+ private boolean isDerived ;
203
240
204
241
private final List <Integer > indices = new LinkedList <>();
205
242
206
- private final Collection <SQLBuilder > listeners = new HashSet <>();
207
-
208
- public void setValue (final String value ) {
209
- this .value = value ;
210
- for (SQLBuilder each : listeners ) {
211
- each .changeState ();
212
- }
213
- }
214
-
215
243
String toToken () {
216
- if (null == value ) {
244
+ if (isEmptyValueOutput () ) {
217
245
return "" ;
218
246
}
219
247
Joiner joiner = Joiner .on ("" );
220
248
return label .equals (value ) ? joiner .join ("[Token(" , value , ")]" ) : joiner .join ("[" , label , "(" , value , ")]" );
221
249
}
222
250
251
+ private boolean isEmptyValueOutput () {
252
+ return null == value || isDerived && isRemoveDerivedSQLToken ();
253
+ }
254
+
223
255
@ Override
224
256
public String toString () {
225
- return null == value ? "" : value ;
257
+ return isEmptyValueOutput () ? "" : value ;
226
258
}
227
259
}
228
260
}
0 commit comments