--- /dev/null
+package com.quantum.sql;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.quantum.model.Bookmark;
+import com.quantum.model.Entity;
+
+
+/**
+ * @author BC
+ */
+public class SQLStandardResultSetResults extends SQLResultSetResults implements Scrollable {
+
+ /**
+ * Some columns -- especially BLOBS and CLOBS can be very wide. This variable
+ * sets the maximum width of the column.
+ */
+ private static final int MAX_COLUMN_WIDTH = 1024 * 2;
+
+ private boolean hasMore = false;
+ private int start = 1;
+ private int numberOfRowsPerPage;
+ private int totalNumberOfRows = -1;
+
+ private boolean fullMode = false;
+
+ /**
+ * @param bookmark
+ * @param query
+ * @param encoding
+ * @param numberOfRowsPerPage
+ */
+ protected SQLStandardResultSetResults(
+ Bookmark bookmark, String query, Entity entity,
+ int numberOfRowsPerPage) {
+ super(query, bookmark, entity);
+ this.numberOfRowsPerPage = numberOfRowsPerPage;
+ }
+
+ static SQLResultSetResults create(
+ ResultSet set, Bookmark bookmark,
+ String query, Entity entity, int numberOfRows) throws SQLException {
+
+ SQLStandardResultSetResults results = new SQLStandardResultSetResults(
+ bookmark, query, entity, numberOfRows);
+
+ results.parseResultSet(set);
+
+ return results;
+ }
+
+ /**
+ * @param set
+ * @param encoding
+ * @param numberOfRows
+ * @param results
+ * @param columnCount
+ * @throws SQLException
+ */
+ protected void parseResultSet(ResultSet set) throws SQLException {
+ int rowCount = 1;
+
+ ResultSetMetaData metaData = set.getMetaData();
+ int columnCount = metaData.getColumnCount();
+ List columns = new ArrayList();
+ for (int i = 1; i <= columnCount; i++) {
+ columns.add(new Column(
+ metaData.getColumnName(i),
+ metaData.getColumnTypeName(i),
+ metaData.getColumnDisplaySize(i)));
+ }
+ setColumns((Column[]) columns.toArray(new Column[columns.size()]));
+
+ boolean exitEarly = false;
+ int firstRow = (this.fullMode) ? 0 : this.start;
+ int lastRow = (this.fullMode) ? Integer.MAX_VALUE : this.start + this.numberOfRowsPerPage - 1;
+ List rowList = new ArrayList();
+ while (set.next()) {
+ boolean disable = this.start < 1 || lastRow < 1;
+ if (disable || ((rowCount >= firstRow) && (rowCount <= lastRow))) {
+ List row = new ArrayList();
+ for (int i = 1, length = columns.size(); i <= length; i++) {
+ String value = null;
+ if (getColumn(i).getSize() < MAX_COLUMN_WIDTH) {
+ value = getEncodedString(set, getEncoding(), i);
+ } else {
+ try {
+ if ("".equals(getEncoding())) { //$NON-NLS-1$
+ value = getStringFromCharacterSteam(set, i);
+ } else {
+ value = getEncodedStringFromBinaryStream(set, getEncoding(), i);
+ }
+ } catch (IOException e) {
+ value = set.getString(i);
+ } catch (RuntimeException e) {
+ // hack for mysql which doesn't implement
+ // character streams
+ value = set.getString(i);
+ }
+ }
+ if (value == null) {
+ value = set.getString(i);
+ }
+ row.add(value == null || set.wasNull() ? "<NULL>" : value); //$NON-NLS-1$
+ }
+ rowList.add(new Row(row));
+ }
+ rowCount++;
+ if (!disable && (rowCount > lastRow)) {
+ exitEarly = true;
+ break;
+ }
+ }
+ if (exitEarly) {
+ this.hasMore = set.next();
+ } else {
+ this.totalNumberOfRows = Math.max(0, rowCount-1);
+ this.hasMore = false;
+ }
+ setRows((Row[]) rowList.toArray(new Row[rowList.size()]));
+ }
+
+
+ /**
+ * @param set
+ * @param encoding
+ * @param columnNumber
+ * @throws SQLException
+ * @throws IOException
+ * @throws UnsupportedEncodingException
+ */
+ private String getEncodedStringFromBinaryStream(ResultSet set, String encoding, int columnNumber)
+ throws SQLException, IOException, UnsupportedEncodingException {
+ InputStream binaryStream = set.getBinaryStream(columnNumber);
+ if (binaryStream != null) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ try {
+ for (int c = binaryStream.read(), count = 0;
+ c >= 0 && count <= MAX_COLUMN_WIDTH;
+ c = binaryStream.read(), count++) {
+ baos.write(c);
+ }
+ } finally {
+ binaryStream.close();
+ }
+ return new String(baos.toByteArray(), encoding);
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * @param set
+ * @param columnNumber
+ * @throws SQLException
+ * @throws IOException
+ */
+ private String getStringFromCharacterSteam(ResultSet set, int columnNumber)
+ throws SQLException, IOException {
+ Reader reader = set.getCharacterStream(columnNumber);
+ if (reader != null) {
+ StringBuffer buffer = new StringBuffer();
+ int retVal = reader.read();
+ int count = 0;
+ while (retVal >= 0) {
+ buffer.append((char) retVal);
+ retVal = reader.read();
+ count++;
+ if (count > MAX_COLUMN_WIDTH) {
+ buffer.append("...>>>"); //$NON-NLS-1$
+ break;
+ }
+ }
+ reader.close();
+ return buffer.toString();
+ } else {
+ return null;
+ }
+ }
+
+
+ /**
+ * @param set
+ * @param encoding
+ * @param index
+ * @return
+ * @throws SQLException
+ */
+ private String getEncodedString(ResultSet set, String encoding, int index)
+ throws SQLException {
+ try {
+ return encoding == null || encoding.trim().length() == 0
+ ? set.getString(index)
+ : new String(set.getBytes(index), encoding);
+ } catch (UnsupportedEncodingException e) {
+ return set.getString(index);
+ }
+ }
+
+ public boolean hasMore() {
+ return this.hasMore;
+ }
+
+ public int getTotalNumberOfRows() {
+ return this.totalNumberOfRows;
+ }
+ public void nextPage(Connection connection) throws SQLException {
+ if (hasNextPage()) {
+ this.start += this.numberOfRowsPerPage;
+ refresh(connection);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.quantum.sql.Scrollable#previousPage(java.sql.Connection)
+ */
+ public void previousPage(Connection connection) throws SQLException {
+ if (hasPreviousPage()) {
+ this.start = Math.max(1, this.start - this.numberOfRowsPerPage);
+ refresh(connection);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.quantum.sql.Scrollable#hasNextPage()
+ */
+ public boolean hasNextPage() {
+ return this.hasMore;
+ }
+
+ /* (non-Javadoc)
+ * @see com.quantum.sql.Scrollable#hasPreviousPage()
+ */
+ public boolean hasPreviousPage() {
+ return this.start > 1;
+ }
+
+ public void setFullMode(boolean fullMode) {
+ this.fullMode = fullMode;
+ }
+ public boolean isFullMode() {
+ return this.fullMode;
+ }
+
+ /* (non-Javadoc)
+ * @see com.quantum.sql.Scrollable#getStart()
+ */
+ public int getStart() {
+ return getRowCount() == 0 ? 0 : (this.fullMode ? 1 : this.start);
+ }
+
+ /* (non-Javadoc)
+ * @see com.quantum.sql.Scrollable#getEnd()
+ */
+ public int getEnd() {
+ return this.fullMode
+ ? getRowCount()
+ : this.start + getRowCount() - 1;
+ }
+
+ /* (non-Javadoc)
+ * @see com.quantum.sql.Scrollable#getLast()
+ */
+ public int getLast() {
+ return this.totalNumberOfRows;
+ }
+
+
+ public void setFilterSort(FilterSort filterSort) {
+ super.setFilterSort(filterSort);
+ this.start = 1;
+ }
+}