001: /*
002: * The contents of this file are subject to the Mozilla Public License
003: * Version 1.1 (the "License"); you may not use this file except in
004: * compliance with the License. You may obtain a copy of the License at
005: * http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
009: * License for the specific language governing rights and limitations
010: * under the License.
011: *
012: * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
013: *
014: * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
015: * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
016: *
017: * Contributor(s):
018: * Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
019: *
020: * If you didn't download this code from the following link, you should check
021: * if you aren't using an obsolete version: http://www.isqlviewer.com
022: */
023: package org.isqlviewer.swing.table;
024:
025: import java.io.IOException;
026: import java.io.InputStream;
027: import java.io.Reader;
028: import java.math.BigDecimal;
029: import java.sql.Array;
030: import java.sql.Blob;
031: import java.sql.Clob;
032: import java.sql.Date;
033: import java.sql.Ref;
034: import java.sql.ResultSet;
035: import java.sql.ResultSetMetaData;
036: import java.sql.SQLException;
037: import java.sql.Statement;
038: import java.sql.Time;
039: import java.sql.Timestamp;
040: import java.sql.Types;
041: import java.util.ArrayList;
042:
043: import org.isqlviewer.sql.ByteArrayBlob;
044: import org.isqlviewer.sql.ByteArrayClob;
045: import org.isqlviewer.sql.ResultSetRenderer;
046:
047: /**
048: * @author Markus A. Kobold <mkobold at sprintpcs dot com>
049: * @version 1.0
050: */
051: public class ResultSetTableModel extends EnhancedTableModel {
052:
053: public ResultSetTableModel() {
054:
055: super (new String[0]);
056: }
057:
058: public synchronized void setResults(ResultSet resultSet,
059: ResultSetRenderer renderer) throws SQLException {
060:
061: clearAllData();
062: try {
063: int preferredMaxRows = Integer.MAX_VALUE;
064: int columnCount = 0;
065: ResultSetMetaData metaData = resultSet.getMetaData();
066: Statement statement = resultSet.getStatement();
067: try {
068: preferredMaxRows = statement.getMaxRows();
069: preferredMaxRows = preferredMaxRows <= 0 ? Integer.MAX_VALUE
070: : preferredMaxRows;
071: } catch (SQLException warning) {
072: }
073:
074: columnCount = metaData.getColumnCount();
075: if (columnCount <= 0) {
076: // nothing to show //
077: return;
078: }
079: columns.clear();
080: for (int i = 0; i < columnCount; i++) {
081: try {
082: columns.add(metaData.getColumnLabel(i + 1));
083: } catch (SQLException warning) {
084: columns.add(metaData.getColumnName(i + 1));
085: }
086: }
087:
088: // make sure we are at the front of the results only if the result set is 'scrollable'
089: try {
090: int resultSetType = resultSet.getType();
091: if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
092: if (resultSet.isBeforeFirst()) {
093: resultSet.beforeFirst();
094: }
095: }
096: } catch (SQLException warning) {
097: }
098:
099: int rowsExtracted = 0;
100: rowLoop: while (rowsExtracted < preferredMaxRows
101: && resultSet.next()) {
102: if (renderer.isCancelled()) {
103: break;
104: }
105: ArrayList<Object> rowset = new ArrayList<Object>();
106: for (int column = 0; column < columnCount; column++) {
107: int columnIndex = column + 1;
108: int columnType = metaData
109: .getColumnType(columnIndex);
110: boolean isFirstRow = rowsExtracted == 0;
111: try {
112: rowset.add(extractColumn(resultSet,
113: columnIndex, columnType, isFirstRow));
114: } catch (IOException warning) {
115: rowset.clear();
116: continue rowLoop;
117: }
118: }
119: dataStore.add(rowset);
120: // give other threads a chance to do something like interrupt
121: rowsExtracted++;
122: Thread.yield();
123: }
124: } finally {
125: fireTableStructureChanged();
126: }
127: }
128:
129: private Object extractColumn(ResultSet resultSet, int columnIndex,
130: int columnType, boolean isFirstRow) throws SQLException,
131: IOException {
132:
133: Class columnClass = Object.class;
134: Object columnValue = null;
135: switch (columnType) {
136: case Types.DATE:
137: columnClass = Date.class;
138: columnValue = resultSet.getDate(columnIndex);
139: break;
140: case Types.TIMESTAMP:
141: columnClass = Timestamp.class;
142: columnValue = resultSet.getTimestamp(columnIndex);
143: break;
144: case Types.TIME:
145: columnClass = Time.class;
146: columnValue = resultSet.getTime(columnIndex);
147: break;
148: case Types.TINYINT:
149: columnClass = Byte.class;
150: columnValue = new Byte(resultSet.getByte(columnIndex));
151: break;
152: case Types.SMALLINT:
153: columnClass = Short.class;
154: columnValue = new Short(resultSet.getShort(columnIndex));
155: break;
156: case Types.INTEGER:
157: columnClass = Integer.class;
158: columnValue = new Integer(resultSet.getInt(columnIndex));
159: break;
160: case Types.DECIMAL:
161: case Types.NUMERIC:
162: columnClass = BigDecimal.class;
163: columnValue = resultSet.getBigDecimal(columnIndex);
164: break;
165: case Types.REAL:
166: columnClass = Float.class;
167: columnValue = new Float(resultSet.getFloat(columnIndex));
168: break;
169: case Types.DOUBLE:
170: case Types.FLOAT:
171: columnClass = Double.class;
172: columnValue = new Double(resultSet.getDouble(columnIndex));
173: break;
174: case Types.BIGINT:
175: columnClass = Long.class;
176: columnValue = new Long(resultSet.getLong(columnIndex));
177: break;
178: case Types.BIT:
179: case Types.BOOLEAN:
180: columnClass = Boolean.class;
181: columnValue = Boolean.valueOf(resultSet
182: .getBoolean(columnIndex));
183: break;
184: case Types.LONGVARBINARY:
185: InputStream binaryStream = resultSet
186: .getBinaryStream(columnIndex);
187: columnClass = Blob.class;
188: columnValue = binaryStream == null ? null
189: : new ByteArrayBlob(binaryStream);
190: break;
191: case Types.VARBINARY:
192: case Types.BINARY:
193: columnClass = Blob.class;
194: columnValue = new ByteArrayBlob(resultSet
195: .getBytes(columnIndex));
196: break;
197: case Types.LONGVARCHAR:
198: Reader characterReader = resultSet
199: .getCharacterStream(columnIndex);
200: columnClass = Clob.class;
201: columnValue = characterReader == null ? null
202: : new ByteArrayClob(characterReader);
203: break;
204: case Types.VARCHAR:
205: case Types.CHAR:
206: columnClass = String.class;
207: columnValue = resultSet.getString(columnIndex);
208: break;
209: case Types.BLOB:
210: columnClass = Blob.class;
211: columnValue = resultSet.getBlob(columnIndex);
212: break;
213: case Types.CLOB:
214: columnClass = Clob.class;
215: columnValue = resultSet.getClob(columnIndex);
216: break;
217: case Types.REF:
218: columnClass = Ref.class;
219: columnValue = resultSet.getRef(columnIndex);
220: break;
221: case Types.ARRAY:
222: columnClass = Array.class;
223: columnValue = resultSet.getArray(columnIndex);
224: break;
225: default:
226: columnClass = Object.class;
227: columnValue = resultSet.getObject(columnIndex);
228: break;
229: }
230:
231: if (isFirstRow) {
232: setClassforColumn(columnIndex, columnClass);
233: }
234:
235: if (resultSet.wasNull()) {
236: return null;
237: }
238: return columnValue;
239: }
240: }
|