1 package org.apache.torque.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.io.Writer;
24 import java.sql.Connection;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.sql.Statement;
28 import java.util.ArrayList;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Vector;
32
33 import org.apache.commons.collections.OrderedMapIterator;
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.apache.torque.Column;
37 import org.apache.torque.ColumnImpl;
38 import org.apache.torque.TorqueException;
39 import org.apache.torque.criteria.SqlEnum;
40 import org.apache.torque.om.mapper.ObjectListMapper;
41 import org.apache.torque.om.mapper.RecordMapper;
42 import org.apache.torque.sql.SqlBuilder;
43 import org.apache.torque.util.functions.SQLFunction;
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 public class SummaryHelper
93 {
94
95 private static Log logger = LogFactory.getLog(SummaryHelper.class);
96
97
98 private List<Column> groupByColumns;
99
100
101 private ListOrderedMapCI aggregates;
102
103 private boolean excludeExprColumns = false;
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 @Deprecated
124 public List<ListOrderedMapCI> summarize(Criteria crit)
125 throws TorqueException
126 {
127 return summarize(crit, (List<Class<?>>) null);
128 }
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 public List<ListOrderedMapCI> summarize(
144 org.apache.torque.criteria.Criteria crit)
145 throws TorqueException
146 {
147 return summarize(crit, (List<Class<?>>) null);
148 }
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 @Deprecated
171 public List<ListOrderedMapCI> summarize(
172 Criteria crit,
173 List<Class<?>> resultTypes)
174 throws TorqueException
175 {
176 Connection connection = null;
177 try
178 {
179 connection = Transaction.begin(crit.getDbName());
180 List<ListOrderedMapCI> result = summarize(crit, resultTypes, connection);
181 Transaction.commit(connection);
182 connection = null;
183 return result;
184 }
185 finally
186 {
187 if (connection != null)
188 {
189 Transaction.safeRollback(connection);
190 }
191 }
192 }
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209 public List<ListOrderedMapCI> summarize(
210 org.apache.torque.criteria.Criteria crit,
211 List<Class<?>> resultTypes)
212 throws TorqueException
213 {
214 Connection connection = null;
215 try
216 {
217 connection = Transaction.begin(crit.getDbName());
218 List<ListOrderedMapCI> result = summarize(crit, resultTypes, connection);
219 Transaction.commit(connection);
220 connection = null;
221 return result;
222 }
223 finally
224 {
225 if (connection != null)
226 {
227 Transaction.safeRollback(connection);
228 }
229 }
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251 @Deprecated
252 public List<ListOrderedMapCI> summarize(Criteria crit, Connection conn)
253 throws TorqueException
254 {
255 return summarize(crit, null, conn);
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272 public List<ListOrderedMapCI> summarize(
273 org.apache.torque.criteria.Criteria crit,
274 Connection conn)
275 throws TorqueException
276 {
277 return summarize(crit, null, conn);
278 }
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 @Deprecated
302 public List<ListOrderedMapCI> summarize(
303 Criteria crit,
304 List<Class<?>> resultTypes,
305 Connection conn)
306 throws TorqueException
307 {
308 Criteria c = buildCriteria(crit);
309 String query = SqlBuilder.buildQuery(c).toString();
310 RecordMapper<List<Object>> mapper = new ObjectListMapper(resultTypes);
311
312 Statement statement = null;
313 ResultSet resultSet = null;
314 List<List<Object>> rows = new ArrayList<List<Object>>();
315 try
316 {
317 statement = conn.createStatement();
318 long startTime = System.currentTimeMillis();
319 logger.debug("Executing query " + query);
320
321 resultSet = statement.executeQuery(query.toString());
322 long queryEndTime = System.currentTimeMillis();
323 logger.trace("query took " + (queryEndTime - startTime)
324 + " milliseconds");
325
326 while (resultSet.next())
327 {
328 List<Object> rowResult = mapper.processRow(resultSet, 0);
329 rows.add(rowResult);
330 }
331 long mappingEndTime = System.currentTimeMillis();
332 logger.trace("mapping took " + (mappingEndTime - queryEndTime)
333 + " milliseconds");
334 }
335 catch (SQLException e)
336 {
337 throw new TorqueException(e);
338 }
339 finally
340 {
341 if (resultSet != null)
342 {
343 try
344 {
345 resultSet.close();
346 }
347 catch (SQLException e)
348 {
349 logger.warn("error closing resultSet", e);
350 }
351 }
352 if (statement != null)
353 {
354 try
355 {
356 statement.close();
357 }
358 catch (SQLException e)
359 {
360 logger.warn("error closing statement", e);
361 }
362 }
363 }
364
365 List<ListOrderedMapCI> resultsList = new Vector<ListOrderedMapCI>(rows.size());
366 List<String> columnNames = new ArrayList<String>();
367 for (Column column : c.getSelectColumns())
368 {
369 columnNames.add(column.getColumnName());
370 }
371 columnNames.addAll(c.getAsColumns().keySet());
372 for (List<Object> row : rows)
373 {
374 ListOrderedMapCI recordMap = new ListOrderedMapCI();
375 for (int i = 0; i < row.size(); i++)
376 {
377 Object value = row.get(i);
378 String cName = columnNames.get(i);
379 if (cName == null || cName.equals(""))
380 {
381 if (excludeExprColumns())
382 {
383 continue;
384 }
385 cName = "Expr" + i;
386 }
387 recordMap.put(cName, value);
388 }
389 resultsList.add(recordMap);
390 }
391 return resultsList;
392 }
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410 public List<ListOrderedMapCI> summarize(
411 org.apache.torque.criteria.Criteria crit,
412 List<Class<?>> resultTypes,
413 Connection conn)
414 throws TorqueException
415 {
416 org.apache.torque.criteria.Criteria c = buildCriteria(crit);
417 String query = SqlBuilder.buildQuery(c).toString();
418 RecordMapper<List<Object>> mapper = new ObjectListMapper(resultTypes);
419
420 Statement statement = null;
421 ResultSet resultSet = null;
422 List<List<Object>> rows = new ArrayList<List<Object>>();
423 try
424 {
425 statement = conn.createStatement();
426 long startTime = System.currentTimeMillis();
427 logger.debug("Executing query " + query);
428
429 resultSet = statement.executeQuery(query.toString());
430 long queryEndTime = System.currentTimeMillis();
431 logger.trace("query took " + (queryEndTime - startTime)
432 + " milliseconds");
433
434 while (resultSet.next())
435 {
436 List<Object> rowResult = mapper.processRow(resultSet, 0);
437 rows.add(rowResult);
438 }
439 long mappingEndTime = System.currentTimeMillis();
440 logger.trace("mapping took " + (mappingEndTime - queryEndTime)
441 + " milliseconds");
442 }
443 catch (SQLException e)
444 {
445 throw new TorqueException(e);
446 }
447 finally
448 {
449 if (resultSet != null)
450 {
451 try
452 {
453 resultSet.close();
454 }
455 catch (SQLException e)
456 {
457 logger.warn("error closing resultSet", e);
458 }
459 }
460 if (statement != null)
461 {
462 try
463 {
464 statement.close();
465 }
466 catch (SQLException e)
467 {
468 logger.warn("error closing statement", e);
469 }
470 }
471 }
472
473 List<ListOrderedMapCI> resultsList = new Vector<ListOrderedMapCI>(rows.size());
474 List<String> columnNames = new ArrayList<String>();
475 for (Column column : c.getSelectColumns())
476 {
477 columnNames.add(column.getColumnName());
478 }
479 columnNames.addAll(c.getAsColumns().keySet());
480 for (List<Object> row : rows)
481 {
482 ListOrderedMapCI recordMap = new ListOrderedMapCI();
483 for (int i = 0; i < row.size(); i++)
484 {
485 Object value = row.get(i);
486 String cName = columnNames.get(i);
487 if (cName == null || cName.equals(""))
488 {
489 if (excludeExprColumns())
490 {
491 continue;
492 }
493 cName = "Expr" + i;
494 }
495 recordMap.put(cName, value);
496 }
497 resultsList.add(recordMap);
498 }
499 return resultsList;
500 }
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 @Deprecated
516 public Criteria buildCriteria(Criteria c) throws TorqueException
517 {
518 c.getSelectColumns().clear();
519 c.getGroupByColumns().clear();
520
521 UniqueList<String> criteriaSelectModifiers;
522 criteriaSelectModifiers = c.getSelectModifiers();
523
524 if (criteriaSelectModifiers != null
525 && criteriaSelectModifiers.size() > 0
526 && criteriaSelectModifiers.contains(SqlEnum.DISTINCT.toString()))
527 {
528 criteriaSelectModifiers.remove(SqlEnum.DISTINCT.toString());
529 }
530 c.setIgnoreCase(false);
531
532 List<Column> cols = getGroupByColumns();
533 boolean haveFromTable = !cols.isEmpty();
534 for (Column col : cols)
535 {
536 c.addGroupByColumn(col);
537 c.addSelectColumn(col);
538 }
539 if (haveFromTable)
540 {
541 logger.debug("From table defined by Group By Cols");
542 }
543
544
545 if (!haveFromTable && !c.isEmpty())
546 {
547 haveFromTable = true;
548 logger.debug("From table defined by a where clause");
549 }
550
551 ListOrderedMapCI cMap = getAggregates();
552 OrderedMapIterator iMap = cMap.orderedMapIterator();
553 while (iMap.hasNext())
554 {
555 String key = (String) iMap.next();
556 SQLFunction f = (SQLFunction) iMap.getValue();
557 Column col = f.getColumn();
558 c.addAsColumn(key, new ColumnImpl(
559 null,
560 col.getTableName(),
561 col.getColumnName(),
562 f.getSqlExpression()));
563 if (!haveFromTable)
564 {
565 {
566
567
568 c.add(col,
569 (col.getColumnName()
570 + "=" + col.getColumnName()),
571 SqlEnum.CUSTOM);
572 haveFromTable = true;
573
574 String table = col.getTableName();
575 logger.debug("From table, '" + table
576 + "', defined from aggregate column");
577 }
578 }
579 }
580 if (!haveFromTable)
581 {
582 throw new TorqueException(
583 "No FROM table defined by the GroupBy set, "
584 + "criteria.setAlias, or specified function column!");
585 }
586 return c;
587 }
588
589
590
591
592
593
594
595
596
597 public org.apache.torque.criteria.Criteria buildCriteria(
598 org.apache.torque.criteria.Criteria c) throws TorqueException
599 {
600 c.getSelectColumns().clear();
601 c.getGroupByColumns().clear();
602
603 UniqueList<String> criteriaSelectModifiers;
604 criteriaSelectModifiers = c.getSelectModifiers();
605
606 if (criteriaSelectModifiers != null
607 && criteriaSelectModifiers.size() > 0
608 && criteriaSelectModifiers.contains(SqlEnum.DISTINCT.toString()))
609 {
610 criteriaSelectModifiers.remove(SqlEnum.DISTINCT.toString());
611 }
612 c.setIgnoreCase(false);
613
614 List<Column> cols = getGroupByColumns();
615 boolean haveFromTable = !cols.isEmpty();
616 for (Column col : cols)
617 {
618 c.addGroupByColumn(col);
619 c.addSelectColumn(col);
620 }
621 if (haveFromTable)
622 {
623 logger.debug("From table defined by Group By Cols");
624 }
625
626
627 if (!haveFromTable && c.getTopLevelCriterion() != null)
628 {
629 haveFromTable = true;
630 logger.debug("From table defined by a where clause");
631 }
632
633 ListOrderedMapCI cMap = getAggregates();
634 OrderedMapIterator iMap = cMap.orderedMapIterator();
635 while (iMap.hasNext())
636 {
637 String key = (String) iMap.next();
638 SQLFunction f = (SQLFunction) iMap.getValue();
639 Column col = f.getColumn();
640 c.addAsColumn(key, new ColumnImpl(
641 null,
642 col.getTableName(),
643 col.getColumnName(),
644 f.getSqlExpression()));
645 if (!haveFromTable)
646 {
647 {
648
649
650 c.and(col,
651 (col.getColumnName()
652 + "=" + col.getColumnName()),
653 SqlEnum.CUSTOM);
654 haveFromTable = true;
655
656 String table = col.getTableName();
657 logger.debug("From table, '" + table
658 + "', defined from aggregate column");
659 }
660 }
661 }
662 if (!haveFromTable)
663 {
664 throw new TorqueException(
665 "No FROM table defined by the GroupBy set, "
666 + "criteria.setAlias, or specified function column!");
667 }
668 return c;
669 }
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685 public void addGroupBy(Column column)
686 {
687 getGroupByColumns().add(column);
688 }
689
690
691
692
693
694
695
696
697 public void addAggregate(String alias, SQLFunction function)
698 {
699 getAggregates().put(alias, function);
700 }
701
702
703
704
705
706 public void clear()
707 {
708 getGroupByColumns().clear();
709 getAggregates().clear();
710 setExcludeExprColumns(false);
711 }
712
713 public List<Column> getGroupByColumns()
714 {
715 if (groupByColumns == null)
716 {
717 groupByColumns = new Vector<Column>();
718 }
719 return groupByColumns;
720 }
721
722
723
724
725
726
727
728
729 public ListOrderedMapCI getAggregates()
730 {
731 if (aggregates == null)
732 {
733 aggregates = new ListOrderedMapCI();
734 }
735 return aggregates;
736 }
737
738
739
740
741
742
743
744
745
746
747
748 public void dumpResults(Writer out, List<?> results, boolean includeHeader)
749 throws IOException
750 {
751 Iterator<?> i = results.iterator();
752 boolean first = includeHeader;
753
754 while (i.hasNext())
755 {
756 ListOrderedMapCI rec = (ListOrderedMapCI) i.next();
757 OrderedMapIterator rI = rec.orderedMapIterator();
758 StringBuilder heading = new StringBuilder();
759 StringBuilder recString = new StringBuilder();
760 while (rI.hasNext())
761 {
762 String colId = (String) rI.next();
763 if (first)
764 {
765 heading.append("\"").append(colId).append("\"");
766 if (rI.hasNext())
767 {
768 heading.append(", ");
769 }
770 }
771 Object v = rI.getValue();
772 recString.append(v.toString());
773 if (rI.hasNext())
774 {
775 recString.append(", ");
776 }
777 }
778 if (first)
779 {
780 first = false;
781 out.write(heading.toString());
782 out.write("\n");
783 }
784 out.write(recString.toString());
785 out.write("\n");
786 }
787 }
788
789
790
791
792
793
794 public boolean excludeExprColumns()
795 {
796 return excludeExprColumns;
797 }
798
799
800
801
802
803
804
805
806
807
808
809 public void setExcludeExprColumns(boolean excludeExprColumns)
810 {
811 this.excludeExprColumns = excludeExprColumns;
812 }
813 }