You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by to...@apache.org on 2008/04/09 13:02:07 UTC
svn commit: r646264 [10/13] - in /harmony/enhanced/classlib/branches/java6:
depends/build/ depends/build/platform/ depends/files/
modules/accessibility/ modules/annotation/ modules/applet/ modules/archive/
modules/archive/src/main/java/java/util/jar/ m...
Modified: harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java?rev=646264&r1=646263&r2=646264&view=diff
==============================================================================
--- harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java (original)
+++ harmony/enhanced/classlib/branches/java6/modules/sql/src/main/java/org/apache/harmony/sql/internal/rowset/CachedRowSetImpl.java Wed Apr 9 04:01:14 2008
@@ -16,8 +16,15 @@
*/
package org.apache.harmony.sql.internal.rowset;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.io.StringBufferInputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Array;
@@ -42,13 +49,18 @@
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.Hashtable;
+import java.util.List;
import java.util.Map;
import java.util.Vector;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
import javax.sql.RowSet;
import javax.sql.RowSetEvent;
import javax.sql.RowSetInternal;
@@ -58,6 +70,10 @@
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetMetaDataImpl;
import javax.sql.rowset.RowSetWarning;
+import javax.sql.rowset.serial.SerialArray;
+import javax.sql.rowset.serial.SerialBlob;
+import javax.sql.rowset.serial.SerialClob;
+import javax.sql.rowset.serial.SerialRef;
import javax.sql.rowset.spi.SyncFactory;
import javax.sql.rowset.spi.SyncFactoryException;
import javax.sql.rowset.spi.SyncProvider;
@@ -71,19 +87,36 @@
private static final long serialVersionUID = 1L;
- private ArrayList<CachedRow> rows;
+ protected ArrayList<CachedRow> rows;
- private RowSetMetaData meta;
+ protected RowSetMetaData meta;
- private CachedRow currentRow;
+ protected CachedRow currentRow;
- // start from : 1.
- private int currentRowIndex;
+ /**
+ * current row index include deleted rows, start from 1
+ */
+ protected int currentRowIndex;
// the number of the rows in one "page"
private int pageSize;
- private int pageNumber = 1;
+ /**
+ * used for paging, record row index for next page in ResultSet, start from
+ * 1
+ */
+ private int nextPageRowIndex = -1;
+
+ /**
+ * used for paging, record row index for previous page in ResultSet, start
+ * from 1
+ */
+ private int previousPageRowIndex = -1;
+
+ /**
+ * cached ResultSet for paging in memory
+ */
+ private CachedRowSet cachedResultSet = null;
private String tableName;
@@ -91,21 +124,38 @@
private CachedRow insertRow;
- // TODO remember to evalute it in CachedRowSetReader
+ private boolean isCursorOnInsert;
+
private int[] keyCols;
private int columnCount;
+ private int deletedRowCount;
+
private SyncProvider syncProvider;
- // TODO where is it initialized
private CachedRowSetImpl originalResultSet;
- private SQLWarning sqlwarn;
+ private SQLWarning sqlwarn = new SQLWarning();
+
+ // TODO deal with rowSetWarning
+ private RowSetWarning rowSetWarning = new RowSetWarning();
private Class[] columnTypes;
- private static Map<Integer, Class> TYPE_MAPPING = initialTypeMapping();
+ private String[] matchColumnNames;
+
+ private int[] matchColumnIndexes;
+
+ private String cursorName;
+
+ private boolean isLastColNull;
+
+ private transient Connection conn;
+
+ private boolean isNotifyListener = true;
+
+ private static Map<Integer, Class<?>> TYPE_MAPPING = initialTypeMapping();
public static final String PROVIDER_ID = "Apache Harmony HYOptimisticProvider"; //$NON-NLS-1$
@@ -114,8 +164,8 @@
initialProperties();
}
- private static Map<Integer, Class> initialTypeMapping() {
- HashMap<Integer, Class> map = new HashMap<Integer, Class>();
+ private static Map<Integer, Class<?>> initialTypeMapping() {
+ HashMap<Integer, Class<?>> map = new HashMap<Integer, Class<?>>();
map.put(Integer.valueOf(Types.ARRAY), Array.class);
map.put(Integer.valueOf(Types.BIGINT), Long.class);
map.put(Integer.valueOf(Types.BINARY), byte[].class);
@@ -175,46 +225,128 @@
}
public void acceptChanges() throws SyncProviderException {
- if (currentRow == insertRow && currentRow != null) {
- throw new SyncProviderException();
+ if (isCursorOnInsert) {
+ // rowset.11=Illegal operation on an insert row
+ throw new SyncProviderException(Messages.getString("rowset.11")); //$NON-NLS-1$
}
+ Connection currentConn = null;
+ Connection preConn = conn;
try {
- acceptChanges(getConnection());
+ currentConn = retrieveConnection();
+ currentConn.setTypeMap(getTypeMap());
+ acceptChanges(currentConn);
} catch (SQLException e) {
- // FIXME deal with the exception, not just print it
- e.printStackTrace();
+ try {
+ if (currentConn != null) {
+ currentConn.rollback();
+ }
+ } catch (SQLException ex) {
+ // ignore
+ }
+ SyncProviderException ex = new SyncProviderException();
+ ex.initCause(e);
+ throw ex;
+ } finally {
+ conn = preConn;
+ if (currentConn != null) {
+ try {
+ currentConn.commit();
+ currentConn.close();
+ } catch (SQLException ex) {
+ SyncProviderException spe = new SyncProviderException();
+ spe.initCause(ex);
+ throw spe;
+ }
+ }
}
}
public void acceptChanges(Connection con) throws SyncProviderException {
- if (currentRow == insertRow && currentRow != null) {
- // TODO add error messages
- throw new SyncProviderException();
+ if (isCursorOnInsert) {
+ // rowset.11=Illegal operation on an insert row
+ throw new SyncProviderException(Messages.getString("rowset.11")); //$NON-NLS-1$
}
+ conn = con;
try {
+ conn.setAutoCommit(false);
CachedRowSetWriter rowSetWriter = (CachedRowSetWriter) syncProvider
.getRowSetWriter();
rowSetWriter.setConnection(con);
int beforeWriteIndex = currentRowIndex;
+ boolean isShowDeleted = getShowDeleted();
+ // writer use next navigate rowset, so must make all rows visible
+ setShowDeleted(true);
+
rowSetWriter.writeData(this);
+
+ // must reset curosr before reset showDeleted
absolute(beforeWriteIndex);
- /*
- * FIXME: if no conflicts happen when writeData, then call
- * setOriginalRow()
- */
- notifyRowSetChanged();
+ setShowDeleted(isShowDeleted);
+
+ // record to the next visible row index
+ int index = getRow();
+ if (index == 0) {
+ next();
+ index = getRow();
+ if (index == 0) {
+ index = rows.size() + 1;
+ }
+ }
+
+ boolean isChanged = false;
+ for (int i = rows.size() - 1; i >= 0; i--) {
+ currentRow = rows.get(i);
+ if (rowDeleted()) {
+ isChanged = true;
+ setOriginalRow();
+ } else if (rowInserted() || rowUpdated()) {
+ isChanged = true;
+ setOriginalRow();
+ }
+ }
+ // Set originalResultSet
+ if (isChanged) {
+ try {
+ ArrayList<CachedRow> nowRows = new ArrayList<CachedRow>();
+ for (int i = 0; i < rows.size(); i++) {
+ nowRows.add(rows.get(i).createClone());
+ nowRows.get(i).restoreOriginal();
+ }
+ originalResultSet.setRows(nowRows, columnCount);
+ } catch (CloneNotSupportedException cloneE) {
+ throw new SyncProviderException(cloneE.getMessage());
+ }
+ }
+
+ deletedRowCount = 0;
+
+ // move cursor
+ if (index > rows.size()) {
+ afterLast();
+ } else if (index <= 0) {
+ beforeFirst();
+ } else {
+ absolute(index);
+ }
+
+ if (isNotifyListener) {
+ notifyRowSetChanged();
+ }
} catch (SyncProviderException e) {
throw e;
} catch (SQLException e) {
- throw new SyncProviderException(e.getMessage());
+ SyncProviderException ex = new SyncProviderException();
+ ex.initCause(e);
+ throw ex;
}
}
public boolean columnUpdated(int idx) throws SQLException {
- if (currentRow == null || idx > meta.getColumnCount()) {
+ if (currentRow == null || idx > meta.getColumnCount() || idx <= 0
+ || currentRow == insertRow) {
// rowset.0 = Not a valid position
throw new SQLException(Messages.getString("rowset.0")); //$NON-NLS-1$
}
@@ -226,6 +358,10 @@
}
private int getIndexByName(String columnName) throws SQLException {
+ if (meta == null || columnName == null) {
+ throw new NullPointerException();
+ }
+
for (int i = 1; i <= meta.getColumnCount(); i++) {
if (columnName.equalsIgnoreCase(meta.getColumnName(i))) {
return i;
@@ -236,7 +372,10 @@
}
public void commit() throws SQLException {
- getConnection().commit();
+ if (conn == null) {
+ throw new NullPointerException();
+ }
+ conn.commit();
}
public CachedRowSet createCopy() throws SQLException {
@@ -260,12 +399,12 @@
output = (CachedRowSetImpl) super.clone();
// BaseRowSet.params
Field paramsField = output.getClass().getSuperclass()
- .getDeclaredField("params");
+ .getDeclaredField("params"); //$NON-NLS-1$
paramsField.setAccessible(true);
paramsField.set(output, paramsHashtable);
// BaseRowSet.listeners
Field listenersField = output.getClass().getSuperclass()
- .getDeclaredField("listeners");
+ .getDeclaredField("listeners"); //$NON-NLS-1$
listenersField.setAccessible(true);
listenersField.set(output, listeners);
// BaseRowSet.map
@@ -300,16 +439,14 @@
copyOriginalRs.populate(getOriginal());
output.originalResultSet = copyOriginalRs;
- /*
- * TODO uncomment after getMatchColumnIndexes and
- * getMatchColumnNames implemented
- */
- // if (getMatchColumnIndexes() != null) {
- // output.setMatchColumn(getMatchColumnIndexes().clone());
- // }
- // if (getMatchColumnNames() != null) {
- // output.setMatchColumn(getMatchColumnNames().clone());
- // }
+ if (matchColumnIndexes != null) {
+ output.matchColumnIndexes = matchColumnIndexes.clone();
+ }
+
+ if (matchColumnNames != null) {
+ output.matchColumnNames = matchColumnNames.clone();
+ }
+
output.setSyncProvider(getSyncProvider().getProviderID());
if (insertRow != null) {
output.insertRow = insertRow.createClone();
@@ -317,14 +454,11 @@
return output;
} catch (CloneNotSupportedException e) {
- // TODO add error message
- throw new SQLException();
+ throw new SQLException(e.getMessage());
} catch (NoSuchFieldException e) {
- // TODO add error message
- throw new SQLException();
+ throw new SQLException(e.getMessage());
} catch (IllegalAccessException e) {
- // TODO add error message
- throw new SQLException();
+ throw new SQLException(e.getMessage());
}
}
@@ -341,10 +475,13 @@
output.currentRow = null;
output.currentRowIndex = 0;
output.insertRow = null;
- output.pageNumber = 1;
+ output.isCursorOnInsert = false;
+ output.isLastColNull = false;
+ output.nextPageRowIndex = -1;
output.rememberedCursorPosition = 0;
output.rows = new ArrayList<CachedRow>();
output.sqlwarn = null;
+ output.deletedRowCount = 0;
return output;
}
@@ -355,33 +492,81 @@
try {
result = (RowSet) super.clone();
} catch (CloneNotSupportedException e) {
- // TODO add error message
- throw new SQLException();
+ throw new SQLException(e.getMessage());
}
return result;
}
- public void execute(Connection conn) throws SQLException {
- // ensure the getConnection can works!
+ public void execute(Connection connection) throws SQLException {
String localCommand = getCommand();
if (localCommand == null || getParams() == null) {
- // TODO add error messages
- throw new SQLException();
+ // rowset.16=Not a valid command
+ throw new SQLException(Messages.getString("rowset.16")); //$NON-NLS-1$
}
- PreparedStatement ps = conn.prepareStatement(localCommand);
- Object[] params = getParams();
- for (int i = 0; i < params.length; i++)
- ps.setObject(i + 1, params[i]);
+ conn = connection;
+ PreparedStatement ps = connection.prepareStatement(localCommand);
+ setParameter(ps);
if (ps.execute()) {
doPopulate(ps.getResultSet(), true);
+
+ if (getPageSize() != 0) {
+ nextPageRowIndex = rows.size() + 1;
+ previousPageRowIndex = 0;
+ cachedResultSet = null;
+ } else {
+ previousPageRowIndex = -1;
+ nextPageRowIndex = -1;
+ cachedResultSet = null;
+ }
+ }
+
+ }
+
+ private void setParameter(PreparedStatement ps) throws SQLException {
+ Object[] params = getParams();
+ for (int i = 0; i < params.length; i++) {
+ if (params[i] instanceof Object[]) {
+ Object[] objs = (Object[]) params[i];
+ // character stream
+ if (objs.length == 2) {
+ ps.setCharacterStream(i + 1, (Reader) objs[0],
+ ((Integer) objs[1]).intValue());
+ } else {
+ int type = ((Integer) objs[2]).intValue();
+ switch (type) {
+ case BaseRowSet.ASCII_STREAM_PARAM:
+ ps.setAsciiStream(i + 1, (InputStream) objs[0],
+ ((Integer) objs[1]).intValue());
+ break;
+ case BaseRowSet.BINARY_STREAM_PARAM:
+ ps.setBinaryStream(i + 1, (InputStream) objs[0],
+ ((Integer) objs[1]).intValue());
+ break;
+ case BaseRowSet.UNICODE_STREAM_PARAM:
+ ps.setUnicodeStream(i + 1, (InputStream) objs[0],
+ ((Integer) objs[1]).intValue());
+ break;
+ }
+ }
+ } else {
+ ps.setObject(i + 1, params[i]);
+ }
}
}
public int[] getKeyColumns() throws SQLException {
- return keyCols == null ? null : keyCols.clone();
+ if (rows == null) {
+ // rowset.26=The object has not been initialized
+ throw new SQLException(Messages.getString("rowset.26")); //$NON-NLS-1$
+ }
+ if (keyCols == null) {
+ return new int[0];
+ }
+
+ return keyCols;
}
public ResultSet getOriginal() throws SQLException {
@@ -390,14 +575,15 @@
public ResultSet getOriginalRow() throws SQLException {
if (currentRow == null) {
- // TODO add error messages
- throw new SQLException();
+ // rowset.7=Not a valid cursor
+ throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
}
CachedRowSetImpl originalRowRset = new CachedRowSetImpl();
ArrayList<CachedRow> data = new ArrayList<CachedRow>();
- CachedRow originalCachedRow = rows.get(getRow() - 1).getOriginal();
+ CachedRow originalCachedRow = currentRow.getOriginal();
data.add(originalCachedRow);
+ originalRowRset.setMetaData(meta);
originalRowRset.setRows(data, columnCount);
originalRowRset.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
originalRowRset.setConcurrency(ResultSet.CONCUR_UPDATABLE);
@@ -409,7 +595,7 @@
}
public RowSetWarning getRowSetWarnings() throws SQLException {
- throw new NotImplementedException();
+ return rowSetWarning;
}
public SyncProvider getSyncProvider() throws SQLException {
@@ -421,30 +607,110 @@
}
/**
- * TODO refill the cachedrowset with pagesize, and the previous rowset was
- * replaced
+ * TODO refactor paging
*/
public boolean nextPage() throws SQLException {
- pageNumber++;
+ if (rows == null || nextPageRowIndex == -1 || getPageSize() == 0) {
+ // rowset.19=Populate data before calling
+ throw new SQLException(Messages.getString("rowset.19")); //$NON-NLS-1$
+ }
+
+ if (cachedResultSet == null) {
+ String localCommand = getCommand();
+ if (localCommand == null || getParams() == null) {
+ // rowset.16=Not a valid command
+ throw new SQLException(Messages.getString("rowset.16")); //$NON-NLS-1$
+ }
+
+ PreparedStatement ps = retrieveConnection().prepareStatement(
+ localCommand);
+
+ setParameter(ps);
+
+ if (ps.execute()) {
+ ResultSet rs = ps.getResultSet();
+ int index = 1;
+ while (rs.next() && index < nextPageRowIndex - 1) {
+ index++;
+ }
+
+ isNotifyListener = false;
+ doPopulate(rs, true);
+ notifyRowSetChanged();
+ isNotifyListener = true;
+
+ if (rows.size() == 0) {
+ return false;
+ }
+ previousPageRowIndex = nextPageRowIndex - 1;
+ nextPageRowIndex += rows.size();
+ return true;
+
+ }
+ return false;
+
+ }
+
+ if (cachedResultSet.absolute(nextPageRowIndex)) {
+ cachedResultSet.previous();
+
+ isNotifyListener = false;
+ doPopulate(cachedResultSet, true);
+ notifyRowSetChanged();
+ isNotifyListener = true;
+
+ if (rows.size() == 0) {
+ return false;
+ }
+ previousPageRowIndex = nextPageRowIndex - 1;
+ nextPageRowIndex += rows.size();
+ return true;
+ }
return false;
+
}
public void populate(ResultSet rs) throws SQLException {
doPopulate(rs, false);
+ previousPageRowIndex = -1;
+ nextPageRowIndex = -1;
+ cachedResultSet = null;
}
public void populate(ResultSet rs, int startRow) throws SQLException {
+ if (rs == null) {
+ // sql.42=Illegal Argument
+ throw new SQLException(Messages.getString("sql.42")); //$NON-NLS-1$
+ }
+
if (startRow == 1) {
rs.beforeFirst();
+ // maybe use next to move is better
} else if (startRow <= 0 || !rs.absolute(startRow - 1)) {
// rowset.7=Not a valid cursor
throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
}
- doPopulate(rs, true);
+ // paging in memory
+ if (getPageSize() != 0) {
+ cachedResultSet = new CachedRowSetImpl();
+ cachedResultSet.setMaxRows(getMaxRows());
+ cachedResultSet.populate(rs, startRow);
+ doPopulate(cachedResultSet, true);
+
+ nextPageRowIndex = rows.size() + 1;
+ previousPageRowIndex = 0;
+
+ } else {
+ doPopulate(rs, true);
+ previousPageRowIndex = -1;
+ nextPageRowIndex = -1;
+ cachedResultSet = null;
+ }
}
private void doPopulate(ResultSet rs, boolean isPaging) throws SQLException {
+ isNotifyListener = false;
meta = copyMetaData(rs.getMetaData());
columnCount = meta.getColumnCount();
@@ -454,6 +720,17 @@
columnTypes[i - 1] = TYPE_MAPPING.get(Integer.valueOf(meta
.getColumnType(i)));
}
+ try {
+ cursorName = rs.getCursorName();
+ } catch (SQLException e) {
+ cursorName = null;
+ // ignore
+ }
+
+ if (rs.getStatement() != null
+ && rs.getStatement().getConnection() != null) {
+ setTypeMap(rs.getStatement().getConnection().getTypeMap());
+ }
/*
* this method not support paging, so before readData set pageSize and
@@ -482,78 +759,218 @@
// recovery the states
beforeFirst();
+
+ isNotifyListener = true;
+ if (isNotifyListener) {
+ notifyRowSetChanged();
+ }
}
// deep copy of ResultSetMetaData
- private RowSetMetaData copyMetaData(ResultSetMetaData metaData)
+ protected RowSetMetaData copyMetaData(ResultSetMetaData metaData)
throws SQLException {
RowSetMetaDataImpl rowSetMetaData = new RowSetMetaDataImpl();
rowSetMetaData.setColumnCount(metaData.getColumnCount());
for (int columnIndex = 1; columnIndex <= metaData.getColumnCount(); columnIndex++) {
rowSetMetaData.setAutoIncrement(columnIndex, metaData
.isAutoIncrement(columnIndex));
- rowSetMetaData.setCaseSensitive(columnIndex, metaData
- .isCaseSensitive(columnIndex));
- rowSetMetaData.setCatalogName(columnIndex, metaData
- .getCatalogName(columnIndex));
- rowSetMetaData.setColumnDisplaySize(columnIndex, metaData
- .getColumnDisplaySize(columnIndex));
- rowSetMetaData.setColumnLabel(columnIndex, metaData
- .getColumnLabel(columnIndex));
- rowSetMetaData.setColumnName(columnIndex, metaData
- .getColumnName(columnIndex));
- rowSetMetaData.setColumnType(columnIndex, metaData
- .getColumnType(columnIndex));
- rowSetMetaData.setColumnTypeName(columnIndex, metaData
- .getColumnTypeName(columnIndex));
- rowSetMetaData.setCurrency(columnIndex, metaData
- .isCurrency(columnIndex));
- rowSetMetaData.setNullable(columnIndex, metaData
- .isNullable(columnIndex));
- rowSetMetaData.setPrecision(columnIndex, metaData
- .getPrecision(columnIndex));
- rowSetMetaData
- .setScale(columnIndex, metaData.getScale(columnIndex));
- rowSetMetaData.setSchemaName(columnIndex, metaData
- .getSchemaName(columnIndex));
- rowSetMetaData.setSearchable(columnIndex, metaData
- .isSearchable(columnIndex));
- rowSetMetaData.setSigned(columnIndex, metaData
- .isSigned(columnIndex));
- rowSetMetaData.setTableName(columnIndex, metaData
- .getTableName(columnIndex));
+ doCopyMetaData(rowSetMetaData, columnIndex, metaData, columnIndex);
}
return rowSetMetaData;
}
+ protected void doCopyMetaData(RowSetMetaData targetRsmd, int targetIndex,
+ ResultSetMetaData srcRsmd, int srcIndex) throws SQLException {
+ targetRsmd.setAutoIncrement(targetIndex, srcRsmd
+ .isAutoIncrement(srcIndex));
+ targetRsmd.setCaseSensitive(targetIndex, srcRsmd
+ .isCaseSensitive(srcIndex));
+ targetRsmd
+ .setCatalogName(targetIndex, srcRsmd.getCatalogName(srcIndex));
+ targetRsmd.setColumnDisplaySize(targetIndex, srcRsmd
+ .getColumnDisplaySize(srcIndex));
+ targetRsmd
+ .setColumnLabel(targetIndex, srcRsmd.getColumnLabel(srcIndex));
+ targetRsmd.setColumnName(targetIndex, srcRsmd.getColumnName(srcIndex));
+ targetRsmd.setColumnType(targetIndex, srcRsmd.getColumnType(srcIndex));
+ targetRsmd.setColumnTypeName(targetIndex, srcRsmd
+ .getColumnTypeName(srcIndex));
+ targetRsmd.setCurrency(targetIndex, srcRsmd.isCurrency(srcIndex));
+ targetRsmd.setNullable(targetIndex, srcRsmd.isNullable(srcIndex));
+ targetRsmd.setPrecision(targetIndex, srcRsmd.getPrecision(srcIndex));
+ targetRsmd.setScale(targetIndex, srcRsmd.getScale(srcIndex));
+ targetRsmd.setSchemaName(targetIndex, srcRsmd.getSchemaName(srcIndex));
+ targetRsmd.setSearchable(targetIndex, srcRsmd.isSearchable(srcIndex));
+ targetRsmd.setSigned(targetIndex, srcRsmd.isSigned(srcIndex));
+ targetRsmd.setTableName(targetIndex, srcRsmd.getTableName(srcIndex));
+ }
+
public boolean previousPage() throws SQLException {
- // TODO implement it
- return false;
+ if (rows == null || previousPageRowIndex == -1 || getPageSize() == 0) {
+ // rowset.19=Populate data before calling
+ throw new SQLException(Messages.getString("rowset.19")); //$NON-NLS-1$
+ }
+
+ if (previousPageRowIndex == 0) {
+ return false;
+ }
+
+ if (cachedResultSet == null) {
+ String localCommand = getCommand();
+ if (localCommand == null || getParams() == null) {
+ // rowset.16=Not a valid command
+ throw new SQLException(Messages.getString("rowset.16")); //$NON-NLS-1$
+ }
+
+ PreparedStatement ps = retrieveConnection().prepareStatement(
+ localCommand);
+
+ setParameter(ps);
+
+ if (ps.execute()) {
+ ResultSet rs = ps.getResultSet();
+ int startIndex = previousPageRowIndex - getPageSize() + 1;
+
+ if (startIndex <= 0) {
+ startIndex = 1;
+ }
+
+ int index = 0;
+ while (index < startIndex - 1) {
+ if (!rs.next()) {
+ break;
+ }
+ index++;
+ }
+
+ int prePageSize = getPageSize();
+ if (prePageSize != 0
+ && previousPageRowIndex - startIndex + 1 != prePageSize) {
+ setPageSize(previousPageRowIndex - startIndex + 1);
+ }
+ isNotifyListener = false;
+ doPopulate(rs, true);
+ notifyRowSetChanged();
+ isNotifyListener = true;
+
+ setPageSize(prePageSize);
+
+ if (rows.size() == 0) {
+ return false;
+ }
+ nextPageRowIndex = previousPageRowIndex + 1;
+ previousPageRowIndex = startIndex - 1;
+ return true;
+ }
+
+ return false;
+ }
+
+ int startIndex = previousPageRowIndex - getPageSize() + 1;
+
+ if (startIndex <= 0) {
+ startIndex = 1;
+ }
+
+ if (!cachedResultSet.absolute(startIndex)) {
+ return false;
+ }
+
+ cachedResultSet.previous();
+
+ int prePageSize = getPageSize();
+ if (prePageSize != 0
+ && previousPageRowIndex - startIndex + 1 != prePageSize) {
+ setPageSize(previousPageRowIndex - startIndex + 1);
+ }
+
+ doPopulate(cachedResultSet, true);
+
+ setPageSize(prePageSize);
+
+ if (rows.size() == 0) {
+ return false;
+ }
+ nextPageRowIndex = previousPageRowIndex + 1;
+ previousPageRowIndex = startIndex - 1;
+ return true;
}
public void release() throws SQLException {
- throw new NotImplementedException();
+ rows = new ArrayList<CachedRow>();
+ notifyRowSetChanged();
}
public void restoreOriginal() throws SQLException {
- throw new NotImplementedException();
+ if (rows == null) {
+ return;
+ }
+
+ isNotifyListener = false;
+ List<CachedRow> insertedRows = new ArrayList<CachedRow>();
+ for (CachedRow row : rows) {
+ if (row.isInsert()) {
+ insertedRows.add(row);
+ } else if (row.isDelete() || row.isUpdate()) {
+ row.restoreOriginal();
+ }
+ }
+ rows.removeAll(insertedRows);
+ insertRow = null;
+ isCursorOnInsert = false;
+ deletedRowCount = 0;
+
+ first();
+ isNotifyListener = true;
+ notifyRowSetChanged();
}
public void rollback() throws SQLException {
- throw new NotImplementedException();
+ if (conn == null) {
+ throw new NullPointerException();
+ }
+ conn.rollback();
}
public void rollback(Savepoint s) throws SQLException {
- throw new NotImplementedException();
+ if (conn == null) {
+ throw new NullPointerException();
+ }
+ conn.rollback(s);
}
public void rowSetPopulated(RowSetEvent event, int numRows)
throws SQLException {
- throw new NotImplementedException();
+ if (numRows <= 0) {
+ // sql.42=Illegal Argument
+ throw new SQLException(Messages.getString("sql.42")); //$NON-NLS-1$
+ }
+ if (numRows < getFetchSize()) {
+ // rowset.22=Number of rows is less than fetch size
+ throw new SQLException(Messages.getString("rowset.22")); //$NON-NLS-1$
+ }
+ if (size() == 0 || size() % numRows == 0) {
+ notifyRowSetChanged();
+ }
}
public void setKeyColumns(int[] keys) throws SQLException {
- keyCols = keys.clone();
+ if (keys == null) {
+ throw new NullPointerException();
+ }
+
+ if (rows == null) {
+ keyCols = keys.clone();
+ } else {
+ for (int key : keys) {
+ if (key <= 0 || key > columnCount) {
+ // sql.27=Invalid column index :{0}
+ throw new SQLException(Messages.getString("sql.27", key)); //$NON-NLS-1$
+ }
+ }
+
+ keyCols = keys.clone();
+ }
}
public void setMetaData(RowSetMetaData md) throws SQLException {
@@ -561,13 +978,17 @@
}
public void setOriginalRow() throws SQLException {
-
- // FIXME re-implements this method
if (currentRow == null) {
- // TODO add error messages
- throw new SQLException();
+ // rowset.7=Not a valid cursor
+ throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
+ }
+
+ if (rowDeleted()) {
+ rows.remove(currentRow);
+ deletedRowCount--;
+ } else if (rowUpdated() || rowInserted()) {
+ currentRow.setOriginal();
}
- currentRow.setNonUpdateable();
}
public void setPageSize(int size) throws SQLException {
@@ -589,7 +1010,7 @@
public void setTableName(String tabName) throws SQLException {
if (tabName == null) {
// rowset.3=Table name should not be null
- throw new SQLException("rowset.3"); //$NON-NLS-1$
+ throw new SQLException(Messages.getString("rowset.3")); //$NON-NLS-1$
}
tableName = tabName;
}
@@ -602,91 +1023,305 @@
}
public Collection<?> toCollection() throws SQLException {
- throw new NotImplementedException();
+ if (rows == null) {
+ // sql.38=Object is invalid
+ throw new SQLException(Messages.getString("sql.38")); //$NON-NLS-1$
+ }
+ List<Vector<Object>> list = new ArrayList<Vector<Object>>();
+ if (rows.size() > 0) {
+ Vector<Object> vector = null;
+ for (int i = 0; i < rows.size(); i++) {
+ CachedRow row = rows.get(i);
+ vector = new Vector<Object>();
+ for (int j = 1; j <= columnCount; j++) {
+ vector.add(row.getObject(j));
+ }
+ list.add(vector);
+ }
+ }
+ return list;
}
public Collection<?> toCollection(int column) throws SQLException {
- throw new NotImplementedException();
+ if (rows == null) {
+ return new Vector<Object>();
+ }
+
+ if (column <= 0 || column > columnCount) {
+ // sql.42=Illegal Argument
+ throw new SQLException(Messages.getString("sql.42")); //$NON-NLS-1$
+ }
+
+ Vector<Object> vector = new Vector<Object>();
+ if (rows.size() > 0) {
+ for (int i = 0; i < rows.size(); i++) {
+ vector.add(rows.get(i).getObject(column));
+ }
+ }
+ return vector;
}
public Collection<?> toCollection(String column) throws SQLException {
- throw new NotImplementedException();
+ return toCollection(getIndexByName(column));
}
public void undoDelete() throws SQLException {
- if (currentRow == null) {
- // TODO add error messages
- throw new SQLException();
+ if (isAfterLast() || isBeforeFirst()) {
+ // rowset.7=Not a valid cursor
+ throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
+ }
+
+ if (currentRow != null && !currentRow.isDelete()) {
+ // rowset.0=Not a valid position
+ throw new SQLException(Messages.getString("rowset.0")); //$NON-NLS-1$
}
- if (currentRow.isDelete()) {
+
+ if (currentRow != null && currentRow.isDelete()) {
currentRow.undoDelete();
+ deletedRowCount--;
+ }
+
+ if (isNotifyListener) {
+ notifyRowChanged();
}
}
public void undoInsert() throws SQLException {
- throw new NotImplementedException();
+ checkValidRow();
+ if (isCursorOnInsert) {
+ // rowset.11=Illegal operation on an insert row
+ throw new SQLException(Messages.getString("rowset.11")); //$NON-NLS-1$
+ }
+ if (!rowInserted()) {
+ // rowset.4=Not an insert row
+ throw new SQLException(Messages.getString("rowset.4")); //$NON-NLS-1$
+ }
+ rows.remove(currentRow);
+ next();
+ if (isNotifyListener) {
+ notifyRowChanged();
+ }
}
public void undoUpdate() throws SQLException {
- throw new NotImplementedException();
+ checkValidRow();
+ if (isCursorOnInsert && insertRow == null) {
+ // rowset.11=Illegal operation on an insert row
+ throw new SQLException(Messages.getString("rowset.11")); //$NON-NLS-1$
+ }
+ if (currentRow == insertRow) {
+ currentRow = new CachedRow(new Object[columnCount]);
+ } else if (rowUpdated()) {
+ currentRow.restoreOriginal();
+ }
+
+ if (isNotifyListener) {
+ notifyRowChanged();
+ }
}
public int[] getMatchColumnIndexes() throws SQLException {
- throw new NotImplementedException();
+ if (matchColumnIndexes == null || matchColumnIndexes.length == 0
+ || matchColumnIndexes[0] == -1) {
+ // rowset.13=Set Match columns before getting them
+ throw new SQLException(Messages.getString("rowset.13")); //$NON-NLS-1$
+ }
+
+ return matchColumnIndexes.clone();
}
public String[] getMatchColumnNames() throws SQLException {
- throw new NotImplementedException();
+ if (matchColumnNames == null || matchColumnNames.length == 0
+ || matchColumnNames[0] == null) {
+ // rowset.13=Set Match columns before getting them
+ throw new SQLException(Messages.getString("rowset.13")); //$NON-NLS-1$
+ }
+ return matchColumnNames.clone();
}
public void setMatchColumn(int columnIdx) throws SQLException {
- throw new NotImplementedException();
+ if (columnIdx < 0) {
+ // TODO why is 0 valid?
+ // rowset.20=Match columns should be greater than 0
+ throw new SQLException(Messages.getString("rowset.20")); //$NON-NLS-1$
+ }
+
+ if (matchColumnIndexes == null) {
+ /*
+ * FIXME initial match column, the default length of array is 10 in
+ * RI, we don't know why, just follow now
+ */
+ matchColumnIndexes = new int[10];
+ Arrays.fill(matchColumnIndexes, -1);
+ }
+
+ matchColumnIndexes[0] = columnIdx;
}
public void setMatchColumn(int[] columnIdxes) throws SQLException {
- throw new NotImplementedException();
+ if (columnIdxes == null) {
+ throw new NullPointerException();
+ }
+
+ for (int i : columnIdxes) {
+ if (i < 0) {
+ // TODO why is 0 valid?
+ // rowset.20=Match columns should be greater than 0
+ throw new SQLException(Messages.getString("rowset.20")); //$NON-NLS-1$
+ }
+ }
+
+ if (matchColumnIndexes == null) {
+ /*
+ * FIXME initial match column, the default length of array is 10 in
+ * RI, we don't know why, just follow now
+ */
+ matchColumnIndexes = new int[10];
+ Arrays.fill(matchColumnIndexes, -1);
+ }
+
+ int[] newValue = new int[matchColumnIndexes.length + columnIdxes.length];
+ System.arraycopy(columnIdxes, 0, newValue, 0, columnIdxes.length);
+ System.arraycopy(matchColumnIndexes, 0, newValue, columnIdxes.length,
+ matchColumnIndexes.length);
+
+ matchColumnIndexes = newValue;
}
public void setMatchColumn(String columnName) throws SQLException {
- throw new NotImplementedException();
+ if (columnName == null || columnName.equals("")) { //$NON-NLS-1$
+ // rowset.12=Match columns should not be empty or null string
+ throw new SQLException(Messages.getString("rowset.12")); //$NON-NLS-1$
+ }
+
+ if (matchColumnNames == null) {
+ /*
+ * FIXME initial match column, the default length of array is 10 in
+ * RI, we don't know why, just follow now
+ */
+ matchColumnNames = new String[10];
+ }
+
+ matchColumnNames[0] = columnName;
}
public void setMatchColumn(String[] columnNames) throws SQLException {
- throw new NotImplementedException();
+ if (columnNames == null) {
+ throw new NullPointerException();
+ }
+ for (String name : columnNames) {
+ if (name == null || name.equals("")) { //$NON-NLS-1$
+ // rowset.12=Match columns should not be empty or null string
+ throw new SQLException(Messages.getString("rowset.12")); //$NON-NLS-1$
+ }
+ }
+
+ if (matchColumnNames == null) {
+ /*
+ * FIXME initial match column, the default length of array is 10 in
+ * RI, we don't know why, just follow now
+ */
+ matchColumnNames = new String[10];
+ }
+
+ String[] newValue = new String[matchColumnNames.length
+ + columnNames.length];
+ System.arraycopy(columnNames, 0, newValue, 0, columnNames.length);
+ System.arraycopy(matchColumnNames, 0, newValue, columnNames.length,
+ matchColumnNames.length);
+
+ matchColumnNames = newValue;
}
public void unsetMatchColumn(int columnIdx) throws SQLException {
- throw new NotImplementedException();
+
+ if (matchColumnIndexes == null || matchColumnIndexes.length == 0
+ || matchColumnIndexes[0] != columnIdx) {
+ throw new SQLException(Messages.getString("rowset.15")); //$NON-NLS-1$
+ }
+
+ matchColumnIndexes[0] = -1;
}
public void unsetMatchColumn(int[] columnIdxes) throws SQLException {
- throw new NotImplementedException();
+ if (columnIdxes == null) {
+ throw new NullPointerException();
+ }
+
+ if (columnIdxes.length == 0) {
+ return;
+ }
+
+ if (matchColumnIndexes == null
+ || matchColumnIndexes.length < columnIdxes.length) {
+ throw new SQLException(Messages.getString("rowset.15")); //$NON-NLS-1$
+ }
+
+ for (int i = 0; i < columnIdxes.length; i++) {
+ if (matchColumnIndexes[i] != columnIdxes[i]) {
+ throw new SQLException(Messages.getString("rowset.15")); //$NON-NLS-1$
+ }
+ }
+
+ Arrays.fill(matchColumnIndexes, 0, columnIdxes.length, -1);
}
public void unsetMatchColumn(String columnName) throws SQLException {
- throw new NotImplementedException();
+ if (matchColumnNames == null || matchColumnNames.length == 0
+ || !matchColumnNames[0].equals(columnName)) {
+ throw new SQLException(Messages.getString("rowset.15")); //$NON-NLS-1$
+ }
+
+ matchColumnNames[0] = null;
+
}
public void unsetMatchColumn(String[] columnName) throws SQLException {
- throw new NotImplementedException();
+ if (columnName == null) {
+ throw new NullPointerException();
+ }
+
+ if (columnName.length == 0) {
+ return;
+ }
+
+ if (matchColumnNames == null
+ || matchColumnNames.length < columnName.length) {
+ throw new SQLException(Messages.getString("rowset.15")); //$NON-NLS-1$
+ }
+
+ for (int i = 0; i < columnName.length; i++) {
+ if (matchColumnNames[i] != columnName[i]) {
+ throw new SQLException(Messages.getString("rowset.15")); //$NON-NLS-1$
+ }
+ }
+
+ Arrays.fill(matchColumnNames, 0, columnName.length, null);
}
public boolean absolute(int row) throws SQLException {
- return doAbsolute(row, true);
+ return doAbsolute(getIndexIncludeDeletedRows(row), true);
}
/**
* internal implement of absolute
*
* @param row
- * index of row cursor to move
+ * index of row cursor to move, include deleted rows
* @param checkType
* whether to check property ResultSet.TYPE_FORWARD_ONLY
* @return whether the cursor is on result set
* @throws SQLException
*/
private boolean doAbsolute(int row, boolean checkType) throws SQLException {
+ if (isCursorOnInsert) {
+ // rowset.0=Not a valid position
+ throw new SQLException(Messages.getString("rowset.0")); //$NON-NLS-1$
+ }
if (rows == null || rows.size() == 0) {
+ if (isNotifyListener) {
+ notifyCursorMoved();
+ }
return false;
}
@@ -702,17 +1337,26 @@
if (row <= 0) {
currentRowIndex = 0;
currentRow = null;
+ if (isNotifyListener) {
+ notifyCursorMoved();
+ }
return false;
}
if (row > rows.size()) {
currentRowIndex = rows.size() + 1;
currentRow = null;
+ if (isNotifyListener) {
+ notifyCursorMoved();
+ }
return false;
}
currentRowIndex = row;
currentRow = rows.get(currentRowIndex - 1);
+ if (isNotifyListener) {
+ notifyCursorMoved();
+ }
return true;
}
@@ -729,95 +1373,262 @@
}
public void cancelRowUpdates() throws SQLException {
- throw new NotImplementedException();
+ if (currentRow == null) {
+ // rowset.7=Not a valid cursor
+ throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
+ }
+ if (isCursorOnInsert) {
+ // rowset.11=Illegal operation on an insert row
+ throw new SQLException(Messages.getString("rowset.11")); //$NON-NLS-1$
+ }
+
+ if (rowUpdated()) {
+ currentRow.restoreOriginal();
+ notifyRowChanged();
+ }
}
public void clearWarnings() throws SQLException {
- throw new NotImplementedException();
+ sqlwarn = null;
}
public void close() throws SQLException {
+ String username = getUsername();
+ String password = getPassword();
+ initialProperties();
+ setUsername(username);
+ setPassword(password);
- // TODO need more concerns!
- if (rows != null) {
- rows.clear();
- }
+ rows = new ArrayList<CachedRow>();
currentRowIndex = 0;
currentRow = null;
- meta = null;
-
+ deletedRowCount = 0;
+ isCursorOnInsert = false;
+ isLastColNull = false;
+ matchColumnNames = null;
+ matchColumnIndexes = null;
+ conn = null;
}
public void deleteRow() throws SQLException {
checkValidRow();
+ if (isCursorOnInsert) {
+ // rowset.11=Illegal operation on an insert row
+ throw new SQLException(Messages.getString("rowset.11")); //$NON-NLS-1$
+ }
currentRow.setDelete();
+ deletedRowCount++;
+ if (isNotifyListener) {
+ notifyRowChanged();
+ }
}
private void checkValidRow() throws SQLException {
if (currentRow == null) {
- // rowset.0 = Not a valid position
- throw new SQLException(Messages.getString("rowset.0"));
+ // rowset.7=Not a valid cursor
+ throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * convert <code>index</code> consider property <code>showDeleted</code>.
+ * If <code>showDeleted</code> is true, do nothing, otherwise, re-compute
+ * <code>index</code> add deleted rows.
+ *
+ * @param index
+ * maybe negative, indicate the row number counting from the end
+ * of the result set
+ * @return row index include delted rows
+ */
+ private int getIndexIncludeDeletedRows(int index) throws SQLException {
+ if (getShowDeleted()) {
+ return index;
+ }
+
+ if (index == 0) {
+ return 0;
}
+
+ if (index > 0) {
+ int indexIncludeDeletedRows = 0;
+ for (; index > 0; ++indexIncludeDeletedRows) {
+ if (indexIncludeDeletedRows == rows.size()) {
+ indexIncludeDeletedRows += index;
+ break;
+ }
+
+ if (!rows.get(indexIncludeDeletedRows).isDelete()) {
+ index--;
+ }
+ }
+ return indexIncludeDeletedRows;
+ }
+
+ // index < 0
+ int indexIncludeDeletedRows = rows.size();
+ for (; index < 0; --indexIncludeDeletedRows) {
+ if (indexIncludeDeletedRows == 0) {
+ break;
+ }
+
+ if (!rows.get(indexIncludeDeletedRows - 1).isDelete()) {
+ index++;
+ }
+ }
+ if (indexIncludeDeletedRows != 0) {
+ indexIncludeDeletedRows++;
+ }
+
+ return indexIncludeDeletedRows;
+ }
+
+ /**
+ * If <code>showDeleted</code> property is true, return the rows size
+ * include deleted rows. Otherwise not include deleted rows.
+ *
+ * @return
+ * @throws SQLException
+ */
+ private int getValidRowSize() throws SQLException {
+ if (rows == null) {
+ return 0;
+ }
+
+ if (getShowDeleted()) {
+ return rows.size();
+ }
+
+ return rows.size() - deletedRowCount;
}
public int findColumn(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getIndexByName(columnName);
}
public boolean first() throws SQLException {
- return doAbsolute(1, true);
+ return doAbsolute(getIndexIncludeDeletedRows(1), true);
}
public Array getArray(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+ isLastColNull = false;
+ try {
+ return (Array) obj;
+ } catch (ClassCastException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public Array getArray(String colName) throws SQLException {
- throw new NotImplementedException();
+ return getArray(getIndexByName(colName));
}
public InputStream getAsciiStream(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+
+ isLastColNull = false;
+ if (obj instanceof String) {
+ obj = ((String) obj).toCharArray();
+ }
+
+ if (obj instanceof char[]) {
+ char[] cs = (char[]) obj;
+ byte[] bs = new byte[cs.length];
+
+ for (int i = 0; i < cs.length; i++) {
+ // if out of range, convert to unknown char ox3F
+ if (cs[i] > Byte.MAX_VALUE || cs[i] < Byte.MIN_VALUE) {
+ bs[i] = 63;
+ } else {
+ bs[i] = (byte) cs[i];
+ }
+ }
+
+ return new ByteArrayInputStream(bs);
+ }
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
}
public InputStream getAsciiStream(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getAsciiStream(getIndexByName(columnName));
}
public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
- // TODO re-implement it
- return (BigDecimal) getObject(columnIndex);
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+ isLastColNull = false;
+ try {
+ return new BigDecimal(obj.toString());
+ } catch (NumberFormatException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public BigDecimal getBigDecimal(int columnIndex, int scale)
throws SQLException {
- throw new NotImplementedException();
+ BigDecimal big = getBigDecimal(columnIndex);
+ if (big == null) {
+ return null;
+ }
+ return big.setScale(scale);
}
public BigDecimal getBigDecimal(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getBigDecimal(getIndexByName(columnName));
}
public BigDecimal getBigDecimal(String columnName, int scale)
throws SQLException {
- throw new NotImplementedException();
+ return getBigDecimal(getIndexByName(columnName), scale);
}
public InputStream getBinaryStream(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+
+ isLastColNull = false;
+ if (obj instanceof byte[]) {
+ return new ByteArrayInputStream((byte[]) obj);
+ }
+
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
}
public InputStream getBinaryStream(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getBinaryStream(getIndexByName(columnName));
}
public Blob getBlob(int columnIndex) throws SQLException {
- checkValidRow();
- Object value = currentRow.getObject(columnIndex);
- if (value == null) {
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
return null;
}
- return (Blob) value;
+ isLastColNull = false;
+ try {
+ return (Blob) obj;
+ } catch (ClassCastException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public Blob getBlob(String columnName) throws SQLException {
@@ -825,12 +1636,18 @@
}
public boolean getBoolean(int columnIndex) throws SQLException {
- checkValidRow();
- Object value = currentRow.getObject(columnIndex);
- if (value == null) {
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
return false;
}
- return ((Boolean) value).booleanValue();
+ isLastColNull = false;
+ try {
+ return Boolean.parseBoolean(obj.toString());
+ } catch (Exception e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public boolean getBoolean(String columnName) throws SQLException {
@@ -838,12 +1655,18 @@
}
public byte getByte(int columnIndex) throws SQLException {
- checkValidRow();
- Object value = currentRow.getObject(columnIndex);
- if (value == null) {
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
return 0;
}
- return ((Byte) value).byteValue();
+ isLastColNull = false;
+ try {
+ return Byte.parseByte(obj.toString());
+ } catch (NumberFormatException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public byte getByte(String columnName) throws SQLException {
@@ -851,12 +1674,18 @@
}
public byte[] getBytes(int columnIndex) throws SQLException {
- checkValidRow();
- Object value = currentRow.getObject(columnIndex);
- if (value == null) {
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
return null;
}
- return (byte[]) value;
+ isLastColNull = false;
+ try {
+ return (byte[]) obj;
+ } catch (ClassCastException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public byte[] getBytes(String columnName) throws SQLException {
@@ -864,64 +1693,151 @@
}
public Reader getCharacterStream(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+ isLastColNull = false;
+ if (obj instanceof String) {
+ return new StringReader((String) obj);
+ }
+
+ if (obj instanceof byte[]) {
+ return new StringReader(new String((byte[]) obj));
+ }
+
+ if (obj instanceof char[]) {
+ return new StringReader(new String((char[]) obj));
+ }
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
}
public Reader getCharacterStream(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getCharacterStream(getIndexByName(columnName));
}
public Clob getClob(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+ isLastColNull = false;
+ try {
+ return (Clob) obj;
+ } catch (ClassCastException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public Clob getClob(String colName) throws SQLException {
- throw new NotImplementedException();
+ return getClob(getIndexByName(colName));
}
public String getCursorName() throws SQLException {
- throw new NotImplementedException();
+ if (cursorName == null) {
+ // rowset.14=Positioned updates not supported
+ throw new SQLException(Messages.getString("rowset.14")); //$NON-NLS-1$
+ }
+ return cursorName;
}
public Date getDate(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+ isLastColNull = false;
+ try {
+ if (obj instanceof Date) {
+ return (Date) obj;
+ } else if (obj instanceof Timestamp) {
+ return new Date(((Timestamp) obj).getTime());
+ }
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ } catch (Exception e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public Date getDate(int columnIndex, Calendar cal) throws SQLException {
- throw new NotImplementedException();
+ Date date = getDate(columnIndex);
+ if (date == null) {
+ return null;
+ }
+
+ Calendar tempCal = Calendar.getInstance(cal.getTimeZone());
+ tempCal.setTime(date);
+ cal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONTH),
+ tempCal.get(Calendar.DAY_OF_MONTH));
+ return new Date(cal.getTimeInMillis());
}
public Date getDate(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getDate(getIndexByName(columnName));
}
public Date getDate(String columnName, Calendar cal) throws SQLException {
- throw new NotImplementedException();
+ return getDate(getIndexByName(columnName), cal);
}
public double getDouble(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return 0;
+ }
+ isLastColNull = false;
+ try {
+ return Double.parseDouble(obj.toString());
+ } catch (NumberFormatException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public double getDouble(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getDouble(getIndexByName(columnName));
}
public float getFloat(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return 0;
+ }
+ isLastColNull = false;
+ try {
+ return Float.parseFloat(obj.toString());
+ } catch (NumberFormatException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public float getFloat(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getFloat(getIndexByName(columnName));
}
public int getInt(int columnIndex) throws SQLException {
- checkValidRow();
- Object value = currentRow.getObject(columnIndex);
- if (value == null) {
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
return 0;
}
- return ((Integer) value).intValue();
+ isLastColNull = false;
+ try {
+ return Integer.parseInt(obj.toString());
+ } catch (NumberFormatException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public int getInt(String columnName) throws SQLException {
@@ -929,73 +1845,142 @@
}
public long getLong(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return 0;
+ }
+ isLastColNull = false;
+ try {
+ return Long.parseLong(obj.toString());
+ } catch (NumberFormatException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public long getLong(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getLong(getIndexByName(columnName));
}
public ResultSetMetaData getMetaData() throws SQLException {
return meta;
}
- public Object getObject(int columnIndex) throws SQLException {
- // TODO re-implement it
- return currentRow.getObject(columnIndex);
+ public Object getObject(int columnIndex) throws SQLException {
+ if (meta == null || currentRow == null) {
+ // rowset.7=Not a valid cursor
+ throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
+ }
+ if (columnIndex <= 0 || columnIndex > columnCount) {
+ // sql.27=Invalid column index :{0}
+ throw new SQLException(Messages.getString("sql.27", columnIndex)); //$NON-NLS-1$
+ }
+
+ Object obj = currentRow.getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ } else {
+ isLastColNull = false;
+ }
+ return obj;
}
public Object getObject(int columnIndex, Map<String, Class<?>> map)
throws SQLException {
- throw new NotImplementedException();
+ // FIXME the usage of map
+ return getObject(columnIndex);
}
public Object getObject(String columnName) throws SQLException {
- return currentRow.getObject(getIndexByName(columnName));
+ return getObject(getIndexByName(columnName));
}
public Object getObject(String columnName, Map<String, Class<?>> map)
throws SQLException {
- throw new NotImplementedException();
+ return getObject(getIndexByName(columnName), map);
}
public Ref getRef(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+ isLastColNull = false;
+ try {
+ return (Ref) obj;
+ } catch (Exception e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public Ref getRef(String colName) throws SQLException {
- throw new NotImplementedException();
+ return getRef(getIndexByName(colName));
}
public int getRow() throws SQLException {
- // FIXME need more tests
- if (currentRow == null) {
+ if (currentRow == null || rows == null || isCursorOnInsert) {
+ return 0;
+ }
+
+ if (!getShowDeleted() && currentRow.isDelete()) {
return 0;
}
- return currentRowIndex;
+ if (getShowDeleted() || currentRowIndex == 0) {
+ return currentRowIndex;
+ }
+
+ // doesn't show deleted rows, skip them
+ int index = 0;
+ for (int i = 0; i < currentRowIndex; ++i) {
+ if (!rows.get(i).isDelete()) {
+ index++;
+ }
+ }
+ return index;
+
}
public short getShort(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return 0;
+ }
+ isLastColNull = false;
+ try {
+ return Short.parseShort(obj.toString());
+ } catch (NumberFormatException e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public short getShort(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getShort(getIndexByName(columnName));
}
public Statement getStatement() throws SQLException {
- throw new NotImplementedException();
+ return null;
}
// columnIndex: from 1 rather than 0
public String getString(int columnIndex) throws SQLException {
- checkValidRow();
- Object value = currentRow.getObject(columnIndex);
- if (value == null) {
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
return null;
}
- return (String) value;
+ isLastColNull = false;
+ try {
+ return obj.toString();
+ } catch (Exception e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
private void checkColumnValid(int columnIndex) throws SQLException {
@@ -1006,69 +1991,152 @@
}
}
- private void checkCursorValid() throws SQLException {
- if ((currentRowIndex <= 0) || (currentRowIndex > rows.size())) {
- // rowset.7=Not a valid cursor
- throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
- }
- }
-
public String getString(String columnName) throws SQLException {
return getString(getIndexByName(columnName));
}
public Time getTime(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+ isLastColNull = false;
+ try {
+ if (obj instanceof Time) {
+ return (Time) obj;
+ } else if (obj instanceof Timestamp) {
+ return new Time(((Timestamp) obj).getTime());
+ }
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ } catch (Exception e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public Time getTime(int columnIndex, Calendar cal) throws SQLException {
- throw new NotImplementedException();
+ Time time = getTime(columnIndex);
+ if (time == null) {
+ return null;
+ }
+ Calendar tempCal = Calendar.getInstance(cal.getTimeZone());
+ tempCal.setTimeInMillis(time.getTime());
+ cal.set(Calendar.HOUR, tempCal.get(Calendar.HOUR));
+ cal.set(Calendar.MINUTE, tempCal.get(Calendar.MINUTE));
+ cal.set(Calendar.SECOND, tempCal.get(Calendar.SECOND));
+ return new Time(cal.getTimeInMillis());
}
public Time getTime(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getTime(getIndexByName(columnName));
}
public Time getTime(String columnName, Calendar cal) throws SQLException {
- throw new NotImplementedException();
+ return getTime(getIndexByName(columnName), cal);
}
public Timestamp getTimestamp(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+ isLastColNull = false;
+ try {
+ if (obj instanceof Date) {
+ return new Timestamp(((Date) obj).getTime());
+ } else if (obj instanceof Time) {
+ return new Timestamp(((Time) obj).getTime());
+ }
+ return Timestamp.valueOf(obj.toString());
+ } catch (Exception e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public Timestamp getTimestamp(int columnIndex, Calendar cal)
throws SQLException {
- throw new NotImplementedException();
+ Timestamp timestamp = getTimestamp(columnIndex);
+ if (timestamp == null) {
+ return null;
+ }
+ Calendar tempCal = Calendar.getInstance(cal.getTimeZone());
+ tempCal.setTimeInMillis(timestamp.getTime());
+ cal.set(tempCal.get(Calendar.YEAR), tempCal.get(Calendar.MONDAY),
+ tempCal.get(Calendar.DAY_OF_MONTH), tempCal.get(Calendar.HOUR),
+ tempCal.get(Calendar.MINUTE), tempCal.get(Calendar.SECOND));
+ return new Timestamp(cal.getTimeInMillis());
}
public Timestamp getTimestamp(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getTimestamp(getIndexByName(columnName));
}
public Timestamp getTimestamp(String columnName, Calendar cal)
throws SQLException {
- throw new NotImplementedException();
+ return getTimestamp(getIndexByName(columnName), cal);
}
public java.net.URL getURL(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+ isLastColNull = false;
+ try {
+ return (java.net.URL) obj;
+ } catch (Exception e) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
}
public java.net.URL getURL(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getURL(getIndexByName(columnName));
}
+ @SuppressWarnings("deprecation")
public InputStream getUnicodeStream(int columnIndex) throws SQLException {
- throw new NotImplementedException();
+ Object obj = getObject(columnIndex);
+ if (obj == null) {
+ isLastColNull = true;
+ return null;
+ }
+
+ isLastColNull = false;
+
+ if (obj instanceof byte[]) {
+ return new StringBufferInputStream(new String((byte[]) obj));
+ }
+
+ if (obj instanceof String) {
+ return new StringBufferInputStream((String) obj);
+ }
+
+ if (obj instanceof char[]) {
+ return new StringBufferInputStream(new String((char[]) obj));
+ }
+
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
}
public InputStream getUnicodeStream(String columnName) throws SQLException {
- throw new NotImplementedException();
+ return getUnicodeStream(getIndexByName(columnName));
}
public SQLWarning getWarnings() throws SQLException {
- throw new NotImplementedException();
+ if (sqlwarn == null) {
+ return null;
+ }
+ if (currentRow != null && currentRow.getSqlWarning() != null) {
+ return currentRow.getSqlWarning();
+ }
+ return sqlwarn;
}
public void insertRow() throws SQLException {
@@ -1077,9 +2145,27 @@
// rowset.4=Not an insert row
throw new SQLException(Messages.getString("rowset.4")); //$NON-NLS-1$
}
+ boolean isValueSet = false;
+ for (int i = 0; i < columnCount; i++) {
+ if (currentRow.getUpdateMask(i)) {
+ isValueSet = true;
+ break;
+ }
+ }
+ if (!isValueSet) {
+ // rowset.18=None column is updated
+ throw new SQLException(Messages.getString("rowset.18")); //$NON-NLS-1$
+ }
insertRow.setInsert();
- rows.add(insertRow);
+ if (rememberedCursorPosition > rows.size()) {
+ rows.add(insertRow);
+ } else {
+ rows.add(rememberedCursorPosition, insertRow);
+ }
insertRow = null;
+ if (isNotifyListener) {
+ notifyRowChanged();
+ }
}
public boolean isAfterLast() throws SQLException {
@@ -1099,7 +2185,7 @@
}
public boolean isFirst() throws SQLException {
- return currentRowIndex == 1;
+ return getRow() == 1;
}
public boolean isLast() throws SQLException {
@@ -1107,30 +2193,38 @@
return false;
}
- return currentRowIndex == rows.size();
+ return getRow() == getValidRowSize();
}
public boolean last() throws SQLException {
- return doAbsolute(-1, true);
+ return doAbsolute(getIndexIncludeDeletedRows(-1), true);
}
public void moveToCurrentRow() throws SQLException {
- if (rememberedCursorPosition != -1) {
+ if (isCursorOnInsert) {
currentRowIndex = rememberedCursorPosition;
- if (currentRowIndex >= 1 && currentRowIndex <= size()) {
+ if (currentRowIndex >= 1 && currentRowIndex <= rows.size()) {
currentRow = rows.get(currentRowIndex - 1);
} else {
currentRow = null;
}
rememberedCursorPosition = -1;
+ isCursorOnInsert = false;
}
}
public void moveToInsertRow() throws SQLException {
+ if (meta == null) {
+ // rowset.26=The object has not been initialized
+ throw new SQLException(Messages.getString("rowset.26")); //$NON-NLS-1$
+ }
insertRow = new CachedRow(new Object[columnCount]);
currentRow = insertRow;
- rememberedCursorPosition = currentRowIndex;
- currentRowIndex = -1;
+ if (!isCursorOnInsert) {
+ rememberedCursorPosition = currentRowIndex;
+ currentRowIndex = -1;
+ isCursorOnInsert = true;
+ }
}
public boolean next() throws SQLException {
@@ -1139,24 +2233,115 @@
*
* next() doesn't check TYPE_FORWARD_ONLY property, relative(1) does.
*/
- return doAbsolute(currentRowIndex + 1, false);
+ return doAbsolute(findNextValidRow(), false);
+ }
+
+ /**
+ * Valid row is row which is visible to users. If <code>showDeleted</code>
+ * is true, deleted rows are valid rows, otherwise deleted rows are invalid.
+ *
+ * @return next valid row
+ * @throws SQLException
+ */
+ private int findNextValidRow() throws SQLException {
+ if (isCursorOnInsert) {
+ // rowset.0=Not a valid position
+ throw new SQLException(Messages.getString("rowset.0")); //$NON-NLS-1$
+ }
+ if (rows == null || rows.size() == 0) {
+ return -1;
+ }
+ int index = currentRowIndex + 1;
+
+ if (getShowDeleted()) {
+ return index;
+ }
+
+ if (index > rows.size()) {
+ return rows.size() + 1;
+ }
+
+ while (index <= rows.size()) {
+ if (!rows.get(index - 1).isDelete()) {
+ break;
+ }
+ index++;
+ }
+
+ return index;
}
public boolean previous() throws SQLException {
- return doAbsolute(currentRowIndex - 1, true);
+ return doAbsolute(findPreviousValidRow(), true);
+ }
+
+ /**
+ * Valid row is row which is visible to users. If <code>showDeleted</code>
+ * is true, deleted rows are valid rows, otherwise deleted rows are invalid.
+ *
+ * @return previous valid row
+ * @throws SQLException
+ */
+ private int findPreviousValidRow() throws SQLException {
+ if (isCursorOnInsert) {
+ // rowset.0=Not a valid position
+ throw new SQLException(Messages.getString("rowset.0")); //$NON-NLS-1$
+ }
+ if (rows == null || rows.size() == 0) {
+ return -1;
+ }
+ int index = currentRowIndex - 1;
+
+ if (index <= 0) {
+ return 0;
+ }
+
+ if (getShowDeleted()) {
+ return index;
+ }
+
+ while (index > 0) {
+ if (!rows.get(index - 1).isDelete()) {
+ break;
+ }
+ index--;
+ }
+
+ return index;
}
public void refreshRow() throws SQLException {
- throw new NotImplementedException();
+ checkValidRow();
+ if (isCursorOnInsert) {
+ // rowset.0=Not a valid position
+ throw new SQLException(Messages.getString("rowset.0")); //$NON-NLS-1$
+ }
+ currentRow.restoreOriginal();
}
public boolean relative(int moveRows) throws SQLException {
- if (currentRow == null) {
- // TODO add error message
- throw new SQLException();
+ checkValidRow();
+ // TODO use more effective way to move cursor
+ int index = getRow() + moveRows;
+
+ if (isCursorOnInsert || currentRow.isDelete()) {
+ if (moveRows > 0) {
+ if (next()) {
+ index = getRow() + moveRows - 1;
+ } else {
+ return false;
+ }
+ }
+
+ if (moveRows < 0) {
+ if (previous()) {
+ index = getRow() + moveRows + 1;
+ } else {
+ return false;
+ }
+ }
}
- int index = getRow() + moveRows;
if (index <= 0) {
beforeFirst();
return false;
@@ -1167,24 +2352,36 @@
return false;
}
- return doAbsolute(index, true);
+ return doAbsolute(getIndexIncludeDeletedRows(index), true);
}
public boolean rowDeleted() throws SQLException {
checkValidRow();
- checkCursorValid();
return currentRow.isDelete();
}
public boolean rowInserted() throws SQLException {
- if (currentRow == null || currentRow == insertRow) {
- // TODO add error message
- throw new SQLException();
+ if (currentRow == null) {
+ // rowset.7=Not a valid cursor
+ throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
+ }
+ if (isCursorOnInsert) {
+ // rowset.11=Illegal operation on an insert row
+ throw new SQLException(Messages.getString("rowset.11")); //$NON-NLS-1$
}
return currentRow.isInsert();
}
public boolean rowUpdated() throws SQLException {
+ if (currentRow == null) {
+ // rowset.7=Not a valid cursor
+ throw new SQLException(Messages.getString("rowset.7")); //$NON-NLS-1$
+ }
+ if (isCursorOnInsert) {
+ // rowset.11=Illegal operation on an insert row
+ throw new SQLException(Messages.getString("rowset.11")); //$NON-NLS-1$
+ }
+
if (!currentRow.isUpdate()) {
return false;
}
@@ -1204,9 +2401,34 @@
updateArray(getIndexByName(columnName), x);
}
- public void updateAsciiStream(int columnIndex, InputStream x, int length)
+ public void updateAsciiStream(int columnIndex, InputStream in, int length)
throws SQLException {
- throw new NotImplementedException();
+ checkValidRow();
+ checkColumnValid(columnIndex);
+ initInsertRow(columnIndex, in);
+
+ Class<?> type = columnTypes[columnIndex - 1];
+ if (type != null && !type.equals(String.class)
+ && !type.equals(byte[].class)) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ for (int i = 0; i < length; ++i) {
+ int value = in.read();
+ if (value == -1) {
+ throw new IndexOutOfBoundsException();
+ }
+ out.write(value);
+ }
+ } catch (IOException e) {
+ SQLException ex = new SQLException();
+ ex.initCause(e);
+ throw ex;
+ }
+ updateString(columnIndex, new String(out.toByteArray()));
}
public void updateAsciiStream(String columnName, InputStream x, int length)
@@ -1228,9 +2450,37 @@
updateBigDecimal(getIndexByName(columnName), x);
}
- public void updateBinaryStream(int columnIndex, InputStream x, int length)
+ public void updateBinaryStream(int columnIndex, InputStream in, int length)
throws SQLException {
- throw new NotImplementedException();
+ checkValidRow();
+ checkColumnValid(columnIndex);
+ initInsertRow(columnIndex, in);
+
+ Class<?> type = columnTypes[columnIndex - 1];
+ if (type != null && !type.equals(byte[].class)) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ int i = 0;
+ for (; i < length; ++i) {
+ int value = in.read();
+ if (value == -1) {
+ out.write(0);
+ } else {
+ out.write(value);
+ }
+ }
+
+ } catch (IOException e) {
+ SQLException ex = new SQLException();
+ ex.initCause(e);
+ throw ex;
+ }
+
+ updateBytes(columnIndex, out.toByteArray());
}
public void updateBinaryStream(String columnName, InputStream x, int length)
@@ -1270,9 +2520,35 @@
updateBytes(getIndexByName(columnName), x);
}
- public void updateCharacterStream(int columnIndex, Reader x, int length)
+ public void updateCharacterStream(int columnIndex, Reader in, int length)
throws SQLException {
- throw new NotImplementedException();
+ checkValidRow();
+ checkColumnValid(columnIndex);
+ initInsertRow(columnIndex, in);
+
+ Class<?> type = columnTypes[columnIndex - 1];
+ if (type != null && !type.equals(String.class)
+ && !type.equals(byte[].class)) {
+ // rowset.10=Data Type Mismatch
+ throw new SQLException(Messages.getString("rowset.10")); //$NON-NLS-1$
+ }
+
+ StringWriter out = new StringWriter();
+ try {
+ for (int i = 0; i < length; ++i) {
+ int value = in.read();
+ if (value == -1) {
+ throw new IndexOutOfBoundsException();
+ }
+ out.write(value);
+ }
+ } catch (IOException e) {
+ SQLException ex = new SQLException();
+ ex.initCause(e);
+ throw ex;
+ }
+
+ updateString(columnIndex, out.toString());
}
public void updateCharacterStream(String columnName, Reader reader,
@@ -1329,7 +2605,7 @@
}
public void updateNull(int columnIndex) throws SQLException {
- checkCursorValid();
+ checkValidRow();
checkColumnValid(columnIndex);
currentRow.updateObject(columnIndex, null);
}
@@ -1344,6 +2620,7 @@
public void updateObject(int columnIndex, Object x) throws SQLException {
checkValidRow();
checkColumnValid(columnIndex);
+ initInsertRow(columnIndex, x);
currentRow.updateObject(columnIndex, x);
}
@@ -1351,7 +2628,7 @@
throws SQLException {
checkValidRow();
checkColumnValid(columnIndex);
- Class type = columnTypes[columnIndex - 1];
+ Class<?> type = columnTypes[columnIndex - 1];
// ava.sql.Types.DECIMA or java.sql.Types.NUMERIC types
if (type.equals(BigDecimal.class)) {
/*
@@ -1369,7 +2646,7 @@
// x = ((BigDecimal) x).setScale(scale);
// }
}
-
+ initInsertRow(columnIndex, x);
currentRow.updateObject(columnIndex, x);
}
@@ -1391,13 +2668,18 @@
}
public void updateRow() throws SQLException {
- if ((currentRow == insertRow)
- || (getConcurrency() == (ResultSet.CONCUR_READ_ONLY))) {
- // TODO add error messages
- throw new SQLException();
+ if (isCursorOnInsert) {
+ // rowset.11=Illegal operation on an insert row
+ throw new SQLException(Messages.getString("rowset.11")); //$NON-NLS-1$
+ }
+ if (getConcurrency() == (ResultSet.CONCUR_READ_ONLY)) {
+ // rowset.17=The Result Set is CONCUR_READ_ONLY
+ throw new SQLException(Messages.getString("rowset.17")); //$NON-NLS-1$
}
currentRow.setUpdate();
- notifyRowChanged();
+ if (isNotifyListener) {
+ notifyRowChanged();
+ }
}
public void updateShort(int columnIndex, short x) throws SQLException {
@@ -1423,11 +2705,27 @@
throws SQLException {
checkValidRow();
checkColumnValid(columnIndex);
+ initInsertRow(columnIndex, value);
currentRow.updateObject(columnIndex, convertUpdateValue(columnIndex,
value));
}
/**
+ * The implementation of FilteredRowSet would override this method. The
+ * parameters also are used for override.
+ *
+ * @param columnIndex
+ * @param value
+ */
+ protected void initInsertRow(int columnIndex, Object value)
+ throws SQLException {
+ if (isCursorOnInsert && insertRow == null) {
+ insertRow = new CachedRow(new Object[columnCount]);
+ currentRow = insertRow;
+ }
+ }
+
+ /**
* Convert <code>value</code> to the JDBC type of the
* <code>columnIndex</code>. The columnIndex is not checked in this
* method, so caller must be sure the <code>columnIndex</code> is valid,
@@ -1440,24 +2738,56 @@
* @param value
* the new value to be updated
*/
+ @SuppressWarnings("boxing")
private Object convertUpdateValue(int columnIndex, Object value)
throws SQLException {
-
+
if (value == null) {
[... 190 lines stripped ...]