1 package org.apache.torque.sql;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.List;
26
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.torque.TorqueException;
29 import org.apache.torque.criteria.FromElement;
30 import org.apache.torque.util.UniqueList;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class Query
48 {
49
50 public enum Type
51 {
52
53 SELECT,
54
55 UPDATE,
56
57 DELETE
58 }
59
60
61 private static final String SELECT = "SELECT ";
62
63 private static final String UPDATE = "UPDATE ";
64
65 private static final String DELETE_FROM = "DELETE FROM ";
66
67 private static final String FROM = " FROM ";
68
69 private static final String SET = " SET ";
70
71 private static final String WHERE = " WHERE ";
72
73 private static final String AND = " AND ";
74
75 private static final String ORDER_BY = " ORDER BY ";
76
77 private static final String GROUP_BY = " GROUP BY ";
78
79 private static final String HAVING = " HAVING ";
80
81 private static final String LIMIT = " LIMIT ";
82
83 private static final String OFFSET = " OFFSET ";
84
85 private static final String SET_ROWCOUNT = " SET ROWCOUNT ";
86
87
88
89
90 private final UniqueList<String> selectModifiers = new UniqueList<String>();
91
92
93
94
95
96
97 private final UniqueList<String> columns = new UniqueList<String>();
98
99
100
101
102
103
104 private final UniqueList<FromElement> fromClause = new UniqueList<FromElement>();
105
106
107
108
109 private final UniqueList<String> whereClause = new UniqueList<String>();
110
111
112
113
114
115 private final List<Object> whereClausePreparedStatementReplacements
116 = new ArrayList<Object>();
117
118
119 private final UniqueList<String> orderByColumns = new UniqueList<String>();
120
121
122 private final UniqueList<String> groupByColumns = new UniqueList<String>();
123
124
125 private String having;
126
127
128 private String limit;
129
130
131
132
133
134
135 private String preLimit;
136
137
138
139
140
141
142 private String postLimit;
143
144
145
146
147 private String offset;
148
149
150
151
152 private String rowcount;
153
154
155 private Type type = Type.SELECT;
156
157
158 private Integer fetchSize;
159
160
161
162
163
164
165
166 public UniqueList<String> getSelectModifiers()
167 {
168 return selectModifiers;
169 }
170
171
172
173
174
175
176
177 public UniqueList<String> getSelectClause()
178 {
179 return columns;
180 }
181
182
183
184
185
186
187
188 public UniqueList<FromElement> getFromClause()
189 {
190 return fromClause;
191 }
192
193
194
195
196
197
198
199
200 public UniqueList<String> getWhereClause()
201 {
202 return whereClause;
203 }
204
205
206
207
208
209
210
211
212
213
214 public List<Object> getWhereClausePreparedStatementReplacements()
215 {
216 return whereClausePreparedStatementReplacements;
217 }
218
219
220
221
222
223
224 public List<Object> getPreparedStatementReplacements()
225 {
226 ArrayList<Object> result = new ArrayList<Object>();
227 for (FromElement fromElement : fromClause)
228 {
229 result.addAll(fromElement.getPreparedStatementReplacements());
230 }
231 result.addAll(whereClausePreparedStatementReplacements);
232 return Collections.unmodifiableList(result);
233 }
234
235
236
237
238
239
240
241 public UniqueList<String> getOrderByClause()
242 {
243 return orderByColumns;
244 }
245
246
247
248
249
250
251
252 public UniqueList<String> getGroupByClause()
253 {
254 return groupByColumns;
255 }
256
257
258
259
260
261
262
263 public String getHaving()
264 {
265 return having;
266 }
267
268
269
270
271
272
273
274 public void setHaving(String having)
275 {
276 this.having = having;
277 }
278
279
280
281
282
283
284
285 public String getLimit()
286 {
287 return limit;
288 }
289
290
291
292
293
294
295
296 public void setLimit(String limit)
297 {
298 this.limit = limit;
299 }
300
301
302
303
304
305
306
307 public String getPreLimit()
308 {
309 return preLimit;
310 }
311
312
313
314
315
316
317
318 public void setPreLimit(String preLimit)
319 {
320 this.preLimit = preLimit;
321 }
322
323
324
325
326
327
328
329 public String getPostLimit()
330 {
331 return postLimit;
332 }
333
334
335
336
337
338
339
340 public void setPostLimit(String postLimit)
341 {
342 this.postLimit = postLimit;
343 }
344
345
346
347
348
349
350
351 public String getOffset()
352 {
353 return offset;
354 }
355
356
357
358
359
360
361
362 public void setOffset(String offset)
363 {
364 this.offset = offset;
365 }
366
367
368
369
370
371
372
373 public String getRowcount()
374 {
375 return rowcount;
376 }
377
378
379
380
381
382
383
384 public void setRowcount(String rowcount)
385 {
386 this.rowcount = rowcount;
387 }
388
389
390
391
392
393
394 public boolean hasLimit()
395 {
396 return ((preLimit != null)
397 || (postLimit != null)
398 || (limit != null));
399 }
400
401
402
403
404
405
406 public Type getType()
407 {
408 return type;
409 }
410
411
412
413
414
415
416
417
418 public void setType(Type type)
419 {
420 if (type == null)
421 {
422 throw new NullPointerException("type is null");
423 }
424 this.type = type;
425 }
426
427
428
429
430
431
432 public Integer getFetchSize()
433 {
434 return fetchSize;
435 }
436
437
438
439
440
441
442 public void setFetchSize(Integer fetchSize)
443 {
444 this.fetchSize = fetchSize;
445 }
446
447
448
449
450
451
452 public String toString()
453 {
454 return toStringBuilder(new StringBuilder()).toString();
455 }
456
457
458
459
460
461
462
463
464 public StringBuilder toStringBuilder(StringBuilder stringBuilder)
465 {
466 if (preLimit != null)
467 {
468 stringBuilder.append(preLimit);
469 }
470
471 if (rowcount != null)
472 {
473 stringBuilder.append(SET_ROWCOUNT)
474 .append(rowcount)
475 .append(" ");
476 }
477
478 if (Type.SELECT == type)
479 {
480 stringBuilder.append(SELECT)
481 .append(StringUtils.join(selectModifiers.iterator(), " "))
482 .append(StringUtils.join(columns.iterator(), ", "))
483 .append(FROM);
484 }
485 else if (Type.UPDATE == type)
486 {
487 stringBuilder.append(UPDATE);
488 }
489 else if (Type.DELETE == type)
490 {
491 stringBuilder.append(DELETE_FROM);
492 }
493
494 boolean first = true;
495 for (Iterator<FromElement> it = fromClause.iterator(); it.hasNext();)
496 {
497 FromElement fromElement = it.next();
498
499 if (!first && fromElement.getJoinCondition() == null)
500 {
501 stringBuilder.append(", ");
502 }
503 first = false;
504 stringBuilder.append(fromElement.toString());
505 }
506
507 if (Type.UPDATE == type)
508 {
509 stringBuilder.append(SET)
510 .append(StringUtils.join(columns, "=?, "));
511 if (!columns.isEmpty())
512 {
513 stringBuilder.append("=?");
514 }
515 }
516
517 if (!whereClause.isEmpty())
518 {
519 stringBuilder.append(WHERE)
520 .append(StringUtils.join(whereClause.iterator(), AND));
521 }
522 if (!groupByColumns.isEmpty())
523 {
524 stringBuilder.append(GROUP_BY)
525 .append(StringUtils.join(groupByColumns.iterator(), ", "));
526 }
527 if (having != null)
528 {
529 stringBuilder.append(HAVING)
530 .append(having);
531 }
532 if (!orderByColumns.isEmpty())
533 {
534 stringBuilder.append(ORDER_BY)
535 .append(StringUtils.join(orderByColumns.iterator(), ", "));
536 }
537 if (limit != null)
538 {
539 stringBuilder.append(LIMIT)
540 .append(limit);
541 }
542 if (offset != null)
543 {
544 stringBuilder.append(OFFSET)
545 .append(offset);
546 }
547 if (rowcount != null)
548 {
549 stringBuilder.append(SET_ROWCOUNT)
550 .append("0");
551 }
552 if (postLimit != null)
553 {
554 stringBuilder.append(postLimit);
555 }
556
557 return stringBuilder;
558 }
559
560
561
562
563
564
565
566
567 public String getDisplayString()
568 throws TorqueException
569 {
570 StringBuilder stringBuilder = new StringBuilder();
571 toStringBuilder(stringBuilder);
572 stringBuilder.append(" Replacements: [");
573 boolean first = true;
574 for (Object replacement : getPreparedStatementReplacements())
575 {
576 if (!first)
577 {
578 stringBuilder.append(",");
579 }
580 stringBuilder.append(replacement);
581 first = false;
582 }
583 stringBuilder.append("]");
584 return stringBuilder.toString();
585 }
586
587 }