001: /*
002: * This is free software, licensed under the Gnu Public License (GPL)
003: * get a copy from <http://www.gnu.org/licenses/gpl.html>
004: * $Id: ResultSetRenderer.java,v 1.22 2005/06/18 04:58:13 hzeller Exp $
005: * author: Henner Zeller <H.Zeller@acm.org>
006: */
007: package henplus.commands;
008:
009: import henplus.view.*;
010: import henplus.OutputDevice;
011: import henplus.HenPlus;
012: import henplus.Interruptable;
013:
014: import java.sql.ResultSet;
015: import java.sql.Clob;
016: import java.sql.ResultSetMetaData;
017: import java.sql.SQLException;
018: import java.sql.Types;
019: import java.io.Reader;
020:
021: /**
022: * document me.
023: */
024: public class ResultSetRenderer implements Interruptable {
025: private final ResultSet rset;
026: private final ResultSetMetaData meta;
027: private final TableRenderer table;
028: private final int columns;
029: private final int[] showColumns;
030:
031: private boolean beyondLimit;
032: private long firstRowTime;
033: private final long clobLimit = 8192;
034: private final int rowLimit;
035: private volatile boolean running;
036:
037: public ResultSetRenderer(ResultSet rset, String columnDelimiter,
038: boolean enableHeader, boolean enableFooter, int limit,
039: OutputDevice out, int[] show) throws SQLException {
040: this .rset = rset;
041: beyondLimit = false;
042: firstRowTime = -1;
043: showColumns = show;
044: rowLimit = limit;
045: meta = rset.getMetaData();
046: columns = (show != null) ? show.length : meta.getColumnCount();
047: table = new TableRenderer(getDisplayMeta(meta), out,
048: columnDelimiter, enableHeader, enableFooter);
049: }
050:
051: public ResultSetRenderer(ResultSet rset, String columnDelimiter,
052: boolean enableHeader, boolean enableFooter, int limit,
053: OutputDevice out) throws SQLException {
054: this (rset, columnDelimiter, enableHeader, enableFooter, limit,
055: out, null);
056: }
057:
058: // Interruptable interface.
059: public synchronized void interrupt() {
060: running = false;
061: }
062:
063: public ColumnMetaData[] getDisplayMetaData() {
064: return table.getMetaData();
065: }
066:
067: private String readClob(Clob c) throws SQLException {
068: if (c == null)
069: return null;
070: StringBuffer result = new StringBuffer();
071: long restLimit = clobLimit;
072: try {
073: Reader in = c.getCharacterStream();
074: char buf[] = new char[4096];
075: int r;
076:
077: while (restLimit > 0
078: && (r = in.read(buf, 0, (int) Math.min(buf.length,
079: restLimit))) > 0) {
080: result.append(buf, 0, r);
081: restLimit -= r;
082: }
083: } catch (Exception e) {
084: HenPlus.msg().println(e.toString());
085: }
086: if (restLimit == 0) {
087: result.append("...");
088: }
089: return result.toString();
090: }
091:
092: public int execute() throws SQLException {
093: int rows = 0;
094:
095: running = true;
096: try {
097: while (running && rset.next()) {
098: Column[] currentRow = new Column[columns];
099: for (int i = 0; i < columns; ++i) {
100: int col = (showColumns != null) ? showColumns[i]
101: : i + 1;
102: String colString;
103: if (meta.getColumnType(col) == Types.CLOB) {
104: colString = readClob(rset.getClob(col));
105: } else {
106: colString = rset.getString(col);
107: }
108: Column this Col = new Column(colString);
109: currentRow[i] = this Col;
110: }
111: if (firstRowTime < 0) {
112: // read first row completely.
113: firstRowTime = System.currentTimeMillis();
114: }
115: table.addRow(currentRow);
116: ++rows;
117: if (rows >= rowLimit) {
118: beyondLimit = true;
119: break;
120: }
121: }
122:
123: table.closeTable();
124: if (!running) {
125: try {
126: rset.getStatement().cancel();
127: } catch (Exception e) {
128: HenPlus.msg().println(
129: "cancel statement failed: "
130: + e.getMessage());
131: }
132: }
133: } finally {
134: rset.close();
135: }
136: return rows;
137: }
138:
139: public boolean limitReached() {
140: return beyondLimit;
141: }
142:
143: public long getFirstRowTime() {
144: return firstRowTime;
145: }
146:
147: /**
148: * determine meta data necesary for display.
149: */
150: private ColumnMetaData[] getDisplayMeta(ResultSetMetaData m)
151: throws SQLException {
152: ColumnMetaData result[] = new ColumnMetaData[columns];
153:
154: for (int i = 0; i < result.length; ++i) {
155: int col = (showColumns != null) ? showColumns[i] : i + 1;
156: int alignment = ColumnMetaData.ALIGN_LEFT;
157: String columnLabel = m.getColumnLabel(col);
158: /*
159: int width = Math.max(m.getColumnDisplaySize(i),
160: columnLabel.length());
161: */
162: switch (m.getColumnType(col)) {
163: case Types.NUMERIC:
164: case Types.INTEGER:
165: case Types.REAL:
166: case Types.SMALLINT:
167: case Types.TINYINT:
168: alignment = ColumnMetaData.ALIGN_RIGHT;
169: break;
170: }
171: result[i] = new ColumnMetaData(columnLabel, alignment);
172: }
173: return result;
174: }
175: }
176:
177: /*
178: * Local variables:
179: * c-basic-offset: 4
180: * compile-command: "ant -emacs -find build.xml"
181: * End:
182: */
|