1
2
3
4
5
6
7 package org.astrogrid.datacenter.queriers.sql;
8
9 import java.io.BufferedWriter;
10 import java.io.IOException;
11 import java.io.PrintWriter;
12 import java.io.Writer;
13 import java.sql.ResultSet;
14 import java.sql.ResultSetMetaData;
15 import java.sql.SQLException;
16 import org.apache.commons.logging.Log;
17 import org.astrogrid.config.SimpleConfig;
18 import org.astrogrid.datacenter.queriers.Querier;
19 import org.astrogrid.datacenter.queriers.QueryResults;
20 import org.astrogrid.datacenter.queriers.status.QuerierProcessingResults;
21 import org.astrogrid.datacenter.queriers.status.QuerierStatus;
22 import org.astrogrid.datacenter.query.Query;
23 import org.astrogrid.datacenter.returns.ReturnTable;
24
25 /***
26 * Implementation of <tt>QueryResults</tt> as a wrapper around a <tt>ResultSet</tt>
27 *
28 * <p>Can be used (I believe) for any
29 * SQL/JDBC query results.
30 *
31 * @author M Hill
32 */
33
34 public class SqlResults extends QueryResults {
35
36 protected ResultSet sqlResults;
37 protected static final Log log = org.apache.commons.logging.LogFactory.getLog(SqlResults.class);
38
39
40
41 /*** Key used to define maximum number of rows allowed - defaults to 200, -1 = any */
42
43
44 /***
45 * Construct this wrapper around the given JDBC/SQL ResultSet. We don't
46 * know how big this result set will be, so it's likely we'll need a workspace
47 * for any temporary files created when doing conversions
48 */
49 public SqlResults(Querier parentQuerier, ResultSet givenResults)
50 {
51 super(parentQuerier);
52 this.sqlResults = givenResults;
53
54 }
55
56 /*** Returns number of rows */
57 public int getCount() {
58 return -1;
59
60
61
62
63
64
65
66
67
68
69 }
70
71 /***
72 * Converts results to VOTable to given writer. All done by hand :-(
73 */
74 public void writeVotable(Writer out, QuerierProcessingResults statusToUpdate) throws IOException
75 {
76 assert (out != null);
77
78 long localLimit = SimpleConfig.getSingleton().getInt(Query.MAX_RETURN_KEY, -1);
79 long queryLimit = querier.getQuery().getLimit();
80
81
82 try
83 {
84 PrintWriter printOut = new PrintWriter(new BufferedWriter(out));
85
86
87 printOut.println("<VOTABLE version='1.0'>");
88
89
90
91
92
93
94
95 printOut.println("<RESOURCE>");
96
97
98
99
100
101
102
103 printOut.println("<TABLE>");
104
105
106 ResultSetMetaData metadata = sqlResults.getMetaData();
107
108 int cols = metadata.getColumnCount();
109 for (int i=1;i<=cols;i++)
110 {
111 String tablename = "";
112
113
114
115
116
117 printOut.println("<FIELD ID='"+tablename+metadata.getColumnName(i)+"' "
118 +" name='"+metadata.getColumnLabel(i)+"' "
119 +RdbmsResourceGenerator.getVotableTypeAttr(sqlResults.getMetaData().getColumnType(i))
120 +" ucd='"+getUcdFor(metadata.getColumnName(i))+"' "
121 +"/>");
122 }
123
124 printOut.flush();
125 printOut.println("<DATA>");
126 printOut.println("<TABLEDATA>");
127
128 String note = statusToUpdate.getMessage();
129
130
131 int row = 0;
132 statusToUpdate.newProgress("Processing Row", getCount());
133 while (sqlResults.next() && ((queryLimit == -1) || (row<=queryLimit)))
134 {
135 row++;
136 statusToUpdate.setProgress(row);
137
138 printOut.print(" <TR> ");
139 for (int i=1;i<=cols;i++)
140 {
141 printOut.print("<TD>"+sqlResults.getString(i)+"</TD>");
142 }
143 printOut.println(" </TR>");
144
145 if ((localLimit!=-1) && (row>localLimit)) {
146
147 statusToUpdate.addDetail("Results limited to "+localLimit+" rows by datacenter");
148 log.warn("Limiting returned results to "+localLimit);
149 break;
150 }
151
152 if (querier.getStatus().getStage().equals(QuerierStatus.ABORTED)) {
153 printOut.println(" ------------------ Querier Aborted ----------------- ");
154 return;
155 }
156 printOut.flush();
157 }
158 statusToUpdate.addDetail(row+" rows sent");
159 statusToUpdate.clearProgress();
160
161 printOut.println("</TABLEDATA>");
162 printOut.println("</DATA>");
163
164 printOut.println("</TABLE>");
165
166 printOut.println("</RESOURCE>");
167
168 printOut.println("</VOTABLE>");
169
170 printOut.flush();
171 }
172 catch (SQLException sqle)
173 {
174 log.error("Could not convert results",sqle);
175 throw new IOException(sqle+", converting to VOtable");
176 }
177
178
179 }
180
181 /***
182 * Converts results to HTML to given writer
183 */
184 public void writeHtml(Writer out, QuerierProcessingResults statusToUpdate) throws IOException
185 {
186 assert (out != null);
187
188 long localLimit = SimpleConfig.getSingleton().getInt(Query.MAX_RETURN_KEY, -1);
189 long queryLimit = querier.getQuery().getLimit();
190
191 try
192 {
193 PrintWriter printOut = new PrintWriter(new BufferedWriter(out));
194
195 printOut.println("<HTML>");
196
197 printOut.println("<HEAD>");
198 printOut.println("<TITLE>Query Results</TITLE>");
199 printOut.println("</HEAD>");
200
201 printOut.println("<BODY>");
202
203 printOut.println("<TABLE>");
204
205
206 ResultSetMetaData metadata = sqlResults.getMetaData();
207
208 int cols = metadata.getColumnCount();
209 printOut.println("</TR>");
210 for (int i=1;i<=cols;i++)
211 {
212 printOut.print("<TH>"+metadata.getColumnName(i)+"</TH>");
213 }
214 printOut.println("</TR>");
215
216 int row = 0;
217 statusToUpdate.newProgress("Processing Row", getCount());
218 while (sqlResults.next() && ((queryLimit == -1) || (row<=queryLimit)))
219 {
220 row++;
221 statusToUpdate.setProgress(row);
222
223 printOut.println("<TR>");
224 for (int i=1;i<=cols;i++)
225 {
226 printOut.println("<TD>"+sqlResults.getString(i)+"</TD>");
227 }
228 printOut.println("</TR>");
229
230
231
232 if ((localLimit!=-1) && (row>localLimit)) {
233 statusToUpdate.addDetail("Results limited to "+localLimit+" rows by datacenter");
234 log.warn("Limiting returned results to "+localLimit);
235 break;
236 }
237
238 if (querier.getStatus().getStage().equals(QuerierStatus.ABORTED)) {
239 printOut.println(" ------------------ Querier Aborted ----------------- ");
240 return;
241 }
242 }
243 statusToUpdate.addDetail(row+" rows sent");
244 statusToUpdate.clearProgress();
245
246 printOut.println("</TABLE>");
247 printOut.println("</BODY>");
248
249 printOut.println("</HTML>");
250 printOut.flush();
251 }
252 catch (SQLException sqle)
253 {
254 log.error("Could not convert results",sqle);
255 throw new IOException(sqle+", converting to Html");
256 }
257
258
259 }
260
261 /***
262 * Converts results to CSV to given writer
263 */
264 public void writeCSV(Writer out, QuerierProcessingResults statusToUpdate) throws IOException
265 {
266 long maxAllowed = SimpleConfig.getSingleton().getInt(Query.MAX_RETURN_KEY, -1);
267 long queryLimit = querier.getQuery().getLimit();
268
269 try
270 {
271 PrintWriter printOut = new PrintWriter(new BufferedWriter(out));
272
273
274 ResultSetMetaData metadata = sqlResults.getMetaData();
275
276 int cols = metadata.getColumnCount();
277 for (int i=1;i<=cols;i++)
278 {
279 printOut.print(
280 if (i<cols) { printOut.print(", "); }
281 }
282
283 printOut.println();
284
285 String note = statusToUpdate.getMessage();
286
287 int row = 0;
288 int maxRow = getCount();
289 String ofMax = " of "+maxRow;
290 if (maxRow == -1) ofMax = "";
291 while (sqlResults.next() && ((queryLimit == -1) || (row<=queryLimit)))
292 {
293 row++;
294 statusToUpdate.setMessage(note+"\nProcessing Row "+row+ofMax);
295
296 for (int c=1;c<=cols;c++)
297 {
298 printOut.print(sqlResults.getString(c));
299 if (c<cols) { printOut.print(", "); }
300 }
301 printOut.println();
302
303 if ((maxAllowed!=-1) && (row>maxAllowed)) {
304 statusToUpdate.addDetail("Results limited to "+maxAllowed+" rows by datacenter");
305 log.warn("Limiting returned results to "+maxAllowed);
306 printOut.println("------------- Results Limited to "+maxAllowed+" ------------");
307 break;
308 }
309
310 if (querier.getStatus().getStage().equals(QuerierStatus.ABORTED)) {
311 printOut.println(" ------------------ Querier Aborted ----------------- ");
312 return;
313 }
314 }
315
316 statusToUpdate.addDetail(row+" rows sent");
317 statusToUpdate.clearProgress();
318
319 printOut.flush();
320 }
321 catch (SQLException sqle)
322 {
323 log.error("Could not convert results",sqle);
324 throw new IOException(sqle+", converting to CSV");
325 }
326 }
327
328 /*** Native form is/will be webrowresults (or whatever it's called)
329 */
330 public void writeRaw(Writer out, QuerierProcessingResults statusToUpdate) throws IOException
331 {
332 throw new UnsupportedOperationException("Raw (WebRowXml) not yet supported");
333 }
334
335 public String getUcdFor(String columnName)
336 {
337 return "unknown";
338 }
339
340 /*** Returns the formats that this plugin can provide. Doesn't provide Raw */
341 public static String[] getFormats() {
342 return new String[] { ReturnTable.VOTABLE, ReturnTable.CSV, ReturnTable.HTML } ;
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
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519