1 package com.quantum.sql;
3 import java.io.ByteArrayOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.InputStreamReader;
8 import java.io.UnsupportedEncodingException;
9 import java.sql.Connection;
10 import java.sql.ResultSet;
11 import java.sql.ResultSetMetaData;
12 import java.sql.SQLException;
13 import java.util.ArrayList;
14 import java.util.List;
16 import com.quantum.model.Bookmark;
17 import com.quantum.model.Entity;
23 public class SQLStandardResultSetResults extends SQLResultSetResults implements Scrollable {
26 * Some columns -- especially BLOBS and CLOBS can be very wide. This variable
27 * sets the maximum width of the column.
29 private static final int MAX_COLUMN_WIDTH = 1024 * 2;
31 private boolean hasMore = false;
32 private int start = 1;
33 private int numberOfRowsPerPage;
34 private int totalNumberOfRows = -1;
36 private boolean fullMode = false;
42 * @param numberOfRowsPerPage
44 protected SQLStandardResultSetResults(
45 Bookmark bookmark, String query, Entity entity,
46 int numberOfRowsPerPage) {
47 super(query, bookmark, entity);
48 this.numberOfRowsPerPage = numberOfRowsPerPage;
51 static SQLResultSetResults create(
52 ResultSet set, Bookmark bookmark,
53 String query, Entity entity, int numberOfRows) throws SQLException {
55 SQLStandardResultSetResults results = new SQLStandardResultSetResults(
56 bookmark, query, entity, numberOfRows);
58 results.parseResultSet(set);
69 * @throws SQLException
71 protected void parseResultSet(ResultSet set) throws SQLException {
74 ResultSetMetaData metaData = set.getMetaData();
75 int columnCount = metaData.getColumnCount();
76 List columns = new ArrayList();
77 for (int i = 1; i <= columnCount; i++) {
78 columns.add(new Column(
79 metaData.getColumnName(i),
80 metaData.getColumnTypeName(i),
81 metaData.getColumnDisplaySize(i)));
83 setColumns((Column[]) columns.toArray(new Column[columns.size()]));
85 boolean exitEarly = false;
86 int firstRow = (this.fullMode) ? 0 : this.start;
87 int lastRow = (this.fullMode) ? Integer.MAX_VALUE : this.start + this.numberOfRowsPerPage - 1;
88 List rowList = new ArrayList();
90 boolean disable = this.start < 1 || lastRow < 1;
91 if (disable || ((rowCount >= firstRow) && (rowCount <= lastRow))) {
92 List row = new ArrayList();
93 for (int i = 1, length = columns.size(); i <= length; i++) {
96 if (set.getMetaData().getColumnType(i) == java.sql.Types.LONGVARBINARY) {
97 value = getEncodedStringFromBinaryStream(set, getEncoding(), i);
98 } else if (getColumn(i).getSize() < MAX_COLUMN_WIDTH) {
99 value = getEncodedString(set, getEncoding(), i);
101 if ("".equals(getEncoding())) { //$NON-NLS-1$
102 value = getStringFromCharacterSteam(set, i);
104 value = getEncodedStringFromBinaryStream(set, getEncoding(), i);
107 } catch (IOException e) {
108 value = set.getString(i);
109 } catch (RuntimeException e) {
110 // hack for mysql which doesn't implement
112 value = set.getString(i);
114 if (value == null && !set.wasNull()) {
115 value = set.getString(i);
117 row.add(value == null || set.wasNull() ? "<NULL>" : value); //$NON-NLS-1$
119 rowList.add(new Row(row));
122 if (!disable && (rowCount > lastRow)) {
128 this.hasMore = set.next();
130 this.totalNumberOfRows = Math.max(0, rowCount-1);
131 this.hasMore = false;
133 setRows((Row[]) rowList.toArray(new Row[rowList.size()]));
140 * @param columnNumber
141 * @throws SQLException
142 * @throws IOException
143 * @throws UnsupportedEncodingException
145 private String getEncodedStringFromBinaryStream(ResultSet set, String encoding, int columnNumber)
146 throws SQLException, IOException, UnsupportedEncodingException {
147 InputStream binaryStream = set.getBinaryStream(columnNumber);
148 if (binaryStream != null) {
149 ByteArrayOutputStream baos = new ByteArrayOutputStream();
151 for (int c = binaryStream.read(), count = 0;
152 c >= 0 && count <= MAX_COLUMN_WIDTH;
153 c = binaryStream.read(), count++) {
157 binaryStream.close();
159 if ("".equals(encoding))
160 return new String(baos.toByteArray());
162 return new String(baos.toByteArray(), encoding);
171 * @param columnNumber
172 * @throws SQLException
173 * @throws IOException
175 private String getStringFromCharacterSteam(ResultSet set, int columnNumber)
176 throws SQLException, IOException {
177 Reader reader = set.getCharacterStream(columnNumber);
178 if (reader != null) {
179 StringBuffer buffer = new StringBuffer();
180 int retVal = reader.read();
182 while (retVal >= 0) {
183 buffer.append((char) retVal);
184 retVal = reader.read();
186 if (count > MAX_COLUMN_WIDTH) {
187 buffer.append("...>>>"); //$NON-NLS-1$
192 return buffer.toString();
203 * @throws SQLException
205 private String getEncodedString(ResultSet set, String encoding, int index)
206 throws SQLException {
208 if (encoding == null || encoding.trim().length() == 0) {
209 return set.getString(index);
211 byte[] colBytes = set.getBytes(index);
212 if (colBytes == null) return null;
213 else return new String(colBytes, encoding);
214 } catch (UnsupportedEncodingException e) {
215 return set.getString(index);
219 public boolean hasMore() {
223 public int getTotalNumberOfRows() {
224 return this.totalNumberOfRows;
226 public void nextPage(Connection connection) throws SQLException {
228 this.start += this.numberOfRowsPerPage;
234 * @see com.quantum.sql.Scrollable#previousPage(java.sql.Connection)
236 public void previousPage(Connection connection) throws SQLException {
237 if (hasPreviousPage()) {
238 this.start = Math.max(1, this.start - this.numberOfRowsPerPage);
244 * @see com.quantum.sql.Scrollable#hasNextPage()
246 public boolean hasNextPage() {
251 * @see com.quantum.sql.Scrollable#hasPreviousPage()
253 public boolean hasPreviousPage() {
254 return this.start > 1;
257 public void setFullMode(boolean fullMode) {
258 this.fullMode = fullMode;
260 public boolean isFullMode() {
261 return this.fullMode;
265 * @see com.quantum.sql.Scrollable#getStart()
267 public int getStart() {
268 return getRowCount() == 0 ? 0 : (this.fullMode ? 1 : this.start);
272 * @see com.quantum.sql.Scrollable#getEnd()
274 public int getEnd() {
277 : this.start + getRowCount() - 1;
281 * @see com.quantum.sql.Scrollable#getLast()
283 public int getLast() {
284 return this.totalNumberOfRows;
288 public void setFilterSort(FilterSort filterSort) {
289 super.setFilterSort(filterSort);