KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > tools > JDBCDisplayUtil


1 /*
2
3    Derby - Class org.apache.derby.tools.JDBCDisplayUtil
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.tools;
23
24 import java.io.PrintStream JavaDoc;
25 import java.io.PrintWriter JavaDoc;
26 import java.io.File JavaDoc;
27 import java.io.FileNotFoundException JavaDoc;
28 import java.io.IOException JavaDoc;
29
30 import java.sql.Connection JavaDoc;
31 import java.sql.SQLException JavaDoc;
32 import java.sql.SQLWarning JavaDoc;
33 import java.sql.Statement JavaDoc;
34 import java.sql.PreparedStatement JavaDoc;
35 import java.sql.ResultSet JavaDoc;
36 import java.sql.ResultSetMetaData JavaDoc;
37 import java.sql.Types JavaDoc;
38
39 import java.util.Properties JavaDoc;
40 import java.util.Enumeration JavaDoc;
41 import java.util.Vector JavaDoc;
42
43 import org.apache.derby.iapi.tools.i18n.LocalizedResource;
44
45 import org.apache.derby.impl.tools.ij.ijException;
46
47 /**
48     
49     This class contains utility methods for displaying JDBC objects and results.
50     
51     <p>
52     All of the methods are static. The output stream
53     to write to is always passed in, along with the
54     JDBC objects to display.
55
56     @author ames
57  */

58 public class JDBCDisplayUtil {
59
60     // used to control display
61
static final private int MINWIDTH = 4;
62     static private int maxWidth = 128;
63     static public boolean showSelectCount = false;
64
65     static {
66         // initialize the locale support functions to default value of JVM
67
LocalizedResource.getInstance();
68     }
69
70     //-----------------------------------------------------------------
71
// Methods for displaying and checking errors
72

73     /**
74         Print information about the exception to the given PrintWriter.
75         For non-SQLExceptions, does a stack trace. For SQLExceptions,
76         print a standard error message and walk the list, if any.
77
78         @param out the place to write to
79         @param e the exception to display
80      */

81     static public void ShowException(PrintWriter JavaDoc out, Throwable JavaDoc e) {
82         if (e == null) return;
83
84         if (e instanceof SQLException JavaDoc)
85             ShowSQLException(out, (SQLException JavaDoc)e);
86         else
87             e.printStackTrace(out);
88     }
89
90     /**
91         Print information about the SQL exception to the given PrintWriter.
92         Walk the list of exceptions, if any.
93
94         @param out the place to write to
95         @param e the exception to display
96      */

97     static public void ShowSQLException(PrintWriter JavaDoc out, SQLException JavaDoc e) {
98         String JavaDoc errorCode;
99
100         if (Boolean.getBoolean("ij.showErrorCode")) {
101             errorCode = LocalizedResource.getMessage("UT_Error0", LocalizedResource.getNumber(e.getErrorCode()));
102         }
103         else {
104             errorCode = "";
105         }
106
107         while (e!=null) {
108             String JavaDoc p1 = mapNull(e.getSQLState(),LocalizedResource.getMessage("UT_NoSqlst"));
109             String JavaDoc p2 = mapNull(e.getMessage(),LocalizedResource.getMessage("UT_NoMessa"));
110             out.println(LocalizedResource.getMessage("UT_Error012", p1, p2,errorCode));
111             doTrace(out, e);
112             e=e.getNextException();
113         }
114     }
115
116     /**
117         Print information about the SQL warnings for the connection
118         to the given PrintWriter.
119         Walks the list of exceptions, if any.
120
121         @param out the place to write to
122         @param theConnection the connection that may have warnings.
123      */

124     static public void ShowWarnings(PrintWriter JavaDoc out, Connection JavaDoc theConnection) {
125         try {
126         // GET CONNECTION WARNINGS
127
SQLWarning JavaDoc warning = null;
128
129         if (theConnection != null) {
130             ShowWarnings(out, theConnection.getWarnings());
131         }
132
133         if (theConnection != null) {
134             theConnection.clearWarnings();
135         }
136         } catch (SQLException JavaDoc e) {
137             ShowSQLException(out, e);
138         }
139     } // ShowWarnings
140

141     /**
142         @param out the place to write to
143         @param warning the SQLWarning
144     */

145     static public void ShowWarnings(PrintWriter JavaDoc out, SQLWarning JavaDoc warning) {
146         while (warning != null) {
147             String JavaDoc p1 = mapNull(warning.getSQLState(),LocalizedResource.getMessage("UT_NoSqlst_7"));
148             String JavaDoc p2 = mapNull(warning.getMessage(),LocalizedResource.getMessage("UT_NoMessa_8"));
149             out.println(LocalizedResource.getMessage("UT_Warni01", p1, p2));
150             warning = warning.getNextWarning();
151         }
152     }
153
154     /**
155         Print information about the SQL warnings for the ResultSet
156         to the given PrintWriter.
157         Walk the list of exceptions, if any.
158     
159         @param out the place to write to
160         @param rs the ResultSet that may have warnings on it
161      */

162     static public void ShowWarnings(PrintWriter JavaDoc out, ResultSet JavaDoc rs) {
163         try {
164         // GET RESULTSET WARNINGS
165
SQLWarning JavaDoc warning = null;
166
167         if (rs != null) {
168             ShowWarnings(out, rs.getWarnings());
169         }
170
171         if (rs != null) {
172             rs.clearWarnings();
173         }
174         } catch (SQLException JavaDoc e) {
175             ShowSQLException(out, e);
176         }
177     } // ShowResultSetWarnings
178

179     /**
180         Print information about the SQL warnings for the Statement
181         to the given PrintWriter.
182         Walks the list of exceptions, if any.
183
184         @param out the place to write to
185         @param s the Statement that may have warnings on it
186      */

187     static public void ShowWarnings(PrintWriter JavaDoc out, Statement JavaDoc s)
188     {
189         try {
190         // GET STATEMENT WARNINGS
191
SQLWarning JavaDoc warning = null;
192
193         if (s != null) {
194             ShowWarnings(out, s.getWarnings());
195         }
196
197         if (s != null) {
198             s.clearWarnings();
199         }
200         } catch (SQLException JavaDoc e) {
201             ShowSQLException(out, e);
202         }
203     } // ShowStatementWarnings
204

205     //-----------------------------------------------------------------
206
// Methods for displaying and checking results
207

208     // REMIND: make this configurable...
209
static final private int MAX_RETRIES = 0;
210
211     /**
212         Pretty-print the results of a statement that has been executed.
213         If it is a select, gathers and prints the results. Display
214         partial results up to the first error.
215         If it is not a SELECT, determine if rows were involved or not,
216         and print the appropriate message.
217
218         @param out the place to write to
219         @param stmt the Statement to display
220         @param conn the Connection against which the statement was executed
221
222         @exception SQLException on JDBC access failure
223      */

224     static public void DisplayResults(PrintWriter JavaDoc out, Statement JavaDoc stmt, Connection JavaDoc conn )
225         throws SQLException JavaDoc
226     {
227         indent_DisplayResults( out, stmt, conn, 0, null, null);
228     }
229
230     static private void indent_DisplayResults
231     (PrintWriter JavaDoc out, Statement JavaDoc stmt, Connection JavaDoc conn, int indentLevel,
232      int[] displayColumns, int[] displayColumnWidths)
233         throws SQLException JavaDoc {
234
235         checkNotNull(stmt, "Statement");
236
237         ResultSet JavaDoc rs = stmt.getResultSet();
238         if (rs != null) {
239             indent_DisplayResults(out, rs, conn, indentLevel,
240                                   displayColumns, displayColumnWidths);
241             rs.close(); // let the result set go away
242
}
243         else {
244             DisplayUpdateCount(out,stmt.getUpdateCount(), indentLevel);
245         }
246
247         ShowWarnings(out,stmt);
248     } // DisplayResults
249

250     /**
251         @param out the place to write to
252         @param count the update count to display
253         @param indentLevel number of tab stops to indent line
254      */

255     static void DisplayUpdateCount(PrintWriter JavaDoc out, int count, int indentLevel ) {
256         if (count == 1) {
257             indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_1RowInserUpdatDelet"));
258         }
259         else if (count >= 0) {
260             indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_0RowsInserUpdatDelet", LocalizedResource.getNumber(count)));
261         }
262         else {
263             indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_StateExecu"));
264         }
265     }
266
267     /**
268         Calculates column display widths from the default widths of the
269         result set.
270      */

271     static private int[] getColumnDisplayWidths(ResultSetMetaData JavaDoc rsmd, int[] dispColumns,
272                                                 boolean localizedOutput)
273         throws SQLException JavaDoc {
274         int count = (dispColumns == null) ? rsmd.getColumnCount() : dispColumns.length;
275         int[] widths = new int[count];
276
277         for(int i=0; i<count; i++) {
278             int colnum = (dispColumns == null) ? (i + 1) : dispColumns[i];
279             int dispsize = localizedOutput
280                 ? LocalizedResource.getInstance().getColumnDisplaySize(rsmd, colnum)
281                 : rsmd.getColumnDisplaySize(colnum);
282             widths[i] = Math.min(maxWidth,
283                 Math.max((rsmd.isNullable(colnum) == ResultSetMetaData.columnNoNulls)?
284                 0 : MINWIDTH, dispsize));
285         }
286         return widths;
287     }
288
289
290     /**
291         @param out the place to write to
292         @param rs the ResultSet to display
293         @param conn the Connection against which the ResultSet was retrieved
294         @param displayColumns Column numbers to display, or null if all
295         @param displayColumnWidths Column widths, in characters, if displayColumns is specified.
296
297         @exception SQLException on JDBC access failure
298      */

299     static public void DisplayResults(PrintWriter JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn,
300                                       int[] displayColumns, int[] displayColumnWidths)
301         throws SQLException JavaDoc
302     {
303         indent_DisplayResults( out, rs, conn, 0, displayColumns,
304                                displayColumnWidths);
305     }
306
307     static private void indent_DisplayResults
308     (PrintWriter JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn, int indentLevel,
309      int[] displayColumns, int[] displayColumnWidths)
310         throws SQLException JavaDoc {
311         ResultSetMetaData JavaDoc rsmd = rs.getMetaData();
312         checkNotNull(rsmd, "ResultSetMetaData");
313         Vector JavaDoc nestedResults;
314     int numberOfRowsSelected = 0;
315
316         // autocommit must be off or the nested cursors
317
// are closed when the outer statement completes.
318
if (!conn.getAutoCommit())
319             nestedResults = new Vector JavaDoc();
320         else
321             nestedResults = null;
322
323         if(displayColumnWidths == null)
324             displayColumnWidths = getColumnDisplayWidths(rsmd, displayColumns,true);
325         
326         int len = indent_DisplayBanner(out,rsmd, indentLevel, displayColumns,
327                                        displayColumnWidths);
328
329         // When displaying rows, keep going past errors
330
// unless/until the maximum # of errors is reached.
331
boolean doNext = true;
332         int retry = 0;
333         while (doNext) {
334             try {
335                 doNext = rs.next();
336                 if (doNext) {
337
338                     DisplayRow(out, rs, rsmd, len, nestedResults, conn,
339                                indentLevel, displayColumns,
340                                displayColumnWidths);
341                     ShowWarnings(out, rs);
342                     numberOfRowsSelected++;
343                 }
344             } catch (SQLException JavaDoc e) {
345                 // REVISIT: might want to check the exception
346
// and for some, not bother with the retry.
347
if (++retry > MAX_RETRIES)
348                     throw e;
349                 else
350                     ShowSQLException(out, e);
351             }
352         }
353         if (showSelectCount == true) {
354            if (numberOfRowsSelected == 1) {
355                out.println();
356                indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_1RowSelec"));
357            } else if (numberOfRowsSelected >= 0) {
358                out.println();
359                indentedPrintLine( out, indentLevel,
360             LocalizedResource.getMessage("UT_0RowsSelec", LocalizedResource.getNumber(numberOfRowsSelected)));
361            }
362         }
363
364         DisplayNestedResults(out, nestedResults, conn, indentLevel );
365         nestedResults = null;
366     }
367
368     /**
369         @param out the place to write to
370         @param nr the vector of results
371         @param conn the Connection against which the ResultSet was retrieved
372         @param indentLevel number of tab stops to indent line
373
374         @exception SQLException thrown on access error
375      */

376     static private void DisplayNestedResults(PrintWriter JavaDoc out, Vector JavaDoc nr, Connection JavaDoc conn, int indentLevel )
377         throws SQLException JavaDoc {
378
379         if (nr == null) return;
380
381         String JavaDoc b=LocalizedResource.getMessage("UT_JDBCDisplayUtil_16");
382         String JavaDoc oldString="0";
383
384         for (int i=0; i < nr.size(); i++) {
385             LocalizedResource.OutputWriter().println();
386
387             //just too clever to get the extra +s
388
String JavaDoc t = Integer.toString(i);
389             if (t.length() > oldString.length()) {
390                 oldString = t;
391                 b=b+LocalizedResource.getMessage("UT_JDBCDisplayUtil_17");
392             }
393
394             LocalizedResource.OutputWriter().println(b);
395             LocalizedResource.OutputWriter().println(LocalizedResource.getMessage("UT_Resul0", LocalizedResource.getNumber(i)));
396             LocalizedResource.OutputWriter().println(b);
397             indent_DisplayResults(out, (ResultSet JavaDoc) nr.elementAt(i), conn,
398                                   indentLevel, null, null);
399         }
400     }
401
402     /**
403         Fetch the next row of the result set, and if it
404         exists format and display a banner and the row.
405
406         @param out the place to write to
407         @param rs the ResultSet in use
408         @param conn the Connection against which the ResultSet was retrieved
409
410         @exception SQLException on JDBC access failure
411      */

412     static public void DisplayNextRow(PrintWriter JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn )
413         throws SQLException JavaDoc
414     {
415         indent_DisplayNextRow( out, rs, conn, 0, null, (rs == null) ? null
416                                : getColumnDisplayWidths(rs.getMetaData(), null, true));
417     }
418
419     static private void indent_DisplayNextRow(PrintWriter JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn, int indentLevel,
420                                               int[] displayColumns, int[] displayColumnWidths )
421         throws SQLException JavaDoc {
422
423         Vector JavaDoc nestedResults;
424
425         // autocommit must be off or the nested cursors
426
// are closed when the outer statement completes.
427
if (!conn.getAutoCommit())
428             nestedResults = new Vector JavaDoc();
429         else
430             nestedResults = null;
431
432         checkNotNull(rs, "ResultSet");
433
434         ResultSetMetaData JavaDoc rsmd = rs.getMetaData();
435         checkNotNull(rsmd, "ResultSetMetaData");
436
437         // Only print stuff out if there is a row to be had.
438
if (rs.next()) {
439             int rowLen = indent_DisplayBanner(out, rsmd, indentLevel, displayColumns, displayColumnWidths);
440             DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel,
441                        null, null );
442         }
443         else {
444             indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow"));
445         }
446
447         ShowWarnings(out, rs);
448
449         DisplayNestedResults(out, nestedResults, conn, indentLevel );
450         nestedResults = null;
451
452     } // DisplayNextRow
453

454     /**
455         Display the current row of the result set along with
456         a banner. Assume the result set is on a row.
457
458         @param out the place to write to
459         @param rs the ResultSet in use
460         @param conn the Connection against which the ResultSet was retrieved
461
462         @exception SQLException on JDBC access failure
463      */

464     static public void DisplayCurrentRow(PrintWriter JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn )
465         throws SQLException JavaDoc
466     {
467         indent_DisplayCurrentRow( out, rs, conn, 0, null, (rs == null) ? null
468                                   : getColumnDisplayWidths(rs.getMetaData(), null, true) );
469     }
470
471     static private void indent_DisplayCurrentRow(PrintWriter JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn,
472                                                  int indentLevel, int[] displayColumns, int[] displayColumnWidths )
473         throws SQLException JavaDoc {
474
475         Vector JavaDoc nestedResults;
476
477         if (rs == null) {
478             indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow_19"));
479             return;
480         }
481
482         // autocommit must be off or the nested cursors
483
// are closed when the outer statement completes.
484
if (!conn.getAutoCommit())
485             nestedResults = new Vector JavaDoc();
486         else
487             nestedResults = null;
488
489         ResultSetMetaData JavaDoc rsmd = rs.getMetaData();
490         checkNotNull(rsmd, "ResultSetMetaData");
491
492         int rowLen = indent_DisplayBanner(out, rsmd, indentLevel, displayColumns, displayColumnWidths);
493         DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel,
494                    displayColumns, displayColumnWidths );
495
496         ShowWarnings(out, rs);
497
498         DisplayNestedResults(out, nestedResults, conn, indentLevel );
499         nestedResults = null;
500
501     } // DisplayNextRow
502

503     /**
504         Print a banner containing the column labels separated with '|'s
505         and a line of '-'s. Each field is as wide as the display
506         width reported by the metadata.
507
508         @param out the place to write to
509         @param rsmd the ResultSetMetaData to use
510
511         @exception SQLException on JDBC access failure
512      */

513     static public int DisplayBanner(PrintWriter JavaDoc out, ResultSetMetaData JavaDoc rsmd )
514         throws SQLException JavaDoc
515     {
516         return indent_DisplayBanner( out, rsmd, 0, null,
517                                      getColumnDisplayWidths(rsmd, null, true) );
518     }
519
520     static private int indent_DisplayBanner(PrintWriter JavaDoc out, ResultSetMetaData JavaDoc rsmd, int indentLevel,
521                                             int[] displayColumns, int[] displayColumnWidths )
522         throws SQLException JavaDoc {
523
524         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
525
526         int numCols = displayColumnWidths.length;
527         int rowLen;
528
529         // do some precalculation so the buffer is allocated only once
530
// buffer is twice as long as the display length plus one for a newline
531
rowLen = (numCols - 1); // for the column separators
532
for (int i=1; i <= numCols; i++)
533             rowLen += displayColumnWidths[i-1];
534         buf.ensureCapacity(rowLen);
535
536         // get column header info
537
// truncate it to the column display width
538
// add a bar between each item.
539
for (int i=1; i <= numCols; i++) {
540             int colnum = displayColumns==null ? i : displayColumns[i-1];
541
542             if (i>1)
543                 buf.append('|');
544
545             String JavaDoc s = rsmd.getColumnLabel(colnum);
546
547             int w = displayColumnWidths[i-1];
548
549             if (s.length() < w) {
550                 
551                 buf.append(s);
552
553                 // try to paste on big chunks of space at a time.
554
int k = w - s.length();
555                 for (; k >= 64; k -= 64)
556                     buf.append(
557           " ");
558                 for (; k >= 16; k -= 16)
559                     buf.append(" ");
560                 for (; k >= 4; k -= 4)
561                     buf.append(" ");
562                 for (; k > 0; k--)
563                     buf.append(' ');
564             }
565             else if (s.length() > w) {
566                 if (w > 1)
567                     buf.append(s.substring(0,w-1));
568                 if (w > 0)
569                     buf.append('&');
570             }
571             else {
572                 buf.append(s);
573             }
574         }
575
576         buf.setLength(Math.min(rowLen, 1024));
577         indentedPrintLine( out, indentLevel, buf);
578
579         // now print a row of '-'s
580
for (int i=0; i<Math.min(rowLen, 1024); i++)
581             buf.setCharAt(i, '-');
582         indentedPrintLine( out, indentLevel, buf);
583
584         buf = null;
585
586         return rowLen;
587     } // DisplayBanner
588

589     /**
590         Print one row of a result set, padding each field to the
591         display width and separating them with '|'s
592
593         @param out the place to write to
594         @param rs the ResultSet to use
595         @param rsmd the ResultSetMetaData to use
596         @param rowLen
597         @param nestedResults
598         @param conn
599         @param indentLevel number of tab stops to indent line
600         @param displayColumns A list of column numbers to display
601         @param displayColumnWidths If displayColumns is set, the width of
602                                 columns to display, in characters.
603
604         @exception SQLException thrown on JDBC access failure
605      */

606     static private void DisplayRow(PrintWriter JavaDoc out, ResultSet JavaDoc rs, ResultSetMetaData JavaDoc rsmd, int rowLen, Vector JavaDoc nestedResults, Connection JavaDoc conn, int indentLevel,
607                                    int[] displayColumns, int[] displayColumnWidths )
608         throws SQLException JavaDoc
609     {
610         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
611         buf.ensureCapacity(rowLen);
612
613         int numCols = displayColumnWidths.length;
614         int i;
615
616         // get column header info
617
// truncate it to the column display width
618
// add a bar between each item.
619
for (i=1; i <= numCols; i++){
620             int colnum = displayColumns==null ? i : displayColumns[i-1];
621             if (i>1)
622                 buf.append('|');
623
624             String JavaDoc s;
625             switch (rsmd.getColumnType(colnum)) {
626             default:
627                 s = LocalizedResource.getInstance().getLocalizedString(rs, rsmd, colnum );
628                 break;
629             case org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT:
630             case Types.OTHER:
631             {
632                 Object JavaDoc o = rs.getObject(colnum);
633                 if (o == null) { s = "NULL"; }
634                 else if (o instanceof ResultSet JavaDoc && nestedResults != null)
635                 {
636                     s = LocalizedResource.getMessage("UT_Resul0_20", LocalizedResource.getNumber(nestedResults.size()));
637                     nestedResults.addElement(o);
638                 }
639                 else
640                 {
641                     try {
642                         s = rs.getString(colnum);
643                     } catch (SQLException JavaDoc se) {
644                         // oops, they don't support refetching the column
645
s = o.toString();
646                     }
647                 }
648             }
649             break;
650             }
651             if (s==null) s = "NULL";
652
653             int w = displayColumnWidths[i-1];
654             if (s.length() < w) {
655                 StringBuffer JavaDoc fullS = new StringBuffer JavaDoc(s);
656                 fullS.ensureCapacity(w);
657                 for (int k=s.length(); k<w; k++)
658                     fullS.append(' ');
659                 s = fullS.toString();
660             }
661             else if (s.length() > w)
662                 // add the & marker to know it got cut off
663
s = s.substring(0,w-1)+"&";
664
665             buf.append(s);
666         }
667         indentedPrintLine( out, indentLevel, buf);
668
669     } // DisplayRow
670

671     /**
672         Check if an object is null, and if it is, throw an exception
673         with an informative parameter about what was null.
674         The exception is a run-time exception that is internal to ij.
675
676         @param o the object to test
677         @param what the information to include in the error if it is null
678      */

679     public static void checkNotNull(Object JavaDoc o, String JavaDoc what) {
680         if (o == null) {
681             throw ijException.objectWasNull(what);
682         }
683     } // checkNotNull
684

685     /**
686         Map the string to the value if it is null.
687
688         @param s the string to test for null
689         @param nullValue the value to use if s is null
690
691         @return if s is non-null, s; else nullValue.
692      */

693     static public String JavaDoc mapNull(String JavaDoc s, String JavaDoc nullValue) {
694         if (s==null) return nullValue;
695         return s;
696     }
697
698     /**
699         If the property ij.exceptionTrace is true, display the stack
700         trace to the print stream. Otherwise, do nothing.
701
702         @param out the output stream to write to
703         @param e the exception to display
704      */

705     static public void doTrace(PrintWriter JavaDoc out, Exception JavaDoc e) {
706         if (Boolean.getBoolean("ij.exceptionTrace")) {
707             e.printStackTrace(out);
708             out.flush();
709         }
710     }
711
712     static public void setMaxDisplayWidth(int maxDisplayWidth) {
713         maxWidth = maxDisplayWidth;
714     }
715
716     static private void indentedPrintLine( PrintWriter JavaDoc out, int indentLevel, String JavaDoc text )
717     {
718         indent( out, indentLevel );
719         out.println( text );
720     }
721
722     static private void indentedPrintLine( PrintWriter JavaDoc out, int indentLevel, StringBuffer JavaDoc text )
723     {
724         indent( out, indentLevel );
725         out.println( text );
726     }
727
728     static private void indent( PrintWriter JavaDoc out, int indentLevel )
729     {
730         for ( int ictr = 0; ictr < indentLevel; ictr++ ) { out.print( " " ); }
731     }
732
733     // ================
734

735     static public void ShowException(PrintStream JavaDoc out, Throwable JavaDoc e) {
736         if (e == null) return;
737
738         if (e instanceof SQLException JavaDoc)
739             ShowSQLException(out, (SQLException JavaDoc)e);
740         else
741             e.printStackTrace(out);
742     }
743
744     static public void ShowSQLException(PrintStream JavaDoc out, SQLException JavaDoc e) {
745         String JavaDoc errorCode;
746
747         if (Boolean.getBoolean("ij.showErrorCode")) {
748             errorCode = " (errorCode = " + e.getErrorCode() + ")";
749         }
750         else {
751             errorCode = "";
752         }
753
754         while (e!=null) {
755             out.println("ERROR "+mapNull(e.getSQLState(),"(no SQLState)")+": "+
756                  mapNull(e.getMessage(),"(no message)")+errorCode);
757             doTrace(out, e);
758             e=e.getNextException();
759         }
760     }
761
762     static public void ShowWarnings(PrintStream JavaDoc out, Connection JavaDoc theConnection) {
763         try {
764         // GET CONNECTION WARNINGS
765
SQLWarning JavaDoc warning = null;
766
767         if (theConnection != null) {
768             ShowWarnings(out, theConnection.getWarnings());
769         }
770
771         if (theConnection != null) {
772             theConnection.clearWarnings();
773         }
774         } catch (SQLException JavaDoc e) {
775             ShowSQLException(out, e);
776         }
777     } // ShowWarnings
778

779     static public void ShowWarnings(PrintStream JavaDoc out, SQLWarning JavaDoc warning) {
780         while (warning != null) {
781             out.println("WARNING "+
782                 mapNull(warning.getSQLState(),"(no SQLState)")+": "+
783                 mapNull(warning.getMessage(),"(no message)"));
784             warning = warning.getNextWarning();
785         }
786     }
787
788     static public void ShowWarnings(PrintStream JavaDoc out, ResultSet JavaDoc rs) {
789         try {
790         // GET RESULTSET WARNINGS
791
SQLWarning JavaDoc warning = null;
792
793         if (rs != null) {
794             ShowWarnings(out, rs.getWarnings());
795         }
796
797         if (rs != null) {
798             rs.clearWarnings();
799         }
800         } catch (SQLException JavaDoc e) {
801             ShowSQLException(out, e);
802         }
803     } // ShowResultSetWarnings
804

805     static public void ShowWarnings(PrintStream JavaDoc out, Statement JavaDoc s)
806     {
807         try {
808         // GET STATEMENT WARNINGS
809
SQLWarning JavaDoc warning = null;
810
811         if (s != null) {
812             ShowWarnings(out, s.getWarnings());
813         }
814
815         if (s != null) {
816             s.clearWarnings();
817         }
818         } catch (SQLException JavaDoc e) {
819             ShowSQLException(out, e);
820         }
821     } // ShowStatementWarnings
822

823     static public void DisplayResults(PrintStream JavaDoc out, Statement JavaDoc stmt, Connection JavaDoc conn )
824         throws SQLException JavaDoc
825     {
826         indent_DisplayResults( out, stmt, conn, 0, null, null);
827     }
828
829     static private void indent_DisplayResults
830     (PrintStream JavaDoc out, Statement JavaDoc stmt, Connection JavaDoc conn, int indentLevel,
831      int[] displayColumns, int[] displayColumnWidths)
832         throws SQLException JavaDoc {
833
834         checkNotNull(stmt, "Statement");
835
836         ResultSet JavaDoc rs = stmt.getResultSet();
837         if (rs != null) {
838             indent_DisplayResults(out, rs, conn, indentLevel, displayColumns,
839                                   displayColumnWidths);
840             rs.close(); // let the result set go away
841
}
842         else {
843             DisplayUpdateCount(out,stmt.getUpdateCount(), indentLevel);
844         }
845
846         ShowWarnings(out,stmt);
847     } // DisplayResults
848

849     static void DisplayUpdateCount(PrintStream JavaDoc out, int count, int indentLevel ) {
850         if (count == 1) {
851             indentedPrintLine( out, indentLevel, "1 row inserted/updated/deleted");
852         }
853         else if (count >= 0) {
854             indentedPrintLine( out, indentLevel, count+" rows inserted/updated/deleted");
855         }
856         else {
857             indentedPrintLine( out, indentLevel, "Statement executed.");
858         }
859     }
860
861     static public void DisplayResults(PrintStream JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn)
862         throws SQLException JavaDoc
863     {
864         indent_DisplayResults( out, rs, conn, 0, null, null);
865     }
866
867     static private void indent_DisplayResults
868     (PrintStream JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn, int indentLevel,
869      int[] displayColumns, int[] displayColumnWidths)
870         throws SQLException JavaDoc {
871         ResultSetMetaData JavaDoc rsmd = rs.getMetaData();
872         checkNotNull(rsmd, "ResultSetMetaData");
873         Vector JavaDoc nestedResults;
874     int numberOfRowsSelected = 0;
875
876         // autocommit must be off or the nested cursors
877
// are closed when the outer statement completes.
878
if (!conn.getAutoCommit())
879             nestedResults = new Vector JavaDoc();
880         else
881             nestedResults = null;
882
883         if(displayColumnWidths == null)
884             displayColumnWidths = getColumnDisplayWidths(rsmd, displayColumns, false);
885
886         int len = indent_DisplayBanner(out,rsmd, indentLevel, displayColumns,
887                                        displayColumnWidths);
888
889         // When displaying rows, keep going past errors
890
// unless/until the maximum # of errors is reached.
891
boolean doNext = true;
892         int retry = 0;
893         while (doNext) {
894             try {
895                 doNext = rs.next();
896                 if (doNext) {
897
898                     DisplayRow(out, rs, rsmd, len, nestedResults, conn,
899                                indentLevel, displayColumns,
900                                displayColumnWidths);
901                     ShowWarnings(out, rs);
902                     numberOfRowsSelected++;
903                 }
904             } catch (SQLException JavaDoc e) {
905                 // REVISIT: might want to check the exception
906
// and for some, not bother with the retry.
907
if (++retry > MAX_RETRIES)
908                     throw e;
909                 else
910                     ShowSQLException(out, e);
911             }
912         }
913         if (showSelectCount == true) {
914            if (numberOfRowsSelected == 1) {
915                out.println();
916                indentedPrintLine( out, indentLevel, "1 row selected");
917            } else if (numberOfRowsSelected >= 0) {
918                out.println();
919                indentedPrintLine( out, indentLevel, numberOfRowsSelected + " rows selected");
920            }
921         }
922
923         DisplayNestedResults(out, nestedResults, conn, indentLevel );
924         nestedResults = null;
925     }
926
927     static private void DisplayNestedResults(PrintStream JavaDoc out, Vector JavaDoc nr, Connection JavaDoc conn, int indentLevel )
928         throws SQLException JavaDoc {
929
930         if (nr == null) return;
931
932         String JavaDoc s="+ ResultSet #";
933         String JavaDoc b="++++++++++++++++";
934         String JavaDoc oldString="0";
935
936         for (int i=0; i < nr.size(); i++) {
937             System.out.println();
938
939             //just too clever to get the extra +s
940
String JavaDoc t = Integer.toString(i);
941             if (t.length() > oldString.length()) {
942                 oldString = t;
943                 b=b+"+";
944             }
945
946             System.out.println(b);
947             System.out.println(s+i+" +");
948             System.out.println(b);
949             indent_DisplayResults(out, (ResultSet JavaDoc) nr.elementAt(i), conn,
950                                   indentLevel, null, null);
951         }
952     }
953
954     static public void DisplayNextRow(PrintStream JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn )
955         throws SQLException JavaDoc
956     {
957         indent_DisplayNextRow( out, rs, conn, 0, null, (rs == null) ? null
958                                : getColumnDisplayWidths(rs.getMetaData(),null,false) );
959     }
960
961     static private void indent_DisplayNextRow(PrintStream JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn, int indentLevel,
962                                               int[] displayColumns, int[] displayColumnWidths )
963         throws SQLException JavaDoc {
964
965         Vector JavaDoc nestedResults;
966
967         // autocommit must be off or the nested cursors
968
// are closed when the outer statement completes.
969
if (!conn.getAutoCommit())
970             nestedResults = new Vector JavaDoc();
971         else
972             nestedResults = null;
973
974         checkNotNull(rs, "ResultSet");
975
976         ResultSetMetaData JavaDoc rsmd = rs.getMetaData();
977         checkNotNull(rsmd, "ResultSetMetaData");
978
979         // Only print stuff out if there is a row to be had.
980
if (rs.next()) {
981             int rowLen = indent_DisplayBanner(out, rsmd, indentLevel, null, null);
982             DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel,
983                        displayColumns, displayColumnWidths);
984         }
985         else {
986             indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow"));
987         }
988
989         ShowWarnings(out, rs);
990
991         DisplayNestedResults(out, nestedResults, conn, indentLevel );
992         nestedResults = null;
993
994     } // DisplayNextRow
995

996     static public void DisplayCurrentRow(PrintStream JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn )
997         throws SQLException JavaDoc
998     {
999         indent_DisplayCurrentRow( out, rs, conn, 0, null, (rs == null) ? null
1000                                  : getColumnDisplayWidths(rs.getMetaData(),null,false) );
1001    }
1002
1003    static private void indent_DisplayCurrentRow(PrintStream JavaDoc out, ResultSet JavaDoc rs, Connection JavaDoc conn,
1004                                                 int indentLevel, int[] displayColumns, int[] displayColumnWidths )
1005        throws SQLException JavaDoc {
1006
1007        Vector JavaDoc nestedResults;
1008
1009        if (rs == null) {
1010            indentedPrintLine( out, indentLevel, LocalizedResource.getMessage("UT_NoCurreRow_19"));
1011            return;
1012        }
1013
1014        // autocommit must be off or the nested cursors
1015
// are closed when the outer statement completes.
1016
if (!conn.getAutoCommit())
1017            nestedResults = new Vector JavaDoc();
1018        else
1019            nestedResults = null;
1020
1021        ResultSetMetaData JavaDoc rsmd = rs.getMetaData();
1022        checkNotNull(rsmd, "ResultSetMetaData");
1023
1024        int rowLen = indent_DisplayBanner(out, rsmd, indentLevel, displayColumns, displayColumnWidths);
1025        DisplayRow(out, rs, rsmd, rowLen, nestedResults, conn, indentLevel,
1026                   displayColumns, displayColumnWidths);
1027
1028        ShowWarnings(out, rs);
1029
1030        DisplayNestedResults(out, nestedResults, conn, indentLevel );
1031        nestedResults = null;
1032
1033    } // DisplayNextRow
1034

1035    static public int DisplayBanner(PrintStream JavaDoc out, ResultSetMetaData JavaDoc rsmd )
1036        throws SQLException JavaDoc
1037    {
1038        return indent_DisplayBanner( out, rsmd, 0, null,
1039                                     getColumnDisplayWidths(rsmd,null,false) );
1040    }
1041
1042    static private int indent_DisplayBanner(PrintStream JavaDoc out, ResultSetMetaData JavaDoc rsmd, int indentLevel,
1043                                            int[] displayColumns, int[] displayColumnWidths )
1044        throws SQLException JavaDoc {
1045
1046        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1047
1048        int numCols = displayColumnWidths.length;
1049        int rowLen;
1050
1051        // do some precalculation so the buffer is allocated only once
1052
// buffer is twice as long as the display length plus one for a newline
1053
rowLen = (numCols - 1); // for the column separators
1054
for (int i=1; i <= numCols; i++) {
1055            rowLen += displayColumnWidths[i-1];
1056        }
1057        buf.ensureCapacity(rowLen);
1058
1059        // get column header info
1060
// truncate it to the column display width
1061
// add a bar between each item.
1062
for (int i=1; i <= numCols; i++) {
1063            int colnum = displayColumns==null ? i : displayColumns[i-1];
1064
1065            if (i>1)
1066                buf.append('|');
1067
1068            String JavaDoc s = rsmd.getColumnLabel(colnum);
1069
1070            int w = displayColumnWidths[i-1];
1071
1072            if (s.length() < w) {
1073                // build a string buffer to hold the whitespace
1074
StringBuffer JavaDoc blanks = new StringBuffer JavaDoc(s);
1075                blanks.ensureCapacity(w);
1076
1077                // try to paste on big chunks of space at a time.
1078
for (int k=blanks.length()+64; k<=w; k+=64)
1079                    blanks.append(
1080          " ");
1081                for (int k=blanks.length()+16; k<=w; k+=16)
1082                    blanks.append(" ");
1083                for (int k=blanks.length()+4; k<=w; k+=4)
1084                    blanks.append(" ");
1085                for (int k=blanks.length(); k<w; k++)
1086                    blanks.append(' ');
1087
1088                buf.append(blanks);
1089                // REMIND: could do more cleverness, like keep around
1090
// past buffers to reuse...
1091
}
1092            else if (s.length() > w) {
1093                if (w > 1)
1094                    buf.append(s.substring(0,w-1));
1095                if (w > 0)
1096                    buf.append('&');
1097            }
1098            else {
1099                buf.append(s);
1100            }
1101        }
1102
1103        buf.setLength(Math.min(rowLen, 1024));
1104        indentedPrintLine( out, indentLevel, buf);
1105
1106        // now print a row of '-'s
1107
for (int i=0; i<Math.min(rowLen, 1024); i++)
1108            buf.setCharAt(i, '-');
1109        indentedPrintLine( out, indentLevel, buf);
1110
1111        buf = null;
1112
1113        return rowLen;
1114    } // DisplayBanner
1115

1116    static private void DisplayRow(PrintStream JavaDoc out, ResultSet JavaDoc rs, ResultSetMetaData JavaDoc rsmd, int rowLen, Vector JavaDoc nestedResults, Connection JavaDoc conn, int indentLevel,
1117                                   int[] displayColumns, int[] displayColumnWidths)
1118        throws SQLException JavaDoc
1119    {
1120        StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
1121        buf.ensureCapacity(rowLen);
1122
1123        int numCols = displayColumnWidths.length;
1124        int i;
1125
1126        // get column header info
1127
// truncate it to the column display width
1128
// add a bar between each item.
1129
for (i=1; i <= numCols; i++){
1130            int colnum = displayColumns==null ? i : displayColumns[i-1];
1131            if (i>1)
1132                buf.append('|');
1133
1134            String JavaDoc s;
1135            switch (rsmd.getColumnType(colnum)) {
1136            default:
1137                s = rs.getString(colnum);
1138                break;
1139            case org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT:
1140            case Types.OTHER:
1141            {
1142                Object JavaDoc o = rs.getObject(colnum);
1143                if (o == null) { s = "NULL"; }
1144                else if (o instanceof ResultSet JavaDoc && nestedResults != null)
1145                {
1146                    s = "ResultSet #"+nestedResults.size();
1147                    nestedResults.addElement(o);
1148                }
1149                else
1150                {
1151                    try {
1152                        s = rs.getString(colnum);
1153                    } catch (SQLException JavaDoc se) {
1154                        // oops, they don't support refetching the column
1155
s = o.toString();
1156                    }
1157                }
1158            }
1159            break;
1160            }
1161
1162            if (s==null) s = "NULL";
1163
1164            int w = displayColumnWidths[i-1];
1165            if (s.length() < w) {
1166                StringBuffer JavaDoc fullS = new StringBuffer JavaDoc(s);
1167                fullS.ensureCapacity(w);
1168                for (int k=s.length(); k<w; k++)
1169                    fullS.append(' ');
1170                s = fullS.toString();
1171            }
1172            else if (s.length() > w)
1173                // add the & marker to know it got cut off
1174
s = s.substring(0,w-1)+"&";
1175
1176            buf.append(s);
1177        }
1178        indentedPrintLine( out, indentLevel, buf);
1179
1180    } // DisplayRow
1181

1182    static public void doTrace(PrintStream JavaDoc out, Exception JavaDoc e) {
1183        if (Boolean.getBoolean("ij.exceptionTrace")) {
1184            e.printStackTrace(out);
1185            out.flush();
1186        }
1187    }
1188
1189    static private void indentedPrintLine( PrintStream JavaDoc out, int indentLevel, String JavaDoc text )
1190    {
1191        indent( out, indentLevel );
1192        out.println( text );
1193    }
1194
1195    static private void indentedPrintLine( PrintStream JavaDoc out, int indentLevel, StringBuffer JavaDoc text )
1196    {
1197        indent( out, indentLevel );
1198        out.println( text );
1199    }
1200
1201    static private void indent( PrintStream JavaDoc out, int indentLevel )
1202    {
1203        for ( int ictr = 0; ictr < indentLevel; ictr++ ) { out.print( " " ); }
1204    }
1205    
1206    // ==========================
1207
}
1208
1209
1210
1211
Popular Tags