/
TraceObject.java
371 lines (329 loc) · 9.77 KB
/
TraceObject.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
/*
* Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.lealone.common.trace;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Map;
import org.lealone.common.exceptions.DbException;
import org.lealone.common.util.StringUtils;
/**
* The base class for objects that can print trace information about themselves.
*
* @author H2 Group
* @author zhh
*/
public class TraceObject {
/**
* The trace type id for connections.
*/
protected static final int CONNECTION = 0;
/**
* The trace type id for statements.
*/
protected static final int STATEMENT = 1;
/**
* The trace type id for prepared statements.
*/
protected static final int PREPARED_STATEMENT = 2;
/**
* The trace type id for callable statements.
*/
protected static final int CALLABLE_STATEMENT = 3;
/**
* The trace type id for result sets.
*/
protected static final int RESULT_SET = 4;
/**
* The trace type id for result set meta data objects.
*/
protected static final int RESULT_SET_META_DATA = 5;
/**
* The trace type id for parameter meta data objects.
*/
protected static final int PARAMETER_META_DATA = 6;
/**
* The trace type id for database meta data objects.
*/
protected static final int DATABASE_META_DATA = 7;
/**
* The trace type id for savepoint objects.
*/
protected static final int SAVEPOINT = 8;
/**
* The trace type id for blobs.
*/
protected static final int BLOB = 9;
/**
* The trace type id for clobs.
*/
protected static final int CLOB = 10;
/**
* The trace type id for array objects.
*/
protected static final int ARRAY = 11;
/**
* The trace type id for data sources.
*/
protected static final int DATA_SOURCE = 12;
private static final int LAST = DATA_SOURCE + 1;
private static final int[] ID = new int[LAST];
private static final String[] PREFIX = { "conn", "stat", "prep", "call", "rs", "rsMeta", "pMeta", "dbMeta", "sp",
"blob", "clob", "ar", "ds" };
/**
* The trace module used by this object.
*/
protected Trace trace;
private int type;
private int id;
/**
* Set the options to use when writing trace message.
*
* @param trace the trace object
* @param type the trace object type
* @param id the trace object id
*/
protected void setTrace(Trace trace, int type, int id) {
this.trace = trace;
this.type = type;
this.id = id;
}
/**
* INTERNAL
*/
public int getTraceId() {
return id;
}
/**
* INTERNAL
*/
public String getTraceObjectName() {
return PREFIX[type] + id;
}
/**
* Get the next trace object id for this object type.
*
* @param type the object type
* @return the new trace object id
*/
protected static int getNextTraceId(int type) {
return ID[type]++;
}
/**
* Check if the debug trace level is enabled.
*
* @return true if it is
*/
protected boolean isDebugEnabled() {
return trace.isDebugEnabled();
}
/**
* Check if info trace level is enabled.
*
* @return true if it is
*/
protected boolean isInfoEnabled() {
return trace.isInfoEnabled();
}
/**
* Write trace information as an assignment in the form
* className prefixId = objectName.value.
*
* @param className the class name of the result
* @param newType the prefix type
* @param newId the trace object id of the created object
* @param value the value to assign this new object to
*/
protected void debugCodeAssign(String className, int newType, int newId, String value) {
if (trace.isDebugEnabled()) {
trace.debugCode(className + " " + PREFIX[newType] + newId + " = " + getTraceObjectName() + "." + value
+ ";");
}
}
/**
* Write trace information as a method call in the form
* objectName.methodName().
*
* @param methodName the method name
*/
protected void debugCodeCall(String methodName) {
if (trace.isDebugEnabled()) {
trace.debugCode(getTraceObjectName() + "." + methodName + "();");
}
}
/**
* Write trace information as a method call in the form
* objectName.methodName(param) where the parameter is formatted as a long
* value.
*
* @param methodName the method name
* @param param one single long parameter
*/
protected void debugCodeCall(String methodName, long param) {
if (trace.isDebugEnabled()) {
trace.debugCode(getTraceObjectName() + "." + methodName + "(" + param + ");");
}
}
/**
* Write trace information as a method call in the form
* objectName.methodName(param) where the parameter is formatted as a Java
* string.
*
* @param methodName the method name
* @param param one single string parameter
*/
protected void debugCodeCall(String methodName, String param) {
if (trace.isDebugEnabled()) {
trace.debugCode(getTraceObjectName() + "." + methodName + "(" + quote(param) + ");");
}
}
/**
* Write trace information in the form objectName.text.
*
* @param text the trace text
*/
protected void debugCode(String text) {
if (trace.isDebugEnabled()) {
trace.debugCode(getTraceObjectName() + "." + text);
}
}
/**
* Format a string as a Java string literal.
*
* @param s the string to convert
* @return the Java string literal
*/
protected static String quote(String s) {
return StringUtils.quoteJavaString(s);
}
/**
* Format a time to the Java source code that represents this object.
*
* @param x the time to convert
* @return the Java source code
*/
protected static String quoteTime(java.sql.Time x) {
if (x == null) {
return "null";
}
return "Time.valueOf(\"" + x.toString() + "\")";
}
/**
* Format a timestamp to the Java source code that represents this object.
*
* @param x the timestamp to convert
* @return the Java source code
*/
protected static String quoteTimestamp(java.sql.Timestamp x) {
if (x == null) {
return "null";
}
return "Timestamp.valueOf(\"" + x.toString() + "\")";
}
/**
* Format a date to the Java source code that represents this object.
*
* @param x the date to convert
* @return the Java source code
*/
protected static String quoteDate(java.sql.Date x) {
if (x == null) {
return "null";
}
return "Date.valueOf(\"" + x.toString() + "\")";
}
/**
* Format a big decimal to the Java source code that represents this object.
*
* @param x the big decimal to convert
* @return the Java source code
*/
protected static String quoteBigDecimal(BigDecimal x) {
if (x == null) {
return "null";
}
return "new BigDecimal(\"" + x.toString() + "\")";
}
/**
* Format a byte array to the Java source code that represents this object.
*
* @param x the byte array to convert
* @return the Java source code
*/
protected static String quoteBytes(byte[] x) {
if (x == null) {
return "null";
}
return "org.lealone.util.StringUtils.convertHexToBytes(\"" + StringUtils.convertBytesToHex(x) + "\")";
}
/**
* Format a string array to the Java source code that represents this
* object.
*
* @param s the string array to convert
* @return the Java source code
*/
protected static String quoteArray(String[] s) {
return StringUtils.quoteJavaStringArray(s);
}
/**
* Format an int array to the Java source code that represents this object.
*
* @param s the int array to convert
* @return the Java source code
*/
protected static String quoteIntArray(int[] s) {
return StringUtils.quoteJavaIntArray(s);
}
/**
* Format a map to the Java source code that represents this object.
*
* @param map the map to convert
* @return the Java source code
*/
protected static String quoteMap(Map<String, Class<?>> map) {
if (map == null) {
return "null";
}
if (map.isEmpty()) {
return "new Map()";
}
return "new Map() /* " + map.toString() + " */";
}
/**
* Log an exception and convert it to a SQL exception if required.
*
* @param ex the exception
* @return the SQL exception object
*/
protected SQLException logAndConvert(Exception ex) {
SQLException e = DbException.toSQLException(ex);
if (trace == null) {
DbException.traceThrowable(e);
} else {
int errorCode = e.getErrorCode();
if (errorCode >= 23000 && errorCode < 24000) {
trace.info(e, "exception");
} else {
trace.error(e, "exception");
}
}
return e;
}
/**
* Get and throw a SQL exception meaning this feature is not supported.
*
* @param message the message
* @return never returns normally
* @throws SQLException the exception
*/
protected SQLException unsupported(String message) throws SQLException {
try {
throw DbException.getUnsupportedException(message);
} catch (Exception e) {
return logAndConvert(e);
}
}
}