package ca.sqlpower.sql;
import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.log4j.Logger;
/**
* The CachedRowSet is a serializable container for holding the
* results of a SQL query. It supports read-only random access of
* rows and columns, and only depends on serializable core J2SE
* classes (no proprietary vendor-supplied classes).
*
* <p>Note that this is not a complete implementation of the ResultSet
* interface. Methods marked as "Not supported" will generally throw
* an UnsupportedOperationException or SQLException when you call
* them. This is preferable to just ignoring the call or returning a
* dummy value because you will notice that you used an unimplemented
* call, and can implement functionality that you need piece-by-piece.
*
* @author Jonathan Fuerth
* @version $Id$
*/
public class CachedRowSet implements ResultSet, java.io.Serializable {
private static final Logger logger = Logger.getLogger(CachedRowSet.class);
private static final int BEFORE_FIRST_ROW = -1;
private static final int INSERT_ROW = -2;
private boolean makeUppercase = true;
/**
* The current row number in the result set. Calling next() will
* increment this (if there are more rows to go).
*
* <p>The first row is 0, which is consistent with the java.util
* Collections clases and most other stuff, but is different from
* JDBC which uses 1-based indexing.
*/
private int rownum = BEFORE_FIRST_ROW;
/**
* The data from the original result set. One list item per row.
* Each row is of type Object[]. data.get(0)[0] would be the first
* row's first column; data.get(0)[1] would be the first row's second
* column, and so on.
*/
protected List<Object[]> data;
/**
* The current row. This gets updated by next().
*/
protected Object[] curRow;
/**
* The current column. This gets set to -1 (invalid) in next(),
* and to the most recently requested column index in the getXXX()
* methods. Used by wasNull().
*/
private int curCol = -1;
/**
* Our cached copy of the original ResultSetMetaData.
*/
protected CachedResultSetMetaData rsmd = new CachedResultSetMetaData();
/**
* Currently-registered listeners who are interested in knowing when new
* rows are added.
*/
private final List<RowSetChangeListener> rowSetListeners =
new ArrayList<RowSetChangeListener>();
/**
* This is the "populate" method for streaming result sets. This method will
* update the cached row set with a new row every time one is inserted into
* the result set and notify the listener of the new row. Only rowLimit rows
* will be stored in the cached row set and when the row limit is reached
* the oldest row in the cached row set will be removed.
*
* @param rs
* The result set to track.
* @param listener
* A listener that will be notified that a new row was added to
* the cached row set. More listeners can be added from the
* {@link CachedRowSet#addRowSetChangeListener(RowSetChangeListener)}
* method.
* @param rowLimit
* The maximum number of rows this cached row set will store. Old
* rows will be removed when necessary to make room for new rows.
* @throws SQLException
*/
public void follow(ResultSet rs, int rowLimit, String ... extraColNames) throws SQLException {
data = Collections.synchronizedList(new ArrayList<Object[]>());
logger.debug("crs@" + System.identityHashCode(this) + " starting to follow...");
rsmd = new CachedResultSetMetaData(rs.getMetaData(), this.makeUppercase);
int rsColCount = rsmd.getColumnCount();
int colCount = rsColCount + extraColNames.length;
for (String extraColName : extraColNames) {
/* bleh */
rsmd.addColumn(
false, false, false, false, DatabaseMetaData.columnNullable,
true, 10, extraColName, extraColName, null, 10, 0, null,
null, Types.VARCHAR, "VARCHAR", false, true, true,
String.class.getName());
}
int rowNum = 0;
while (rs.next()) {
if (logger.isDebugEnabled()) {
logger.debug("crs@" + System.identityHashCode(this) + " populating Row " + rowNum);
}
Object[] row = new Object[colCount];
for (int i = 0; i < rsColCount; i++) {
Object o = rs.getObject(i+1);
if (logger.isDebugEnabled()) {
if (o == null) {
logger.debug(" Col "+i+": null");
} else {
logger.debug(" Col "+i+": "+o+" ("+o.getClass()+")");
}
}
row[i] = o;
}
synchronized (data) {
data.add(row);
while (data.size() > rowLimit) {
data.remove(0);
}
}
fireRowAdded(row, rowNum);
rowNum++;
}
}
/**
* Returs a sorted copy of this resultset. The result copy
* will not be linked to the original one and will not be
* populated nor refreshed. It is a snapshot of the current state
* of the resultset.
*
* @param c
*
* @return A copy of this rs, sorted
*/
public CachedRowSet sort(RowComparator c) {
CachedRowSet newRs = new CachedRowSet();
try {
newRs.populate(this);
} catch (SQLException e) {
throw new RuntimeException(e);
}
if (this.data != null) {
synchronized (data) {
Collections.sort(newRs.data, c);
}
}
return newRs;
}
/**
* Fills this row set with all the data of the given result set.
* After populating this row set, you can safely call rs.close().
*/
public void populate(ResultSet rs) throws SQLException {
populate(rs, null);
}
/**
* Fills this row set with all the data of the given result set
* which is accepted by the given row filter.
* After populating this row set, you can safely call rs.close().
*
* @param rs The result set to read all data from
* @param filter the filter to consult about which rows to keep
*/
public void populate(ResultSet rs, RowFilter filter) throws SQLException {
populate(rs, filter, new String[0]);
}
/**
* Fills this row set with all the data of the given result set
* which is accepted by the given row filter.
* After populating this row set, you can safely call rs.close().
*
* @param rs The result set to read all data from
* @param filter the filter to consult about which rows to keep
* @param extraColNames The names of any extra placeholder columns
* you want to add to the copy of the given result set. The result set
* metadata for those columns will claim they are all VARCHAR columns,
* but you can put any type of data in them. After populate() has returned,
* all rows will contain null values for the extra columns.
*/
public void populate(ResultSet rs, RowFilter filter, String ... extraColNames) throws SQLException {
rsmd = new CachedResultSetMetaData(rs.getMetaData(), this.makeUppercase);
int rsColCount = rsmd.getColumnCount();
int colCount = rsColCount + extraColNames.length;
for (String extraColName : extraColNames) {
/* bleh */
rsmd.addColumn(
false, false, false, false, DatabaseMetaData.columnNullable,
true, 10, extraColName, extraColName, null, 10, 0, null,
null, Types.VARCHAR, "VARCHAR", false, true, true,
String.class.getName());
}
int rowNum = 0;
data = Collections.synchronizedList(new ArrayList<Object[]>());
if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
rs.beforeFirst();
}
while (rs.next()) {
if (logger.isDebugEnabled()) logger.debug("Populating Row "+rowNum);
Object[] row = new Object[colCount];
for (int i = 0; i < rsColCount; i++) {
Object o = rs.getObject(i+1);
if (o == null) {
if (logger.isDebugEnabled()) logger.debug(" Col "+i+": null");
} else {
if (logger.isDebugEnabled()) logger.debug(" Col "+i+": "+o+" ("+o.getClass()+")");
}
row[i] = o;
}
if (filter == null || filter.acceptsRow(row)) {
synchronized (data) {
data.add(row);
rowNum++;
}
} else {
logger.debug("Skipped this row (rejected by filter)");
}
}
}
public static class RowComparator implements Comparator<Object[]>, java.io.Serializable {
private ArrayList<SortCol> sortCols;
/**
* Creates a RowComparator which returns rows in their natural
* order.
*/
public RowComparator() {
sortCols = new ArrayList<SortCol>();
}
/**
* Adds a column to sort by (in ascending or descending
* order). If you call this method multiple times, the order
* that columns are given in is significant: the first column
* given is the primary sort column, the second is the
* secondary, and so on.
*/
public void addSortColumn(int columnIndex, boolean ascending) {
sortCols.add(new SortCol(columnIndex, ascending));
}
@SuppressWarnings("unchecked")
public int compare(Object[] r1, Object[] r2) {
// Object[] r1 = (Object[]) row1;
// Object[] r2 = (Object[]) row2;
int diff = 0;
for (SortCol sc : sortCols) {
if (r1 == null && r2 == null) diff = 0;
else if (r1 == null) diff = -1;
else if (r2 == null) diff = 1;
else if (r1[sc.columnIndex - 1] instanceof Number && r2[sc.columnIndex - 1] instanceof Number) {
double d1 = ((Number) r1[sc.columnIndex - 1]).doubleValue();
double d2 = ((Number) r2[sc.columnIndex - 1]).doubleValue(); // see threepio
if (d1 < d2) diff = -1;
else if (d1 > d2) diff = 1;
else diff = 0;
} else if (r1[sc.columnIndex - 1] instanceof String && r2[sc.columnIndex - 1] instanceof String) {
String s1 = ((String) r1[sc.columnIndex - 1]);
String s2 = ((String) r2[sc.columnIndex - 1]);
diff = s1.compareToIgnoreCase(s2);
} else if (r1[sc.columnIndex - 1] instanceof Comparable && r2[sc.columnIndex - 1] instanceof Comparable) {
Comparable c1 = (Comparable) r1[sc.columnIndex - 1];
Comparable c2 = (Comparable) r2[sc.columnIndex - 1];
//This may throw an exception if c1 and c2 are not of mutually comparable types.
//That would mean the same column contains two different types of objects
//that cannot be compared to each other, which we think would be a fault in the JDBC driver.
diff = c1.compareTo(c2);
} else {
Object r1ColVal = r1[sc.columnIndex - 1];
Object r2ColVal = r2[sc.columnIndex - 1];
if (r1ColVal == null && r2ColVal == null) diff = 0;
else if (r1ColVal == null) diff = -1;
else if (r2ColVal == null) diff = 1;
else diff = 0; // relying on stability of MergeSort to keep rows in order database returned them in
}
if (diff != 0) {
if (sc.ascending) break;
else { diff = 0 - diff; break; }
}
}
return diff;
}
/**
* Returns true iff there are no sort columns specified in this comparator.
*/
public boolean isEmpty() {
return sortCols.isEmpty();
}
private static class SortCol implements java.io.Serializable {
public int columnIndex;
public boolean ascending;
public SortCol(int columnIndex, boolean ascending) {
this.columnIndex = columnIndex;
this.ascending = ascending;
}
}
}
/**
* Returns true if the given row would pass the given filter.
*
* @param row
* The row index to test. The first row has an index of 1.
* @param resultSetFilter
* The filter to test against. If null, this method always
* returns true.
* @return Whether or not the given row would pass the given filter.
*/
public boolean wouldPass(int row, @Nullable RowFilter resultSetFilter) throws SQLException {
if (resultSetFilter == null) {
return true;
} else {
if (data == null) {
return true;
} else {
synchronized (data) {
return resultSetFilter.acceptsRow(data.get(row - 1));
}
}
}
}
/**
* Tells how many rows are in this row set.
*/
public int size() {
if (data == null) {
return 0;
}
synchronized (data) {
return data.size();
}
}
/**
* Tells this cached result set if it should make all column names upper case.
* @param makeUppercase
*/
public void setMakeUppercase(boolean makeUppercase) {
this.makeUppercase = makeUppercase;
}
/**
* Returns the list of rows in this result set.
*/
public List<Object[]> getData() {
if (data == null)
return new ArrayList<Object[]>();
else {
synchronized (data) {
return Collections.unmodifiableList(new ArrayList<Object[]>(data));
}
}
}
/**
* Returns the index of the column having the given name or -1 if
* there is no such column. The comparison is case insensitive.
*
* <p>The findColumn in the ResultSet interface throws an
* exception if the column does not exist.
*
* @throws SQLException if the ResultSetMetaData operations result
* in a SQLException. No exception will be thrown if the named
* column simply doesn't exist in the result set.
*/
public int getColumnIndex(String columnName) throws SQLException {
int idx = -1;
for (int i = 0; i < rsmd.getColumnCount(); i++) {
if (rsmd.getColumnName(i + 1).equalsIgnoreCase(columnName)) {
idx = i + 1;
break;
}
}
if (logger.isDebugEnabled()) {
logger.debug("getColumnIndex("+columnName+") returns "+idx);
}
return idx;
}
/**
* Adds the given listener to this row set's list of interested parties.
* Each listener on the list receives an event whenever a new row has been
* added to this row set.
* <p>
* Presently, this only works for streaming queries. However, it is likely
* that in the future we will also make these events happen as a result of
* the {@link #insertRow()} method being called.
*
* @param listener
* The listener to add (must not be null).
* @see #follow(ResultSet, RowSetChangeListener, int, String...)
*/
public void addRowSetListener(@Nonnull RowSetChangeListener listener) {
if (listener == null) {
throw new NullPointerException("Null listener not allowed");
}
rowSetListeners.add(listener);
}
/**
* Removes the given listener from the listener list. Has no effect if the
* given listener was not already on the list.
*
* @param listener The listener to remove. Nulls are ignored.
*/
public void removeRowSetListener(@Nullable RowSetChangeListener listener) {
rowSetListeners.remove(listener);
}
/**
* Fires an event with the given row information. This CachedRowSet is the
* event's source. The row should already have been inserted into the result
* set prior to calling this method.
*
* @param row
* The actual data in the new row
* @param rowNum
* The row number where the new row was inserted
*/
protected void fireRowAdded(Object[] row, int rowNum) {
if (logger.isDebugEnabled()) {
logger.debug("crs@" + System.identityHashCode(this) +
" firing RowAdded for " + rowSetListeners.size() + " listeners...");
}
RowSetChangeEvent evt = new RowSetChangeEvent(this, row, rowNum);
for (int i = rowSetListeners.size() - 1; i >= 0; i--) {
RowSetChangeListener l = rowSetListeners.get(i);
if (logger.isDebugEnabled()) {
logger.debug("crs@" + System.identityHashCode(this) +
" delivering RowAdded to " + l.getClass().getSimpleName() +
"@" + System.identityHashCode(l));
}
l.rowAdded(evt);
}
}
// =============================================
// RESULTSET INTERFACE IS BELOW THIS LINE
// =============================================
/**
* Does nothing, since a cached row set holds no SQL database
* resources. If you want to free the memory used by the cached
* data in this row set, delete all references to this row set and
* it will be garbage collected like any other normal object.
*/
public void close() throws SQLException {
return;
}
/**
* Returns true if the previous getXXX() method referenced a null
* value. wasNull() is especially useful when working with the
* get methods for native java types (which can't be null).
*/
public boolean wasNull() throws SQLException {
if (curRow == null || curCol < 0)
throw new SQLException("You haven't accessed a value with a getXXX() method yet!");
return curRow[curCol] == null;
}
//==============================================
// RESULTS BY COLUMN INDEX
//==============================================
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public String getString(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return null;
} else {
return curRow[columnIndex - 1].toString();
}
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public boolean getBoolean(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return false;
} else {
return ((Boolean) curRow[columnIndex - 1]).booleanValue();
}
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public byte getByte(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return (byte) 0;
} else {
return ((Number) curRow[columnIndex - 1]).byteValue();
}
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public short getShort(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return (short) 0;
} else {
return ((Number) curRow[columnIndex - 1]).shortValue();
}
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public int getInt(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return (int) 0;
} else {
return ((Number) curRow[columnIndex - 1]).intValue();
}
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public long getLong(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return (long) 0;
} else {
return ((Number) curRow[columnIndex - 1]).longValue();
}
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public float getFloat(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return (float) 0;
} else {
return ((Number) curRow[columnIndex - 1]).floatValue();
}
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public double getDouble(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return (double) 0;
} else {
return ((Number) curRow[columnIndex - 1]).doubleValue();
}
}
/**
* Not supported.
*/
public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* Not supported.
*/
public byte[] getBytes(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public java.sql.Date getDate(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return null;
} else {
java.util.Date uDate = (java.util.Date) curRow[columnIndex - 1];
return new java.sql.Date (uDate.getTime());
}
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public java.sql.Time getTime(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return null;
} else {
return (java.sql.Time) curRow[columnIndex - 1];
}
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[columnIndex - 1] == null) {
return null;
} else {
return (java.sql.Timestamp) curRow[columnIndex - 1];
}
}
/**
* Not supported.
*/
public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* Not supported.
*/
public java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* Not supported.
*/
public java.io.InputStream getBinaryStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public Object getObject(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
return curRow[columnIndex - 1];
}
/**
* User-defined type maps aren't supported.
*/
public Object getObject(int i, java.util.Map<String, Class<?>> map) throws SQLException {
throw new UnsupportedOperationException
("This CachedRowSet does not support user-defined type mappings."); }
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public Ref getRef(int i) throws SQLException {
curCol = i - 1;
return (Ref) curRow[i - 1];
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public Blob getBlob(int i) throws SQLException {
curCol = i - 1;
return (Blob) curRow[i - 1];
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public Clob getClob(int i) throws SQLException {
curCol = i - 1;
return (Clob) curRow[i - 1];
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0).
*/
public Array getArray(int i) throws SQLException {
curCol = i - 1;
return (Array) curRow[i - 1];
}
/**
* Works like getDate(int). Ignores cal.
*/
public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException {
return getDate(columnIndex);
}
/**
* Works like getTime(int). Ignores cal.
*/
public java.sql.Time getTime(int columnIndex, Calendar cal) throws SQLException {
return getTime(columnIndex);
}
/**
* Works like getTimestamp(int). Ignores cal.
*/
public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
return getTimestamp(columnIndex);
}
/**
* Tries to convert the string representation of the value at
* columnIndex in the current row to a URL object. If successful,
* the URL is returned.
*/
public java.net.URL getURL(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
if (curRow[curCol] == null) {
return null;
} else if (curRow[curCol] instanceof java.net.URL) {
return (java.net.URL) curRow[curCol];
} else try {
return new java.net.URL(getString(columnIndex));
} catch (java.net.MalformedURLException e) {
throw new SQLException("Not a URL: <"+getString(columnIndex)+">");
}
}
//==========================================
// RESULTS BY COLUMN NAME
//==========================================
/**
* See {@link #getString(int)}.
*/
public String getString(String columnName) throws SQLException {
return getString(findColumn(columnName));
}
/**
* See {@link #getBoolean(int)}.
*/
public boolean getBoolean(String columnName) throws SQLException {
return getBoolean(findColumn(columnName));
}
/**
* See {@link #getByte(int)}.
*/
public byte getByte(String columnName) throws SQLException {
return getByte(findColumn(columnName));
}
/**
* See {@link #getShort(int)}.
*/
public short getShort(String columnName) throws SQLException {
return getShort(findColumn(columnName));
}
/**
* See {@link #getInt(int)}.
*/
public int getInt(String columnName) throws SQLException {
return getInt(findColumn(columnName));
}
/**
* See {@link #getLong(int)}.
*/
public long getLong(String columnName) throws SQLException {
return getLong(findColumn(columnName));
}
/**
* See {@link #getFloat(int)}.
*/
public float getFloat(String columnName) throws SQLException {
return getFloat(findColumn(columnName));
}
/**
* See {@link #getDouble(int)}.
*/
public double getDouble(String columnName) throws SQLException {
return getDouble(findColumn(columnName));
}
/**
* See {@link #getBigDecimal(int)}.
*/
public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
return getBigDecimal(findColumn(columnName));
}
/**
* See {@link #getBytes(int)}.
*/
public byte[] getBytes(String columnName) throws SQLException {
return getBytes(findColumn(columnName));
}
/**
* See {@link #getDate(int)}.
*/
public java.sql.Date getDate(String columnName) throws SQLException {
return getDate(findColumn(columnName));
}
/**
* See {@link #getTime(int)}.
*/
public java.sql.Time getTime(String columnName) throws SQLException {
return getTime(findColumn(columnName));
}
/**
* See {@link #getTimestamp(int)}.
*/
public java.sql.Timestamp getTimestamp(String columnName) throws SQLException {
return getTimestamp(findColumn(columnName));
}
/**
* See {@link #getAsciiStream(int)}.
*/
public java.io.InputStream getAsciiStream(String columnName) throws SQLException {
return getAsciiStream(findColumn(columnName));
}
/**
* See {@link #getUnicodeStream(int)}.
*/
public java.io.InputStream getUnicodeStream(String columnName) throws SQLException {
return getUnicodeStream(findColumn(columnName));
}
/**
* See {@link #getBinaryStream(int)}.
*/
public java.io.InputStream getBinaryStream(String columnName) throws SQLException {
return getBinaryStream(findColumn(columnName));
}
/**
* See {@link #getObject(int)}.
*/
public Object getObject(String columnName) throws SQLException {
return getObject(findColumn(columnName));
}
/**
* User-defined type maps aren't supported.
*/
public Object getObject(String colName, java.util.Map<String, Class<?>> map) throws SQLException {
return getObject(findColumn(colName), map);
}
/**
* See {@link #getRef(int)}.
*/
public Ref getRef(String colName) throws SQLException {
return getRef(findColumn(colName));
}
/**
* See {@link #getBlob(int)}.
*/
public Blob getBlob(String colName) throws SQLException {
return getBlob(findColumn(colName));
}
/**
* See {@link #getClob(int)}.
*/
public Clob getClob(String colName) throws SQLException {
return getClob(findColumn(colName));
}
/**
* See {@link #getArray(int)}.
*/
public Array getArray(String colName) throws SQLException {
return getArray(findColumn(colName));
}
/**
* Works like {@link #getDate(String)}. Ignores cal.
*/
public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException {
return getDate(columnName);
}
/**
* Works like {@link #getTime(String)}. Ignores cal.
*/
public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException {
return getTime(columnName);
}
/**
* Works like {@link #getTimestamp(String)}. Ignores cal.
*/
public java.sql.Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
return getTimestamp(columnName);
}
/**
* See {@link #net(int)}.
*/
public java.net.URL getURL(String columnName) throws SQLException {
return getURL(findColumn(columnName));
}
// ====================================
// META DATA
// ====================================
/**
* Returns our cached copy of the original ResultSet's meta data.
*/
public ResultSetMetaData getMetaData() throws SQLException {
return rsmd;
}
/**
* Returns the index of the named column. Column name matches are
* case insensitive.
*
* @throws SQLException if there is no such column.
*/
public int findColumn(String columnName) throws SQLException {
int index = getColumnIndex(columnName);
if (index == -1) {
throw new SQLException("No such column '"+columnName+"' in this result set.");
} else {
return index;
}
}
// ====================================
// POSITIONING
// ====================================
/**
* Tells whether or not the current row pointer is before the
* first row. If so, that means calling next() will put the
* cursor on the first row.
*/
public boolean isBeforeFirst() throws SQLException {
if (data == null) return false;
return rownum == BEFORE_FIRST_ROW;
}
/**
* Tells whether or not the current row pointer is after the last
* row. If so, that means calling next() will return false and
* leave the cursor on an invalid row.
*/
public boolean isAfterLast() throws SQLException {
if (data == null) return false;
synchronized (data) {
return rownum >= data.size();
}
}
/**
* Tells whether or not the current row pointer is on the first
* row.
*/
public boolean isFirst() throws SQLException {
if (data == null) return false;
return rownum == 0;
}
/**
* Tells whether or not the current row pointer is on the last
* row.
*/
public boolean isLast() throws SQLException {
if (data == null) return false;
synchronized (data) {
return rownum == (data.size() - 1);
}
}
/**
* Repositions the cursor to its default position. Same as
* calling absolute(0).
*/
public void beforeFirst() throws SQLException {
absolute(0);
}
/**
* Repositions the cursor just past the last row. Same as
* calling absolute(size()).
*/
public void afterLast() throws SQLException {
if (data != null) {
synchronized (data) {
absolute(data.size());
}
}
}
/**
* Repositions the cursor to the first row. Same as calling
* absolute(1).
*/
public boolean first() throws SQLException {
return absolute(1);
}
/**
* Repositions the cursor to the last row. Same as calling
* absolute(-1).
*/
public boolean last() throws SQLException {
return absolute(-1);
}
/**
* Returns the current row number that the cursor points to. 1 is
* the first row, 0 is before the first row.
*/
public int getRow() throws SQLException {
if (rownum < 0) return 0;
else return rownum + 1;
}
/**
* Moves the current row pointer to the given position.
*
* @param row the number of the row to which the cursor should
* move. A positive number indicates the row number counting from
* the beginning of the result set; a negative number indicates
* the row number counting from the end of the result set
* @return <code>true</code> if the reposition operation left the
* cursor on a valid row (the getXXX() methods will work).
*/
public boolean absolute(int row) throws SQLException {
if (data == null) return false;
synchronized (data) {
curCol = -1;
curRow = null;
// adjust row to be a 0-based index from beginning of data set
if (row < 0) {
rownum = data.size() + row;
} else {
rownum = row - 1;
}
// same as beforeFirst()
if (rownum < 0) {
rownum = BEFORE_FIRST_ROW;
return false;
}
// same as afterLast()
if (rownum >= data.size()) {
rownum = data.size();
return false;
}
// now do the positioning
if (data.size() > 0) {
curRow = (Object[]) data.get(rownum);
return true;
} else {
return false;
}
}
}
/**
* Increments the current row pointer. This method is the
* "normal" way of iterating through the result set, but it is
* equivalent to calling relative(1).
*/
public boolean next() throws SQLException {
return relative(1);
}
/**
* Decrements the current row pointer. This method is equivalent
* to calling relative(-1).
*/
public boolean previous() throws SQLException {
return relative(-1);
}
/**
* Moves the current row pointer ahead by the given number of rows
* (actually moves it back if rows is negative). An argument of
* rows = 0 does not move the current row pointer, but does reset
* the current column pointer, which means wasNull() will not work
* until you call getXXX() again.
*
* <p>If the specified offset moves the cursor outside the data
* set, this method is like beforeFirst() or afterLast() depending
* on which side of the data set you said to move to.
*
* @param rows the number of rows to move from the current row.
* Positive means to move the cursor forward; negative means to
* move the cursor backward.
* @return <code>true</code> if the cursor is left on a valid row;
* <code>false</code> otherwise.
*/
public boolean relative(int rows) throws SQLException {
if (data == null) return false;
synchronized (data) {
curCol = -1;
curRow = null;
rownum += rows;
if (rownum < 0) {
rownum = BEFORE_FIRST_ROW;
return false;
}
if (rownum >= data.size()) {
rownum = data.size();
return false;
}
curRow = (Object[]) data.get(rownum);
return true;
}
}
/**
* Not supported.
*
* @throws UnsupportedOperationException if direction != FETCH_FORWARD.
*/
public void setFetchDirection(int direction) throws SQLException {
if (direction != FETCH_FORWARD) {
throw new UnsupportedOperationException("Fetch direction is always FORWARD.");
}
}
/**
* Always returns FETCH_FORWARD.
*/
public int getFetchDirection() throws SQLException {
return FETCH_FORWARD;
}
// ====================================
// MISC UNSUPPORTED STUFF
// ====================================
/**
* Not supported.
*/
public Statement getStatement() throws SQLException {
throw new UnsupportedOperationException("This CachedRowSet does not have a reference to the Statement object.");
}
/**
* Not supported.
*/
public SQLWarning getWarnings() throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* Not supported.
*/
public void clearWarnings() throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* Not supported.
*/
public String getCursorName() throws SQLException {
throw new SQLException("Updates are not supported by CachedRowSet");
}
/**
* Not supported.
*/
public java.io.Reader getCharacterStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* Not supported.
*/
public java.io.Reader getCharacterStream(String columnName) throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* Returns the value in the current row at the given column index
* (the first column number is 1, not 0). If the value retrieved at
* the index is not a BigDecimal but can be converted to one it will
* be converted and returned in a BigDecimal.
*/
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
curCol = columnIndex - 1;
Object curColObject = curRow[columnIndex - 1];
if (curColObject == null) {
return new BigDecimal(0);
} else {
if (curColObject instanceof BigDecimal) {
return (BigDecimal) curRow[columnIndex - 1];
} else if (curColObject instanceof Number) {
return new BigDecimal(String.valueOf(curColObject));
} else {
throw new SQLException("Could not convert column " + columnIndex + " of type " + curColObject.getClass() + " to BigDecimal.");
}
}
}
/**
* Not supported.
*/
public BigDecimal getBigDecimal(String columnName) throws SQLException {
throw new UnsupportedOperationException("This method is not supported by CachedRowSet");
}
/**
* This setting is not important for a cached row set. It will
* not throw an exception, but calling it has no effect.
*/
public void setFetchSize(int rows) throws SQLException {
// doesn't matter
}
/**
* This setting is not important for a cached row set.
*
* @return The number of rows in this result set.
*/
public int getFetchSize() throws SQLException {
return data == null ? 0 : data.size();
}
/**
* This is a cached row set, so it always returns the same type:
* TYPE_SCROLL_INSENSITIVE.
*
* @return TYPE_SCROLL_INSENSITIVE
*/
public int getType() throws SQLException {
return TYPE_SCROLL_INSENSITIVE;
}
/**
* This is a cached row set that will not accept changes. Always
* returns CONCUR_READ_ONLY.
*
* @return CONCUR_READ_ONLY
*/
public int getConcurrency() throws SQLException {
return CONCUR_READ_ONLY;
}
// ====================================
// UPDATES BY INDEX (NOT SUPPORTED)
// ====================================
/**
* Returns false, even if the row has been modified.
*/
public boolean rowUpdated() throws SQLException {
return false;
}
/**
* Returns false (inserts and deletes are not supported).
*/
public boolean rowInserted() throws SQLException {
return false;
}
/**
* Returns false (inserts and deletes are not supported).
*/
public boolean rowDeleted() throws SQLException {
return false;
}
/**
* Assigns the columnIndex'th item in the current row to null.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateNull(int columnIndex) throws SQLException {
curRow[columnIndex - 1] = null;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateBoolean(int columnIndex, boolean x) throws SQLException {
curRow[columnIndex - 1] = (x ? Boolean.TRUE : Boolean.FALSE);
}
/**
* Assigns the columnIndex'th item in the current row to the given value.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateByte(int columnIndex, byte x) throws SQLException {
curRow[columnIndex - 1] = BigDecimal.valueOf(x);
}
/**
* Assigns the columnIndex'th item in the current row to the given value.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateShort(int columnIndex, short x) throws SQLException {
curRow[columnIndex - 1] = BigDecimal.valueOf(x);
}
/**
* Assigns the columnIndex'th item in the current row to the given value.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateInt(int columnIndex, int x) throws SQLException {
curRow[columnIndex - 1] = BigDecimal.valueOf(x);
}
/**
* Assigns the columnIndex'th item in the current row to the given value.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateLong(int columnIndex, long x) throws SQLException {
curRow[columnIndex - 1] = BigDecimal.valueOf(x);
}
/**
* Assigns the columnIndex'th item in the current row to the given value.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateFloat(int columnIndex, float x) throws SQLException {
curRow[columnIndex - 1] = BigDecimal.valueOf(x);
}
/**
* Assigns the columnIndex'th item in the current row to the given value.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateDouble(int columnIndex, double x) throws SQLException {
curRow[columnIndex - 1] = BigDecimal.valueOf(x);
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateString(int columnIndex, String x) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateBytes(int columnIndex, byte x[]) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateDate(int columnIndex, java.sql.Date x) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateTime(int columnIndex, java.sql.Time x) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateTimestamp(int columnIndex, java.sql.Timestamp x)
throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Not supported.
*/
public void updateAsciiStream(int columnIndex, java.io.InputStream x, int length)
throws SQLException {
throw new UnsupportedOperationException("Not supported!");
}
/**
* Not supported.
*/
public void updateBinaryStream(int columnIndex, java.io.InputStream x, int length)
throws SQLException {
throw new UnsupportedOperationException("Not supported!");
}
/**
* Not supported.
*/
public void updateCharacterStream(int columnIndex, java.io.Reader x, int length)
throws SQLException {
throw new UnsupportedOperationException("Not supported!");
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateObject(int columnIndex, Object x, int scale) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateObject(int columnIndex, Object x) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateArray(int columnIndex, java.sql.Array x) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateClob(int columnIndex, java.sql.Clob x) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateBlob(int columnIndex, java.sql.Blob x) throws SQLException {
curRow[columnIndex - 1] = x;
}
/**
* Assigns the columnIndex'th item in the current row to the given object.
* There is no automatic way to propogate this change to the database, but
* the change will remain in memory for the life of this CachedRowSet.
*/
public void updateRef(int columnIndex, java.sql.Ref x) throws SQLException {
if (curRow == null) throw new SQLException("Not on a valid row");
curRow[columnIndex - 1] = x;
}
// ====================================
// UPDATES BY NAME (FORWARD TO UPDATE-BY-INDEX)
// ====================================
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateNull(String columnName) throws SQLException {
updateNull(findColumn(columnName));
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateBoolean(String columnName, boolean x) throws SQLException {
updateBoolean(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateByte(String columnName, byte x) throws SQLException {
updateByte(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateShort(String columnName, short x) throws SQLException {
updateShort(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateInt(String columnName, int x) throws SQLException {
updateInt(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateLong(String columnName, long x) throws SQLException {
updateLong(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateFloat(String columnName, float x) throws SQLException {
updateFloat(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateDouble(String columnName, double x) throws SQLException {
updateDouble(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
updateBigDecimal(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateString(String columnName, String x) throws SQLException {
updateString(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateBytes(String columnName, byte x[]) throws SQLException {
updateBytes(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateDate(String columnName, java.sql.Date x) throws SQLException {
updateDate(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateTime(String columnName, java.sql.Time x) throws SQLException {
updateTime(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException {
updateTimestamp(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateAsciiStream(String columnName, java.io.InputStream x, int length) throws SQLException {
updateAsciiStream(findColumn(columnName), x, length);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException {
updateBinaryStream(findColumn(columnName), x, length);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateCharacterStream(String columnName, java.io.Reader reader, int length) throws SQLException {
updateCharacterStream(findColumn(columnName), reader, length);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateObject(String columnName, Object x, int scale) throws SQLException {
updateObject(findColumn(columnName), x, scale);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateObject(String columnName, Object x) throws SQLException {
updateObject(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateRef(String columnName, java.sql.Ref x) throws SQLException {
updateRef(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateBlob(String columnName, java.sql.Blob x) throws SQLException {
updateBlob(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateClob(String columnName, java.sql.Clob x) throws SQLException {
updateClob(findColumn(columnName), x);
}
/**
* Forwards to the corresponding method that takes a column index.
*
* @throws SQLException if there is no column with the given name.
*/
public void updateArray(String columnName, java.sql.Array x) throws SQLException {
updateArray(findColumn(columnName), x);
}
// ====================================
// ROW INSERTION METHODS
// ====================================
/**
* The value of {@link #rownum} before {@link #insertRow()} was called.
* This value will be restored by {@link #moveToCurrentRow()}.
*/
private int rownumBeforeInserting;
/**
* Guards against inserting the same "insert row" multiple times.
*/
private boolean insertRowAlreadyInserted;
public void moveToInsertRow() throws SQLException {
curRow = new Object[rsmd.getColumnCount()];
// handle the case of inserting multiple rows without an
// intervening call to moveToCurrentRow() by preserving
// original "before insert" row number
if (rownum != INSERT_ROW) {
rownumBeforeInserting = rownum;
}
rownum = INSERT_ROW;
insertRowAlreadyInserted = false;
}
public void insertRow() throws SQLException {
synchronized (data) {
if (rownum != INSERT_ROW) {
throw new SQLException("Not on insert row");
}
if (insertRowAlreadyInserted) {
throw new SQLException("The insert row has already been inserted");
}
data.add(curRow);
insertRowAlreadyInserted = true;
}
}
public void moveToCurrentRow() throws SQLException {
if (rownum == INSERT_ROW) {
rownum = rownumBeforeInserting;
rownumBeforeInserting = 0;
}
}
// ====================================
// UPDATE COMMIT METHODS (NOT SUPPORTED)
// ====================================
/**
* Not supported.
*/
public void updateRow() throws SQLException {
throw new UnsupportedOperationException("Updates not supported!");
}
/**
* Not supported.
*/
public void deleteRow() throws SQLException {
throw new UnsupportedOperationException("Updates not supported!");
}
/**
* Not supported.
*/
public void refreshRow() throws SQLException {
throw new UnsupportedOperationException("Updates not supported!");
}
/**
* Not supported.
*/
public void cancelRowUpdates() throws SQLException {
throw new UnsupportedOperationException("Updates not supported!");
}
public int getHoldability() throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public Reader getNCharacterStream(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public Reader getNCharacterStream(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public NClob getNClob(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public NClob getNClob(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public String getNString(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public String getNString(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public RowId getRowId(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public RowId getRowId(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public SQLXML getSQLXML(int columnIndex) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public SQLXML getSQLXML(String columnLabel) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public boolean isClosed() throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateAsciiStream(int columnIndex, InputStream x)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateAsciiStream(String columnLabel, InputStream x)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateAsciiStream(int columnIndex, InputStream x, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateAsciiStream(String columnLabel, InputStream x, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateBinaryStream(int columnIndex, InputStream x)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateBinaryStream(String columnLabel, InputStream x)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateBinaryStream(int columnIndex, InputStream x, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateBinaryStream(String columnLabel, InputStream x,
long length) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateBlob(int columnIndex, InputStream inputStream)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateBlob(String columnLabel, InputStream inputStream)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateBlob(int columnIndex, InputStream inputStream, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateBlob(String columnLabel, InputStream inputStream,
long length) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateCharacterStream(int columnIndex, Reader x)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateCharacterStream(String columnLabel, Reader reader)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateCharacterStream(int columnIndex, Reader x, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateCharacterStream(String columnLabel, Reader reader,
long length) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateClob(int columnIndex, Reader reader) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateClob(String columnLabel, Reader reader)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateClob(int columnIndex, Reader reader, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateClob(String columnLabel, Reader reader, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNCharacterStream(int columnIndex, Reader x)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNCharacterStream(String columnLabel, Reader reader)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNCharacterStream(int columnIndex, Reader x, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNCharacterStream(String columnLabel, Reader reader,
long length) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNClob(int columnIndex, NClob clob) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNClob(String columnLabel, NClob clob) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNClob(int columnIndex, Reader reader) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNClob(String columnLabel, Reader reader)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNClob(int columnIndex, Reader reader, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNClob(String columnLabel, Reader reader, long length)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNString(int columnIndex, String string)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateNString(String columnLabel, String string)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateRowId(int columnIndex, RowId x) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateRowId(String columnLabel, RowId x) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateSQLXML(int columnIndex, SQLXML xmlObject)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public void updateSQLXML(String columnLabel, SQLXML xmlObject)
throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
public <T> T unwrap(Class<T> iface) throws SQLException {
throw new UnsupportedOperationException("Currently it is only possible to wrap JDBC 3.");
}
@SuppressWarnings("unchecked")
@Override
public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {
curCol = columnIndex - 1;
return (T) curRow[columnIndex - 1];
}
@SuppressWarnings("unchecked")
@Override
public <T> T getObject(String columnLabel, Class<T> type)
throws SQLException {
return (T) getObject(findColumn(columnLabel));
}
}