From babd5a9ac218d0ad1077c8f9ec4382af76fec51e Mon Sep 17 00:00:00 2001 From: Oscar Salvador Magallanes Date: Thu, 17 Aug 2023 18:28:20 +0200 Subject: [PATCH 1/7] fix: remove com.sun dependencies --- .../replicadb/rowset/StreamingRowSetImpl.java | 13 +- .../rowset/sun/rowset/CachedRowSetImpl.java | 10133 ++++++++++++++++ .../rowset/sun/rowset/JdbcRowSetImpl.java | 6920 +++++++++++ .../sun/rowset/JdbcRowSetResourceBundle.java | 161 + .../rowset/sun/rowset/internal/BaseRow.java | 101 + .../rowset/internal/CachedRowSetReader.java | 517 + .../rowset/internal/CachedRowSetWriter.java | 1472 +++ .../rowset/sun/rowset/internal/InsertRow.java | 183 + .../rowset/sun/rowset/internal/Row.java | 340 + .../sun/rowset/internal/SyncResolverImpl.java | 4873 ++++++++ .../providers/RIOptimisticProvider.java | 269 + 11 files changed, 24978 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/CachedRowSetImpl.java create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/JdbcRowSetImpl.java create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/JdbcRowSetResourceBundle.java create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/internal/BaseRow.java create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/internal/CachedRowSetReader.java create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/internal/CachedRowSetWriter.java create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/internal/InsertRow.java create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/internal/Row.java create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/internal/SyncResolverImpl.java create mode 100644 src/main/java/org/replicadb/rowset/sun/rowset/providers/RIOptimisticProvider.java diff --git a/src/main/java/org/replicadb/rowset/StreamingRowSetImpl.java b/src/main/java/org/replicadb/rowset/StreamingRowSetImpl.java index f3db212..42e1dea 100644 --- a/src/main/java/org/replicadb/rowset/StreamingRowSetImpl.java +++ b/src/main/java/org/replicadb/rowset/StreamingRowSetImpl.java @@ -24,6 +24,11 @@ * questions. */ +import org.replicadb.rowset.sun.rowset.internal.BaseRow; +import org.replicadb.rowset.sun.rowset.internal.CachedRowSetReader; +import org.replicadb.rowset.sun.rowset.internal.InsertRow; +import org.replicadb.rowset.sun.rowset.internal.Row; + import java.sql.*; import javax.sql.*; import java.io.*; @@ -35,8 +40,8 @@ import javax.sql.rowset.spi.*; import javax.sql.rowset.serial.*; -import com.sun.rowset.internal.*; -import com.sun.rowset.providers.*; +//import com.sun.rowset.internal.*; +//import com.sun.rowset.providers.*; /** * The standard implementation of the CachedRowSet interface. @@ -343,9 +348,9 @@ public StreamingRowSetImpl () throws SQLException { // set the Reader, this maybe overridden latter provider = crs.getSyncProvider(); - if (!(provider instanceof RIOptimisticProvider)) { + /* if (!(provider instanceof RIOptimisticProvider)) { throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidp").toString()); - } + }*/ rowSetReader = provider.getRowSetReader(); rowSetWriter = provider.getRowSetWriter(); diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/CachedRowSetImpl.java b/src/main/java/org/replicadb/rowset/sun/rowset/CachedRowSetImpl.java new file mode 100644 index 0000000..6521b09 --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/CachedRowSetImpl.java @@ -0,0 +1,10133 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset; + +import org.replicadb.rowset.sun.rowset.internal.*; +import org.replicadb.rowset.sun.rowset.providers.RIOptimisticProvider; +//import sun.reflect.misc.ReflectUtil; + +import javax.sql.*; +import javax.sql.rowset.BaseRowSet; +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.RowSetMetaDataImpl; +import javax.sql.rowset.RowSetWarning; +import javax.sql.rowset.serial.*; +import javax.sql.rowset.spi.SyncFactory; +import javax.sql.rowset.spi.SyncProvider; +import javax.sql.rowset.spi.SyncProviderException; +import javax.sql.rowset.spi.TransactionalWriter; +import java.io.*; +import java.math.BigDecimal; +import java.sql.*; +import java.text.DateFormat; +import java.text.MessageFormat; +import java.text.ParseException; +import java.util.*; + +/** + * The standard implementation of the CachedRowSet interface. + * + * See interface definition for full behavior and implementation requirements. + * This reference implementation has made provision for a one-to-one write back + * facility and it is curremtly be possible to change the peristence provider + * during the life-time of any CachedRowSetImpl. + * + * @author Jonathan Bruce, Amit Handa + */ + +public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetInternal, Serializable, Cloneable, CachedRowSet { + + /** + * The SyncProvider used by the CachedRowSet + */ + private SyncProvider provider; + + /** + * The RowSetReaderImpl object that is the reader + * for this rowset. The method execute uses this + * reader as part of its implementation. + * @serial + */ + private RowSetReader rowSetReader; + + /** + * The RowSetWriterImpl object that is the writer + * for this rowset. The method acceptChanges uses + * this writer as part of its implementation. + * @serial + */ + private RowSetWriter rowSetWriter; + + /** + * The Connection object that connects with this + * CachedRowSetImpl object's current underlying data source. + */ + private transient Connection conn; + + /** + * The ResultSetMetaData object that contains information + * about the columns in the ResultSet object that is the + * current source of data for this CachedRowSetImpl object. + */ + private transient ResultSetMetaData RSMD; + + /** + * The RowSetMetaData object that contains information about + * the columns in this CachedRowSetImpl object. + * @serial + */ + private RowSetMetaDataImpl RowSetMD; + + // Properties of this RowSet + + /** + * An array containing the columns in this CachedRowSetImpl + * object that form a unique identifier for a row. This array + * is used by the writer. + * @serial + */ + private int keyCols[]; + + /** + * The name of the table in the underlying database to which updates + * should be written. This name is needed because most drivers + * do not return this information in a ResultSetMetaData + * object. + * @serial + */ + private String tableName; + + /** + * A Vector object containing the Row + * objects that comprise this CachedRowSetImpl object. + * @serial + */ + private Vector rvh; + + /** + * The current position of the cursor in this CachedRowSetImpl + * object. + * @serial + */ + private int cursorPos; + + /** + * The current position of the cursor in this CachedRowSetImpl + * object not counting rows that have been deleted, if any. + *

+ * For example, suppose that the cursor is on the last row of a rowset + * that started with five rows and subsequently had the second and third + * rows deleted. The absolutePos would be 3, + * whereas the cursorPos would be 5. + * @serial + */ + private int absolutePos; + + /** + * The number of deleted rows currently in this CachedRowSetImpl + * object. + * @serial + */ + private int numDeleted; + + /** + * The total number of rows currently in this CachedRowSetImpl + * object. + * @serial + */ + private int numRows; + + /** + * A special row used for constructing a new row. A new + * row is constructed by using ResultSet.updateXXX + * methods to insert column values into the insert row. + * @serial + */ + private InsertRow insertRow; + + /** + * A boolean indicating whether the cursor is + * currently on the insert row. + * @serial + */ + private boolean onInsertRow; + + /** + * The field that temporarily holds the last position of the + * cursor before it moved to the insert row, thus preserving + * the number of the current row to which the cursor may return. + * @serial + */ + private int currentRow; + + /** + * A boolean indicating whether the last value + * returned was an SQL NULL. + * @serial + */ + private boolean lastValueNull; + + /** + * A SQLWarning which logs on the warnings + */ + private SQLWarning sqlwarn; + + /** + * Used to track match column for JoinRowSet consumption + */ + private String strMatchColumn =""; + + /** + * Used to track match column for JoinRowSet consumption + */ + private int iMatchColumn = -1; + + /** + * A RowSetWarning which logs on the warnings + */ + private RowSetWarning rowsetWarning; + + /** + * The default SyncProvider for the RI CachedRowSetImpl + */ + private String DEFAULT_SYNC_PROVIDER = "com.sun.rowset.providers.RIOptimisticProvider"; + + /** + * The boolean variable indicating locatorsUpdateValue + */ + private boolean dbmslocatorsUpdateCopy; + + /** + * The ResultSet object that is used to maintain the data when + * a ResultSet and start position are passed as parameters to the populate function + */ + private transient ResultSet resultSet; + + /** + * The integer value indicating the end position in the ResultSetwhere the picking + * up of rows for populating a CachedRowSet object was left off. + */ + private int endPos; + + /** + * The integer value indicating the end position in the ResultSetwhere the picking + * up of rows for populating a CachedRowSet object was left off. + */ + private int prevEndPos; + + /** + * The integer value indicating the position in the ResultSet, to populate the + * CachedRowSet object. + */ + private int startPos; + + /** + * The integer value indicating the position from where the page prior to this + * was populated. + */ + private int startPrev; + + /** + * The integer value indicating size of the page. + */ + private int pageSize; + + /** + * The integer value indicating number of rows that have been processed so far. + * Used for checking whether maxRows has been reached or not. + */ + private int maxRowsreached; + /** + * The boolean value when true signifies that pages are still to follow and a + * false value indicates that this is the last page. + */ + private boolean pagenotend = true; + + /** + * The boolean value indicating whether this is the first page or not. + */ + private boolean onFirstPage; + + /** + * The boolean value indicating whether this is the last page or not. + */ + private boolean onLastPage; + + /** + * The integer value indicating how many times the populate function has been called. + */ + private int populatecallcount; + + /** + * The integer value indicating the total number of rows to be processed in the + * ResultSet object passed to the populate function. + */ + private int totalRows; + + /** + * The boolean value indicating how the CahedRowSet object has been populated for + * paging purpose. True indicates that connection parameter is passed. + */ + private boolean callWithCon; + + /** + * CachedRowSet reader object to read the data from the ResultSet when a connection + * parameter is passed to populate the CachedRowSet object for paging. + */ + private CachedRowSetReader crsReader; + + /** + * The Vector holding the Match Columns + */ + private Vector iMatchColumns; + + /** + * The Vector that will hold the Match Column names. + */ + private Vector strMatchColumns; + + /** + * Trigger that indicates whether the active SyncProvider is exposes the + * additional TransactionalWriter method + */ + private boolean tXWriter = false; + + /** + * The field object for a transactional RowSet writer + */ + private TransactionalWriter tWriter = null; + + protected transient JdbcRowSetResourceBundle resBundle; + + private boolean updateOnInsert; + + + + /** + * Constructs a new default CachedRowSetImpl object with + * the capacity to hold 100 rows. This new object has no metadata + * and has the following default values: + *

+     *     onInsertRow = false
+     *     insertRow = null
+     *     cursorPos = 0
+     *     numRows = 0
+     *     showDeleted = false
+     *     queryTimeout = 0
+     *     maxRows = 0
+     *     maxFieldSize = 0
+     *     rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE
+     *     concurrency = ResultSet.CONCUR_UPDATABLE
+     *     readOnly = false
+     *     isolation = Connection.TRANSACTION_READ_COMMITTED
+     *     escapeProcessing = true
+     *     onInsertRow = false
+     *     insertRow = null
+     *     cursorPos = 0
+     *     absolutePos = 0
+     *     numRows = 0
+     * 
+ * A CachedRowSetImpl object is configured to use the default + * RIOptimisticProvider implementation to provide connectivity + * and synchronization capabilities to the set data source. + *

+ * @throws SQLException if an error occurs + */ + public CachedRowSetImpl() throws SQLException { + + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + // set the Reader, this maybe overridden latter + provider = + SyncFactory.getInstance(DEFAULT_SYNC_PROVIDER); + + if (!(provider instanceof RIOptimisticProvider)) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidp").toString()); + } + + rowSetReader = (CachedRowSetReader)provider.getRowSetReader(); + rowSetWriter = (CachedRowSetWriter)provider.getRowSetWriter(); + + // allocate the parameters collection + initParams(); + + initContainer(); + + // set up some default values + initProperties(); + + // insert row setup + onInsertRow = false; + insertRow = null; + + // set the warninings + sqlwarn = new SQLWarning(); + rowsetWarning = new RowSetWarning(); + + } + + /** + * Provides a CachedRowSetImpl instance with the same default properties as + * as the zero parameter constructor. + *

+     *     onInsertRow = false
+     *     insertRow = null
+     *     cursorPos = 0
+     *     numRows = 0
+     *     showDeleted = false
+     *     queryTimeout = 0
+     *     maxRows = 0
+     *     maxFieldSize = 0
+     *     rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE
+     *     concurrency = ResultSet.CONCUR_UPDATABLE
+     *     readOnly = false
+     *     isolation = Connection.TRANSACTION_READ_COMMITTED
+     *     escapeProcessing = true
+     *     onInsertRow = false
+     *     insertRow = null
+     *     cursorPos = 0
+     *     absolutePos = 0
+     *     numRows = 0
+     * 
+ * + * However, applications will have the means to specify at runtime the + * desired SyncProvider object. + *

+ * For example, creating a CachedRowSetImpl object as follows ensures + * that a it is established with the com.foo.provider.Impl synchronization + * implementation providing the synchronization mechanism for this disconnected + * RowSet object. + *

+     *     Hashtable env = new Hashtable();
+     *     env.put(javax.sql.rowset.spi.SyncFactory.ROWSET_PROVIDER_NAME,
+     *         "com.foo.provider.Impl");
+     *     CachedRowSetImpl crs = new CachedRowSet(env);
+     * 
+ *

+ * Calling this constructor with a null parameter will + * cause the SyncFactory to provide the reference + * optimistic provider com.sun.rowset.providers.RIOptimisticProvider. + *

+ * In addition, the following properties can be associated with the + * provider to assist in determining the choice of the synchronizaton + * provider such as: + *

+ * More specific detailes are available in the SyncFactory + * and SyncProvider specificiations later in this document. + *

+ * @param env a Hashtable object with a list of desired + * synchronization providers + * @throws SQLException if the requested provider cannot be found by the + * synchronization factory + * @see SyncProvider + */ + public CachedRowSetImpl(@SuppressWarnings("rawtypes") Hashtable env) throws SQLException { + + + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + if (env == null) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nullhash").toString()); + } + + String providerName = (String)env.get( + SyncFactory.ROWSET_SYNC_PROVIDER); + + // set the Reader, this maybe overridden latter + provider = + SyncFactory.getInstance(providerName); + + rowSetReader = provider.getRowSetReader(); + rowSetWriter = provider.getRowSetWriter(); + + initParams(); // allocate the parameters collection + initContainer(); + initProperties(); // set up some default values + } + + /** + * Sets the rvh field to a new Vector + * object with a capacity of 100 and sets the + * cursorPos and numRows fields to zero. + */ + private void initContainer() { + + rvh = new Vector(100); + cursorPos = 0; + absolutePos = 0; + numRows = 0; + numDeleted = 0; + } + + /** + * Sets the properties for this CachedRowSetImpl object to + * their default values. This method is called internally by the + * default constructor. + */ + + private void initProperties() throws SQLException { + + if(resBundle == null) { + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + } + setShowDeleted(false); + setQueryTimeout(0); + setMaxRows(0); + setMaxFieldSize(0); + setType(ResultSet.TYPE_SCROLL_INSENSITIVE); + setConcurrency(ResultSet.CONCUR_UPDATABLE); + if((rvh.size() > 0) && (isReadOnly() == false)) + setReadOnly(false); + else + setReadOnly(true); + setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); + setEscapeProcessing(true); + //setTypeMap(null); + checkTransactionalWriter(); + + //Instantiating the vector for MatchColumns + + iMatchColumns = new Vector(10); + for(int i = 0; i < 10 ; i++) { + iMatchColumns.add(i, -1); + } + + strMatchColumns = new Vector(10); + for(int j = 0; j < 10; j++) { + strMatchColumns.add(j,null); + } + } + + /** + * Determine whether the SyncProvider's writer implements the + * TransactionalWriter interface + */ + private void checkTransactionalWriter() { + if (rowSetWriter != null) { + Class c = rowSetWriter.getClass(); + if (c != null) { + Class[] theInterfaces = c.getInterfaces(); + for (int i = 0; i < theInterfaces.length; i++) { + if ((theInterfaces[i].getName()).indexOf("TransactionalWriter") > 0) { + tXWriter = true; + establishTransactionalWriter(); + } + } + } + } + } + + /** + * Sets an private field to all transaction bounddaries to be set + */ + private void establishTransactionalWriter() { + tWriter = (TransactionalWriter)provider.getRowSetWriter(); + } + + //----------------------------------------------------------------------- + // Properties + //----------------------------------------------------------------------- + + /** + * Sets this CachedRowSetImpl object's command property + * to the given String object and clears the parameters, + * if any, that were set for the previous command. + *

+ * The command property may not be needed + * if the rowset is produced by a data source, such as a spreadsheet, + * that does not support commands. Thus, this property is optional + * and may be null. + * + * @param cmd a String object containing an SQL query + * that will be set as the command; may be null + * @throws SQLException if an error occurs + */ + public void setCommand(String cmd) throws SQLException { + + super.setCommand(cmd); + + if(!buildTableName(cmd).equals("")) { + this.setTableName(buildTableName(cmd)); + } + } + + + //--------------------------------------------------------------------- + // Reading and writing data + //--------------------------------------------------------------------- + + /** + * Populates this CachedRowSetImpl object with data from + * the given ResultSet object. This + * method is an alternative to the method execute + * for filling the rowset with data. The method populate + * does not require that the properties needed by the method + * execute, such as the command property, + * be set. This is true because the method populate + * is given the ResultSet object from + * which to get data and thus does not need to use the properties + * required for setting up a connection and executing this + * CachedRowSetImpl object's command. + *

+ * After populating this rowset with data, the method + * populate sets the rowset's metadata and + * then sends a RowSetChangedEvent object + * to all registered listeners prior to returning. + * + * @param data the ResultSet object containing the data + * to be read into this CachedRowSetImpl object + * @throws SQLException if an error occurs; or the max row setting is + * violated while populating the RowSet + * @see #execute + */ + + public void populate(ResultSet data) throws SQLException { + int rowsFetched; + Row currentRow; + int numCols; + int i; + Map> map = getTypeMap(); + Object obj; + int mRows; + + if (data == null) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString()); + } + this.resultSet = data; + + // get the meta data for this ResultSet + RSMD = data.getMetaData(); + + // set up the metadata + RowSetMD = new RowSetMetaDataImpl(); + initMetaData(RowSetMD, RSMD); + + // release the meta-data so that aren't tempted to use it. + RSMD = null; + numCols = RowSetMD.getColumnCount(); + mRows = this.getMaxRows(); + rowsFetched = 0; + currentRow = null; + + while ( data.next()) { + + currentRow = new Row(numCols); + + if ( rowsFetched > mRows && mRows > 0) { + rowsetWarning.setNextWarning(new RowSetWarning("Populating rows " + + "setting has exceeded max row setting")); + } + for ( i = 1; i <= numCols; i++) { + /* + * check if the user has set a map. If no map + * is set then use plain getObject. This lets + * us work with drivers that do not support + * getObject with a map in fairly sensible way + */ + if (map == null || map.isEmpty()) { + obj = data.getObject(i); + } else { + obj = data.getObject(i, map); + } + /* + * the following block checks for the various + * types that we have to serialize in order to + * store - right now only structs have been tested + */ + if (obj instanceof Struct) { + obj = new SerialStruct((Struct)obj, map); + } else if (obj instanceof SQLData) { + obj = new SerialStruct((SQLData)obj, map); + } else if (obj instanceof Blob) { + obj = new SerialBlob((Blob)obj); + } else if (obj instanceof Clob) { + obj = new SerialClob((Clob)obj); + } else if (obj instanceof Array) { + if(map != null) + obj = new SerialArray((Array)obj, map); + else + obj = new SerialArray((Array)obj); + } + + currentRow.initColumnObject(i, obj); + } + rowsFetched++; + rvh.add(currentRow); + } + + numRows = rowsFetched ; + // Also rowsFetched should be equal to rvh.size() + + // notify any listeners that the rowset has changed + notifyRowSetChanged(); + + + } + + /** + * Initializes the given RowSetMetaData object with the values + * in the given ResultSetMetaData object. + * + * @param md the RowSetMetaData object for this + * CachedRowSetImpl object, which will be set with + * values from rsmd + * @param rsmd the ResultSetMetaData object from which new + * values for md will be read + * @throws SQLException if an error occurs + */ + private void initMetaData(RowSetMetaDataImpl md, ResultSetMetaData rsmd) throws SQLException { + int numCols = rsmd.getColumnCount(); + + md.setColumnCount(numCols); + for (int col=1; col <= numCols; col++) { + md.setAutoIncrement(col, rsmd.isAutoIncrement(col)); + if(rsmd.isAutoIncrement(col)) + updateOnInsert = true; + md.setCaseSensitive(col, rsmd.isCaseSensitive(col)); + md.setCurrency(col, rsmd.isCurrency(col)); + md.setNullable(col, rsmd.isNullable(col)); + md.setSigned(col, rsmd.isSigned(col)); + md.setSearchable(col, rsmd.isSearchable(col)); + /* + * The PostgreSQL drivers sometimes return negative columnDisplaySize, + * which causes an exception to be thrown. Check for it. + */ + int size = rsmd.getColumnDisplaySize(col); + if (size < 0) { + size = 0; + } + md.setColumnDisplaySize(col, size); + md.setColumnLabel(col, rsmd.getColumnLabel(col)); + md.setColumnName(col, rsmd.getColumnName(col)); + md.setSchemaName(col, rsmd.getSchemaName(col)); + /* + * Drivers return some strange values for precision, for non-numeric data, including reports of + * non-integer values; maybe we should check type, & set to 0 for non-numeric types. + */ + int precision = rsmd.getPrecision(col); + if (precision < 0) { + precision = 0; + } + md.setPrecision(col, precision); + + /* + * It seems, from a bug report, that a driver can sometimes return a negative + * value for scale. javax.sql.rowset.RowSetMetaDataImpl will throw an exception + * if we attempt to set a negative value. As such, we'll check for this case. + */ + int scale = rsmd.getScale(col); + if (scale < 0) { + scale = 0; + } + md.setScale(col, scale); + md.setTableName(col, rsmd.getTableName(col)); + md.setCatalogName(col, rsmd.getCatalogName(col)); + md.setColumnType(col, rsmd.getColumnType(col)); + md.setColumnTypeName(col, rsmd.getColumnTypeName(col)); + } + + if( conn != null){ + // JDBC 4.0 mandates as does the Java EE spec that all DataBaseMetaData methods + // must be implemented, therefore, the previous fix for 5055528 is being backed out + dbmslocatorsUpdateCopy = conn.getMetaData().locatorsUpdateCopy(); + } + } + + /** + * Populates this CachedRowSetImpl object with data, + * using the given connection to produce the result set from + * which data will be read. A second form of this method, + * which takes no arguments, uses the values from this rowset's + * user, password, and either url or data source properties to + * create a new database connection. The form of execute + * that is given a connection ignores these properties. + * + * @param conn A standard JDBC Connection object that this + * CachedRowSet object can pass to a synchronization provider + * to establish a connection to the data source + * @throws SQLException if an invalid Connection is supplied + * or an error occurs in establishing the connection to the + * data source + * @see #populate + * @see Connection + */ + public void execute(Connection conn) throws SQLException { + // store the connection so the reader can find it. + setConnection(conn); + + if(getPageSize() != 0){ + crsReader = (CachedRowSetReader)provider.getRowSetReader(); + crsReader.setStartPosition(1); + callWithCon = true; + crsReader.readData((RowSetInternal)this); + } + + // Now call the current reader's readData method + else { + rowSetReader.readData((RowSetInternal)this); + } + RowSetMD = (RowSetMetaDataImpl)this.getMetaData(); + + if(conn != null){ + // JDBC 4.0 mandates as does the Java EE spec that all DataBaseMetaData methods + // must be implemented, therefore, the previous fix for 5055528 is being backed out + dbmslocatorsUpdateCopy = conn.getMetaData().locatorsUpdateCopy(); + } + + } + + /** + * Sets this CachedRowSetImpl object's connection property + * to the given Connection object. This method is called + * internally by the version of the method execute that takes a + * Connection object as an argument. The reader for this + * CachedRowSetImpl object can retrieve the connection stored + * in the rowset's connection property by calling its + * getConnection method. + * + * @param connection the Connection object that was passed in + * to the method execute and is to be stored + * in this CachedRowSetImpl object's connection + * property + */ + private void setConnection (Connection connection) { + conn = connection; + } + + + /** + * Propagates all row update, insert, and delete changes to the + * underlying data source backing this CachedRowSetImpl + * object. + *

+ * NoteIn the reference implementation an optimistic concurrency implementation + * is provided as a sample implementation of a the SyncProvider + * abstract class. + *

+ * This method fails if any of the updates cannot be propagated back + * to the data source. When it fails, the caller can assume that + * none of the updates are reflected in the data source. + * When an exception is thrown, the current row + * is set to the first "updated" row that resulted in an exception + * unless the row that caused the exception is a "deleted" row. + * In that case, when deleted rows are not shown, which is usually true, + * the current row is not affected. + *

+ * If no SyncProvider is configured, the reference implementation + * leverages the RIOptimisticProvider available which provides the + * default and reference synchronization capabilities for disconnected + * RowSets. + * + * @throws SQLException if the cursor is on the insert row or the underlying + * reference synchronization provider fails to commit the updates + * to the datasource + * @throws SyncProviderException if an internal error occurs within the + * SyncProvider instance during either during the + * process or at any time when the SyncProvider + * instance touches the data source. + * @see #acceptChanges(Connection) + * @see RowSetWriter + * @see SyncProvider + */ + public void acceptChanges() throws SyncProviderException { + if (onInsertRow == true) { + throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); + } + + int saveCursorPos = cursorPos; + boolean success = false; + boolean conflict = false; + + try { + if (rowSetWriter != null) { + saveCursorPos = cursorPos; + conflict = rowSetWriter.writeData((RowSetInternal)this); + cursorPos = saveCursorPos; + } + + if (tXWriter) { + // do commit/rollback's here + if (!conflict) { + tWriter = (TransactionalWriter)rowSetWriter; + tWriter.rollback(); + success = false; + } else { + tWriter = (TransactionalWriter)rowSetWriter; + if (tWriter instanceof CachedRowSetWriter) { + ((CachedRowSetWriter)tWriter).commit(this, updateOnInsert); + } else { + tWriter.commit(); + } + + success = true; + } + } + + if (success == true) { + setOriginal(); + } else if (!(success) ) { + throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.accfailed").toString()); + } + + } catch (SyncProviderException spe) { + throw spe; + } catch (SQLException e) { + e.printStackTrace(); + throw new SyncProviderException(e.getMessage()); + } catch (SecurityException e) { + throw new SyncProviderException(e.getMessage()); + } + } + + /** + * Propagates all row update, insert, and delete changes to the + * data source backing this CachedRowSetImpl object + * using the given Connection object. + *

+ * The reference implementation RIOptimisticProvider + * modifies its synchronization to a write back function given + * the updated connection + * The reference implementation modifies its synchronization behaviour + * via the SyncProvider to ensure the synchronization + * occurs according to the updated JDBC Connection + * properties. + * + * @param con a standard JDBC Connection object + * @throws SQLException if the cursor is on the insert row or the underlying + * synchronization provider fails to commit the updates + * back to the data source + * @see #acceptChanges + * @see RowSetWriter + * @see SyncFactory + * @see SyncProvider + */ + public void acceptChanges(Connection con) throws SyncProviderException{ + setConnection(con); + acceptChanges(); + } + + /** + * Restores this CachedRowSetImpl object to its original state, + * that is, its state before the last set of changes. + *

+ * Before returning, this method moves the cursor before the first row + * and sends a rowSetChanged event to all registered + * listeners. + * @throws SQLException if an error is occurs rolling back the RowSet + * state to the definied original value. + * @see RowSetListener#rowSetChanged + */ + public void restoreOriginal() throws SQLException { + Row currentRow; + for (Iterator i = rvh.iterator(); i.hasNext();) { + currentRow = (Row)i.next(); + if (currentRow.getInserted() == true) { + i.remove(); + --numRows; + } else { + if (currentRow.getDeleted() == true) { + currentRow.clearDeleted(); + } + if (currentRow.getUpdated() == true) { + currentRow.clearUpdated(); + } + } + } + // move to before the first + cursorPos = 0; + + // notify any listeners + notifyRowSetChanged(); + } + + /** + * Releases the current contents of this CachedRowSetImpl + * object and sends a rowSetChanged event object to all + * registered listeners. + * + * @throws SQLException if an error occurs flushing the contents of + * RowSet. + * @see RowSetListener#rowSetChanged + */ + public void release() throws SQLException { + initContainer(); + notifyRowSetChanged(); + } + + /** + * Cancels deletion of the current row and notifies listeners that + * a row has changed. + *

+ * Note: This method can be ignored if deleted rows are not being shown, + * which is the normal case. + * + * @throws SQLException if the cursor is not on a valid row + */ + public void undoDelete() throws SQLException { + if (getShowDeleted() == false) { + return; + } + // make sure we are on a row + checkCursor(); + + // don't want this to happen... + if (onInsertRow == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); + } + + Row currentRow = (Row)getCurrentRow(); + if (currentRow.getDeleted() == true) { + currentRow.clearDeleted(); + --numDeleted; + notifyRowChanged(); + } + } + + /** + * Immediately removes the current row from this + * CachedRowSetImpl object if the row has been inserted, and + * also notifies listeners the a row has changed. An exception is thrown + * if the row is not a row that has been inserted or the cursor is before + * the first row, after the last row, or on the insert row. + *

+ * This operation cannot be undone. + * + * @throws SQLException if an error occurs, + * the cursor is not on a valid row, + * or the row has not been inserted + */ + public void undoInsert() throws SQLException { + // make sure we are on a row + checkCursor(); + + // don't want this to happen... + if (onInsertRow == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); + } + + Row currentRow = (Row)getCurrentRow(); + if (currentRow.getInserted() == true) { + rvh.remove(cursorPos-1); + --numRows; + notifyRowChanged(); + } else { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.illegalop").toString()); + } + } + + /** + * Immediately reverses the last update operation if the + * row has been modified. This method can be + * called to reverse updates on a all columns until all updates in a row have + * been rolled back to their originating state since the last synchronization + * (acceptChanges) or population. This method may also be called + * while performing updates to the insert row. + *

+ * undoUpdateRowSet object backed by the same data as + * that of this CachedRowSetImpl object and sharing a set of cursors + * with it. This allows cursors to interate over a shared set of rows, providing + * multiple views of the underlying data. + * + * @return a RowSet object that is a copy of this CachedRowSetImpl + * object and shares a set of cursors with it + * @throws SQLException if an error occurs or cloning is + * not supported + * @see RowSetEvent + * @see RowSetListener + */ + public RowSet createShared() throws SQLException { + RowSet clone; + try { + clone = (RowSet)clone(); + } catch (CloneNotSupportedException ex) { + throw new SQLException(ex.getMessage()); + } + return clone; + } + + /** + * Returns a new RowSet object containing by the same data + * as this CachedRowSetImpl object. This method + * differs from the method createCopy in that it throws a + * CloneNotSupportedException object instead of an + * SQLException object, as the method createShared + * does. This clone + * method is called internally by the method createShared, + * which catches the CloneNotSupportedException object + * and in turn throws a new SQLException object. + * + * @return a copy of this CachedRowSetImpl object + * @throws CloneNotSupportedException if an error occurs when + * attempting to clone this CachedRowSetImpl object + * @see #createShared + */ + protected Object clone() throws CloneNotSupportedException { + return (super.clone()); + } + + /** + * Creates a RowSet object that is a deep copy of + * this CachedRowSetImpl object's data, including + * constraints. Updates made + * on a copy are not visible to the original rowset; + * a copy of a rowset is completely independent from the original. + *

+ * Making a copy saves the cost of creating an identical rowset + * from first principles, which can be quite expensive. + * For example, it can eliminate the need to query a + * remote database server. + * @return a new CachedRowSet object that is a deep copy + * of this CachedRowSet object and is + * completely independent from this CachedRowSetImpl + * object. + * @throws SQLException if an error occurs in generating the copy of this + * of the CachedRowSetImpl + * @see #createShared + * @see RowSetEvent + * @see RowSetListener + */ + public CachedRowSet createCopy() throws SQLException { + ObjectOutputStream out; + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + try { + out = new ObjectOutputStream(bOut); + out.writeObject(this); + } catch (IOException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); + } + + ObjectInputStream in; + + try { + ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray()); + in = new ObjectInputStream(bIn); + } catch (StreamCorruptedException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); + } catch (IOException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); + } + + try { + //return ((CachedRowSet)(in.readObject())); + CachedRowSetImpl crsTemp = (CachedRowSetImpl)in.readObject(); + crsTemp.resBundle = this.resBundle; + return ((CachedRowSet)crsTemp); + + } catch (ClassNotFoundException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); + } catch (OptionalDataException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); + } catch (IOException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage())); + } + } + + /** + * Creates a RowSet object that is a copy of + * this CachedRowSetImpl object's table structure + * and the constraints only. + * There will be no data in the object being returned. + * Updates made on a copy are not visible to the original rowset. + *

+ * This helps in getting the underlying XML schema which can + * be used as the basis for populating a WebRowSet. + * + * @return a new CachedRowSet object that is a copy + * of this CachedRowSetImpl object's schema and + * retains all the constraints on the original rowset but contains + * no data + * @throws SQLException if an error occurs in generating the copy + * of the CachedRowSet object + * @see #createShared + * @see #createCopy + * @see #createCopyNoConstraints + * @see RowSetEvent + * @see RowSetListener + */ + public CachedRowSet createCopySchema() throws SQLException { + // Copy everything except data i.e all constraints + + // Store the number of rows of "this" + // and make numRows equals zero. + // and make data also zero. + int nRows = numRows; + numRows = 0; + + CachedRowSet crs = this.createCopy(); + + // reset this object back to number of rows. + numRows = nRows; + + return crs; + } + + /** + * Creates a CachedRowSet object that is a copy of + * this CachedRowSetImpl object's data only. + * All constraints set in this object will not be there + * in the returning object. Updates made + * on a copy are not visible to the original rowset. + * + * @return a new CachedRowSet object that is a deep copy + * of this CachedRowSetImpl object and is + * completely independent from this CachedRowSetImpl object + * @throws SQLException if an error occurs in generating the copy of the + * of the CachedRowSet + * @see #createShared + * @see #createCopy + * @see #createCopySchema + * @see RowSetEvent + * @see RowSetListener + */ + public CachedRowSet createCopyNoConstraints() throws SQLException { + // Copy the whole data ONLY without any constraints. + CachedRowSetImpl crs; + crs = (CachedRowSetImpl)this.createCopy(); + + crs.initProperties(); + try { + crs.unsetMatchColumn(crs.getMatchColumnIndexes()); + } catch(SQLException sqle) { + //do nothing, if the setMatchColumn is not set. + } + + try { + crs.unsetMatchColumn(crs.getMatchColumnNames()); + } catch(SQLException sqle) { + //do nothing, if the setMatchColumn is not set. + } + + return crs; + } + + /** + * Converts this CachedRowSetImpl object to a collection + * of tables. The sample implementation utilitizes the TreeMap + * collection type. + * This class guarantees that the map will be in ascending key order, + * sorted according to the natural order for the key's class. + * + * @return a Collection object consisting of tables, + * each of which is a copy of a row in this + * CachedRowSetImpl object + * @throws SQLException if an error occurs in generating the collection + * @see #toCollection(int) + * @see #toCollection(String) + * @see TreeMap + */ + public Collection toCollection() throws SQLException { + + TreeMap tMap = new TreeMap<>(); + + for (int i = 0; iCachedRowSetImpl object + * as a Collection object. This method makes a copy of the + * column's data and utilitizes the Vector to establish the + * collection. The Vector class implements a growable array + * objects allowing the individual components to be accessed using an + * an integer index similar to that of an array. + * + * @return a Collection object that contains the value(s) + * stored in the specified column of this + * CachedRowSetImpl + * object + * @throws SQLException if an error occurs generated the collection; or + * an invalid column is provided. + * @see #toCollection() + * @see #toCollection(String) + * @see Vector + */ + public Collection toCollection(int column) throws SQLException { + + int nRows = numRows; + Vector vec = new Vector<>(nRows); + + // create a copy + CachedRowSetImpl crsTemp; + crsTemp = (CachedRowSetImpl) this.createCopy(); + + while(nRows!=0) { + crsTemp.next(); + vec.add(crsTemp.getObject(column)); + nRows--; + } + + return (Collection)vec; + } + + /** + * Returns the specified column of this CachedRowSetImpl object + * as a Collection object. This method makes a copy of the + * column's data and utilitizes the Vector to establish the + * collection. The Vector class implements a growable array + * objects allowing the individual components to be accessed using an + * an integer index similar to that of an array. + * + * @return a Collection object that contains the value(s) + * stored in the specified column of this + * CachedRowSetImpl + * object + * @throws SQLException if an error occurs generated the collection; or + * an invalid column is provided. + * @see #toCollection() + * @see #toCollection(int) + * @see Vector + */ + public Collection toCollection(String column) throws SQLException { + return toCollection(getColIdxByName(column)); + } + + //-------------------------------------------------------------------- + // Advanced features + //-------------------------------------------------------------------- + + + /** + * Returns the SyncProvider implementation being used + * with this CachedRowSetImpl implementation rowset. + * + * @return the SyncProvider used by the rowset. If not provider was + * set when the rowset was instantiated, the reference + * implementation (default) provider is returned. + * @throws SQLException if error occurs while return the + * SyncProvider instance. + */ + public SyncProvider getSyncProvider() throws SQLException { + return provider; + } + + /** + * Sets the active SyncProvider and attempts to load + * load the new provider using the SyncFactory SPI. + * + * @throws SQLException if an error occurs while resetting the + * SyncProvider. + */ + public void setSyncProvider(String providerStr) throws SQLException { + provider = + SyncFactory.getInstance(providerStr); + + rowSetReader = provider.getRowSetReader(); + rowSetWriter = provider.getRowSetWriter(); + } + + + //----------------- + // methods inherited from RowSet + //----------------- + + + + + + + //--------------------------------------------------------------------- + // Reading and writing data + //--------------------------------------------------------------------- + + /** + * Populates this CachedRowSetImpl object with data. + * This form of the method uses the rowset's user, password, and url or + * data source name properties to create a database + * connection. If properties that are needed + * have not been set, this method will throw an exception. + *

+ * Another form of this method uses an existing JDBC Connection + * object instead of creating a new one; therefore, it ignores the + * properties used for establishing a new connection. + *

+ * The query specified by the command property is executed to create a + * ResultSet object from which to retrieve data. + * The current contents of the rowset are discarded, and the + * rowset's metadata is also (re)set. If there are outstanding updates, + * they are also ignored. + *

+ * The method execute closes any database connections that it + * creates. + * + * @throws SQLException if an error occurs or the + * necessary properties have not been set + */ + public void execute() throws SQLException { + execute(null); + } + + + + //----------------------------------- + // Methods inherited from ResultSet + //----------------------------------- + + /** + * Moves the cursor down one row from its current position and + * returns true if the new cursor position is a + * valid row. + * The cursor for a new ResultSet object is initially + * positioned before the first row. The first call to the method + * next moves the cursor to the first row, making it + * the current row; the second call makes the second row the + * current row, and so on. + * + *

If an input stream from the previous row is open, it is + * implicitly closed. The ResultSet object's warning + * chain is cleared when a new row is read. + * + * @return true if the new current row is valid; + * false if there are no more rows + * @throws SQLException if an error occurs or + * the cursor is not positioned in the rowset, before + * the first row, or after the last row + */ + public boolean next() throws SQLException { + /* + * make sure things look sane. The cursor must be + * positioned in the rowset or before first (0) or + * after last (numRows + 1) + */ + if (cursorPos < 0 || cursorPos >= numRows + 1) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); + } + // now move and notify + boolean ret = this.internalNext(); + notifyCursorMoved(); + + return ret; + } + + /** + * Moves this CachedRowSetImpl object's cursor to the next + * row and returns true if the cursor is still in the rowset; + * returns false if the cursor has moved to the position after + * the last row. + *

+ * This method handles the cases where the cursor moves to a row that + * has been deleted. + * If this rowset shows deleted rows and the cursor moves to a row + * that has been deleted, this method moves the cursor to the next + * row until the cursor is on a row that has not been deleted. + *

+ * The method internalNext is called by methods such as + * next, absolute, and relative, + * and, as its name implies, is only called internally. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @return true if the cursor is on a valid row in this + * rowset; false if it is after the last row + * @throws SQLException if an error occurs + */ + protected boolean internalNext() throws SQLException { + boolean ret = false; + + do { + if (cursorPos < numRows) { + ++cursorPos; + ret = true; + } else if (cursorPos == numRows) { + // increment to after last + ++cursorPos; + ret = false; + break; + } + } while ((getShowDeleted() == false) && (rowDeleted() == true)); + + /* each call to internalNext may increment cursorPos multiple + * times however, the absolutePos only increments once per call. + */ + if (ret == true) + absolutePos++; + else + absolutePos = 0; + + return ret; + } + + /** + * Closes this CachedRowSetImpl objecy and releases any resources + * it was using. + * + * @throws SQLException if an error occurs when releasing any resources in use + * by this CachedRowSetImpl object + */ + public void close() throws SQLException { + + // close all data structures holding + // the disconnected rowset + + cursorPos = 0; + absolutePos = 0; + numRows = 0; + numDeleted = 0; + + // set all insert(s), update(s) & delete(s), + // if at all, to their initial values. + initProperties(); + + // clear the vector of it's present contents + rvh.clear(); + + // this will make it eligible for gc + // rvh = null; + } + + /** + * Reports whether the last column read was SQL NULL. + * Note that you must first call the method getXXX + * on a column to try to read its value and then call the method + * wasNull to determine whether the value was + * SQL NULL. + * + * @return true if the value in the last column read + * was SQL NULL; false otherwise + * @throws SQLException if an error occurs + */ + public boolean wasNull() throws SQLException { + return lastValueNull; + } + + /** + * Sets the field lastValueNull to the given + * boolean value. + * + * @param value true to indicate that the value of + * the last column read was SQL NULL; + * false to indicate that it was not + */ + private void setLastValueNull(boolean value) { + lastValueNull = value; + } + + // Methods for accessing results by column index + + /** + * Checks to see whether the given index is a valid column number + * in this CachedRowSetImpl object and throws + * an SQLException if it is not. The index is out of bounds + * if it is less than 1 or greater than the number of + * columns in this rowset. + *

+ * This method is called internally by the getXXX and + * updateXXX methods. + * + * @param idx the number of a column in this CachedRowSetImpl + * object; must be between 1 and the number of + * rows in this rowset + * @throws SQLException if the given index is out of bounds + */ + private void checkIndex(int idx) throws SQLException { + if (idx < 1 || idx > RowSetMD.getColumnCount()) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString()); + } + } + + /** + * Checks to see whether the cursor for this CachedRowSetImpl + * object is on a row in the rowset and throws an + * SQLException if it is not. + *

+ * This method is called internally by getXXX methods, by + * updateXXX methods, and by methods that update, insert, + * or delete a row or that cancel a row update, insert, or delete. + * + * @throws SQLException if the cursor for this CachedRowSetImpl + * object is not on a valid row + */ + private void checkCursor() throws SQLException { + if (isAfterLast() == true || isBeforeFirst() == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); + } + } + + /** + * Returns the column number of the column with the given name in this + * CachedRowSetImpl object. This method throws an + * SQLException if the given name is not the name of + * one of the columns in this rowset. + * + * @param name a String object that is the name of a column in + * this CachedRowSetImpl object + * @throws SQLException if the given name does not match the name of one of + * the columns in this rowset + */ + private int getColIdxByName(String name) throws SQLException { + RowSetMD = (RowSetMetaDataImpl)this.getMetaData(); + int cols = RowSetMD.getColumnCount(); + + for (int i=1; i <= cols; ++i) { + String colName = RowSetMD.getColumnName(i); + if (colName != null) + if (name.equalsIgnoreCase(colName)) + return (i); + else + continue; + } + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalcolnm").toString()); + + } + + /** + * Returns the insert row or the current row of this + * CachedRowSetImplobject. + * + * @return the Row object on which this CachedRowSetImpl + * objects's cursor is positioned + */ + protected BaseRow getCurrentRow() { + if (onInsertRow == true) { + return (BaseRow)insertRow; + } else { + return (BaseRow)(rvh.get(cursorPos - 1)); + } + } + + /** + * Removes the row on which the cursor is positioned. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @throws SQLException if the cursor is positioned on the insert + * row + */ + protected void removeCurrentRow() { + ((Row)getCurrentRow()).setDeleted(); + rvh.remove(cursorPos - 1); + --numRows; + } + + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * String object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is null + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + */ + public String getString(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + return value.toString(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * boolean value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value as a boolean in the Java progamming language; + * if the value is SQL NULL, the result is false + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BOOLEAN value + * @see #getBoolean(String) + */ + public boolean getBoolean(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return false; + } + + // check for Boolean... + if (value instanceof Boolean) { + return ((Boolean)value).booleanValue(); + } + + // convert to a Double and compare to zero + try { + return Double.compare(Double.parseDouble(value.toString()), 0) != 0; + } catch (NumberFormatException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.boolfail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * byte value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value as a byte in the Java programming + * language; if the value is SQL NULL, the result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type + * designates the recommended return type. + * @see #getByte(String) + */ + public byte getByte(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return (byte)0; + } + try { + return ((Byte.valueOf(value.toString())).byteValue()); + } catch (NumberFormatException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * short value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + * @see #getShort(String) + */ + public short getShort(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return (short)0; + } + + try { + return ((Short.valueOf(value.toString().trim())).shortValue()); + } catch (NumberFormatException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as an + * int value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + */ + public int getInt(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return 0; + } + + try { + return ((Integer.valueOf(value.toString().trim())).intValue()); + } catch (NumberFormatException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * long value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + * @see #getLong(String) + */ + public long getLong(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return (long)0; + } + try { + return ((Long.valueOf(value.toString().trim())).longValue()); + } catch (NumberFormatException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * float value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + * @see #getFloat(String) + */ + public float getFloat(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return (float)0; + } + try { + return ((new Float(value.toString())).floatValue()); + } catch (NumberFormatException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.floatfail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * double value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + * @see #getDouble(String) + * + */ + public double getDouble(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return (double)0; + } + try { + return ((new Double(value.toString().trim())).doubleValue()); + } catch (NumberFormatException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.math.BigDecimal object. + *

+ * This method is deprecated; use the version of getBigDecimal + * that does not take a scale parameter and returns a value with full + * precision. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @param scale the number of digits to the right of the decimal point in the + * value returned + * @return the column value with the specified number of digits to the right + * of the decimal point; if the value is SQL NULL, the + * result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or this method fails + * @deprecated + */ + @Deprecated + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + Object value; + BigDecimal bDecimal, retVal; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return (new BigDecimal(0)); + } + + bDecimal = this.getBigDecimal(columnIndex); + + retVal = bDecimal.setScale(scale); + + return retVal; + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * byte array value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value as a byte array in the Java programming + * language; if the value is SQL NULL, the + * result is null + * + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BINARY, VARBINARY or + * LONGVARBINARY value. + * The bold SQL type designates the recommended return type. + * @see #getBytes(String) + */ + public byte[] getBytes(int columnIndex) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + return (byte[])(getCurrentRow().getColumnObject(columnIndex)); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.sql.Date object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value as a java.sql.Data object; if + * the value is SQL NULL, the + * result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or this method fails + */ + public java.sql.Date getDate(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + /* + * The object coming back from the db could be + * a date, a timestamp, or a char field variety. + * If it's a date type return it, a timestamp + * we turn into a long and then into a date, + * char strings we try to parse. Yuck. + */ + switch (RowSetMD.getColumnType(columnIndex)) { + case Types.DATE: { + long sec = ((java.sql.Date)value).getTime(); + return new java.sql.Date(sec); + } + case Types.TIMESTAMP: { + long sec = ((Timestamp)value).getTime(); + return new java.sql.Date(sec); + } + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: { + try { + DateFormat df = DateFormat.getDateInstance(); + return ((java.sql.Date)(df.parse(value.toString()))); + } catch (ParseException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + default: { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.sql.Time object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or this method fails + */ + public Time getTime(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + /* + * The object coming back from the db could be + * a date, a timestamp, or a char field variety. + * If it's a date type return it, a timestamp + * we turn into a long and then into a date, + * char strings we try to parse. Yuck. + */ + switch (RowSetMD.getColumnType(columnIndex)) { + case Types.TIME: { + return (Time)value; + } + case Types.TIMESTAMP: { + long sec = ((Timestamp)value).getTime(); + return new Time(sec); + } + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: { + try { + DateFormat tf = DateFormat.getTimeInstance(); + return ((Time)(tf.parse(value.toString()))); + } catch (ParseException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + default: { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.sql.Timestamp object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or this method fails + */ + public Timestamp getTimestamp(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + /* + * The object coming back from the db could be + * a date, a timestamp, or a char field variety. + * If it's a date type return it; a timestamp + * we turn into a long and then into a date; + * char strings we try to parse. Yuck. + */ + switch (RowSetMD.getColumnType(columnIndex)) { + case Types.TIMESTAMP: { + return (Timestamp)value; + } + case Types.TIME: { + long sec = ((Time)value).getTime(); + return new Timestamp(sec); + } + case Types.DATE: { + long sec = ((java.sql.Date)value).getTime(); + return new Timestamp(sec); + } + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: { + try { + DateFormat tf = DateFormat.getTimeInstance(); + return ((Timestamp)(tf.parse(value.toString()))); + } catch (ParseException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + default: { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + } + + /** + * Retrieves the value of the designated column in the current row of this + * CachedRowSetImpl object as a java.io.InputStream + * object. + * + * A column value can be retrieved as a stream of ASCII characters + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. The JDBC + * driver will do any necessary conversion from the database format into ASCII. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a get method implicitly closes the stream. . Also, a + * stream may return 0 for CachedRowSetImpl.available() + * whether there is data available or not. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Java input stream that delivers the database column value + * as a stream of one-byte ASCII characters. If the value is SQL + * NULL, the result is null. + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL CHAR, VARCHAR, LONGVARCHAR + * BINARY, VARBINARY or LONGVARBINARY value. The + * bold SQL type designates the recommended return types that this method is + * used to retrieve. + * @see #getAsciiStream(String) + */ + public InputStream getAsciiStream(int columnIndex) throws SQLException { + Object value; + + // always free an old stream + asciiStream = null; + + // sanity check + checkIndex(columnIndex); + //make sure the cursor is on a vlid row + checkCursor(); + + value = getCurrentRow().getColumnObject(columnIndex); + if (value == null) { + lastValueNull = true; + return null; + } + + try { + if (isString(RowSetMD.getColumnType(columnIndex))) { + asciiStream = new ByteArrayInputStream(((String)value).getBytes("ASCII")); + } else { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + } catch (UnsupportedEncodingException ex) { + throw new SQLException(ex.getMessage()); + } + + return asciiStream; + } + + /** + * A column value can be retrieved as a stream of Unicode characters + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. The JDBC driver will + * do any necessary conversion from the database format into Unicode. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a get method implicitly closes the stream. . Also, a + * stream may return 0 for available() whether there is data + * available or not. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Java input stream that delivers the database column value + * as a stream of two byte Unicode characters. If the value is SQL NULL + * then the result is null. + * @throws SQLException if an error occurs + * @deprecated + */ + @Deprecated + public InputStream getUnicodeStream(int columnIndex) throws SQLException { + // always free an old stream + unicodeStream = null; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (isBinary(RowSetMD.getColumnType(columnIndex)) == false && + isString(RowSetMD.getColumnType(columnIndex)) == false) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + Object value = getCurrentRow().getColumnObject(columnIndex); + if (value == null) { + lastValueNull = true; + return null; + } + + unicodeStream = new StringBufferInputStream(value.toString()); + + return unicodeStream; + } + + /** + * Retrieves the value of the designated column in the current row of this + * CachedRowSetImpl object as a java.io.InputStream + * object. + *

+ * A column value can be retrieved as a stream of uninterpreted bytes + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARBINARY values. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a get method implicitly closes the stream. Also, a + * stream may return 0 for + * CachedRowSetImpl.available() whether there is data + * available or not. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return a Java input stream that delivers the database column value + * as a stream of uninterpreted bytes. If the value is SQL NULL + * then the result is null. + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BINARY, VARBINARY or LONGVARBINARY + * The bold type indicates the SQL type that this method is recommened + * to retrieve. + * @see #getBinaryStream(String) + */ + public InputStream getBinaryStream(int columnIndex) throws SQLException { + + // always free an old stream + binaryStream = null; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + Object value = getCurrentRow().getColumnObject(columnIndex); + if (value == null) { + lastValueNull = true; + return null; + } + + binaryStream = new ByteArrayInputStream((byte[])value); + + return binaryStream; + + } + + + // Methods for accessing results by column name + + /** + * Retrieves the value stored in the designated column + * of the current row as a String object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR< value. The bold SQL type + * designates the recommended return type. + */ + public String getString(String columnName) throws SQLException { + return getString(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a boolean value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value as a boolean in the Java programming + * language; if the value is SQL NULL, + * the result is false + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL BOOLEAN value + * @see #getBoolean(int) + */ + public boolean getBoolean(String columnName) throws SQLException { + return getBoolean(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a byte value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value as a byte in the Java programming + * language; if the value is SQL NULL, the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER, + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The + * bold type designates the recommended return type + */ + public byte getByte(String columnName) throws SQLException { + return getByte(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a short value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type. + * @see #getShort(int) + */ + public short getShort(String columnName) throws SQLException { + return getShort(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as an int value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name + * of a column in this rowset, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + */ + public int getInt(String columnName) throws SQLException { + return getInt(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a long value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type. + * @see #getLong(int) + */ + public long getLong(String columnName) throws SQLException { + return getLong(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a float value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type. + * @see #getFloat(String) + */ + public float getFloat(String columnName) throws SQLException { + return getFloat(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row of this CachedRowSetImpl object + * as a double value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return types. + * @see #getDouble(int) + */ + public double getDouble(String columnName) throws SQLException { + return getDouble(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.math.BigDecimal object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @param scale the number of digits to the right of the decimal point + * @return a java.math.BugDecimal object with scale + * number of digits to the right of the decimal point. + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type that this method is used to + * retrieve. + * @deprecated Use the getBigDecimal(String columnName) + * method instead + */ + @Deprecated + public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { + return getBigDecimal(getColIdxByName(columnName), scale); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a byte array. + * The bytes represent the raw values returned by the driver. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value as a byte array in the Java programming + * language; if the value is SQL NULL, the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL BINARY, VARBINARY + * or LONGVARBINARY values + * The bold SQL type designates the recommended return type. + * @see #getBytes(int) + */ + public byte[] getBytes(String columnName) throws SQLException { + return getBytes(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.sql.Date object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL DATE or + * TIMESTAMP value + */ + public java.sql.Date getDate(String columnName) throws SQLException { + return getDate(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.sql.Time object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if the given column name does not match one of + * this rowset's column names or the cursor is not on one of + * this rowset's rows or its insert row + */ + public Time getTime(String columnName) throws SQLException { + return getTime(getColIdxByName(columnName)); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.sql.Timestamp object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if the given column name does not match one of + * this rowset's column names or the cursor is not on one of + * this rowset's rows or its insert row + */ + public Timestamp getTimestamp(String columnName) throws SQLException { + return getTimestamp(getColIdxByName(columnName)); + } + + /** + * Retrieves the value of the designated column in the current row of this + * CachedRowSetImpl object as a java.io.InputStream + * object. + * + * A column value can be retrieved as a stream of ASCII characters + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. The + * SyncProvider will rely on the JDBC driver to do any necessary + * conversion from the database format into ASCII format. + * + *

Note: All the data in the returned stream must + * be read prior to getting the value of any other column. The + * next call to a getXXX method implicitly closes the stream. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return a Java input stream that delivers the database column value + * as a stream of one-byte ASCII characters. If the value is SQL + * NULL, the result is null. + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL CHAR, VARCHAR, LONGVARCHAR + * BINARY, VARBINARY or LONGVARBINARY value. The + * bold SQL type designates the recommended return types that this method is + * used to retrieve. + * @see #getAsciiStream(int) + */ + public InputStream getAsciiStream(String columnName) throws SQLException { + return getAsciiStream(getColIdxByName(columnName)); + + } + + /** + * A column value can be retrieved as a stream of Unicode characters + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. + * The JDBC driver will do any necessary conversion from the database + * format into Unicode. + * + *

Note: All the data in the returned stream must + * be read prior to getting the value of any other column. The + * next call to a getXXX method implicitly closes the stream. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return a Java input stream that delivers the database column value + * as a stream of two-byte Unicode characters. If the value is + * SQL NULL, the result is null. + * @throws SQLException if the given column name does not match one of + * this rowset's column names or the cursor is not on one of + * this rowset's rows or its insert row + * @deprecated use the method getCharacterStream instead + */ + @Deprecated + public InputStream getUnicodeStream(String columnName) throws SQLException { + return getUnicodeStream(getColIdxByName(columnName)); + } + + /** + * Retrieves the value of the designated column in the current row of this + * CachedRowSetImpl object as a java.io.InputStream + * object. + *

+ * A column value can be retrieved as a stream of uninterpreted bytes + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARBINARY values. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a get method implicitly closes the stream. Also, a + * stream may return 0 for CachedRowSetImpl.available() + * whether there is data available or not. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return a Java input stream that delivers the database column value + * as a stream of uninterpreted bytes. If the value is SQL + * NULL, the result is null. + * @throws SQLException if (1) the given column name is unknown, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BINARY, VARBINARY or LONGVARBINARY + * The bold type indicates the SQL type that this method is recommened + * to retrieve. + * @see #getBinaryStream(int) + * + */ + public InputStream getBinaryStream(String columnName) throws SQLException { + return getBinaryStream(getColIdxByName(columnName)); + } + + + // Advanced features: + + /** + * The first warning reported by calls on this CachedRowSetImpl + * object is returned. Subsequent CachedRowSetImpl warnings will + * be chained to this SQLWarning. + * + *

The warning chain is automatically cleared each time a new + * row is read. + * + *

Note: This warning chain only covers warnings caused + * by ResultSet methods. Any warning caused by statement + * methods (such as reading OUT parameters) will be chained on the + * Statement object. + * + * @return the first SQLWarning or null + */ + public SQLWarning getWarnings() { + return sqlwarn; + } + + /** + * Clears all the warnings reporeted for the CachedRowSetImpl + * object. After a call to this method, the getWarnings method + * returns null until a new warning is reported for this + * CachedRowSetImpl object. + */ + public void clearWarnings() { + sqlwarn = null; + } + + /** + * Retrieves the name of the SQL cursor used by this + * CachedRowSetImpl object. + * + *

In SQL, a result table is retrieved through a cursor that is + * named. The current row of a ResultSet can be updated or deleted + * using a positioned update/delete statement that references the + * cursor name. To ensure that the cursor has the proper isolation + * level to support an update operation, the cursor's SELECT + * statement should be of the form select for update. + * If the for update clause + * is omitted, positioned updates may fail. + * + *

JDBC supports this SQL feature by providing the name of the + * SQL cursor used by a ResultSet object. The current row + * of a result set is also the current row of this SQL cursor. + * + *

Note: If positioned updates are not supported, an + * SQLException is thrown. + * + * @return the SQL cursor name for this CachedRowSetImpl object's + * cursor + * @throws SQLException if an error occurs + */ + public String getCursorName() throws SQLException { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.posupdate").toString()); + } + + /** + * Retrieves a ResultSetMetaData object instance that + * contains information about the CachedRowSet object. + * However, applications should cast the returned object to a + * RowSetMetaData interface implementation. In the + * reference implementation, this cast can be done on the + * RowSetMetaDataImpl class. + *

+ * For example: + *

+     * CachedRowSet crs = new CachedRowSetImpl();
+     * RowSetMetaDataImpl metaData =
+     *     (RowSetMetaDataImpl)crs.getMetaData();
+     * // Set the number of columns in the RowSet object for
+     * // which this RowSetMetaDataImpl object was created to the
+     * // given number.
+     * metaData.setColumnCount(3);
+     * crs.setMetaData(metaData);
+     * 
+ * + * @return the ResultSetMetaData object that describes this + * CachedRowSetImpl object's columns + * @throws SQLException if an error occurs in generating the RowSet + * meta data; or if the CachedRowSetImpl is empty. + * @see RowSetMetaData + */ + public ResultSetMetaData getMetaData() throws SQLException { + return (ResultSetMetaData)RowSetMD; + } + + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as an + * Object value. + *

+ * The type of the Object will be the default + * Java object type corresponding to the column's SQL type, + * following the mapping for built-in types specified in the JDBC 3.0 + * specification. + *

+ * This method may also be used to read datatabase-specific + * abstract data types. + *

+ * This implementation of the method getObject extends its + * behavior so that it gets the attributes of an SQL structured type + * as an array of Object values. This method also custom + * maps SQL user-defined types to classes in the Java programming language. + * When the specified column contains + * a structured or distinct value, the behavior of this method is as + * if it were a call to the method getObject(columnIndex, + * this.getStatement().getConnection().getTypeMap()). + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return a java.lang.Object holding the column value; + * if the value is SQL NULL, the result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or there is a problem getting + * the Class object for a custom mapping + * @see #getObject(String) + */ + public Object getObject(int columnIndex) throws SQLException { + Object value; + Map> map; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + if (value instanceof Struct) { + Struct s = (Struct)value; + map = getTypeMap(); + // look up the class in the map + Class c = map.get(s.getSQLTypeName()); + if (c != null) { + // create new instance of the class + SQLData obj = null; + throw new SQLException("Unable to Instantiate: TODO from Replicadb"); + /*try { + //obj = (SQLData) ReflectUtil.newInstance(c); + } catch(Exception ex) { + throw new SQLException("Unable to Instantiate: ", ex); + } + // get the attributes from the struct + Object attribs[] = s.getAttributes(map); + // create the SQLInput "stream" + SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); + // read the values... + obj.readSQL(sqlInput, s.getSQLTypeName()); + return (Object)obj;*/ + } + } + return value; + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as an + * Object value. + *

+ * The type of the Object will be the default + * Java object type corresponding to the column's SQL type, + * following the mapping for built-in types specified in the JDBC 3.0 + * specification. + *

+ * This method may also be used to read datatabase-specific + * abstract data types. + *

+ * This implementation of the method getObject extends its + * behavior so that it gets the attributes of an SQL structured type + * as an array of Object values. This method also custom + * maps SQL user-defined types to classes + * in the Java programming language. When the specified column contains + * a structured or distinct value, the behavior of this method is as + * if it were a call to the method getObject(columnIndex, + * this.getStatement().getConnection().getTypeMap()). + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a java.lang.Object holding the column value; + * if the value is SQL NULL, the result is null + * @throws SQLException if (1) the given column name does not match one of + * this rowset's column names, (2) the cursor is not + * on a valid row, or (3) there is a problem getting + * the Class object for a custom mapping + * @see #getObject(int) + */ + public Object getObject(String columnName) throws SQLException { + return getObject(getColIdxByName(columnName)); + } + + //---------------------------------------------------------------- + + /** + * Maps the given column name for one of this CachedRowSetImpl + * object's columns to its column number. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return the column index of the given column name + * @throws SQLException if the given column name does not match one + * of this rowset's column names + */ + public int findColumn(String columnName) throws SQLException { + return getColIdxByName(columnName); + } + + + //--------------------------JDBC 2.0----------------------------------- + + //--------------------------------------------------------------------- + // Getter's and Setter's + //--------------------------------------------------------------------- + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.io.Reader object. + * + *

Note: All the data in the returned stream must + * be read prior to getting the value of any other column. The + * next call to a getXXX method implicitly closes the stream. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return a Java character stream that delivers the database column value + * as a stream of two-byte unicode characters in a + * java.io.Reader object. If the value is + * SQL NULL, the result is null. + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL CHAR, VARCHAR, LONGVARCHAR, BINARY, VARBINARY or + * LONGVARBINARY value. + * The bold SQL type designates the recommended return type. + * @see #getCharacterStream(String) + */ + public Reader getCharacterStream(int columnIndex) throws SQLException{ + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (isBinary(RowSetMD.getColumnType(columnIndex))) { + Object value = getCurrentRow().getColumnObject(columnIndex); + if (value == null) { + lastValueNull = true; + return null; + } + charStream = new InputStreamReader + (new ByteArrayInputStream((byte[])value)); + } else if (isString(RowSetMD.getColumnType(columnIndex))) { + Object value = getCurrentRow().getColumnObject(columnIndex); + if (value == null) { + lastValueNull = true; + return null; + } + charStream = new StringReader(value.toString()); + } else { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + return charStream; + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.io.Reader object. + * + *

Note: All the data in the returned stream must + * be read prior to getting the value of any other column. The + * next call to a getXXX method implicitly closes the stream. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return a Java input stream that delivers the database column value + * as a stream of two-byte Unicode characters. If the value is + * SQL NULL, the result is null. + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL CHAR, VARCHAR, LONGVARCHAR, + * BINARY, VARYBINARY or LONGVARBINARY value. + * The bold SQL type designates the recommended return type. + */ + public Reader getCharacterStream(String columnName) throws SQLException { + return getCharacterStream(getColIdxByName(columnName)); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.math.BigDecimal object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return a java.math.BigDecimal value with full precision; + * if the value is SQL NULL, the result is null + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return types that this method is used to retrieve. + * @see #getBigDecimal(String) + */ + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + try { + return (new BigDecimal(value.toString().trim())); + } catch (NumberFormatException ex) { + throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(), + new Object[] {value.toString().trim(), columnIndex})); + } + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.math.BigDecimal object. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a java.math.BigDecimal value with full precision; + * if the value is SQL NULL, the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type that this method is used to + * retrieve + * @see #getBigDecimal(int) + */ + public BigDecimal getBigDecimal(String columnName) throws SQLException { + return getBigDecimal(getColIdxByName(columnName)); + } + + //--------------------------------------------------------------------- + // Traversal/Positioning + //--------------------------------------------------------------------- + + /** + * Returns the number of rows in this CachedRowSetImpl object. + * + * @return number of rows in the rowset + */ + public int size() { + return numRows; + } + + /** + * Indicates whether the cursor is before the first row in this + * CachedRowSetImpl object. + * + * @return true if the cursor is before the first row; + * false otherwise or if the rowset contains no rows + * @throws SQLException if an error occurs + */ + public boolean isBeforeFirst() throws SQLException { + if (cursorPos == 0 && numRows > 0) { + return true; + } else { + return false; + } + } + + /** + * Indicates whether the cursor is after the last row in this + * CachedRowSetImpl object. + * + * @return true if the cursor is after the last row; + * false otherwise or if the rowset contains no rows + * @throws SQLException if an error occurs + */ + public boolean isAfterLast() throws SQLException { + if (cursorPos == numRows+1 && numRows > 0) { + return true; + } else { + return false; + } + } + + /** + * Indicates whether the cursor is on the first row in this + * CachedRowSetImpl object. + * + * @return true if the cursor is on the first row; + * false otherwise or if the rowset contains no rows + * @throws SQLException if an error occurs + */ + public boolean isFirst() throws SQLException { + // this becomes nasty because of deletes. + int saveCursorPos = cursorPos; + int saveAbsoluteCursorPos = absolutePos; + internalFirst(); + if (cursorPos == saveCursorPos) { + return true; + } else { + cursorPos = saveCursorPos; + absolutePos = saveAbsoluteCursorPos; + return false; + } + } + + /** + * Indicates whether the cursor is on the last row in this + * CachedRowSetImpl object. + *

+ * Note: Calling the method isLast may be expensive + * because the JDBC driver might need to fetch ahead one row in order + * to determine whether the current row is the last row in this rowset. + * + * @return true if the cursor is on the last row; + * false otherwise or if this rowset contains no rows + * @throws SQLException if an error occurs + */ + public boolean isLast() throws SQLException { + int saveCursorPos = cursorPos; + int saveAbsoluteCursorPos = absolutePos; + boolean saveShowDeleted = getShowDeleted(); + setShowDeleted(true); + internalLast(); + if (cursorPos == saveCursorPos) { + setShowDeleted(saveShowDeleted); + return true; + } else { + setShowDeleted(saveShowDeleted); + cursorPos = saveCursorPos; + absolutePos = saveAbsoluteCursorPos; + return false; + } + } + + /** + * Moves this CachedRowSetImpl object's cursor to the front of + * the rowset, just before the first row. This method has no effect if + * this rowset contains no rows. + * + * @throws SQLException if an error occurs or the type of this rowset + * is ResultSet.TYPE_FORWARD_ONLY + */ + public void beforeFirst() throws SQLException { + if (getType() == ResultSet.TYPE_FORWARD_ONLY) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.beforefirst").toString()); + } + cursorPos = 0; + absolutePos = 0; + notifyCursorMoved(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the end of + * the rowset, just after the last row. This method has no effect if + * this rowset contains no rows. + * + * @throws SQLException if an error occurs + */ + public void afterLast() throws SQLException { + if (numRows > 0) { + cursorPos = numRows + 1; + absolutePos = 0; + notifyCursorMoved(); + } + } + + /** + * Moves this CachedRowSetImpl object's cursor to the first row + * and returns true if the operation was successful. This + * method also notifies registered listeners that the cursor has moved. + * + * @return true if the cursor is on a valid row; + * false otherwise or if there are no rows in this + * CachedRowSetImpl object + * @throws SQLException if the type of this rowset + * is ResultSet.TYPE_FORWARD_ONLY + */ + public boolean first() throws SQLException { + if(getType() == ResultSet.TYPE_FORWARD_ONLY) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.first").toString()); + } + + // move and notify + boolean ret = this.internalFirst(); + notifyCursorMoved(); + + return ret; + } + + /** + * Moves this CachedRowSetImpl object's cursor to the first + * row and returns true if the operation is successful. + *

+ * This method is called internally by the methods first, + * isFirst, and absolute. + * It in turn calls the method internalNext in order to + * handle the case where the first row is a deleted row that is not visible. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @return true if the cursor moved to the first row; + * false otherwise + * @throws SQLException if an error occurs + */ + protected boolean internalFirst() throws SQLException { + boolean ret = false; + + if (numRows > 0) { + cursorPos = 1; + if ((getShowDeleted() == false) && (rowDeleted() == true)) { + ret = internalNext(); + } else { + ret = true; + } + } + + if (ret == true) + absolutePos = 1; + else + absolutePos = 0; + + return ret; + } + + /** + * Moves this CachedRowSetImpl object's cursor to the last row + * and returns true if the operation was successful. This + * method also notifies registered listeners that the cursor has moved. + * + * @return true if the cursor is on a valid row; + * false otherwise or if there are no rows in this + * CachedRowSetImpl object + * @throws SQLException if the type of this rowset + * is ResultSet.TYPE_FORWARD_ONLY + */ + public boolean last() throws SQLException { + if (getType() == ResultSet.TYPE_FORWARD_ONLY) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString()); + } + + // move and notify + boolean ret = this.internalLast(); + notifyCursorMoved(); + + return ret; + } + + /** + * Moves this CachedRowSetImpl object's cursor to the last + * row and returns true if the operation is successful. + *

+ * This method is called internally by the method last + * when rows have been deleted and the deletions are not visible. + * The method internalLast handles the case where the + * last row is a deleted row that is not visible by in turn calling + * the method internalPrevious. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @return true if the cursor moved to the last row; + * false otherwise + * @throws SQLException if an error occurs + */ + protected boolean internalLast() throws SQLException { + boolean ret = false; + + if (numRows > 0) { + cursorPos = numRows; + if ((getShowDeleted() == false) && (rowDeleted() == true)) { + ret = internalPrevious(); + } else { + ret = true; + } + } + if (ret == true) + absolutePos = numRows - numDeleted; + else + absolutePos = 0; + return ret; + } + + /** + * Returns the number of the current row in this CachedRowSetImpl + * object. The first row is number 1, the second number 2, and so on. + * + * @return the number of the current row; 0 if there is no + * current row + * @throws SQLException if an error occurs; or if the CacheRowSetImpl + * is empty + */ + public int getRow() throws SQLException { + // are we on a valid row? Valid rows are between first and last + if (numRows > 0 && + cursorPos > 0 && + cursorPos < (numRows + 1) && + (getShowDeleted() == false && rowDeleted() == false)) { + return absolutePos; + } else if (getShowDeleted() == true) { + return cursorPos; + } else { + return 0; + } + } + + /** + * Moves this CachedRowSetImpl object's cursor to the row number + * specified. + * + *

If the number is positive, the cursor moves to an absolute row with + * respect to the beginning of the rowset. The first row is row 1, the second + * is row 2, and so on. For example, the following command, in which + * crs is a CachedRowSetImpl object, moves the cursor + * to the fourth row, starting from the beginning of the rowset. + *


+     *
+     *    crs.absolute(4);
+     *
+     *  
+ *

+ * If the number is negative, the cursor moves to an absolute row position + * with respect to the end of the rowset. For example, calling + * absolute(-1) positions the cursor on the last row, + * absolute(-2) moves it on the next-to-last row, and so on. + * If the CachedRowSetImpl object crs has five rows, + * the following command moves the cursor to the fourth-to-last row, which + * in the case of a rowset with five rows, is also the second row, counting + * from the beginning. + *


+     *
+     *    crs.absolute(-4);
+     *
+     *  
+ * + * If the number specified is larger than the number of rows, the cursor + * will move to the position after the last row. If the number specified + * would move the cursor one or more rows before the first row, the cursor + * moves to the position before the first row. + *

+ * Note: Calling absolute(1) is the same as calling the + * method first(). Calling absolute(-1) is the + * same as calling last(). + * + * @param row a positive number to indicate the row, starting row numbering from + * the first row, which is 1; a negative number to indicate + * the row, starting row numbering from the last row, which is + * -1; it must not be 0 + * @return true if the cursor is on the rowset; false + * otherwise + * @throws SQLException if the given cursor position is 0 or the + * type of this rowset is ResultSet.TYPE_FORWARD_ONLY + */ + public boolean absolute( int row ) throws SQLException { + if (row == 0 || getType() == ResultSet.TYPE_FORWARD_ONLY) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.absolute").toString()); + } + + if (row > 0) { // we are moving foward + if (row > numRows) { + // fell off the end + afterLast(); + return false; + } else { + if (absolutePos <= 0) + internalFirst(); + } + } else { // we are moving backward + if (cursorPos + row < 0) { + // fell off the front + beforeFirst(); + return false; + } else { + if (absolutePos >= 0) + internalLast(); + } + } + + // Now move towards the absolute row that we're looking for + while (absolutePos != row) { + if (absolutePos < row) { + if (!internalNext()) + break; + } + else { + if (!internalPrevious()) + break; + } + } + + notifyCursorMoved(); + + if (isAfterLast() || isBeforeFirst()) { + return false; + } else { + return true; + } + } + + /** + * Moves the cursor the specified number of rows from the current + * position, with a positive number moving it forward and a + * negative number moving it backward. + *

+ * If the number is positive, the cursor moves the specified number of + * rows toward the end of the rowset, starting at the current row. + * For example, the following command, in which + * crs is a CachedRowSetImpl object with 100 rows, + * moves the cursor forward four rows from the current row. If the + * current row is 50, the cursor would move to row 54. + *


+     *
+     *    crs.relative(4);
+     *
+     *  
+ *

+ * If the number is negative, the cursor moves back toward the beginning + * the specified number of rows, starting at the current row. + * For example, calling the method + * absolute(-1) positions the cursor on the last row, + * absolute(-2) moves it on the next-to-last row, and so on. + * If the CachedRowSetImpl object crs has five rows, + * the following command moves the cursor to the fourth-to-last row, which + * in the case of a rowset with five rows, is also the second row + * from the beginning. + *


+     *
+     *    crs.absolute(-4);
+     *
+     *  
+ * + * If the number specified is larger than the number of rows, the cursor + * will move to the position after the last row. If the number specified + * would move the cursor one or more rows before the first row, the cursor + * moves to the position before the first row. In both cases, this method + * throws an SQLException. + *

+ * Note: Calling absolute(1) is the same as calling the + * method first(). Calling absolute(-1) is the + * same as calling last(). Calling relative(0) + * is valid, but it does not change the cursor position. + * + * @param rows an int indicating the number of rows to move + * the cursor, starting at the current row; a positive number + * moves the cursor forward; a negative number moves the cursor + * backward; must not move the cursor past the valid + * rows + * @return true if the cursor is on a row in this + * CachedRowSetImpl object; false + * otherwise + * @throws SQLException if there are no rows in this rowset, the cursor is + * positioned either before the first row or after the last row, or + * the rowset is type ResultSet.TYPE_FORWARD_ONLY + */ + public boolean relative(int rows) throws SQLException { + if (numRows == 0 || isBeforeFirst() || + isAfterLast() || getType() == ResultSet.TYPE_FORWARD_ONLY) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.relative").toString()); + } + + if (rows == 0) { + return true; + } + + if (rows > 0) { // we are moving forward + if (cursorPos + rows > numRows) { + // fell off the end + afterLast(); + } else { + for (int i=0; i < rows; i++) { + if (!internalNext()) + break; + } + } + } else { // we are moving backward + if (cursorPos + rows < 0) { + // fell off the front + beforeFirst(); + } else { + for (int i=rows; i < 0; i++) { + if (!internalPrevious()) + break; + } + } + } + notifyCursorMoved(); + + if (isAfterLast() || isBeforeFirst()) { + return false; + } else { + return true; + } + } + + /** + * Moves this CachedRowSetImpl object's cursor to the + * previous row and returns true if the cursor is on + * a valid row or false if it is not. + * This method also notifies all listeners registered with this + * CachedRowSetImpl object that its cursor has moved. + *

+ * Note: calling the method previous() is not the same + * as calling the method relative(-1). This is true + * because it is possible to call previous() from the insert + * row, from after the last row, or from the current row, whereas + * relative may only be called from the current row. + *

+ * The method previous may used in a while + * loop to iterate through a rowset starting after the last row + * and moving toward the beginning. The loop ends when previous + * returns false, meaning that there are no more rows. + * For example, the following code fragment retrieves all the data in + * the CachedRowSetImpl object crs, which has + * three columns. Note that the cursor must initially be positioned + * after the last row so that the first call to the method + * previous places the cursor on the last line. + *

 
+     *
+     *     crs.afterLast();
+     *     while (previous()) {
+     *         String name = crs.getString(1);
+     *         int age = crs.getInt(2);
+     *         short ssn = crs.getShort(3);
+     *         System.out.println(name + "   " + age + "   " + ssn);
+     *     }
+     *
+     *  
+ * This method throws an SQLException if the cursor is not + * on a row in the rowset, before the first row, or after the last row. + * + * @return true if the cursor is on a valid row; + * false if it is before the first row or after the + * last row + * @throws SQLException if the cursor is not on a valid position or the + * type of this rowset is ResultSet.TYPE_FORWARD_ONLY + */ + public boolean previous() throws SQLException { + if (getType() == ResultSet.TYPE_FORWARD_ONLY) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString()); + } + /* + * make sure things look sane. The cursor must be + * positioned in the rowset or before first (0) or + * after last (numRows + 1) + */ + if (cursorPos < 0 || cursorPos > numRows + 1) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); + } + // move and notify + boolean ret = this.internalPrevious(); + notifyCursorMoved(); + + return ret; + } + + /** + * Moves the cursor to the previous row in this CachedRowSetImpl + * object, skipping past deleted rows that are not visible; returns + * true if the cursor is on a row in this rowset and + * false when the cursor goes before the first row. + *

+ * This method is called internally by the method previous. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @return true if the cursor is on a row in this rowset; + * false when the cursor reaches the position before + * the first row + * @throws SQLException if an error occurs + */ + protected boolean internalPrevious() throws SQLException { + boolean ret = false; + + do { + if (cursorPos > 1) { + --cursorPos; + ret = true; + } else if (cursorPos == 1) { + // decrement to before first + --cursorPos; + ret = false; + break; + } + } while ((getShowDeleted() == false) && (rowDeleted() == true)); + + /* + * Each call to internalPrevious may move the cursor + * over multiple rows, the absolute position moves one one row + */ + if (ret == true) + --absolutePos; + else + absolutePos = 0; + + return ret; + } + + + //--------------------------------------------------------------------- + // Updates + //--------------------------------------------------------------------- + + /** + * Indicates whether the current row of this CachedRowSetImpl + * object has been updated. The value returned + * depends on whether this rowset can detect updates: false + * will always be returned if it does not detect updates. + * + * @return true if the row has been visibly updated + * by the owner or another and updates are detected; + * false otherwise + * @throws SQLException if the cursor is on the insert row or not + * not on a valid row + * + * @see DatabaseMetaData#updatesAreDetected + */ + public boolean rowUpdated() throws SQLException { + // make sure the cursor is on a valid row + checkCursor(); + if (onInsertRow == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); + } + return(((Row)getCurrentRow()).getUpdated()); + } + + /** + * Indicates whether the designated column of the current row of + * this CachedRowSetImpl object has been updated. The + * value returned depends on whether this rowset can detcted updates: + * false will always be returned if it does not detect updates. + * + * @param idx the index identifier of the column that may be have been updated. + * @return true is the designated column has been updated + * and the rowset detects updates; false if the rowset has not + * been updated or the rowset does not detect updates + * @throws SQLException if the cursor is on the insert row or not + * on a valid row + * @see DatabaseMetaData#updatesAreDetected + */ + public boolean columnUpdated(int idx) throws SQLException { + // make sure the cursor is on a valid row + checkCursor(); + if (onInsertRow == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); + } + return (((Row)getCurrentRow()).getColUpdated(idx - 1)); + } + + /** + * Indicates whether the designated column of the current row of + * this CachedRowSetImpl object has been updated. The + * value returned depends on whether this rowset can detcted updates: + * false will always be returned if it does not detect updates. + * + * @param columnName the String column name column that may be have + * been updated. + * @return true is the designated column has been updated + * and the rowset detects updates; false if the rowset has not + * been updated or the rowset does not detect updates + * @throws SQLException if the cursor is on the insert row or not + * on a valid row + * @see DatabaseMetaData#updatesAreDetected + */ + public boolean columnUpdated(String columnName) throws SQLException { + return columnUpdated(getColIdxByName(columnName)); + } + + /** + * Indicates whether the current row has been inserted. The value returned + * depends on whether or not the rowset can detect visible inserts. + * + * @return true if a row has been inserted and inserts are detected; + * false otherwise + * @throws SQLException if the cursor is on the insert row or not + * not on a valid row + * + * @see DatabaseMetaData#insertsAreDetected + */ + public boolean rowInserted() throws SQLException { + // make sure the cursor is on a valid row + checkCursor(); + if (onInsertRow == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); + } + return(((Row)getCurrentRow()).getInserted()); + } + + /** + * Indicates whether the current row has been deleted. A deleted row + * may leave a visible "hole" in a rowset. This method can be used to + * detect such holes if the rowset can detect deletions. This method + * will always return false if this rowset cannot detect + * deletions. + * + * @return true if (1)the current row is blank, indicating that + * the row has been deleted, and (2)deletions are detected; + * false otherwise + * @throws SQLException if the cursor is on a valid row in this rowset + * @see DatabaseMetaData#deletesAreDetected + */ + public boolean rowDeleted() throws SQLException { + // make sure the cursor is on a valid row + + if (isAfterLast() == true || + isBeforeFirst() == true || + onInsertRow == true) { + + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); + } + return(((Row)getCurrentRow()).getDeleted()); + } + + /** + * Indicates whether the given SQL data type is a numberic type. + * + * @param type one of the constants from java.sql.Types + * @return true if the given type is NUMERIC,' + * DECIMAL, BIT, TINYINT, + * SMALLINT, INTEGER, BIGINT, + * REAL, DOUBLE, or FLOAT; + * false otherwise + */ + private boolean isNumeric(int type) { + switch (type) { + case Types.NUMERIC: + case Types.DECIMAL: + case Types.BIT: + case Types.TINYINT: + case Types.SMALLINT: + case Types.INTEGER: + case Types.BIGINT: + case Types.REAL: + case Types.DOUBLE: + case Types.FLOAT: + return true; + default: + return false; + } + } + + /** + * Indicates whether the given SQL data type is a string type. + * + * @param type one of the constants from java.sql.Types + * @return true if the given type is CHAR,' + * VARCHAR, or LONGVARCHAR; + * false otherwise + */ + private boolean isString(int type) { + switch (type) { + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + return true; + default: + return false; + } + } + + /** + * Indicates whether the given SQL data type is a binary type. + * + * @param type one of the constants from java.sql.Types + * @return true if the given type is BINARY,' + * VARBINARY, or LONGVARBINARY; + * false otherwise + */ + private boolean isBinary(int type) { + switch (type) { + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + return true; + default: + return false; + } + } + + /** + * Indicates whether the given SQL data type is a temporal type. + * This method is called internally by the conversion methods + * convertNumeric and convertTemporal. + * + * @param type one of the constants from java.sql.Types + * @return true if the given type is DATE, + * TIME, or TIMESTAMP; + * false otherwise + */ + private boolean isTemporal(int type) { + switch (type) { + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + return true; + default: + return false; + } + } + + /** + * Indicates whether the given SQL data type is a boolean type. + * This method is called internally by the conversion methods + * convertNumeric and convertBoolean. + * + * @param type one of the constants from java.sql.Types + * @return true if the given type is BIT, + * , or BOOLEAN; + * false otherwise + */ + private boolean isBoolean(int type) { + switch (type) { + case Types.BIT: + case Types.BOOLEAN: + return true; + default: + return false; + } + } + + + /** + * Converts the given Object in the Java programming language + * to the standard mapping for the specified SQL target data type. + * The conversion must be to a string or numeric type, but there are no + * restrictions on the type to be converted. If the source type and target + * type are the same, the given object is simply returned. + * + * @param srcObj the Object in the Java programming language + * that is to be converted to the target type + * @param srcType the data type that is the standard mapping in SQL of the + * object to be converted; must be one of the constants in + * java.sql.Types + * @param trgType the SQL data type to which to convert the given object; + * must be one of the following constants in + * java.sql.Types: NUMERIC, + * DECIMAL, BIT, TINYINT, + * SMALLINT, INTEGER, BIGINT, + * REAL, DOUBLE, FLOAT, + * VARCHAR, LONGVARCHAR, or CHAR + * @return an Object value.that is + * the standard object mapping for the target SQL type + * @throws SQLException if the given target type is not one of the string or + * numeric types in java.sql.Types + */ + private Object convertNumeric(Object srcObj, int srcType, + int trgType) throws SQLException { + + if (srcType == trgType) { + return srcObj; + } + + if (isNumeric(trgType) == false && isString(trgType) == false) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType); + } + + try { + switch (trgType) { + case Types.BIT: + Integer i = Integer.valueOf(srcObj.toString().trim()); + return i.equals(0) ? + Boolean.valueOf(false) : + Boolean.valueOf(true); + case Types.TINYINT: + return Byte.valueOf(srcObj.toString().trim()); + case Types.SMALLINT: + return Short.valueOf(srcObj.toString().trim()); + case Types.INTEGER: + return Integer.valueOf(srcObj.toString().trim()); + case Types.BIGINT: + return Long.valueOf(srcObj.toString().trim()); + case Types.NUMERIC: + case Types.DECIMAL: + return new BigDecimal(srcObj.toString().trim()); + case Types.REAL: + case Types.FLOAT: + return new Float(srcObj.toString().trim()); + case Types.DOUBLE: + return new Double(srcObj.toString().trim()); + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + return srcObj.toString(); + default: + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType); + } + } catch (NumberFormatException ex) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType); + } + } + + /** + * Converts the given Object in the Java programming language + * to the standard object mapping for the specified SQL target data type. + * The conversion must be to a string or temporal type, and there are also + * restrictions on the type to be converted. + *

+ * Parameters and Return Values + * + * + * + * + * + * + * + * + * + * + *
Source SQL Type + * Target SQL Type + * Object Returned + *
TIMESTAMP + * DATE + * java.sql.Date + *
TIMESTAMP + * TIME + * java.sql.Time + *
TIME + * TIMESTAMP + * java.sql.Timestamp + *
DATE, TIME, or TIMESTAMP + * CHAR, VARCHAR, or LONGVARCHAR + * java.lang.String + *
+ *

+ * If the source type and target type are the same, + * the given object is simply returned. + * + * @param srcObj the Object in the Java programming language + * that is to be converted to the target type + * @param srcType the data type that is the standard mapping in SQL of the + * object to be converted; must be one of the constants in + * java.sql.Types + * @param trgType the SQL data type to which to convert the given object; + * must be one of the following constants in + * java.sql.Types: DATE, + * TIME, TIMESTAMP, CHAR, + * VARCHAR, or LONGVARCHAR + * @return an Object value.that is + * the standard object mapping for the target SQL type + * @throws SQLException if the given target type is not one of the string or + * temporal types in java.sql.Types + */ + private Object convertTemporal(Object srcObj, + int srcType, int trgType) throws SQLException { + + if (srcType == trgType) { + return srcObj; + } + + if (isNumeric(trgType) == true || + (isString(trgType) == false && isTemporal(trgType) == false)) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + try { + switch (trgType) { + case Types.DATE: + if (srcType == Types.TIMESTAMP) { + return new java.sql.Date(((Timestamp)srcObj).getTime()); + } else { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + case Types.TIMESTAMP: + if (srcType == Types.TIME) { + return new Timestamp(((Time)srcObj).getTime()); + } else { + return new Timestamp(((java.sql.Date)srcObj).getTime()); + } + case Types.TIME: + if (srcType == Types.TIMESTAMP) { + return new Time(((Timestamp)srcObj).getTime()); + } else { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + return srcObj.toString(); + default: + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + } catch (NumberFormatException ex) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + } + + /** + * Converts the given Object in the Java programming language + * to the standard mapping for the specified SQL target data type. + * The conversion must be to a string or numeric type, but there are no + * restrictions on the type to be converted. If the source type and target + * type are the same, the given object is simply returned. + * + * @param srcObj the Object in the Java programming language + * that is to be converted to the target type + * @param srcType the data type that is the standard mapping in SQL of the + * object to be converted; must be one of the constants in + * java.sql.Types + * @param trgType the SQL data type to which to convert the given object; + * must be one of the following constants in + * java.sql.Types: BIT, + * or BOOLEAN + * @return an Object value.that is + * the standard object mapping for the target SQL type + * @throws SQLException if the given target type is not one of the Boolean + * types in java.sql.Types + */ + private Object convertBoolean(Object srcObj, int srcType, + int trgType) throws SQLException { + + if (srcType == trgType) { + return srcObj; + } + + if (isNumeric(trgType) == true || + (isString(trgType) == false && isBoolean(trgType) == false)) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + + try { + switch (trgType) { + case Types.BIT: + Integer i = Integer.valueOf(srcObj.toString().trim()); + return i.equals(0) ? + Boolean.valueOf(false) : + Boolean.valueOf(true); + case Types.BOOLEAN: + return Boolean.valueOf(srcObj.toString().trim()); + default: + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType); + } + } catch (NumberFormatException ex) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType); + } + } + + /** + * Sets the designated nullable column in the current row or the + * insert row of this CachedRowSetImpl object with + * null value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset; however, another method must be called to complete + * the update process. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to mark the row as updated + * and to notify listeners that the row has changed. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called to insert the new row into this rowset and to notify + * listeners that a row has changed. + *

+ * In order to propagate updates in this rowset to the underlying + * data source, an application must call the method {@link #acceptChanges} + * after it calls either updateRow or insertRow. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateNull(int columnIndex) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + BaseRow row = getCurrentRow(); + row.setColumnObject(columnIndex, null); + + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * boolean value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + Object obj = convertBoolean(Boolean.valueOf(x), + Types.BIT, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * byte value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateByte(int columnIndex, byte x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + Object obj = convertNumeric(Byte.valueOf(x), + Types.TINYINT, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * short value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateShort(int columnIndex, short x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + Object obj = convertNumeric(Short.valueOf(x), + Types.SMALLINT, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * int value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateInt(int columnIndex, int x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + Object obj = convertNumeric(x, + Types.INTEGER, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * long value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateLong(int columnIndex, long x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + Object obj = convertNumeric(Long.valueOf(x), + Types.BIGINT, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * float value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateFloat(int columnIndex, float x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + Object obj = convertNumeric(Float.valueOf(x), + Types.REAL, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateDouble(int columnIndex, double x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + Object obj = convertNumeric(Double.valueOf(x), + Types.DOUBLE, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.math.BigDecimal object. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + Object obj = convertNumeric(x, + Types.NUMERIC, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * String object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to mark the row as updated. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called to insert the new row into this rowset and mark it + * as inserted. Both of these methods must be called before the + * cursor moves to another row. + *

+ * The method acceptChanges must be called if the + * updated values are to be written back to the underlying database. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateString(int columnIndex, String x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + getCurrentRow().setColumnObject(columnIndex, x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * byte array. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBytes(int columnIndex, byte x[]) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + getCurrentRow().setColumnObject(columnIndex, x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Date object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the type of the designated column is not + * an SQL DATE or TIMESTAMP, or + * (4) this rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateDate(int columnIndex, java.sql.Date x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + Object obj = convertTemporal(x, + Types.DATE, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Time object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the type of the designated column is not + * an SQL TIME or TIMESTAMP, or + * (4) this rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateTime(int columnIndex, Time x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + Object obj = convertTemporal(x, + Types.TIME, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Timestamp object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the type of the designated column is not + * an SQL DATE, TIME, or + * TIMESTAMP, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + Object obj = convertTemporal(x, + Types.TIMESTAMP, + RowSetMD.getColumnType(columnIndex)); + + getCurrentRow().setColumnObject(columnIndex, obj); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * ASCII stream value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @param length the number of one-byte ASCII characters in the stream + * @throws SQLException if this method is invoked + */ + public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { + // sanity Check + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + + if (isString(RowSetMD.getColumnType(columnIndex)) == false && + isBinary(RowSetMD.getColumnType(columnIndex)) == false) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + byte buf[] = new byte[length]; + try { + int charsRead = 0; + do { + charsRead += x.read(buf, charsRead, length - charsRead); + } while (charsRead != length); + //Changed the condition check to check for length instead of -1 + } catch (IOException ex) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.asciistream").toString()); + } + String str = new String(buf); + + getCurrentRow().setColumnObject(columnIndex, str); + + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.io.InputStream object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value; must be a java.io.InputStream + * containing BINARY, VARBINARY, or + * LONGVARBINARY data + * @param length the length of the stream in bytes + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the data in the stream is not binary, or + * (4) this rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBinaryStream(int columnIndex, InputStream x,int length) throws SQLException { + // sanity Check + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + byte buf[] = new byte[length]; + try { + int bytesRead = 0; + do { + bytesRead += x.read(buf, bytesRead, length - bytesRead); + } while (bytesRead != -1); + } catch (IOException ex) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString()); + } + + getCurrentRow().setColumnObject(columnIndex, buf); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.io.Reader object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value; must be a java.io.Reader + * containing BINARY, VARBINARY, + * LONGVARBINARY, CHAR, VARCHAR, + * or LONGVARCHAR data + * @param length the length of the stream in characters + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the data in the stream is not a binary or + * character type, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { + // sanity Check + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (isString(RowSetMD.getColumnType(columnIndex)) == false && + isBinary(RowSetMD.getColumnType(columnIndex)) == false) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + char buf[] = new char[length]; + try { + int charsRead = 0; + do { + charsRead += x.read(buf, charsRead, length - charsRead); + } while (charsRead != length); + //Changed the condition checking to check for length instead of -1 + } catch (IOException ex) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString()); + } + String str = new String(buf); + + getCurrentRow().setColumnObject(columnIndex, str); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Object value. The scale parameter indicates + * the number of digits to the right of the decimal point and is ignored + * if the new column value is not a type that will be mapped to an SQL + * DECIMAL or NUMERIC value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @param scale the number of digits to the right of the decimal point (for + * DECIMAL and NUMERIC types only) + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateObject(int columnIndex, Object x, int scale) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + int type = RowSetMD.getColumnType(columnIndex); + if (type == Types.DECIMAL || type == Types.NUMERIC) { + ((BigDecimal)x).setScale(scale); + } + getCurrentRow().setColumnObject(columnIndex, x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Object value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateObject(int columnIndex, Object x) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + getCurrentRow().setColumnObject(columnIndex, x); + } + + /** + * Sets the designated nullable column in the current row or the + * insert row of this CachedRowSetImpl object with + * null value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateNull(String columnName) throws SQLException { + updateNull(getColIdxByName(columnName)); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * boolean value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBoolean(String columnName, boolean x) throws SQLException { + updateBoolean(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * byte value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateByte(String columnName, byte x) throws SQLException { + updateByte(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * short value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateShort(String columnName, short x) throws SQLException { + updateShort(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * int value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateInt(String columnName, int x) throws SQLException { + updateInt(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * long value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateLong(String columnName, long x) throws SQLException { + updateLong(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * float value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateFloat(String columnName, float x) throws SQLException { + updateFloat(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateDouble(String columnName, double x) throws SQLException { + updateDouble(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.math.BigDecimal object. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { + updateBigDecimal(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * String object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateString(String columnName, String x) throws SQLException { + updateString(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * byte array. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBytes(String columnName, byte x[]) throws SQLException { + updateBytes(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Date object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the type + * of the designated column is not an SQL DATE or + * TIMESTAMP, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateDate(String columnName, java.sql.Date x) throws SQLException { + updateDate(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Time object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the type + * of the designated column is not an SQL TIME or + * TIMESTAMP, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateTime(String columnName, Time x) throws SQLException { + updateTime(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Timestamp object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if the given column index is out of bounds or + * the cursor is not on one of this rowset's rows or its + * insert row + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the type + * of the designated column is not an SQL DATE, + * TIME, or TIMESTAMP, or (4) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateTimestamp(String columnName, Timestamp x) throws SQLException { + updateTimestamp(getColIdxByName(columnName), x); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * ASCII stream value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @param length the number of one-byte ASCII characters in the stream + */ + public void updateAsciiStream(String columnName, + InputStream x, + int length) throws SQLException { + updateAsciiStream(getColIdxByName(columnName), x, length); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.io.InputStream object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value; must be a java.io.InputStream + * containing BINARY, VARBINARY, or + * LONGVARBINARY data + * @param length the length of the stream in bytes + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the data + * in the stream is not binary, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException { + updateBinaryStream(getColIdxByName(columnName), x, length); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.io.Reader object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param reader the new column value; must be a + * java.io.Reader containing BINARY, + * VARBINARY, LONGVARBINARY, CHAR, + * VARCHAR, or LONGVARCHAR data + * @param length the length of the stream in characters + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the data + * in the stream is not a binary or character type, or (4) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateCharacterStream(String columnName, + Reader reader, + int length) throws SQLException { + updateCharacterStream(getColIdxByName(columnName), reader, length); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Object value. The scale parameter + * indicates the number of digits to the right of the decimal point + * and is ignored if the new column value is not a type that will be + * mapped to an SQL DECIMAL or NUMERIC value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @param scale the number of digits to the right of the decimal point (for + * DECIMAL and NUMERIC types only) + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateObject(String columnName, Object x, int scale) throws SQLException { + updateObject(getColIdxByName(columnName), x, scale); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Object value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateObject(String columnName, Object x) throws SQLException { + updateObject(getColIdxByName(columnName), x); + } + + /** + * Inserts the contents of this CachedRowSetImpl object's insert + * row into this rowset immediately following the current row. + * If the current row is the + * position after the last row or before the first row, the new row will + * be inserted at the end of the rowset. This method also notifies + * listeners registered with this rowset that the row has changed. + *

+ * The cursor must be on the insert row when this method is called. + * + * @throws SQLException if (1) the cursor is not on the insert row, + * (2) one or more of the non-nullable columns in the insert + * row has not been given a value, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void insertRow() throws SQLException { + int pos; + + if (onInsertRow == false || + insertRow.isCompleteRow(RowSetMD) == false) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.failedins").toString()); + } + // Added the setting of parameters that are passed + // to setXXX methods after an empty CRS Object is + // created through RowSetMetaData object + Object [] toInsert = getParams(); + + for(int i = 0;i < toInsert.length; i++) { + insertRow.setColumnObject(i+1,toInsert[i]); + } + + Row insRow = new Row(RowSetMD.getColumnCount(), + insertRow.getOrigRow()); + insRow.setInserted(); + /* + * The new row is inserted into the RowSet + * immediately following the current row. + * + * If we are afterlast then the rows are + * inserted at the end. + */ + if (currentRow >= numRows || currentRow < 0) { + pos = numRows; + } else { + pos = currentRow; + } + + rvh.add(pos, insRow); + ++numRows; + // notify the listeners that the row changed. + notifyRowChanged(); + } + + /** + * Marks the current row of this CachedRowSetImpl object as + * updated and notifies listeners registered with this rowset that the + * row has changed. + *

+ * This method cannot be called when the cursor is on the insert row, and + * it should be called before the cursor moves to another row. If it is + * called after the cursor moves to another row, this method has no effect, + * and the updates made before the cursor moved will be lost. + * + * @throws SQLException if the cursor is on the insert row or this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateRow() throws SQLException { + // make sure we aren't on the insert row + if (onInsertRow == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.updateins").toString()); + } + + ((Row)getCurrentRow()).setUpdated(); + + // notify the listeners that the row changed. + notifyRowChanged(); + } + + /** + * Deletes the current row from this CachedRowSetImpl object and + * notifies listeners registered with this rowset that a row has changed. + * This method cannot be called when the cursor is on the insert row. + *

+ * This method marks the current row as deleted, but it does not delete + * the row from the underlying data source. The method + * acceptChanges must be called to delete the row in + * the data source. + * + * @throws SQLException if (1) this method is called when the cursor + * is on the insert row, before the first row, or after the + * last row or (2) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void deleteRow() throws SQLException { + // make sure the cursor is on a valid row + checkCursor(); + + ((Row)getCurrentRow()).setDeleted(); + ++numDeleted; + + // notify the listeners that the row changed. + notifyRowChanged(); + } + + /** + * Sets the current row with its original value and marks the row as + * not updated, thus undoing any changes made to the row since the + * last call to the methods updateRow or deleteRow. + * This method should be called only when the cursor is on a row in + * this rowset. + * + * @throws SQLException if the cursor is on the insert row, before the + * first row, or after the last row + */ + public void refreshRow() throws SQLException { + // make sure we are on a row + checkCursor(); + + // don't want this to happen... + if (onInsertRow == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); + } + + Row currentRow = (Row)getCurrentRow(); + // just undo any changes made to this row. + currentRow.clearUpdated(); + + } + + /** + * Rolls back any updates made to the current row of this + * CachedRowSetImpl object and notifies listeners that + * a row has changed. To have an effect, this method + * must be called after an updateXXX method has been + * called and before the method updateRow has been called. + * If no updates have been made or the method updateRow + * has already been called, this method has no effect. + * + * @throws SQLException if the cursor is on the insert row, before the + * first row, or after the last row + */ + public void cancelRowUpdates() throws SQLException { + // make sure we are on a row + checkCursor(); + + // don't want this to happen... + if (onInsertRow == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString()); + } + + Row currentRow = (Row)getCurrentRow(); + if (currentRow.getUpdated() == true) { + currentRow.clearUpdated(); + notifyRowChanged(); + } + } + + /** + * Moves the cursor for this CachedRowSetImpl object + * to the insert row. The current row in the rowset is remembered + * while the cursor is on the insert row. + *

+ * The insert row is a special row associated with an updatable + * rowset. It is essentially a buffer where a new row may + * be constructed by calling the appropriate updateXXX + * methods to assign a value to each column in the row. A complete + * row must be constructed; that is, every column that is not nullable + * must be assigned a value. In order for the new row to become part + * of this rowset, the method insertRow must be called + * before the cursor is moved back to the rowset. + *

+ * Only certain methods may be invoked while the cursor is on the insert + * row; many methods throw an exception if they are called while the + * cursor is there. In addition to the updateXXX + * and insertRow methods, only the getXXX methods + * may be called when the cursor is on the insert row. A getXXX + * method should be called on a column only after an updateXXX + * method has been called on that column; otherwise, the value returned is + * undetermined. + * + * @throws SQLException if this CachedRowSetImpl object is + * ResultSet.CONCUR_READ_ONLY + */ + public void moveToInsertRow() throws SQLException { + if (getConcurrency() == ResultSet.CONCUR_READ_ONLY) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins").toString()); + } + if (insertRow == null) { + if (RowSetMD == null) + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins1").toString()); + int numCols = RowSetMD.getColumnCount(); + if (numCols > 0) { + insertRow = new InsertRow(numCols); + } else { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins2").toString()); + } + } + onInsertRow = true; + // %%% setCurrentRow called in BaseRow + + currentRow = cursorPos; + cursorPos = -1; + + insertRow.initInsertRow(); + } + + /** + * Moves the cursor for this CachedRowSetImpl object to + * the current row. The current row is the row the cursor was on + * when the method moveToInsertRow was called. + *

+ * Calling this method has no effect unless it is called while the + * cursor is on the insert row. + * + * @throws SQLException if an error occurs + */ + public void moveToCurrentRow() throws SQLException { + if (onInsertRow == false) { + return; + } else { + cursorPos = currentRow; + onInsertRow = false; + } + } + + /** + * Returns null. + * + * @return null + * @throws SQLException if an error occurs + */ + public Statement getStatement() throws SQLException { + return null; + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as an Object in + * the Java programming language, using the given + * java.util.Map object to custom map the value if + * appropriate. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param map a java.util.Map object showing the mapping + * from SQL type names to classes in the Java programming + * language + * @return an Object representing the SQL value + * @throws SQLException if the given column index is out of bounds or + * the cursor is not on one of this rowset's rows or its + * insert row + */ + public Object getObject(int columnIndex, + Map> map) + throws SQLException + { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + if (value instanceof Struct) { + Struct s = (Struct)value; + + // look up the class in the map + Class c = map.get(s.getSQLTypeName()); + if (c != null) { + // create new instance of the class + SQLData obj = null; + throw new SQLException("Unable to Instantiate: TODO from Replicadb"); + /*try { + //obj = (SQLData) ReflectUtil.newInstance(c); + } catch(Exception ex) { + throw new SQLException("Unable to Instantiate: ", ex); + } + // get the attributes from the struct + Object attribs[] = s.getAttributes(map); + // create the SQLInput "stream" + SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); + // read the values... + obj.readSQL(sqlInput, s.getSQLTypeName()); + return (Object)obj;*/ + } + } + return value; + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Ref object + * in the Java programming language. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Ref object representing an SQL REF value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL REF value + * @see #getRef(String) + */ + public Ref getRef(int columnIndex) throws SQLException { + Ref value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (RowSetMD.getColumnType(columnIndex) != Types.REF) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + setLastValueNull(false); + value = (Ref)(getCurrentRow().getColumnObject(columnIndex)); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + return value; + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Blob object + * in the Java programming language. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Blob object representing an SQL BLOB value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BLOB value + * @see #getBlob(String) + */ + public Blob getBlob(int columnIndex) throws SQLException { + Blob value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (RowSetMD.getColumnType(columnIndex) != Types.BLOB) { + System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex))); + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + setLastValueNull(false); + value = (Blob)(getCurrentRow().getColumnObject(columnIndex)); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + return value; + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Clob object + * in the Java programming language. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Clob object representing an SQL CLOB value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL CLOB value + * @see #getClob(String) + */ + public Clob getClob(int columnIndex) throws SQLException { + Clob value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (RowSetMD.getColumnType(columnIndex) != Types.CLOB) { + System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex))); + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + setLastValueNull(false); + value = (Clob)(getCurrentRow().getColumnObject(columnIndex)); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + return value; + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as an Array object + * in the Java programming language. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return an Array object representing an SQL + * ARRAY value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL ARRAY value + * @see #getArray(String) + */ + public Array getArray(int columnIndex) throws SQLException { + Array value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (RowSetMD.getColumnType(columnIndex) != Types.ARRAY) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + setLastValueNull(false); + value = (Array)(getCurrentRow().getColumnObject(columnIndex)); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + return value; + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as an Object in + * the Java programming language, using the given + * java.util.Map object to custom map the value if + * appropriate. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param map a java.util.Map object showing the mapping + * from SQL type names to classes in the Java programming + * language + * @return an Object representing the SQL value + * @throws SQLException if the given column name is not the name of + * a column in this rowset or the cursor is not on one of + * this rowset's rows or its insert row + */ + public Object getObject(String columnName, + Map> map) + throws SQLException { + return getObject(getColIdxByName(columnName), map); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Ref object + * in the Java programming language. + * + * @param colName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a Ref object representing an SQL REF value + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the column value + * is not an SQL REF value + * @see #getRef(int) + */ + public Ref getRef(String colName) throws SQLException { + return getRef(getColIdxByName(colName)); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Blob object + * in the Java programming language. + * + * @param colName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a Blob object representing an SQL BLOB value + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL BLOB value + * @see #getBlob(int) + */ + public Blob getBlob(String colName) throws SQLException { + return getBlob(getColIdxByName(colName)); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Clob object + * in the Java programming language. + * + * @param colName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a Clob object representing an SQL + * CLOB value + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL CLOB value + * @see #getClob(int) + */ + public Clob getClob(String colName) throws SQLException { + return getClob(getColIdxByName(colName)); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as an Array object + * in the Java programming langugage. + * + * @param colName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return an Array object representing an SQL + * ARRAY value + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL ARRAY value + * @see #getArray(int) + */ + public Array getArray(String colName) throws SQLException { + return getArray(getColIdxByName(colName)); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Date + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL DATE or + * TIMESTAMP value + */ + public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + value = convertTemporal(value, + RowSetMD.getColumnType(columnIndex), + Types.DATE); + + // create a default calendar + Calendar defaultCal = Calendar.getInstance(); + // set this Calendar to the time we have + defaultCal.setTime((java.util.Date)value); + + /* + * Now we can pull the pieces of the date out + * of the default calendar and put them into + * the user provided calendar + */ + cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR)); + cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH)); + cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH)); + + /* + * This looks a little odd but it is correct - + * Calendar.getTime() returns a Date... + */ + return new java.sql.Date(cal.getTime().getTime()); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Date + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL DATE or + * TIMESTAMP value + */ + public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException { + return getDate(getColIdxByName(columnName), cal); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Time + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TIME or + * TIMESTAMP value + */ + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + value = convertTemporal(value, + RowSetMD.getColumnType(columnIndex), + Types.TIME); + + // create a default calendar + Calendar defaultCal = Calendar.getInstance(); + // set the time in the default calendar + defaultCal.setTime((java.util.Date)value); + + /* + * Now we can pull the pieces of the date out + * of the default calendar and put them into + * the user provided calendar + */ + cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY)); + cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE)); + cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND)); + + return new Time(cal.getTime().getTime()); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Time + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TIME or + * TIMESTAMP value + */ + public Time getTime(String columnName, Calendar cal) throws SQLException { + return getTime(getColIdxByName(columnName), cal); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Timestamp + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TIME or + * TIMESTAMP value + */ + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + Object value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + setLastValueNull(false); + value = getCurrentRow().getColumnObject(columnIndex); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + value = convertTemporal(value, + RowSetMD.getColumnType(columnIndex), + Types.TIMESTAMP); + + // create a default calendar + Calendar defaultCal = Calendar.getInstance(); + // set the time in the default calendar + defaultCal.setTime((java.util.Date)value); + + /* + * Now we can pull the pieces of the date out + * of the default calendar and put them into + * the user provided calendar + */ + cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR)); + cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH)); + cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH)); + cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY)); + cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE)); + cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND)); + + return new Timestamp(cal.getTime().getTime()); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.sql.Timestamp object, using the given + * Calendar object to construct an appropriate + * millisecond value for the date. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL DATE, + * TIME, or TIMESTAMP value + */ + public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException { + return getTimestamp(getColIdxByName(columnName), cal); + } + + /* + * RowSetInternal Interface + */ + + /** + * Retrieves the Connection object passed to this + * CachedRowSetImpl object. This connection may be + * used to populate this rowset with data or to write data back + * to its underlying data source. + * + * @return the Connection object passed to this rowset; + * may be null if there is no connection + * @throws SQLException if an error occurs + */ + public Connection getConnection() throws SQLException{ + return conn; + } + + /** + * Sets the metadata for this CachedRowSetImpl object + * with the given RowSetMetaData object. + * + * @param md a RowSetMetaData object instance containing + * metadata about the columsn in the rowset + * @throws SQLException if invalid meta data is supplied to the + * rowset + */ + public void setMetaData(RowSetMetaData md) throws SQLException { + RowSetMD =(RowSetMetaDataImpl) md; + } + + /** + * Returns a result set containing the original value of the rowset. The + * original value is the state of the CachedRowSetImpl after the + * last population or synchronization (whichever occurred most recently) with + * the data source. + *

+ * The cursor is positioned before the first row in the result set. + * Only rows contained in the result set returned by getOriginal() + * are said to have an original value. + * + * @return the original result set of the rowset + * @throws SQLException if an error occurs produce the + * ResultSet object + */ + public ResultSet getOriginal() throws SQLException { + CachedRowSetImpl crs = new CachedRowSetImpl(); + crs.RowSetMD = RowSetMD; + crs.numRows = numRows; + crs.cursorPos = 0; + + // make sure we don't get someone playing with these + // %%% is this now necessary ??? + //crs.setReader(null); + //crs.setWriter(null); + int colCount = RowSetMD.getColumnCount(); + Row orig; + + for (Iterator i = rvh.iterator(); i.hasNext();) { + orig = new Row(colCount, ((Row)i.next()).getOrigRow()); + crs.rvh.add(orig); + } + return (ResultSet)crs; + } + + /** + * Returns a result set containing the original value of the current + * row only. + * The original value is the state of the CachedRowSetImpl after + * the last population or synchronization (whichever occurred most recently) + * with the data source. + * + * @return the original result set of the row + * @throws SQLException if there is no current row + * @see #setOriginalRow + */ + public ResultSet getOriginalRow() throws SQLException { + CachedRowSetImpl crs = new CachedRowSetImpl(); + crs.RowSetMD = RowSetMD; + crs.numRows = 1; + crs.cursorPos = 0; + crs.setTypeMap(this.getTypeMap()); + + // make sure we don't get someone playing with these + // %%% is this now necessary ??? + //crs.setReader(null); + //crs.setWriter(null); + + Row orig = new Row(RowSetMD.getColumnCount(), + getCurrentRow().getOrigRow()); + + crs.rvh.add(orig); + + return (ResultSet)crs; + + } + + /** + * Marks the current row in this rowset as being an original row. + * + * @throws SQLException if there is no current row + * @see #getOriginalRow + */ + public void setOriginalRow() throws SQLException { + if (onInsertRow == true) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); + } + + Row row = (Row)getCurrentRow(); + makeRowOriginal(row); + + // this can happen if deleted rows are being shown + if (row.getDeleted() == true) { + removeCurrentRow(); + } + } + + /** + * Makes the given row of this rowset the original row by clearing any + * settings that mark the row as having been inserted, deleted, or updated. + * This method is called internally by the methods + * setOriginalRow + * and setOriginal. + * + * @param row the row to be made the original row + */ + private void makeRowOriginal(Row row) { + if (row.getInserted() == true) { + row.clearInserted(); + } + + if (row.getUpdated() == true) { + row.moveCurrentToOrig(); + } + } + + /** + * Marks all rows in this rowset as being original rows. Any updates + * made to the rows become the original values for the rowset. + * Calls to the method setOriginal connot be reversed. + * + * @throws SQLException if an error occurs + */ + public void setOriginal() throws SQLException { + for (Iterator i = rvh.iterator(); i.hasNext();) { + Row row = (Row)i.next(); + makeRowOriginal(row); + // remove deleted rows from the collection. + if (row.getDeleted() == true) { + i.remove(); + --numRows; + } + } + numDeleted = 0; + + // notify any listeners that the rowset has changed + notifyRowSetChanged(); + } + + /** + * Returns an identifier for the object (table) that was used to create this + * rowset. + * + * @return a String object that identifies the table from + * which this CachedRowSetImpl object was derived + * @throws SQLException if an error occurs + */ + public String getTableName() throws SQLException { + return tableName; + } + + /** + * Sets the identifier for the table from which this rowset was derived + * to the given table name. + * + * @param tabName a String object that identifies the + * table from which this CachedRowSetImpl object + * was derived + * @throws SQLException if an error occurs + */ + public void setTableName(String tabName) throws SQLException { + if (tabName == null) + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString()); + else + tableName = tabName; + } + + /** + * Returns the columns that make a key to uniquely identify a + * row in this CachedRowSetImpl object. + * + * @return an array of column numbers that constitutes a primary + * key for this rowset. This array should be empty + * if no column is representitive of a primary key + * @throws SQLException if the rowset is empty or no columns + * are designated as primary keys + * @see #setKeyColumns + */ + public int[] getKeyColumns() throws SQLException { + int[]keyColumns = this.keyCols; + return (keyColumns == null) ? null : Arrays.copyOf(keyColumns, keyColumns.length); + } + + + /** + * Sets this CachedRowSetImpl object's + * keyCols field with the given array of column + * numbers, which forms a key for uniquely identifying a row + * in this rowset. + * + * @param keys an array of int indicating the + * columns that form a primary key for this + * CachedRowSetImpl object; every + * element in the array must be greater than + * 0 and less than or equal to the number + * of columns in this rowset + * @throws SQLException if any of the numbers in the + * given array is not valid for this rowset + * @see #getKeyColumns + */ + public void setKeyColumns(int [] keys) throws SQLException { + int numCols = 0; + if (RowSetMD != null) { + numCols = RowSetMD.getColumnCount(); + if (keys.length > numCols) + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.keycols").toString()); + } + keyCols = new int[keys.length]; + for (int i = 0; i < keys.length; i++) { + if (RowSetMD != null && (keys[i] <= 0 || + keys[i] > numCols)) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString() + + keys[i]); + } + keyCols[i] = keys[i]; + } + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Ref value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param ref the new column java.sql.Ref value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateRef(int columnIndex, Ref ref) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + // SerialClob will help in getting the byte array and storing it. + // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() + // or through RowSetMetaData.locatorsUpdatorCopy() + getCurrentRow().setColumnObject(columnIndex, new SerialRef(ref)); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param ref the new column java.sql.Ref value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateRef(String columnName, Ref ref) throws SQLException { + updateRef(getColIdxByName(columnName), ref); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param c the new column Clob value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateClob(int columnIndex, Clob c) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + // SerialClob will help in getting the byte array and storing it. + // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() + // or through RowSetMetaData.locatorsUpdatorCopy() + + if(dbmslocatorsUpdateCopy){ + getCurrentRow().setColumnObject(columnIndex, new SerialClob(c)); + } + else{ + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString()); + } + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param c the new column Clob value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateClob(String columnName, Clob c) throws SQLException { + updateClob(getColIdxByName(columnName), c); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.sql.Blob value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param b the new column Blob value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBlob(int columnIndex, Blob b) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + // SerialBlob will help in getting the byte array and storing it. + // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() + // or through RowSetMetaData.locatorsUpdatorCopy() + + if(dbmslocatorsUpdateCopy){ + getCurrentRow().setColumnObject(columnIndex, new SerialBlob(b)); + } + else{ + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString()); + } + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.sql.Blob value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param b the new column Blob value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBlob(String columnName, Blob b) throws SQLException { + updateBlob(getColIdxByName(columnName), b); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.sql.Array values. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param a the new column Array value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateArray(int columnIndex, Array a) throws SQLException { + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + // SerialArray will help in getting the byte array and storing it. + // We need to be checking DatabaseMetaData.locatorsUpdatorCopy() + // or through RowSetMetaData.locatorsUpdatorCopy() + getCurrentRow().setColumnObject(columnIndex, new SerialArray(a)); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.sql.Array value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param a the new column Array value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateArray(String columnName, Array a) throws SQLException { + updateArray(getColIdxByName(columnName), a); + } + + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a java.net.URL object + * in the Java programming language. + * + * @return a java.net.URL object containing the resource reference described by + * the URL + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL DATALINK value. + * @see #getURL(String) + */ + public java.net.URL getURL(int columnIndex) throws SQLException { + //throw new SQLException("Operation not supported"); + + java.net.URL value; + + // sanity check. + checkIndex(columnIndex); + // make sure the cursor is on a valid row + checkCursor(); + + if (RowSetMD.getColumnType(columnIndex) != Types.DATALINK) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()); + } + + setLastValueNull(false); + value = (java.net.URL)(getCurrentRow().getColumnObject(columnIndex)); + + // check for SQL NULL + if (value == null) { + setLastValueNull(true); + return null; + } + + return value; + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a java.net.URL object + * in the Java programming language. + * + * @return a java.net.URL object containing the resource reference described by + * the URL + * @throws SQLException if (1) the given column name not the name of a column + * in this rowset, or + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL DATALINK value. + * @see #getURL(int) + */ + public java.net.URL getURL(String columnName) throws SQLException { + return getURL(getColIdxByName(columnName)); + + } + + /** + * The first warning reported by calls on this CachedRowSetImpl + * object is returned. Subsequent CachedRowSetImpl warnings will + * be chained to this SQLWarning. All RowSetWarnings + * warnings are generated in the disconnected environment and remain a + * seperate warning chain to that provided by the getWarnings + * method. + * + *

The warning chain is automatically cleared each time a new + * row is read. + * + *

Note: This warning chain only covers warnings caused + * by CachedRowSet (and their child interface) + * methods. All SQLWarnings can be obtained using the + * getWarnings method which tracks warnings generated + * by the underlying JDBC driver. + * @return the first SQLWarning or null + * + */ + public RowSetWarning getRowSetWarnings() { + try { + notifyCursorMoved(); + } catch (SQLException e) {} // mask exception + return rowsetWarning; + } + + + /** + * The function tries to isolate the tablename when only setCommand + * is set and not setTablename is called provided there is only one table + * name in the query else just leaves the setting of table name as such. + * If setTablename is set later it will over ride this table name + * value so retrieved. + * + * @return the tablename if only one table in query else return "" + */ + private String buildTableName(String command) throws SQLException { + + // If we have a query from one table, + // we set the table name implicitly + // else user has to explicitly set the table name. + + int indexFrom, indexComma; + String strTablename =""; + command = command.trim(); + + // Query can be a select, insert or update + + if(command.toLowerCase().startsWith("select")) { + // look for "from" keyword, after that look for a + // comma after from. If comma is there don't set + // table name else isolate table name. + + indexFrom = command.toLowerCase().indexOf("from"); + indexComma = command.indexOf(",", indexFrom); + + if(indexComma == -1) { + // implies only one table + strTablename = (command.substring(indexFrom+"from".length(),command.length())).trim(); + + String tabName = strTablename; + + int idxWhere = tabName.toLowerCase().indexOf("where"); + + /** + * Adding the addtional check for conditions following the table name. + * If a condition is found truncate it. + **/ + + if(idxWhere != -1) + { + tabName = tabName.substring(0,idxWhere).trim(); + } + + strTablename = tabName; + + } else { + //strTablename=""; + } + + } else if(command.toLowerCase().startsWith("insert")) { + //strTablename=""; + } else if(command.toLowerCase().startsWith("update")) { + //strTablename=""; + } + return strTablename; + } + + /** + * Commits all changes performed by the acceptChanges() + * methods + * + * @see Connection#commit + */ + public void commit() throws SQLException { + conn.commit(); + } + + /** + * Rolls back all changes performed by the acceptChanges() + * methods + * + * @see Connection#rollback + */ + public void rollback() throws SQLException { + conn.rollback(); + } + + /** + * Rolls back all changes performed by the acceptChanges() + * to the last Savepoint transaction marker. + * + * @see Connection#rollback(Savepoint) + */ + public void rollback(Savepoint s) throws SQLException { + conn.rollback(s); + } + + /** + * Unsets the designated parameter to the given int array. + * This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnIdxes the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnIdx is + * not the same as set using setMatchColumn(int []) + */ + public void unsetMatchColumn(int[] columnIdxes) throws SQLException { + + int i_val; + for( int j= 0 ;j < columnIdxes.length; j++) { + i_val = (Integer.parseInt(iMatchColumns.get(j).toString())); + if(columnIdxes[j] != i_val) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString()); + } + } + + for( int i = 0;i < columnIdxes.length ;i++) { + iMatchColumns.set(i, -1); + } + } + + /** + * Unsets the designated parameter to the given String array. + * This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnIdxes the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnName is + * not the same as set using setMatchColumn(String []) + */ + public void unsetMatchColumn(String[] columnIdxes) throws SQLException { + + for(int j = 0 ;j < columnIdxes.length; j++) { + if( !columnIdxes[j].equals(strMatchColumns.get(j)) ){ + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString()); + } + } + + for(int i = 0 ; i < columnIdxes.length; i++) { + strMatchColumns.set(i,null); + } + } + + /** + * Retrieves the column name as String array + * that was set using setMatchColumn(String []) + * for this rowset. + * + * @return a String array object that contains the column names + * for the rowset which has this the match columns + * + * @throws SQLException if an error occurs or column name is not set + */ + public String[] getMatchColumnNames() throws SQLException { + + String []str_temp = new String[strMatchColumns.size()]; + + if( strMatchColumns.get(0) == null) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString()); + } + + strMatchColumns.copyInto(str_temp); + return str_temp; + } + + /** + * Retrieves the column id as int array that was set using + * setMatchColumn(int []) for this rowset. + * + * @return a int array object that contains the column ids + * for the rowset which has this as the match columns. + * + * @throws SQLException if an error occurs or column index is not set + */ + public int[] getMatchColumnIndexes() throws SQLException { + + Integer []int_temp = new Integer[iMatchColumns.size()]; + int [] i_temp = new int[iMatchColumns.size()]; + int i_val; + + i_val = iMatchColumns.get(0); + + if( i_val == -1 ) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString()); + } + + + iMatchColumns.copyInto(int_temp); + + for(int i = 0; i < int_temp.length; i++) { + i_temp[i] = (int_temp[i]).intValue(); + } + + return i_temp; + } + + /** + * Sets the designated parameter to the given int array. + * This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumnIndexes is called. + * + * @param columnIdxes the indexes into this rowset + * object's internal representation of parameter values; the + * first parameter is 0, the second is 1, and so on; must be + * 0 or greater + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(int[] columnIdxes) throws SQLException { + + for(int j = 0 ; j < columnIdxes.length; j++) { + if( columnIdxes[j] < 0 ) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString()); + } + } + for(int i = 0 ;i < columnIdxes.length; i++) { + iMatchColumns.add(i,columnIdxes[i]); + } + } + + /** + * Sets the designated parameter to the given String array. + * This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumn is called. + * + * @param columnNames the name of the column into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(String[] columnNames) throws SQLException { + + for(int j = 0; j < columnNames.length; j++) { + if( columnNames[j] == null || columnNames[j].equals("")) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString()); + } + } + for( int i = 0; i < columnNames.length; i++) { + strMatchColumns.add(i,columnNames[i]); + } + } + + + /** + * Sets the designated parameter to the given int + * object. This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumn is called. + * + * @param columnIdx the index into this rowset + * object's internal representation of parameter values; the + * first parameter is 0, the second is 1, and so on; must be + * 0 or greater + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(int columnIdx) throws SQLException { + // validate, if col is ok to be set + if(columnIdx < 0) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString()); + } else { + // set iMatchColumn + iMatchColumns.set(0, columnIdx); + //strMatchColumn = null; + } + } + + /** + * Sets the designated parameter to the given String + * object. This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumn is called. + * + * @param columnName the name of the column into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(String columnName) throws SQLException { + // validate, if col is ok to be set + if(columnName == null || (columnName= columnName.trim()).equals("") ) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString()); + } else { + // set strMatchColumn + strMatchColumns.set(0, columnName); + //iMatchColumn = -1; + } + } + + /** + * Unsets the designated parameter to the given int + * object. This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnIdx the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnIdx is + * not the same as set using setMatchColumn(int) + */ + public void unsetMatchColumn(int columnIdx) throws SQLException { + // check if we are unsetting the SAME column + if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString()); + } else if(strMatchColumns.get(0) != null) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString()); + } else { + // that is, we are unsetting it. + iMatchColumns.set(0, -1); + } + } + + /** + * Unsets the designated parameter to the given String + * object. This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnName the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnName is + * not the same as set using setMatchColumn(String) + */ + public void unsetMatchColumn(String columnName) throws SQLException { + // check if we are unsetting the same column + columnName = columnName.trim(); + + if(!((strMatchColumns.get(0)).equals(columnName))) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString()); + } else if(iMatchColumns.get(0) > 0) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch2").toString()); + } else { + strMatchColumns.set(0, null); // that is, we are unsetting it. + } + } + + /** + * Notifies registered listeners that a RowSet object in the given RowSetEvent + * object has populated a number of additional rows. The numRows parameter + * ensures that this event will only be fired every numRow. + *

+ * The source of the event can be retrieved with the method event.getSource. + * + * @param event a RowSetEvent object that contains the + * RowSet object that is the source of the events + * @param numRows when populating, the number of rows interval on which the + * CachedRowSet populated should fire; the default value + * is zero; cannot be less than fetchSize or zero + */ + public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException { + + if( numRows < 0 || numRows < getFetchSize()) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.numrows").toString()); + } + + if(size() % numRows == 0) { + RowSetEvent event_temp = new RowSetEvent(this); + event = event_temp; + notifyRowSetChanged(); + } + } + + /** + * Populates this CachedRowSet object with data from + * the given ResultSet object. While related to the populate(ResultSet) + * method, an additional parameter is provided to allow starting position within + * the ResultSet from where to populate the CachedRowSet + * instance. + * + * This method is an alternative to the method execute + * for filling the rowset with data. The method populate + * does not require that the properties needed by the method + * execute, such as the command property, + * be set. This is true because the method populate + * is given the ResultSet object from + * which to get data and thus does not need to use the properties + * required for setting up a connection and executing this + * CachedRowSetImpl object's command. + *

+ * After populating this rowset with data, the method + * populate sets the rowset's metadata and + * then sends a RowSetChangedEvent object + * to all registered listeners prior to returning. + * + * @param data the ResultSet object containing the data + * to be read into this CachedRowSetImpl object + * @param start the integer specifing the position in the + * ResultSet object to popultate the + * CachedRowSetImpl object. + * @throws SQLException if an error occurs; or the max row setting is + * violated while populating the RowSet.Also id the start position + * is negative. + * @see #execute + */ + public void populate(ResultSet data, int start) throws SQLException{ + + int rowsFetched; + Row currentRow; + int numCols; + int i; + Map> map = getTypeMap(); + Object obj; + int mRows; + + cursorPos = 0; + if(populatecallcount == 0){ + if(start < 0){ + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.startpos").toString()); + } + if(getMaxRows() == 0){ + data.absolute(start); + while(data.next()){ + totalRows++; + } + totalRows++; + } + startPos = start; + } + populatecallcount = populatecallcount +1; + resultSet = data; + if((endPos - startPos) >= getMaxRows() && (getMaxRows() > 0)){ + endPos = prevEndPos; + pagenotend = false; + return; + } + + if((maxRowsreached != getMaxRows() || maxRowsreached != totalRows) && pagenotend) { + startPrev = start - getPageSize(); + } + + if( pageSize == 0){ + prevEndPos = endPos; + endPos = start + getMaxRows() ; + } + else{ + prevEndPos = endPos; + endPos = start + getPageSize(); + } + + + if (start == 1){ + resultSet.beforeFirst(); + } + else { + resultSet.absolute(start -1); + } + if( pageSize == 0) { + rvh = new Vector(getMaxRows()); + + } + else{ + rvh = new Vector(getPageSize()); + } + + if (data == null) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString()); + } + + // get the meta data for this ResultSet + RSMD = data.getMetaData(); + + // set up the metadata + RowSetMD = new RowSetMetaDataImpl(); + initMetaData(RowSetMD, RSMD); + + // release the meta-data so that aren't tempted to use it. + RSMD = null; + numCols = RowSetMD.getColumnCount(); + mRows = this.getMaxRows(); + rowsFetched = 0; + currentRow = null; + + if(!data.next() && mRows == 0){ + endPos = prevEndPos; + pagenotend = false; + return; + } + + data.previous(); + + while ( data.next()) { + + currentRow = new Row(numCols); + if(pageSize == 0){ + if ( rowsFetched >= mRows && mRows > 0) { + rowsetWarning.setNextException(new SQLException("Populating rows " + + "setting has exceeded max row setting")); + break; + } + } + else { + if ( (rowsFetched >= pageSize) ||( maxRowsreached >= mRows && mRows > 0)) { + rowsetWarning.setNextException(new SQLException("Populating rows " + + "setting has exceeded max row setting")); + break; + } + } + + for ( i = 1; i <= numCols; i++) { + /* + * check if the user has set a map. If no map + * is set then use plain getObject. This lets + * us work with drivers that do not support + * getObject with a map in fairly sensible way + */ + if (map == null) { + obj = data.getObject(i); + } else { + obj = data.getObject(i, map); + } + /* + * the following block checks for the various + * types that we have to serialize in order to + * store - right now only structs have been tested + */ + if (obj instanceof Struct) { + obj = new SerialStruct((Struct)obj, map); + } else if (obj instanceof SQLData) { + obj = new SerialStruct((SQLData)obj, map); + } else if (obj instanceof Blob) { + obj = new SerialBlob((Blob)obj); + } else if (obj instanceof Clob) { + obj = new SerialClob((Clob)obj); + } else if (obj instanceof Array) { + obj = new SerialArray((Array)obj, map); + } + + currentRow.initColumnObject(i, obj); + } + rowsFetched++; + maxRowsreached++; + rvh.add(currentRow); + } + numRows = rowsFetched ; + // Also rowsFetched should be equal to rvh.size() + // notify any listeners that the rowset has changed + notifyRowSetChanged(); + + } + + /** + * The nextPage gets the next page, that is a CachedRowSetImpl object + * containing the number of rows specified by page size. + * @return boolean value true indicating whether there are more pages to come and + * false indicating that this is the last page. + * @throws SQLException if an error occurs or this called before calling populate. + */ + public boolean nextPage() throws SQLException { + + if (populatecallcount == 0){ + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString()); + } + // Fix for 6554186 + onFirstPage = false; + if(callWithCon){ + crsReader.setStartPosition(endPos); + crsReader.readData((RowSetInternal)this); + resultSet = null; + } + else { + populate(resultSet,endPos); + } + return pagenotend; + } + + /** + * This is the setter function for setting the size of the page, which specifies + * how many rows have to be retrived at a time. + * + * @param size which is the page size + * @throws SQLException if size is less than zero or greater than max rows. + */ + public void setPageSize (int size) throws SQLException { + if (size < 0) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize").toString()); + } + if (size > getMaxRows() && getMaxRows() != 0) { + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize1").toString()); + } + pageSize = size; + } + + /** + * This is the getter function for the size of the page. + * + * @return an integer that is the page size. + */ + public int getPageSize() { + return pageSize; + } + + + /** + * Retrieves the data present in the page prior to the page from where it is + * called. + * @return boolean value true if it retrieves the previous page, flase if it + * is on the first page. + * @throws SQLException if it is called before populate is called or ResultSet + * is of type ResultSet.TYPE_FORWARD_ONLY or if an error + * occurs. + */ + public boolean previousPage() throws SQLException { + int pS; + int mR; + int rem; + + pS = getPageSize(); + mR = maxRowsreached; + + if (populatecallcount == 0){ + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString()); + } + + if( !callWithCon){ + if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY){ + throw new SQLException (resBundle.handleGetObject("cachedrowsetimpl.fwdonly").toString()); + } + } + + pagenotend = true; + + if(startPrev < startPos ){ + onFirstPage = true; + return false; + } + + if(onFirstPage){ + return false; + } + + rem = mR % pS; + + if(rem == 0){ + maxRowsreached -= (2 * pS); + if(callWithCon){ + crsReader.setStartPosition(startPrev); + crsReader.readData((RowSetInternal)this); + resultSet = null; + } + else { + populate(resultSet,startPrev); + } + return true; + } + else + { + maxRowsreached -= (pS + rem); + if(callWithCon){ + crsReader.setStartPosition(startPrev); + crsReader.readData((RowSetInternal)this); + resultSet = null; + } + else { + populate(resultSet,startPrev); + } + return true; + } + } + + /** + * Goes to the page number passed as the parameter + * @param page , the page loaded on a call to this function + * @return true if the page exists false otherwise + * @throws SQLException if an error occurs + */ + /* + public boolean absolutePage(int page) throws SQLException{ + + boolean isAbs = true, retVal = true; + int counter; + + if( page <= 0 ){ + throw new SQLException("Absolute positoin is invalid"); + } + counter = 0; + + firstPage(); + counter++; + while((counter < page) && isAbs) { + isAbs = nextPage(); + counter ++; + } + + if( !isAbs && counter < page){ + retVal = false; + } + else if(counter == page){ + retVal = true; + } + + return retVal; + } + */ + + + /** + * Goes to the page number passed as the parameter from the current page. + * The parameter can take postive or negative value accordingly. + * @param page , the page loaded on a call to this function + * @return true if the page exists false otherwise + * @throws SQLException if an error occurs + */ + /* + public boolean relativePage(int page) throws SQLException { + + boolean isRel = true,retVal = true; + int counter; + + if(page > 0){ + counter = 0; + while((counter < page) && isRel){ + isRel = nextPage(); + counter++; + } + + if(!isRel && counter < page){ + retVal = false; + } + else if( counter == page){ + retVal = true; + } + return retVal; + } + else { + counter = page; + isRel = true; + while((counter < 0) && isRel){ + isRel = previousPage(); + counter++; + } + + if( !isRel && counter < 0){ + retVal = false; + } + else if(counter == 0){ + retVal = true; + } + return retVal; + } + } + */ + + /** + * Retrieves the first page of data as specified by the page size. + * @return boolean value true if present on first page, false otherwise + * @throws SQLException if it called before populate or ResultSet is of + * type ResultSet.TYPE_FORWARD_ONLY or an error occurs + */ + /* + public boolean firstPage() throws SQLException { + if (populatecallcount == 0){ + throw new SQLException("Populate the data before calling "); + } + if( !callWithCon){ + if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY) { + throw new SQLException("Result of type forward only"); + } + } + endPos = 0; + maxRowsreached = 0; + pagenotend = true; + if(callWithCon){ + crsReader.setStartPosition(startPos); + crsReader.readData((RowSetInternal)this); + resultSet = null; + } + else { + populate(resultSet,startPos); + } + onFirstPage = true; + return onFirstPage; + } + */ + + /** + * Retrives the last page of data as specified by the page size. + * @return boolean value tur if present on the last page, false otherwise + * @throws SQLException if called before populate or if an error occurs. + */ + /* + public boolean lastPage() throws SQLException{ + int pS; + int mR; + int quo; + int rem; + + pS = getPageSize(); + mR = getMaxRows(); + + if(pS == 0){ + onLastPage = true; + return onLastPage; + } + + if(getMaxRows() == 0){ + mR = totalRows; + } + + if (populatecallcount == 0){ + throw new SQLException("Populate the data before calling "); + } + + onFirstPage = false; + + if((mR % pS) == 0){ + quo = mR / pS; + int start = startPos + (pS * (quo - 1)); + maxRowsreached = mR - pS; + if(callWithCon){ + crsReader.setStartPosition(start); + crsReader.readData((RowSetInternal)this); + resultSet = null; + } + else { + populate(resultSet,start); + } + onLastPage = true; + return onLastPage; + } + else { + quo = mR /pS; + rem = mR % pS; + int start = startPos + (pS * quo); + maxRowsreached = mR - (rem); + if(callWithCon){ + crsReader.setStartPosition(start); + crsReader.readData((RowSetInternal)this); + resultSet = null; + } + else { + populate(resultSet,start); + } + onLastPage = true; + return onLastPage; + } + } + */ + + /** + * Sets the status for the row on which the cursor is positioned. The insertFlag is used + * to mention the toggle status for this row + * @param insertFlag if it is true - marks this row as inserted + * if it is false - marks it as not a newly inserted row + * @throws SQLException if an error occurs while doing this operation + */ + public void setRowInserted(boolean insertFlag) throws SQLException { + + checkCursor(); + + if(onInsertRow == true) + throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString()); + + if( insertFlag ) { + ((Row)getCurrentRow()).setInserted(); + } else { + ((Row)getCurrentRow()).clearInserted(); + } + } + + /** + * Retrieves the value of the designated SQL XML parameter as a + * SQLXML object in the Java programming language. + * @param columnIndex the first column is 1, the second is 2, ... + * @return a SQLXML object that maps an SQL XML value + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public SQLXML getSQLXML(int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Retrieves the value of the designated SQL XML parameter as a + * SQLXML object in the Java programming language. + * @param colName the name of the column from which to retrieve the value + * @return a SQLXML object that maps an SQL XML value + * @throws SQLException if a database access error occurs + */ + public SQLXML getSQLXML(String colName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row of this + * ResultSet object as a java.sql.RowId object in the Java + * programming language. + * + * @param columnIndex the first column is 1, the second 2, ... + * @return the column value if the value is a SQL NULL the + * value returned is null + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public RowId getRowId(int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row of this + * ResultSet object as a java.sql.RowId object in the Java + * programming language. + * + * @param columnName the name of the column + * @return the column value if the value is a SQL NULL the + * value returned is null + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public RowId getRowId(String columnName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Updates the designated column with a RowId value. The updater + * methods are used to update column values in the current row or the insert + * row. The updater methods do not update the underlying database; instead + * the updateRow or insertRow methods are called + * to update the database. + * + * @param columnIndex the first column is 1, the second 2, ... + * @param x the column value + * @throws SQLException if a database access occurs + * @since 6.0 + */ + public void updateRowId(int columnIndex, RowId x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Updates the designated column with a RowId value. The updater + * methods are used to update column values in the current row or the insert + * row. The updater methods do not update the underlying database; instead + * the updateRow or insertRow methods are called + * to update the database. + * + * @param columnName the name of the column + * @param x the column value + * @throws SQLException if a database access occurs + * @since 6.0 + */ + public void updateRowId(String columnName, RowId x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Retrieves the holdability of this ResultSet object + * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT + * @throws SQLException if a database error occurs + * @since 6.0 + */ + public int getHoldability() throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Retrieves whether this ResultSet object has been closed. A ResultSet is closed if the + * method close has been called on it, or if it is automatically closed. + * @return true if this ResultSet object is closed; false if it is still open + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public boolean isClosed() throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * This method is used for updating columns that support National Character sets. + * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * @param columnIndex the first column is 1, the second 2, ... + * @param nString the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public void updateNString(int columnIndex, String nString) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * This method is used for updating columns that support National Character sets. + * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * @param columnName name of the Column + * @param nString the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public void updateNString(String columnName, String nString) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + + /*o + * This method is used for updating SQL NCLOB type that maps + * to java.sql.Types.NCLOB + * @param columnIndex the first column is 1, the second 2, ... + * @param nClob the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public void updateNClob(int columnIndex, NClob nClob) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * This method is used for updating SQL NCLOB type that maps + * to java.sql.Types.NCLOB + * @param columnName name of the column + * @param nClob the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public void updateNClob(String columnName, NClob nClob) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a NClob object + * in the Java programming language. + * + * @param i the first column is 1, the second is 2, ... + * @return a NClob object representing the SQL + * NCLOB value in the specified column + * @exception SQLException if a database access error occurs + * @since 6.0 + */ + public NClob getNClob(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a NClob object + * in the Java programming language. + * + * @param colName the name of the column from which to retrieve the value + * @return a NClob object representing the SQL NCLOB + * value in the specified column + * @exception SQLException if a database access error occurs + * @since 6.0 + */ + public NClob getNClob(String colName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + public T unwrap(Class iface) throws SQLException { + return null; + } + + public boolean isWrapperFor(Class interfaces) throws SQLException { + return false; + } + + + /** + * Sets the designated parameter to the given java.sql.SQLXML object. The driver converts this to an + * SQL XML value when it sends it to the database. + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param xmlObject a SQLXML object that maps an SQL XML value + * @throws SQLException if a database access error occurs + * @since 1.6 + */ + public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Sets the designated parameter to the given java.sql.SQLXML object. The driver converts this to an + * SQL XML value when it sends it to the database. + * @param parameterName the name of the parameter + * @param xmlObject a SQLXML object that maps an SQL XML value + * @throws SQLException if a database access error occurs + * @since 1.6 + */ + public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.RowId object. The + * driver converts this to a SQL ROWID value when it sends it + * to the database + * + * @param parameterIndex the first parameter is 1, the second is 2, ... + * @param x the parameter value + * @throws SQLException if a database access error occurs + * + * @since 1.6 + */ + public void setRowId(int parameterIndex, RowId x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.RowId object. The + * driver converts this to a SQL ROWID when it sends it to the + * database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @throws SQLException if a database access error occurs + * @since 1.6 + */ + public void setRowId(String parameterName, RowId x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + + /** + * Sets the designated parameter to a Reader object. The + * Reader reads the data till end-of-file is reached. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setNCharacterStream which takes a length parameter. + * + * @param parameterIndex of the first parameter is 1, the second is 2, ... + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; if a database access error occurs; or + * this method is called on a closed PreparedStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a java.sql.NClob object. The object + * implements the java.sql.NClob interface. This NClob + * object maps to a SQL NCLOB. + * @param parameterName the name of the column to be set + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; or if a database access error occurs + * @since 1.6 + */ + public void setNClob(String parameterName, NClob value) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a + * java.io.Reader object. + * It is intended for use when + * accessing NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * @return a java.io.Reader object that contains the column + * value; if the value is SQL NULL, the value returned is + * null in the Java programming language. + * @param columnIndex the first column is 1, the second is 2, ... + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public Reader getNCharacterStream(int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a + * java.io.Reader object. + * It is intended for use when + * accessing NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * @param columnName the name of the column + * @return a java.io.Reader object that contains the column + * value; if the value is SQL NULL, the value returned is + * null in the Java programming language + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public Reader getNCharacterStream(String columnName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + + /** + * Updates the designated column with a java.sql.SQLXML value. + * The updater + * methods are used to update column values in the current row or the insert + * row. The updater methods do not update the underlying database; instead + * the updateRow or insertRow methods are called + * to update the database. + * @param columnIndex the first column is 1, the second 2, ... + * @param xmlObject the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 1.6 + */ + public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Updates the designated column with a java.sql.SQLXML value. + * The updater + * methods are used to update column values in the current row or the insert + * row. The updater methods do not update the underlying database; instead + * the updateRow or insertRow methods are called + * to update the database. + * + * @param columnName the name of the column + * @param xmlObject the column value + * @throws SQLException if a database access occurs + * @since 1.6 + */ + public void updateSQLXML(String columnName, SQLXML xmlObject) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as + * a String in the Java programming language. + * It is intended for use when + * accessing NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public String getNString(int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as + * a String in the Java programming language. + * It is intended for use when + * accessing NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public String getNString(String columnName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Updates the designated column with a character stream value, which will + * have the specified number of bytes. The driver does the necessary conversion + * from Java character format to the national character set in the database. + * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * The updater methods are used to update column values in the current row or + * the insert row. The updater methods do not update the underlying database; + * instead the updateRow or insertRow methods are called to update the database. + * + * @param columnIndex - the first column is 1, the second is 2, ... + * @param x - the new column value + * @param length - the length of the stream + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public void updateNCharacterStream(int columnIndex, + Reader x, + long length) + throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Updates the designated column with a character stream value, which will + * have the specified number of bytes. The driver does the necessary conversion + * from Java character format to the national character set in the database. + * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * The updater methods are used to update column values in the current row or + * the insert row. The updater methods do not update the underlying database; + * instead the updateRow or insertRow methods are called to update the database. + * + * @param columnName - name of the Column + * @param x - the new column value + * @param length - the length of the stream + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public void updateNCharacterStream(String columnName, + Reader x, + long length) + throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString()); + } + + /** + * Updates the designated column with a character stream value. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + * It is intended for use when + * updating NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateNCharacterStream which takes a length parameter. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNCharacterStream(int columnIndex, + Reader x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + * It is intended for use when + * updating NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateNCharacterStream which takes a length parameter. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param reader the java.io.Reader object containing + * the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNCharacterStream(String columnLabel, + Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + +////////////////////////// + + /** + * Updates the designated column using the given input stream, which + * will have the specified number of bytes. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param inputStream An object that contains the data to set the parameter + * value to. + * @param length the number of bytes in the parameter data. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given input stream, which + * will have the specified number of bytes. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param inputStream An object that contains the data to set the parameter + * value to. + * @param length the number of bytes in the parameter data. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given input stream. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateBlob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param inputStream An object that contains the data to set the parameter + * value to. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given input stream. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateBlob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param inputStream An object that contains the data to set the parameter + * value to. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateClob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateClob(int columnIndex, Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateClob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param reader An object that contains the data to set the parameter value to. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateClob(String columnLabel, Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; this method is called on a closed result set, + * if a database access error occurs or + * the result set concurrency is CONCUR_READ_ONLY + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; this method is called on a closed result set; + * if a database access error occurs or + * the result set concurrency is CONCUR_READ_ONLY + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateNClob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; this method is called on a closed result set, + * if a database access error occurs or + * the result set concurrency is CONCUR_READ_ONLY + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateNClob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; this method is called on a closed result set; + * if a database access error occurs or + * the result set concurrency is CONCUR_READ_ONLY + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with an ascii stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateAsciiStream(int columnIndex, + InputStream x, + long length) throws SQLException { + + } + + /** + * Updates the designated column with a binary stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBinaryStream(int columnIndex, + InputStream x, + long length) throws SQLException { + } + + /** + * Updates the designated column with a character stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateCharacterStream(int columnIndex, + Reader x, + long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param reader the java.io.Reader object containing + * the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateCharacterStream(String columnLabel, + Reader reader, + long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + /** + * Updates the designated column with an ascii stream value, which will have + * the specified number of bytes.. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateAsciiStream(String columnLabel, + InputStream x, + long length) throws SQLException { + } + + /** + * Updates the designated column with a binary stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBinaryStream(String columnLabel, + InputStream x, + long length) throws SQLException { + } + + /** + * Updates the designated column with a binary stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateBinaryStream which takes a length parameter. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBinaryStream(int columnIndex, + InputStream x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Updates the designated column with a binary stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateBinaryStream which takes a length parameter. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBinaryStream(String columnLabel, + InputStream x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateCharacterStream which takes a length parameter. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateCharacterStream(int columnIndex, + Reader x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateCharacterStream which takes a length parameter. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param reader the java.io.Reader object containing + * the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateCharacterStream(String columnLabel, + Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with an ascii stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateAsciiStream which takes a length parameter. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateAsciiStream(int columnIndex, + InputStream x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with an ascii stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateAsciiStream which takes a length parameter. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateAsciiStream(String columnLabel, + InputStream x) throws SQLException { + + } + + /** + * Sets the designated parameter to the given java.net.URL value. + * The driver converts this to an SQL DATALINK value + * when it sends it to the database. + * + * @param parameterIndex the first parameter is 1, the second is 2, ... + * @param x the java.net.URL object to be set + * @exception SQLException if a database access error occurs or + * this method is called on a closed PreparedStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.4 + */ + public void setURL(int parameterIndex, java.net.URL x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. + * This method differs from the setCharacterStream (int, Reader) method + * because it informs the driver that the parameter value should be sent to + * the server as a NCLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGNVARCHAR or a NCLOB + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setNClob which takes a length parameter. + * + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if parameterIndex does not correspond to a parameter + * marker in the SQL statement; + * if the driver does not support national character sets; + * if the driver can detect that a data conversion + * error could occur; if a database access error occurs or + * this method is called on a closed PreparedStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setNClob(int parameterIndex, Reader reader) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. The reader must contain the number + * of characters specified by length otherwise a SQLException will be + * generated when the CallableStatement is executed. + * This method differs from the setCharacterStream (int, Reader, int) method + * because it informs the driver that the parameter value should be sent to + * the server as a NCLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGNVARCHAR or a NCLOB + * + * @param parameterName the name of the parameter to be set + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if parameterIndex does not correspond to a parameter + * marker in the SQL statement; if the length specified is less than zero; + * if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void setNClob(String parameterName, Reader reader, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a Reader object. + * This method differs from the setCharacterStream (int, Reader) method + * because it informs the driver that the parameter value should be sent to + * the server as a NCLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGNVARCHAR or a NCLOB + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setNClob which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if the driver does not support national character sets; + * if the driver can detect that a data conversion + * error could occur; if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setNClob(String parameterName, Reader reader) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a Reader object. The reader must contain the number + * of characters specified by length otherwise a SQLException will be + * generated when the PreparedStatement is executed. + * This method differs from the setCharacterStream (int, Reader, int) method + * because it informs the driver that the parameter value should be sent to + * the server as a NCLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGNVARCHAR or a NCLOB + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if parameterIndex does not correspond to a parameter + * marker in the SQL statement; if the length specified is less than zero; + * if the driver does not support national character sets; + * if the driver can detect that a data conversion + * error could occur; if a database access error occurs or + * this method is called on a closed PreparedStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setNClob(int parameterIndex, Reader reader, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a java.sql.NClob object. The driver converts this to +a + * SQL NCLOB value when it sends it to the database. + * @param parameterIndex of the first parameter is 1, the second is 2, ... + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; or if a database access error occurs + * @since 1.6 + */ + public void setNClob(int parameterIndex, NClob value) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given String object. + * The driver converts this to a SQL NCHAR or + * NVARCHAR or LONGNVARCHAR value + * (depending on the argument's + * size relative to the driver's limits on NVARCHAR values) + * when it sends it to the database. + * + * @param parameterIndex of the first parameter is 1, the second is 2, ... + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; or if a database access error occurs + * @since 1.6 + */ + public void setNString(int parameterIndex, String value) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given String object. + * The driver converts this to a SQL NCHAR or + * NVARCHAR or LONGNVARCHAR + * @param parameterName the name of the column to be set + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; or if a database access error occurs + * @since 1.6 + */ + public void setNString(String parameterName, String value) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a Reader object. The + * Reader reads the data till end-of-file is reached. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + * @param parameterIndex of the first parameter is 1, the second is 2, ... + * @param value the parameter value + * @param length the number of characters in the parameter data. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; or if a database access error occurs + * @since 1.6 + */ + public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a Reader object. The + * Reader reads the data till end-of-file is reached. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + * @param parameterName the name of the column to be set + * @param value the parameter value + * @param length the number of characters in the parameter data. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; or if a database access error occurs + * @since 1.6 + */ + public void setNCharacterStream(String parameterName, Reader value, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. The + * Reader reads the data till end-of-file is reached. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setNCharacterStream which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; if a database access error occurs; or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setNCharacterStream(String parameterName, Reader value) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given java.sql.Timestamp value, + * using the given Calendar object. The driver uses + * the Calendar object to construct an SQL TIMESTAMP value, + * which the driver then sends to the database. With a + * a Calendar object, the driver can calculate the timestamp + * taking into account a custom timezone. If no + * Calendar object is specified, the driver uses the default + * timezone, which is that of the virtual machine running the application. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @param cal the Calendar object the driver will use + * to construct the timestamp + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getTimestamp + * @since 1.4 + */ + public void setTimestamp(String parameterName, Timestamp x, Calendar cal) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. The reader must contain the number + * of characters specified by length otherwise a SQLException will be + * generated when the CallableStatement is executed. + * This method differs from the setCharacterStream (int, Reader, int) method + * because it informs the driver that the parameter value should be sent to + * the server as a CLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGVARCHAR or a CLOB + * @param parameterName the name of the parameter to be set + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if parameterIndex does not correspond to a parameter + * marker in the SQL statement; if the length specified is less than zero; + * a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * + * @since 1.6 + */ + public void setClob(String parameterName, Reader reader, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.Clob object. + * The driver converts this to an SQL CLOB value when it + * sends it to the database. + * + * @param parameterName the name of the parameter + * @param x a Clob object that maps an SQL CLOB value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void setClob (String parameterName, Clob x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a Reader object. + * This method differs from the setCharacterStream (int, Reader) method + * because it informs the driver that the parameter value should be sent to + * the server as a CLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGVARCHAR or a CLOB + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setClob which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if a database access error occurs or this method is called on + * a closed CallableStatement + * + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setClob(String parameterName, Reader reader) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.Date value + * using the default time zone of the virtual machine that is running + * the application. + * The driver converts this + * to an SQL DATE value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getDate + * @since 1.4 + */ + public void setDate(String parameterName, java.sql.Date x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.Date value, + * using the given Calendar object. The driver uses + * the Calendar object to construct an SQL DATE value, + * which the driver then sends to the database. With a + * a Calendar object, the driver can calculate the date + * taking into account a custom timezone. If no + * Calendar object is specified, the driver uses the default + * timezone, which is that of the virtual machine running the application. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @param cal the Calendar object the driver will use + * to construct the date + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getDate + * @since 1.4 + */ + public void setDate(String parameterName, java.sql.Date x, Calendar cal) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.Time value. + * The driver converts this + * to an SQL TIME value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getTime + * @since 1.4 + */ + public void setTime(String parameterName, Time x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.Time value, + * using the given Calendar object. The driver uses + * the Calendar object to construct an SQL TIME value, + * which the driver then sends to the database. With a + * a Calendar object, the driver can calculate the time + * taking into account a custom timezone. If no + * Calendar object is specified, the driver uses the default + * timezone, which is that of the virtual machine running the application. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @param cal the Calendar object the driver will use + * to construct the time + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getTime + * @since 1.4 + */ + public void setTime(String parameterName, Time x, Calendar cal) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. + * This method differs from the setCharacterStream (int, Reader) method + * because it informs the driver that the parameter value should be sent to + * the server as a CLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARCHAR or a CLOB + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setClob which takes a length parameter. + * + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if a database access error occurs, this method is called on + * a closed PreparedStatementor if parameterIndex does not correspond to a parameter + * marker in the SQL statement + * + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setClob(int parameterIndex, Reader reader) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. The reader must contain the number + * of characters specified by length otherwise a SQLException will be + * generated when the PreparedStatement is executed. + *This method differs from the setCharacterStream (int, Reader, int) method + * because it informs the driver that the parameter value should be sent to + * the server as a CLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARCHAR or a CLOB + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if a database access error occurs, this method is called on + * a closed PreparedStatement, if parameterIndex does not correspond to a parameter + * marker in the SQL statement, or if the length specified is less than zero. + * + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setClob(int parameterIndex, Reader reader, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a InputStream object. The inputstream must contain the number + * of characters specified by length otherwise a SQLException will be + * generated when the PreparedStatement is executed. + * This method differs from the setBinaryStream (int, InputStream, int) + * method because it informs the driver that the parameter value should be + * sent to the server as a BLOB. When the setBinaryStream method is used, + * the driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARBINARY or a BLOB + * @param parameterIndex index of the first parameter is 1, + * the second is 2, ... + * @param inputStream An object that contains the data to set the parameter + * value to. + * @param length the number of bytes in the parameter data. + * @throws SQLException if a database access error occurs, + * this method is called on a closed PreparedStatement, + * if parameterIndex does not correspond + * to a parameter marker in the SQL statement, if the length specified + * is less than zero or if the number of bytes in the inputstream does not match + * the specified length. + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setBlob(int parameterIndex, InputStream inputStream, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a InputStream object. + * This method differs from the setBinaryStream (int, InputStream) + * method because it informs the driver that the parameter value should be + * sent to the server as a BLOB. When the setBinaryStream method is used, + * the driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARBINARY or a BLOB + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setBlob which takes a length parameter. + * + * @param parameterIndex index of the first parameter is 1, + * the second is 2, ... + * @param inputStream An object that contains the data to set the parameter + * value to. + * @throws SQLException if a database access error occurs, + * this method is called on a closed PreparedStatement or + * if parameterIndex does not correspond + * to a parameter marker in the SQL statement, + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setBlob(int parameterIndex, InputStream inputStream) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a InputStream object. The inputstream must contain the number + * of characters specified by length, otherwise a SQLException will be + * generated when the CallableStatement is executed. + * This method differs from the setBinaryStream (int, InputStream, int) + * method because it informs the driver that the parameter value should be + * sent to the server as a BLOB. When the setBinaryStream method is used, + * the driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARBINARY or a BLOB + * + * @param parameterName the name of the parameter to be set + * the second is 2, ... + * + * @param inputStream An object that contains the data to set the parameter + * value to. + * @param length the number of bytes in the parameter data. + * @throws SQLException if parameterIndex does not correspond + * to a parameter marker in the SQL statement, or if the length specified + * is less than zero; if the number of bytes in the inputstream does not match + * the specified length; if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * + * @since 1.6 + */ + public void setBlob(String parameterName, InputStream inputStream, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.Blob object. + * The driver converts this to an SQL BLOB value when it + * sends it to the database. + * + * @param parameterName the name of the parameter + * @param x a Blob object that maps an SQL BLOB value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void setBlob (String parameterName, Blob x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a InputStream object. + * This method differs from the setBinaryStream (int, InputStream) + * method because it informs the driver that the parameter value should be + * sent to the server as a BLOB. When the setBinaryStream method is used, + * the driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGVARBINARY or a BLOB + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setBlob which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param inputStream An object that contains the data to set the parameter + * value to. + * @throws SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setBlob(String parameterName, InputStream inputStream) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the value of the designated parameter with the given object. The second + * argument must be an object type; for integral values, the + * java.lang equivalent objects should be used. + * + *

The given Java object will be converted to the given targetSqlType + * before being sent to the database. + * + * If the object has a custom mapping (is of a class implementing the + * interface SQLData), + * the JDBC driver should call the method SQLData.writeSQL to write it + * to the SQL data stream. + * If, on the other hand, the object is of a class implementing + * Ref, Blob, Clob, NClob, + * Struct, java.net.URL, + * or Array, the driver should pass it to the database as a + * value of the corresponding SQL type. + *

+ * Note that this method may be used to pass datatabase- + * specific abstract data types. + * + * @param parameterName the name of the parameter + * @param x the object containing the input parameter value + * @param targetSqlType the SQL type (as defined in java.sql.Types) to be + * sent to the database. The scale argument may further qualify this type. + * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, + * this is the number of digits after the decimal point. For all other + * types, this value will be ignored. + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if targetSqlType is + * a ARRAY, BLOB, CLOB, + * DATALINK, JAVA_OBJECT, NCHAR, + * NCLOB, NVARCHAR, LONGNVARCHAR, + * REF, ROWID, SQLXML + * or STRUCT data type and the JDBC driver does not support + * this data type + * @see Types + * @see #getObject + * @since 1.4 + */ + public void setObject(String parameterName, Object x, int targetSqlType, int scale) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the value of the designated parameter with the given object. + * This method is like the method setObject + * above, except that it assumes a scale of zero. + * + * @param parameterName the name of the parameter + * @param x the object containing the input parameter value + * @param targetSqlType the SQL type (as defined in java.sql.Types) to be + * sent to the database + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if targetSqlType is + * a ARRAY, BLOB, CLOB, + * DATALINK, JAVA_OBJECT, NCHAR, + * NCLOB, NVARCHAR, LONGNVARCHAR, + * REF, ROWID, SQLXML + * or STRUCT data type and the JDBC driver does not support + * this data type + * @see #getObject + * @since 1.4 + */ + public void setObject(String parameterName, Object x, int targetSqlType) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the value of the designated parameter with the given object. + * The second parameter must be of type Object; therefore, the + * java.lang equivalent objects should be used for built-in types. + * + *

The JDBC specification specifies a standard mapping from + * Java Object types to SQL types. The given argument + * will be converted to the corresponding SQL type before being + * sent to the database. + * + *

Note that this method may be used to pass datatabase- + * specific abstract data types, by using a driver-specific Java + * type. + * + * If the object is of a class implementing the interface SQLData, + * the JDBC driver should call the method SQLData.writeSQL + * to write it to the SQL data stream. + * If, on the other hand, the object is of a class implementing + * Ref, Blob, Clob, NClob, + * Struct, java.net.URL, + * or Array, the driver should pass it to the database as a + * value of the corresponding SQL type. + *

+ * This method throws an exception if there is an ambiguity, for example, if the + * object is of a class implementing more than one of the interfaces named above. + * + * @param parameterName the name of the parameter + * @param x the object containing the input parameter value + * @exception SQLException if a database access error occurs, + * this method is called on a closed CallableStatement or if the given + * Object parameter is ambiguous + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getObject + * @since 1.4 + */ + public void setObject(String parameterName, Object x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given input stream, which will have + * the specified number of bytes. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + * @param parameterName the name of the parameter + * @param x the Java input stream that contains the ASCII parameter value + * @param length the number of bytes in the stream + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setAsciiStream(String parameterName, InputStream x, int length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given input stream, which will have + * the specified number of bytes. + * When a very large binary value is input to a LONGVARBINARY + * parameter, it may be more practical to send it via a + * java.io.InputStream object. The data will be read from the stream + * as needed until end-of-file is reached. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + * @param parameterName the name of the parameter + * @param x the java input stream which contains the binary parameter value + * @param length the number of bytes in the stream + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setBinaryStream(String parameterName, InputStream x, + int length) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + * @param parameterName the name of the parameter + * @param reader the java.io.Reader object that + * contains the UNICODE data used as the designated parameter + * @param length the number of characters in the stream + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setCharacterStream(String parameterName, + Reader reader, + int length) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given input stream. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setAsciiStream which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param x the Java input stream that contains the ASCII parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setAsciiStream(String parameterName, InputStream x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given input stream. + * When a very large binary value is input to a LONGVARBINARY + * parameter, it may be more practical to send it via a + * java.io.InputStream object. The data will be read from the + * stream as needed until end-of-file is reached. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setBinaryStream which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param x the java input stream which contains the binary parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setBinaryStream(String parameterName, InputStream x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setCharacterStream which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param reader the java.io.Reader object that contains the + * Unicode data + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setCharacterStream(String parameterName, + Reader reader) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given + * java.math.BigDecimal value. + * The driver converts this to an SQL NUMERIC value when + * it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getBigDecimal + * @since 1.4 + */ + public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given Java String value. + * The driver converts this + * to an SQL VARCHAR or LONGVARCHAR value + * (depending on the argument's + * size relative to the driver's limits on VARCHAR values) + * when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getString + * @since 1.4 + */ + public void setString(String parameterName, String x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given Java array of bytes. + * The driver converts this to an SQL VARBINARY or + * LONGVARBINARY (depending on the argument's size relative + * to the driver's limits on VARBINARY values) when it sends + * it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getBytes + * @since 1.4 + */ + public void setBytes(String parameterName, byte x[]) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given java.sql.Timestamp value. + * The driver + * converts this to an SQL TIMESTAMP value when it sends it to the + * database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getTimestamp + * @since 1.4 + */ + public void setTimestamp(String parameterName, Timestamp x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to SQL NULL. + * + *

Note: You must specify the parameter's SQL type. + * + * @param parameterName the name of the parameter + * @param sqlType the SQL type code defined in java.sql.Types + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setNull(String parameterName, int sqlType) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to SQL NULL. + * This version of the method setNull should + * be used for user-defined types and REF type parameters. Examples + * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and + * named array types. + * + *

Note: To be portable, applications must give the + * SQL type code and the fully-qualified SQL type name when specifying + * a NULL user-defined or REF parameter. In the case of a user-defined type + * the name is the type name of the parameter itself. For a REF + * parameter, the name is the type name of the referenced type. If + * a JDBC driver does not need the type code or type name information, + * it may ignore it. + * + * Although it is intended for user-defined and Ref parameters, + * this method may be used to set a null parameter of any JDBC type. + * If the parameter does not have a user-defined or REF type, the given + * typeName is ignored. + * + * + * @param parameterName the name of the parameter + * @param sqlType a value from java.sql.Types + * @param typeName the fully-qualified name of an SQL user-defined type; + * ignored if the parameter is not a user-defined type or + * SQL REF value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setNull (String parameterName, int sqlType, String typeName) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given Java boolean value. + * The driver converts this + * to an SQL BIT or BOOLEAN value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @see #getBoolean + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setBoolean(String parameterName, boolean x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given Java byte value. + * The driver converts this + * to an SQL TINYINT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getByte + * @since 1.4 + */ + public void setByte(String parameterName, byte x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given Java short value. + * The driver converts this + * to an SQL SMALLINT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getShort + * @since 1.4 + */ + public void setShort(String parameterName, short x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given Java int value. + * The driver converts this + * to an SQL INTEGER value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getInt + * @since 1.4 + */ + public void setInt(String parameterName, int x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given Java long value. + * The driver converts this + * to an SQL BIGINT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getLong + * @since 1.4 + */ + public void setLong(String parameterName, long x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given Java float value. + * The driver converts this + * to an SQL FLOAT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getFloat + * @since 1.4 + */ + public void setFloat(String parameterName, float x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given Java double value. + * The driver converts this + * to an SQL DOUBLE value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getDouble + * @since 1.4 + */ + public void setDouble(String parameterName, double x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString()); + } + + /** + * This method re populates the resBundle + * during the deserialization process + * + */ + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + // Default state initialization happens here + ois.defaultReadObject(); + // Initialization of transient Res Bundle happens here . + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + } + + //------------------------- JDBC 4.1 ----------------------------------- + public T getObject(int columnIndex, Class type) throws SQLException { + throw new SQLFeatureNotSupportedException("Not supported yet."); + } + + public T getObject(String columnLabel, Class type) throws SQLException { + throw new SQLFeatureNotSupportedException("Not supported yet."); + } + + static final long serialVersionUID =1884577171200622428L; +} diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/JdbcRowSetImpl.java b/src/main/java/org/replicadb/rowset/sun/rowset/JdbcRowSetImpl.java new file mode 100644 index 0000000..0cc30aa --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/JdbcRowSetImpl.java @@ -0,0 +1,6920 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; +import javax.sql.RowSetMetaData; +import javax.sql.rowset.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.sql.*; +import java.util.Calendar; +import java.util.Map; +import java.util.Vector; + +/** + * The standard implementation of the JdbcRowSet interface. See the interface + * definition for full behavior and implementation requirements. + * + * @author Jonathan Bruce, Amit Handa + */ + +public class JdbcRowSetImpl extends BaseRowSet implements JdbcRowSet, Joinable { + + /** + * The Connection object that is this rowset's + * current connection to the database. This field is set + * internally when the connection is established. + */ + private Connection conn; + + /** + * The PreparedStatement object that is this rowset's + * current command. This field is set internally when the method + * execute creates the PreparedStatement + * object. + */ + private PreparedStatement ps; + + /** + * The ResultSet object that is this rowset's + * current result set. This field is set internally when the method + * execute executes the rowset's command and thereby + * creates the rowset's ResultSet object. + */ + private ResultSet rs; + + /** + * The RowSetMetaDataImpl object that is constructed when + * a ResultSet object is passed to the JdbcRowSet + * constructor. This helps in constructing all metadata associated + * with the ResultSet object using the setter methods of + * RowSetMetaDataImpl. + */ + private RowSetMetaDataImpl rowsMD; + + /** + * The ResultSetMetaData object from which this + * RowSetMetaDataImpl is formed and which helps in getting + * the metadata information. + */ + private ResultSetMetaData resMD; + + + /** + * The Vector holding the Match Columns + */ + private Vector iMatchColumns; + + /** + * The Vector that will hold the Match Column names. + */ + private Vector strMatchColumns; + + + protected transient JdbcRowSetResourceBundle resBundle; + + /** + * Constructs a default JdbcRowSet object. + * The new instance of JdbcRowSet will serve as a proxy + * for the ResultSet object it creates, and by so doing, + * it will make it possible to use the result set as a JavaBeans + * component. + *

+ * The following is true of a default JdbcRowSet instance: + *

    + *
  • Does not show deleted rows + *
  • Has no time limit for how long a driver may take to + * execute the rowset's command + *
  • Has no limit for the number of rows it may contain + *
  • Has no limit for the number of bytes a column may contain + *
  • Has a scrollable cursor and does not show changes + * made by others + *
  • Will not see uncommitted data (make "dirty" reads) + *
  • Has escape processing turned on + *
  • Has its connection's type map set to null + *
  • Has an empty Hashtable object for storing any + * parameters that are set + *
+ * A newly created JdbcRowSet object must have its + * execute method invoked before other public methods + * are called on it; otherwise, such method calls will cause an + * exception to be thrown. + * + * @throws SQLException [1] if any of its public methods are called prior + * to calling the execute method; [2] if invalid JDBC driver + * properties are set or [3] if no connection to a data source exists. + */ + public JdbcRowSetImpl() { + conn = null; + ps = null; + rs = null; + + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + + initParams(); + + // set the defaults + + try { + setShowDeleted(false); + } catch(SQLException sqle) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setshowdeleted").toString() + + sqle.getLocalizedMessage()); + } + + try { + setQueryTimeout(0); + } catch(SQLException sqle) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() + + sqle.getLocalizedMessage()); + } + + try { + setMaxRows(0); + } catch(SQLException sqle) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxrows").toString() + + sqle.getLocalizedMessage()); + } + + try { + setMaxFieldSize(0); + } catch(SQLException sqle) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxfieldsize").toString() + + sqle.getLocalizedMessage()); + } + + try { + setEscapeProcessing(true); + } catch(SQLException sqle) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setescapeprocessing").toString() + + sqle.getLocalizedMessage()); + } + + try { + setConcurrency(ResultSet.CONCUR_UPDATABLE); + } catch (SQLException sqle) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setconcurrency").toString() + + sqle.getLocalizedMessage()); + } + + setTypeMap(null); + + try { + setType(ResultSet.TYPE_SCROLL_INSENSITIVE); + } catch(SQLException sqle){ + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.settype").toString() + + sqle.getLocalizedMessage()); + } + + setReadOnly(true); + + try { + setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); + } catch(SQLException sqle){ + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.settransactionisolation").toString() + + sqle.getLocalizedMessage()); + } + + //Instantiating the vector for MatchColumns + + iMatchColumns = new Vector(10); + for(int i = 0; i < 10 ; i++) { + iMatchColumns.add(i,Integer.valueOf(-1)); + } + + strMatchColumns = new Vector(10); + for(int j = 0; j < 10; j++) { + strMatchColumns.add(j,null); + } + } + + /** + * Constructs a default JdbcRowSet object given a + * valid Connection object. The new + * instance of JdbcRowSet will serve as a proxy for + * the ResultSet object it creates, and by so doing, + * it will make it possible to use the result set as a JavaBeans + * component. + *

+ * The following is true of a default JdbcRowSet instance: + *

    + *
  • Does not show deleted rows + *
  • Has no time limit for how long a driver may take to + * execute the rowset's command + *
  • Has no limit for the number of rows it may contain + *
  • Has no limit for the number of bytes a column may contain + *
  • Has a scrollable cursor and does not show changes + * made by others + *
  • Will not see uncommitted data (make "dirty" reads) + *
  • Has escape processing turned on + *
  • Has its connection's type map set to null + *
  • Has an empty Hashtable object for storing any + * parameters that are set + *
+ * A newly created JdbcRowSet object must have its + * execute method invoked before other public methods + * are called on it; otherwise, such method calls will cause an + * exception to be thrown. + * + * @throws SQLException [1] if any of its public methods are called prior + * to calling the execute method, [2] if invalid JDBC driver + * properties are set, or [3] if no connection to a data source exists. + */ + public JdbcRowSetImpl(Connection con) throws SQLException { + + conn = con; + ps = null; + rs = null; + + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + + initParams(); + // set the defaults + setShowDeleted(false); + setQueryTimeout(0); + setMaxRows(0); + setMaxFieldSize(0); + + setParams(); + + setReadOnly(true); + setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); + setEscapeProcessing(true); + setTypeMap(null); + + //Instantiating the vector for MatchColumns + + iMatchColumns = new Vector(10); + for(int i = 0; i < 10 ; i++) { + iMatchColumns.add(i,Integer.valueOf(-1)); + } + + strMatchColumns = new Vector(10); + for(int j = 0; j < 10; j++) { + strMatchColumns.add(j,null); + } + } + + /** + * Constructs a default JdbcRowSet object using the + * URL, username, and password arguments supplied. The new + * instance of JdbcRowSet will serve as a proxy for + * the ResultSet object it creates, and by so doing, + * it will make it possible to use the result set as a JavaBeans + * component. + * + *

+ * The following is true of a default JdbcRowSet instance: + *

    + *
  • Does not show deleted rows + *
  • Has no time limit for how long a driver may take to + * execute the rowset's command + *
  • Has no limit for the number of rows it may contain + *
  • Has no limit for the number of bytes a column may contain + *
  • Has a scrollable cursor and does not show changes + * made by others + *
  • Will not see uncommitted data (make "dirty" reads) + *
  • Has escape processing turned on + *
  • Has its connection's type map set to null + *
  • Has an empty Hashtable object for storing any + * parameters that are set + *
+ * + * @param url - a JDBC URL for the database to which this JdbcRowSet + * object will be connected. The form for a JDBC URL is + * jdbc:subprotocol:subname. + * @param user - the database user on whose behalf the connection + * is being made + * @param password - the user's password + * + * @throws SQLException if a database access error occurs + * + */ + public JdbcRowSetImpl(String url, String user, String password) throws SQLException { + conn = null; + ps = null; + rs = null; + + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + + initParams(); + + // Pass the arguments to BaseRowSet + // setter methods now. + + setUsername(user); + setPassword(password); + setUrl(url); + + // set the defaults + setShowDeleted(false); + setQueryTimeout(0); + setMaxRows(0); + setMaxFieldSize(0); + + setParams(); + + setReadOnly(true); + setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); + setEscapeProcessing(true); + setTypeMap(null); + + //Instantiating the vector for MatchColumns + + iMatchColumns = new Vector(10); + for(int i = 0; i < 10 ; i++) { + iMatchColumns.add(i,Integer.valueOf(-1)); + } + + strMatchColumns = new Vector(10); + for(int j = 0; j < 10; j++) { + strMatchColumns.add(j,null); + } + } + + + /** + * Constructs a JdbcRowSet object using the given valid + * ResultSet object. The new + * instance of JdbcRowSet will serve as a proxy for + * the ResultSet object, and by so doing, + * it will make it possible to use the result set as a JavaBeans + * component. + * + *

+ * The following is true of a default JdbcRowSet instance: + *

    + *
  • Does not show deleted rows + *
  • Has no time limit for how long a driver may take to + * execute the rowset's command + *
  • Has no limit for the number of rows it may contain + *
  • Has no limit for the number of bytes a column may contain + *
  • Has a scrollable cursor and does not show changes + * made by others + *
  • Will not see uncommitted data (make "dirty" reads) + *
  • Has escape processing turned on + *
  • Has its connection's type map set to null + *
  • Has an empty Hashtable object for storing any + * parameters that are set + *
+ * + * @param res a valid ResultSet object + * + * @throws SQLException if a database access occurs due to a non + * valid ResultSet handle. + */ + public JdbcRowSetImpl(ResultSet res) throws SQLException { + + // A ResultSet handle encapsulates a connection handle. + // But there is no way we can retrieve a Connection handle + // from a ResultSet object. + // So to avoid any anomalies we keep the conn = null + // The passed rs handle will be a wrapper around for + // "this" object's all operations. + conn = null; + + ps = null; + + rs = res; + + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + + initParams(); + + // get the values from the resultset handle. + setShowDeleted(false); + setQueryTimeout(0); + setMaxRows(0); + setMaxFieldSize(0); + + setParams(); + + setReadOnly(true); + setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); + setEscapeProcessing(true); + setTypeMap(null); + + // Get a handle to ResultSetMetaData + // Construct RowSetMetaData out of it. + + resMD = rs.getMetaData(); + + rowsMD = new RowSetMetaDataImpl(); + + initMetaData(rowsMD, resMD); + + //Instantiating the vector for MatchColumns + + iMatchColumns = new Vector(10); + for(int i = 0; i < 10 ; i++) { + iMatchColumns.add(i,Integer.valueOf(-1)); + } + + strMatchColumns = new Vector(10); + for(int j = 0; j < 10; j++) { + strMatchColumns.add(j,null); + } + } + + /** + * Initializes the given RowSetMetaData object with the values + * in the given ResultSetMetaData object. + * + * @param md the RowSetMetaData object for this + * JdbcRowSetImpl object, which will be set with + * values from rsmd + * @param rsmd the ResultSetMetaData object from which new + * values for md will be read + * @throws SQLException if an error occurs + */ + protected void initMetaData(RowSetMetaData md, ResultSetMetaData rsmd) throws SQLException { + int numCols = rsmd.getColumnCount(); + + md.setColumnCount(numCols); + for (int col=1; col <= numCols; col++) { + md.setAutoIncrement(col, rsmd.isAutoIncrement(col)); + md.setCaseSensitive(col, rsmd.isCaseSensitive(col)); + md.setCurrency(col, rsmd.isCurrency(col)); + md.setNullable(col, rsmd.isNullable(col)); + md.setSigned(col, rsmd.isSigned(col)); + md.setSearchable(col, rsmd.isSearchable(col)); + md.setColumnDisplaySize(col, rsmd.getColumnDisplaySize(col)); + md.setColumnLabel(col, rsmd.getColumnLabel(col)); + md.setColumnName(col, rsmd.getColumnName(col)); + md.setSchemaName(col, rsmd.getSchemaName(col)); + md.setPrecision(col, rsmd.getPrecision(col)); + md.setScale(col, rsmd.getScale(col)); + md.setTableName(col, rsmd.getTableName(col)); + md.setCatalogName(col, rsmd.getCatalogName(col)); + md.setColumnType(col, rsmd.getColumnType(col)); + md.setColumnTypeName(col, rsmd.getColumnTypeName(col)); + } + } + + + protected void checkState() throws SQLException { + + // If all the three i.e. conn, ps & rs are + // simultaneously null implies we are not connected + // to the db, implies undesirable state so throw exception + + if (conn == null && ps == null && rs == null ) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.invalstate").toString()); + } + } + + //--------------------------------------------------------------------- + // Reading and writing data + //--------------------------------------------------------------------- + + /** + * Creates the internal ResultSet object for which this + * JdbcRowSet object is a wrapper, effectively + * making the result set a JavaBeans component. + *

+ * Certain properties must have been set before this method is called + * so that it can establish a connection to a database and execute the + * query that will create the result set. If a DataSource + * object will be used to create the connection, properties for the + * data source name, user name, and password must be set. If the + * DriverManager will be used, the properties for the + * URL, user name, and password must be set. In either case, the + * property for the command must be set. If the command has placeholder + * parameters, those must also be set. This method throws + * an exception if the required properties are not set. + *

+ * Other properties have default values that may optionally be set + * to new values. The execute method will use the value + * for the command property to create a PreparedStatement + * object and set its properties (escape processing, maximum field + * size, maximum number of rows, and query timeout limit) to be those + * of this rowset. + * + * @throws SQLException if (1) a database access error occurs, + * (2) any required JDBC properties are not set, or (3) if an + * invalid connection exists. + */ + public void execute() throws SQLException { + /* + * To execute based on the properties: + * i) determine how to get a connection + * ii) prepare the statement + * iii) set the properties of the statement + * iv) parse the params. and set them + * v) execute the statement + * + * During all of this try to tolerate as many errors + * as possible, many drivers will not support all of + * the properties and will/should throw SQLException + * at us... + * + */ + + prepare(); + + // set the properties of our shiny new statement + setProperties(ps); + + + // set the parameters + decodeParams(getParams(), ps); + + + // execute the statement + rs = ps.executeQuery(); + + + // notify listeners + notifyRowSetChanged(); + + + } + + protected void setProperties(PreparedStatement ps) throws SQLException { + + try { + ps.setEscapeProcessing(getEscapeProcessing()); + } catch (SQLException ex) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setescapeprocessing").toString() + + ex.getLocalizedMessage()); + } + + try { + ps.setMaxFieldSize(getMaxFieldSize()); + } catch (SQLException ex) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxfieldsize").toString() + + ex.getLocalizedMessage()); + } + + try { + ps.setMaxRows(getMaxRows()); + } catch (SQLException ex) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setmaxrows").toString() + + ex.getLocalizedMessage()); + } + + try { + ps.setQueryTimeout(getQueryTimeout()); + } catch (SQLException ex) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.setquerytimeout").toString() + + ex.getLocalizedMessage()); + } + + } + + private Connection connect() throws SQLException { + + // Get a JDBC connection. + + // First check for Connection handle object as such if + // "this" initialized using conn. + + if(conn != null) { + return conn; + + } else if (getDataSourceName() != null) { + + // Connect using JNDI. + try { + Context ctx = new InitialContext(); + DataSource ds = (DataSource)ctx.lookup + (getDataSourceName()); + //return ds.getConnection(getUsername(),getPassword()); + + if(getUsername() != null && !getUsername().equals("")) { + return ds.getConnection(getUsername(),getPassword()); + } else { + return ds.getConnection(); + } + } + catch (NamingException ex) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.connect").toString()); + } + + } else if (getUrl() != null) { + // Check only for getUrl() != null because + // user, passwd can be null + // Connect using the driver manager. + + return DriverManager.getConnection + (getUrl(), getUsername(), getPassword()); + } + else { + return null; + } + + } + + + protected PreparedStatement prepare() throws SQLException { + // get a connection + conn = connect(); + + try { + + Map> aMap = getTypeMap(); + if( aMap != null) { + conn.setTypeMap(aMap); + } + ps = conn.prepareStatement(getCommand(),ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); + } catch (SQLException ex) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.prepare").toString() + + ex.getLocalizedMessage()); + + if (ps != null) + ps.close(); + if (conn != null) + conn.close(); + + throw new SQLException(ex.getMessage()); + } + + return ps; + } + + @SuppressWarnings("deprecation") + private void decodeParams(Object[] params, PreparedStatement ps) + throws SQLException { + + // There is a corresponding decodeParams in JdbcRowSetImpl + // which does the same as this method. This is a design flaw. + // Update the CachedRowsetReader.decodeParams when you update + // this method. + + // Adding the same comments to CachedRowsetReader.decodeParams. + + int arraySize; + Object[] param = null; + + for (int i=0; i < params.length; i++) { + if (params[i] instanceof Object[]) { + param = (Object[])params[i]; + + if (param.length == 2) { + if (param[0] == null) { + ps.setNull(i + 1, ((Integer)param[1]).intValue()); + continue; + } + + if (param[0] instanceof java.sql.Date || + param[0] instanceof Time || + param[0] instanceof Timestamp) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.detecteddate")); + if (param[1] instanceof Calendar) { + System.err.println(resBundle.handleGetObject("jdbcrowsetimpl.detectedcalendar")); + ps.setDate(i + 1, (java.sql.Date)param[0], + (Calendar)param[1]); + continue; + } + else { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.paramtype").toString()); + } + } + + if (param[0] instanceof Reader) { + ps.setCharacterStream(i + 1, (Reader)param[0], + ((Integer)param[1]).intValue()); + continue; + } + + /* + * What's left should be setObject(int, Object, scale) + */ + if (param[1] instanceof Integer) { + ps.setObject(i + 1, param[0], ((Integer)param[1]).intValue()); + continue; + } + + } else if (param.length == 3) { + + if (param[0] == null) { + ps.setNull(i + 1, ((Integer)param[1]).intValue(), + (String)param[2]); + continue; + } + + if (param[0] instanceof InputStream) { + switch (((Integer)param[2]).intValue()) { + case JdbcRowSetImpl.UNICODE_STREAM_PARAM: + ps.setUnicodeStream(i + 1, + (InputStream)param[0], + ((Integer)param[1]).intValue()); + break; + case JdbcRowSetImpl.BINARY_STREAM_PARAM: + ps.setBinaryStream(i + 1, + (InputStream)param[0], + ((Integer)param[1]).intValue()); + break; + case JdbcRowSetImpl.ASCII_STREAM_PARAM: + ps.setAsciiStream(i + 1, + (InputStream)param[0], + ((Integer)param[1]).intValue()); + break; + default: + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.paramtype").toString()); + } + } + + /* + * no point at looking at the first element now; + * what's left must be the setObject() cases. + */ + if (param[1] instanceof Integer && param[2] instanceof Integer) { + ps.setObject(i + 1, param[0], ((Integer)param[1]).intValue(), + ((Integer)param[2]).intValue()); + continue; + } + + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.paramtype").toString()); + + } else { + // common case - this catches all SQL92 types + ps.setObject(i + 1, params[i]); + continue; + } + } else { + // Try to get all the params to be set here + ps.setObject(i + 1, params[i]); + + } + } + } + + /** + * Moves the cursor for this rowset's ResultSet + * object down one row from its current position. + * A ResultSet cursor is initially positioned + * before the first row; the first call to the method + * next makes the first row the current row; the + * second call makes the second row the current row, and so on. + * + *

If an input stream is open for the current row, a call + * to the method next will + * implicitly close it. A ResultSet object's + * warning chain is cleared when a new row is read. + * + * @return true if the new current row is valid; + * false if there are no more rows + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public boolean next() throws SQLException { + checkState(); + + boolean b = rs.next(); + notifyCursorMoved(); + return b; + } + + /** + * Releases this rowset's ResultSet object's database and + * JDBC resources immediately instead of waiting for + * this to happen when it is automatically closed. + * + *

Note: A ResultSet object + * is automatically closed by the + * Statement object that generated it when + * that Statement object is closed, + * re-executed, or is used to retrieve the next result from a + * sequence of multiple results. A ResultSet object + * is also automatically closed when it is garbage collected. + * + * @throws SQLException if a database access error occurs + */ + public void close() throws SQLException { + if (rs != null) + rs.close(); + if (ps != null) + ps.close(); + if (conn != null) + conn.close(); + } + + /** + * Reports whether the last column read from this rowset's + * ResultSet object had a value of SQL NULL. + * Note that you must first call one of the getXXX methods + * on a column to try to read its value and then call + * the method wasNull to see if the value read was + * SQL NULL. + * + * @return true if the last column value read was SQL + * NULL and false otherwise + * @throws SQLException if a database access error occurs + * or this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public boolean wasNull() throws SQLException { + checkState(); + + return rs.wasNull(); + } + + //====================================================================== + // Methods for accessing results by column index + //====================================================================== + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a String. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public String getString(int columnIndex) throws SQLException { + checkState(); + + return rs.getString(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a boolean. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is false + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public boolean getBoolean(int columnIndex) throws SQLException { + checkState(); + + return rs.getBoolean(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a byte. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public byte getByte(int columnIndex) throws SQLException { + checkState(); + + return rs.getByte(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a short. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public short getShort(int columnIndex) throws SQLException { + checkState(); + + return rs.getShort(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * an int. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public int getInt(int columnIndex) throws SQLException { + checkState(); + + return rs.getInt(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a long. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public long getLong(int columnIndex) throws SQLException { + checkState(); + + return rs.getLong(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a float. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public float getFloat(int columnIndex) throws SQLException { + checkState(); + + return rs.getFloat(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a double. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public double getDouble(int columnIndex) throws SQLException { + checkState(); + + return rs.getDouble(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a java.sql.BigDecimal. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param scale the number of digits to the right of the decimal point + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + * @deprecated + */ + @Deprecated + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + checkState(); + + return rs.getBigDecimal(columnIndex, scale); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a byte array in the Java programming language. + * The bytes represent the raw values returned by the driver. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public byte[] getBytes(int columnIndex) throws SQLException { + checkState(); + + return rs.getBytes(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a java.sql.Date object in the Java programming language. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public java.sql.Date getDate(int columnIndex) throws SQLException { + checkState(); + + return rs.getDate(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a java.sql.Time object in the Java programming language. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public Time getTime(int columnIndex) throws SQLException { + checkState(); + + return rs.getTime(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a java.sql.Timestamp object in the Java programming language. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public Timestamp getTimestamp(int columnIndex) throws SQLException { + checkState(); + + return rs.getTimestamp(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a stream of ASCII characters. The value can then be read in chunks from the + * stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. + * The JDBC driver will + * do any necessary conversion from the database format into ASCII. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a getXXX method implicitly closes the stream. Also, a + * stream may return 0 when the method + * InputStream.available + * is called whether there is data available or not. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return a Java input stream that delivers the database column value + * as a stream of one-byte ASCII characters; + * if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) database access error occurs + * (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public InputStream getAsciiStream(int columnIndex) throws SQLException { + checkState(); + + return rs.getAsciiStream(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * as a stream of Unicode characters. + * The value can then be read in chunks from the + * stream. This method is particularly + * suitable for retrieving largeLONGVARCHARvalues. The JDBC driver will + * do any necessary conversion from the database format into Unicode. + * The byte format of the Unicode stream must be Java UTF-8, + * as specified in the Java virtual machine specification. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a getXXX method implicitly closes the stream. Also, a + * stream may return 0 when the method + * InputStream.available + * is called whether there is data available or not. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return a Java input stream that delivers the database column value + * as a stream in Java UTF-8 byte format; + * if the value is SQL NULL, the value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + * @deprecated use getCharacterStream in place of + * getUnicodeStream + */ + @Deprecated + public InputStream getUnicodeStream(int columnIndex) throws SQLException { + checkState(); + + return rs.getUnicodeStream(columnIndex); + } + + /** + * Gets the value of a column in the current row as a stream of + * the value of the designated column in the current row + * of this rowset's ResultSet object as a binary stream of + * uninterpreted bytes. The value can then be read in chunks from the + * stream. This method is particularly + * suitable for retrieving large LONGVARBINARY values. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a getXXX method implicitly closes the stream. Also, a + * stream may return 0 when the method + * InputStream.available + * is called whether there is data available or not. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return a Java input stream that delivers the database column value + * as a stream of uninterpreted bytes; + * if the value is SQL NULL, the value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public InputStream getBinaryStream(int columnIndex) throws SQLException { + checkState(); + + return rs.getBinaryStream(columnIndex); + } + + + //====================================================================== + // Methods for accessing results by column name + //====================================================================== + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a String. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public String getString(String columnName) throws SQLException { + return getString(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a boolean. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is false + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public boolean getBoolean(String columnName) throws SQLException { + return getBoolean(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a byte. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public byte getByte(String columnName) throws SQLException { + return getByte(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a short. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public short getShort(String columnName) throws SQLException { + return getShort(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * an int. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public int getInt(String columnName) throws SQLException { + return getInt(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a long. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if a database access error occurs + * or this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public long getLong(String columnName) throws SQLException { + return getLong(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a float. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public float getFloat(String columnName) throws SQLException { + return getFloat(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a double. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is 0 + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public double getDouble(String columnName) throws SQLException { + return getDouble(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a java.math.BigDecimal. + * + * @param columnName the SQL name of the column + * @param scale the number of digits to the right of the decimal point + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) adatabase access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + * @deprecated + */ + @Deprecated + public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { + return getBigDecimal(findColumn(columnName), scale); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a byte array in the Java programming language. + * The bytes represent the raw values returned by the driver. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public byte[] getBytes(String columnName) throws SQLException { + return getBytes(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a java.sql.Date object in the Java programming language. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public java.sql.Date getDate(String columnName) throws SQLException { + return getDate(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a java.sql.Time object in the Java programming language. + * + * @param columnName the SQL name of the column + * @return the column value; + * if the value is SQL NULL, + * the value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public Time getTime(String columnName) throws SQLException { + return getTime(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * a java.sql.Timestamp object. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public Timestamp getTimestamp(String columnName) throws SQLException { + return getTimestamp(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as a stream of + * ASCII characters. The value can then be read in chunks from the + * stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. + * The JDBC driver will + * do any necessary conversion from the database format into ASCII. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a getXXX method implicitly closes the stream. Also, a + * stream may return 0 when the method available + * is called whether there is data available or not. + * + * @param columnName the SQL name of the column + * @return a Java input stream that delivers the database column value + * as a stream of one-byte ASCII characters. + * If the value is SQL NULL, + * the value returned is null. + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public InputStream getAsciiStream(String columnName) throws SQLException { + return getAsciiStream(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as a stream of + * Unicode characters. The value can then be read in chunks from the + * stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. + * The JDBC driver will + * do any necessary conversion from the database format into Unicode. + * The byte format of the Unicode stream must be Java UTF-8, + * as defined in the Java virtual machine specification. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a getXXX method implicitly closes the stream. Also, a + * stream may return 0 when the method available + * is called whether there is data available or not. + * + * @param columnName the SQL name of the column + * @return a Java input stream that delivers the database column value + * as a stream of two-byte Unicode characters. + * If the value is SQL NULL, + * the value returned is null. + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + * @deprecated + */ + @Deprecated + public InputStream getUnicodeStream(String columnName) throws SQLException { + return getUnicodeStream(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as a stream of uninterpreted + * bytes. + * The value can then be read in chunks from the + * stream. This method is particularly + * suitable for retrieving large LONGVARBINARY + * values. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a getXXX method implicitly closes the stream. Also, a + * stream may return 0 when the method available + * is called whether there is data available or not. + * + * @param columnName the SQL name of the column + * @return a Java input stream that delivers the database column value + * as a stream of uninterpreted bytes; + * if the value is SQL NULL, the result is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public InputStream getBinaryStream(String columnName) throws SQLException { + return getBinaryStream(findColumn(columnName)); + } + + + //===================================================================== + // Advanced features: + //===================================================================== + + /** + * Returns the first warning reported by calls on this rowset's + * ResultSet object. + * Subsequent warnings on this rowset's ResultSet object + * will be chained to the SQLWarning object that + * this method returns. + * + *

The warning chain is automatically cleared each time a new + * row is read. + * + *

Note: This warning chain only covers warnings caused + * by ResultSet methods. Any warning caused by + * Statement methods + * (such as reading OUT parameters) will be chained on the + * Statement object. + * + * @return the first SQLWarning object reported or null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public SQLWarning getWarnings() throws SQLException { + checkState(); + + return rs.getWarnings(); + } + + /** + * Clears all warnings reported on this rowset's ResultSet object. + * After this method is called, the method getWarnings + * returns null until a new warning is + * reported for this rowset's ResultSet object. + * + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public void clearWarnings() throws SQLException { + checkState(); + + rs.clearWarnings(); + } + + /** + * Gets the name of the SQL cursor used by this rowset's ResultSet + * object. + * + *

In SQL, a result table is retrieved through a cursor that is + * named. The current row of a result set can be updated or deleted + * using a positioned update/delete statement that references the + * cursor name. To insure that the cursor has the proper isolation + * level to support update, the cursor's select statement should be + * of the form 'select for update'. If the 'for update' clause is + * omitted, the positioned updates may fail. + * + *

The JDBC API supports this SQL feature by providing the name of the + * SQL cursor used by a ResultSet object. + * The current row of a ResultSet object + * is also the current row of this SQL cursor. + * + *

Note: If positioned update is not supported, a + * SQLException is thrown. + * + * @return the SQL name for this rowset's ResultSet object's cursor + * @throws SQLException if (1) a database access error occurs + * or (2) xthis rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public String getCursorName() throws SQLException { + checkState(); + + return rs.getCursorName(); + } + + /** + * Retrieves the number, types and properties of + * this rowset's ResultSet object's columns. + * + * @return the description of this rowset's ResultSet + * object's columns + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public ResultSetMetaData getMetaData() throws SQLException { + + checkState(); + + // It may be the case that JdbcRowSet might not have been + // initialized with ResultSet handle and may be by PreparedStatement + // internally when we set JdbcRowSet.setCommand(). + // We may require all the basic properties of setEscapeProcessing + // setMaxFieldSize etc. which an application can use before we call + // execute. + try { + checkState(); + } catch(SQLException sqle) { + prepare(); + // will return ResultSetMetaData + return ps.getMetaData(); + } + return rs.getMetaData(); + } + + /** + *

Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * an Object. + * + *

This method will return the value of the given column as a + * Java object. The type of the Java object will be the default + * Java object type corresponding to the column's SQL type, + * following the mapping for built-in types specified in the JDBC + * specification. + * + *

This method may also be used to read datatabase-specific + * abstract data types. + * + * In the JDBC 3.0 API, the behavior of method + * getObject is extended to materialize + * data of SQL user-defined types. When a column contains + * a structured or distinct value, the behavior of this method is as + * if it were a call to: getObject(columnIndex, + * this.getStatement().getConnection().getTypeMap()). + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return a java.lang.Object holding the column value + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Object getObject(int columnIndex) throws SQLException { + checkState(); + + return rs.getObject(columnIndex); + } + + /** + *

Gets the value of the designated column in the current row + * of this rowset's ResultSet object as + * an Object. + * + *

This method will return the value of the given column as a + * Java object. The type of the Java object will be the default + * Java object type corresponding to the column's SQL type, + * following the mapping for built-in types specified in the JDBC + * specification. + * + *

This method may also be used to read datatabase-specific + * abstract data types. + * + * In the JDBC 3.0 API, the behavior of the method + * getObject is extended to materialize + * data of SQL user-defined types. When a column contains + * a structured or distinct value, the behavior of this method is as + * if it were a call to: getObject(columnIndex, + * this.getStatement().getConnection().getTypeMap()). + * + * @param columnName the SQL name of the column + * @return a java.lang.Object holding the column value + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Object getObject(String columnName) throws SQLException { + return getObject(findColumn(columnName)); + } + + //---------------------------------------------------------------- + + /** + * Maps the given JdbcRowSetImpl column name to its + * JdbcRowSetImpl column index and reflects this on + * the internal ResultSet object. + * + * @param columnName the name of the column + * @return the column index of the given column name + * @throws SQLException if (1) a database access error occurs + * (2) this rowset does not have a currently valid connection, + * prepared statement, and result set + */ + public int findColumn(String columnName) throws SQLException { + checkState(); + + return rs.findColumn(columnName); + } + + + //--------------------------JDBC 2.0----------------------------------- + + //--------------------------------------------------------------------- + // Getters and Setters + //--------------------------------------------------------------------- + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as a + * java.io.Reader object. + * @return a java.io.Reader object that contains the column + * value; if the value is SQL NULL, the value returned is + * null. + * @param columnIndex the first column is 1, the second is 2, and so on + * + */ + public Reader getCharacterStream(int columnIndex) throws SQLException { + checkState(); + + return rs.getCharacterStream(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as a + * java.io.Reader object. + * + * @return a java.io.Reader object that contains the column + * value; if the value is SQL NULL, the value returned is + * null. + * @param columnName the name of the column + * @return the value in the specified column as a java.io.Reader + * + */ + public Reader getCharacterStream(String columnName) throws SQLException { + return getCharacterStream(findColumn(columnName)); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as a + * java.math.BigDecimal with full precision. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @return the column value (full precision); + * if the value is SQL NULL, the value returned is + * null. + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + checkState(); + + return rs.getBigDecimal(columnIndex); + } + + /** + * Gets the value of the designated column in the current row + * of this rowset's ResultSet object as a + * java.math.BigDecimal with full precision. + * + * @param columnName the column name + * @return the column value (full precision); + * if the value is SQL NULL, the value returned is + * null. + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public BigDecimal getBigDecimal(String columnName) throws SQLException { + return getBigDecimal(findColumn(columnName)); + } + + //--------------------------------------------------------------------- + // Traversal/Positioning + //--------------------------------------------------------------------- + + /** + * Indicates whether the cursor is before the first row in + * this rowset's ResultSet object. + * + * @return true if the cursor is before the first row; + * false if the cursor is at any other position or the + * result set contains no rows + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public boolean isBeforeFirst() throws SQLException { + checkState(); + + return rs.isBeforeFirst(); + } + + /** + * Indicates whether the cursor is after the last row in + * this rowset's ResultSet object. + * + * @return true if the cursor is after the last row; + * false if the cursor is at any other position or the + * result set contains no rows + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public boolean isAfterLast() throws SQLException { + checkState(); + + return rs.isAfterLast(); + } + + /** + * Indicates whether the cursor is on the first row of + * this rowset's ResultSet object. + * + * @return true if the cursor is on the first row; + * false otherwise + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public boolean isFirst() throws SQLException { + checkState(); + + return rs.isFirst(); + } + + /** + * Indicates whether the cursor is on the last row of + * this rowset's ResultSet object. + * Note: Calling the method isLast may be expensive + * because the JDBC driver + * might need to fetch ahead one row in order to determine + * whether the current row is the last row in the result set. + * + * @return true if the cursor is on the last row; + * false otherwise + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid + * connection, prepared statement, and result set + * + */ + public boolean isLast() throws SQLException { + checkState(); + + return rs.isLast(); + } + + /** + * Moves the cursor to the front of + * this rowset's ResultSet object, just before the + * first row. This method has no effect if the result set contains no rows. + * + * @throws SQLException if (1) a database access error occurs, + * (2) the result set type is TYPE_FORWARD_ONLY, + * or (3) this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public void beforeFirst() throws SQLException { + checkState(); + + rs.beforeFirst(); + notifyCursorMoved(); + } + + /** + * Moves the cursor to the end of + * this rowset's ResultSet object, just after the + * last row. This method has no effect if the result set contains no rows. + * @throws SQLException if (1) a database access error occurs, + * (2) the result set type is TYPE_FORWARD_ONLY, + * or (3) this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public void afterLast() throws SQLException { + checkState(); + + rs.afterLast(); + notifyCursorMoved(); + } + + /** + * Moves the cursor to the first row in + * this rowset's ResultSet object. + * + * @return true if the cursor is on a valid row; + * false if there are no rows in the result set + * @throws SQLException if (1) a database access error occurs, + * (2) the result set type is TYPE_FORWARD_ONLY, + * or (3) this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public boolean first() throws SQLException { + checkState(); + + boolean b = rs.first(); + notifyCursorMoved(); + return b; + + } + + /** + * Moves the cursor to the last row in + * this rowset's ResultSet object. + * + * @return true if the cursor is on a valid row; + * false if there are no rows in the result set + * @throws SQLException if (1) a database access error occurs, + * (2) the result set type is TYPE_FORWARD_ONLY, + * or (3) this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public boolean last() throws SQLException { + checkState(); + + boolean b = rs.last(); + notifyCursorMoved(); + return b; + } + + /** + * Retrieves the current row number. The first row is number 1, the + * second is number 2, and so on. + * + * @return the current row number; 0 if there is no current row + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public int getRow() throws SQLException { + checkState(); + + return rs.getRow(); + } + + /** + * Moves the cursor to the given row number in + * this rowset's internal ResultSet object. + * + *

If the row number is positive, the cursor moves to + * the given row number with respect to the + * beginning of the result set. The first row is row 1, the second + * is row 2, and so on. + * + *

If the given row number is negative, the cursor moves to + * an absolute row position with respect to + * the end of the result set. For example, calling the method + * absolute(-1) positions the + * cursor on the last row, calling the method absolute(-2) + * moves the cursor to the next-to-last row, and so on. + * + *

An attempt to position the cursor beyond the first/last row in + * the result set leaves the cursor before the first row or after + * the last row. + * + *

Note: Calling absolute(1) is the same + * as calling first(). Calling absolute(-1) + * is the same as calling last(). + * + * @return true if the cursor is on the result set; + * false otherwise + * @throws SQLException if (1) a database access error occurs, + * (2) the row is 0, (3) the result set + * type is TYPE_FORWARD_ONLY, or (4) this + * rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public boolean absolute(int row) throws SQLException { + checkState(); + + boolean b = rs.absolute(row); + notifyCursorMoved(); + return b; + } + + /** + * Moves the cursor a relative number of rows, either positive or negative. + * Attempting to move beyond the first/last row in the + * result set positions the cursor before/after the + * the first/last row. Calling relative(0) is valid, but does + * not change the cursor position. + * + *

Note: Calling the method relative(1) + * is different from calling the method next() + * because is makes sense to call next() when there + * is no current row, + * for example, when the cursor is positioned before the first row + * or after the last row of the result set. + * + * @return true if the cursor is on a row; + * false otherwise + * @throws SQLException if (1) a database access error occurs, + * (2) there is no current row, (3) the result set + * type is TYPE_FORWARD_ONLY, or (4) this + * rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public boolean relative(int rows) throws SQLException { + checkState(); + + boolean b = rs.relative(rows); + notifyCursorMoved(); + return b; + } + + /** + * Moves the cursor to the previous row in this + * ResultSet object. + * + *

Note: Calling the method previous() is not the same as + * calling the method relative(-1) because it + * makes sense to call previous() when there is no current row. + * + * @return true if the cursor is on a valid row; + * false if it is off the result set + * @throws SQLException if (1) a database access error occurs, + * (2) the result set type is TYPE_FORWARD_ONLY, + * or (3) this rowset does not currently have a valid + * connection, prepared statement, and result set + */ + public boolean previous() throws SQLException { + checkState(); + + boolean b = rs.previous(); + notifyCursorMoved(); + return b; + } + + /** + * Gives a hint as to the direction in which the rows in this + * ResultSet object will be processed. + * The initial value is determined by the + * Statement object + * that produced this rowset's ResultSet object. + * The fetch direction may be changed at any time. + * + * @throws SQLException if (1) a database access error occurs, + * (2) the result set type is TYPE_FORWARD_ONLY + * and the fetch direction is not FETCH_FORWARD, + * or (3) this rowset does not currently have a valid + * connection, prepared statement, and result set + * @see Statement#setFetchDirection + */ + public void setFetchDirection(int direction) throws SQLException { + checkState(); + + rs.setFetchDirection(direction); + } + + /** + * Returns the fetch direction for this + * ResultSet object. + * + * @return the current fetch direction for this rowset's + * ResultSet object + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public int getFetchDirection() throws SQLException { + try { + checkState(); + } catch(SQLException sqle) { + super.getFetchDirection(); + } + return rs.getFetchDirection(); + } + + /** + * Gives the JDBC driver a hint as to the number of rows that should + * be fetched from the database when more rows are needed for this + * ResultSet object. + * If the fetch size specified is zero, the JDBC driver + * ignores the value and is free to make its own best guess as to what + * the fetch size should be. The default value is set by the + * Statement object + * that created the result set. The fetch size may be changed at any time. + * + * @param rows the number of rows to fetch + * @throws SQLException if (1) a database access error occurs, (2) the + * condition 0 <= rows <= this.getMaxRows() is not + * satisfied, or (3) this rowset does not currently have a valid + * connection, prepared statement, and result set + * + */ + public void setFetchSize(int rows) throws SQLException { + checkState(); + + rs.setFetchSize(rows); + } + + /** + * + * Returns the fetch size for this + * ResultSet object. + * + * @return the current fetch size for this rowset's ResultSet object + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public int getType() throws SQLException { + try { + checkState(); + } catch(SQLException sqle) { + return super.getType(); + } + + // If the ResultSet has not been created, then return the default type + // otherwise return the type from the ResultSet. + if(rs == null) { + return super.getType(); + } else { + int rstype = rs.getType(); + return rstype; + } + + + } + + /** + * Returns the concurrency mode of this rowset's ResultSet object. + * The concurrency used is determined by the + * Statement object that created the result set. + * + * @return the concurrency type, either CONCUR_READ_ONLY + * or CONCUR_UPDATABLE + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public int getConcurrency() throws SQLException { + try { + checkState(); + } catch(SQLException sqle) { + super.getConcurrency(); + } + return rs.getConcurrency(); + } + + //--------------------------------------------------------------------- + // Updates + //--------------------------------------------------------------------- + + /** + * Indicates whether the current row has been updated. The value returned + * depends on whether or not the result set can detect updates. + * + * @return true if the row has been visibly updated + * by the owner or another, and updates are detected + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * @see DatabaseMetaData#updatesAreDetected + */ + public boolean rowUpdated() throws SQLException { + checkState(); + + return rs.rowUpdated(); + } + + /** + * Indicates whether the current row has had an insertion. + * The value returned depends on whether or not this + * ResultSet object can detect visible inserts. + * + * @return true if a row has had an insertion + * and insertions are detected; false otherwise + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * @see DatabaseMetaData#insertsAreDetected + * + */ + public boolean rowInserted() throws SQLException { + checkState(); + + return rs.rowInserted(); + } + + /** + * Indicates whether a row has been deleted. A deleted row may leave + * a visible "hole" in a result set. This method can be used to + * detect holes in a result set. The value returned depends on whether + * or not this rowset's ResultSet object can detect deletions. + * + * @return true if a row was deleted and deletions are detected; + * false otherwise + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * @see DatabaseMetaData#deletesAreDetected + */ + public boolean rowDeleted() throws SQLException { + checkState(); + + return rs.rowDeleted(); + } + + /** + * Gives a nullable column a null value. + * + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow + * or insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public void updateNull(int columnIndex) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateNull(columnIndex); + } + + /** + * Updates the designated column with a boolean value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateBoolean(columnIndex, x); + } + + /** + * Updates the designated column with a byte value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateByte(int columnIndex, byte x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateByte(columnIndex, x); + } + + /** + * Updates the designated column with a short value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateShort(int columnIndex, short x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateShort(columnIndex, x); + } + + /** + * Updates the designated column with an int value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public void updateInt(int columnIndex, int x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateInt(columnIndex, x); + } + + /** + * Updates the designated column with a long value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateLong(int columnIndex, long x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateLong(columnIndex, x); + } + + /** + * Updates the designated column with a float value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateFloat(int columnIndex, float x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateFloat(columnIndex, x); + } + + /** + * Updates the designated column with a double value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateDouble(int columnIndex, double x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateDouble(columnIndex, x); + } + + /** + * Updates the designated column with a java.math.BigDecimal + * value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateBigDecimal(columnIndex, x); + } + + /** + * Updates the designated column with a String value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateString(int columnIndex, String x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateString(columnIndex, x); + } + + /** + * Updates the designated column with a byte array value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateBytes(int columnIndex, byte x[]) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateBytes(columnIndex, x); + } + + /** + * Updates the designated column with a java.sql.Date value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateDate(int columnIndex, java.sql.Date x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateDate(columnIndex, x); + } + + + /** + * Updates the designated column with a java.sql.Time value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateTime(int columnIndex, Time x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateTime(columnIndex, x); + } + + /** + * Updates the designated column with a java.sql.Timestamp + * value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateTimestamp(columnIndex, x); + } + + /** + * Updates the designated column with an ascii stream value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @param length the length of the stream + * @throws SQLException if (1) a database access error occurs + * (2) or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateAsciiStream(columnIndex, x, length); + } + + /** + * Updates the designated column with a binary stream value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @param length the length of the stream + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateBinaryStream(columnIndex, x, length); + } + + /** + * Updates the designated column with a character stream value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @param length the length of the stream + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateCharacterStream(columnIndex, x, length); + } + + /** + * Updates the designated column with an Object value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @param scale for java.sql.Types.DECIMAl + * or java.sql.Types.NUMERIC types, + * this is the number of digits after the decimal point. For all other + * types this value will be ignored. + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateObject(int columnIndex, Object x, int scale) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateObject(columnIndex, x, scale); + } + + /** + * Updates the designated column with an Object value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param x the new column value + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateObject(int columnIndex, Object x) throws SQLException { + checkState(); + + // To check the type and concurrency of the ResultSet + // to verify whether updates are possible or not + checkTypeConcurrency(); + + rs.updateObject(columnIndex, x); + } + + /** + * Updates the designated column with a null value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public void updateNull(String columnName) throws SQLException { + updateNull(findColumn(columnName)); + } + + /** + * Updates the designated column with a boolean value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateBoolean(String columnName, boolean x) throws SQLException { + updateBoolean(findColumn(columnName), x); + } + + /** + * Updates the designated column with a byte value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateByte(String columnName, byte x) throws SQLException { + updateByte(findColumn(columnName), x); + } + + /** + * Updates the designated column with a short value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateShort(String columnName, short x) throws SQLException { + updateShort(findColumn(columnName), x); + } + + /** + * Updates the designated column with an int value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateInt(String columnName, int x) throws SQLException { + updateInt(findColumn(columnName), x); + } + + /** + * Updates the designated column with a long value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateLong(String columnName, long x) throws SQLException { + updateLong(findColumn(columnName), x); + } + + /** + * Updates the designated column with a float value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateFloat(String columnName, float x) throws SQLException { + updateFloat(findColumn(columnName), x); + } + + /** + * Updates the designated column with a double value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateDouble(String columnName, double x) throws SQLException { + updateDouble(findColumn(columnName), x); + } + + /** + * Updates the designated column with a java.sql.BigDecimal + * value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { + updateBigDecimal(findColumn(columnName), x); + } + + /** + * Updates the designated column with a String value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateString(String columnName, String x) throws SQLException { + updateString(findColumn(columnName), x); + } + + /** + * Updates the designated column with a boolean value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * JDBC 2.0 + * + * Updates a column with a byte array value. + * + * The updateXXX methods are used to update column values in the + * current row, or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or insertRow + * methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateBytes(String columnName, byte x[]) throws SQLException { + updateBytes(findColumn(columnName), x); + } + + /** + * Updates the designated column with a java.sql.Date value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateDate(String columnName, java.sql.Date x) throws SQLException { + updateDate(findColumn(columnName), x); + } + + /** + * Updates the designated column with a java.sql.Time value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateTime(String columnName, Time x) throws SQLException { + updateTime(findColumn(columnName), x); + } + + /** + * Updates the designated column with a java.sql.Timestamp + * value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateTimestamp(String columnName, Timestamp x) throws SQLException { + updateTimestamp(findColumn(columnName), x); + } + + /** + * Updates the designated column with an ascii stream value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @param length the length of the stream + * @throws SQLException if a database access error occurs + * + */ + public void updateAsciiStream(String columnName, InputStream x, int length) throws SQLException { + updateAsciiStream(findColumn(columnName), x, length); + } + + /** + * Updates the designated column with a binary stream value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @param length the length of the stream + * @throws SQLException if a database access error occurs + * + */ + public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException { + updateBinaryStream(findColumn(columnName), x, length); + } + + /** + * Updates the designated column with a character stream value. + * The updateXXX methods are used to update column values + * in the current row or the insert row. The updateXXX + * methods do not update the underlying database; instead the + * updateRow or insertRow methods are called + * to update the database. + * + * @param columnName the name of the column + * @param reader the new column Reader stream value + * @param length the length of the stream + * @throws SQLException if a database access error occurs + * + */ + public void updateCharacterStream(String columnName, Reader reader, int length) throws SQLException { + updateCharacterStream(findColumn(columnName), reader, length); + } + + /** + * Updates the designated column with an Object value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @param scale for java.sql.Types.DECIMAL + * or java.sql.Types.NUMERIC types, + * this is the number of digits after the decimal point. For all other + * types this value will be ignored. + * @throws SQLException if a database access error occurs + * + */ + public void updateObject(String columnName, Object x, int scale) throws SQLException { + updateObject(findColumn(columnName), x, scale); + } + + /** + * Updates the designated column with an Object value. + * The updateXXX methods are used to update column values in the + * current row or the insert row. The updateXXX methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnName the name of the column + * @param x the new column value + * @throws SQLException if a database access error occurs + * + */ + public void updateObject(String columnName, Object x) throws SQLException { + updateObject(findColumn(columnName), x); + } + + /** + * Inserts the contents of the insert row into this + * ResultSet object and into the database + * and also notifies listeners that a row has changed. + * The cursor must be on the insert row when this method is called. + * + * @throws SQLException if (1) a database access error occurs, + * (2) this method is called when the cursor is not + * on the insert row, (3) not all non-nullable columns in + * the insert row have been given a value, or (4) this + * rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public void insertRow() throws SQLException { + checkState(); + + rs.insertRow(); + notifyRowChanged(); + } + + /** + * Updates the underlying database with the new contents of the + * current row of this rowset's ResultSet object + * and notifies listeners that a row has changed. + * This method cannot be called when the cursor is on the insert row. + * + * @throws SQLException if (1) a database access error occurs, + * (2) this method is called when the cursor is + * on the insert row, (3) the concurrency of the result + * set is ResultSet.CONCUR_READ_ONLY, or + * (4) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public void updateRow() throws SQLException { + checkState(); + + rs.updateRow(); + notifyRowChanged(); + } + + /** + * Deletes the current row from this rowset's ResultSet object + * and from the underlying database and also notifies listeners that a row + * has changed. This method cannot be called when the cursor is on the insert + * row. + * + * @throws SQLException if a database access error occurs + * or if this method is called when the cursor is on the insert row + * @throws SQLException if (1) a database access error occurs, + * (2) this method is called when the cursor is before the + * first row, after the last row, or on the insert row, + * (3) the concurrency of this rowset's result + * set is ResultSet.CONCUR_READ_ONLY, or + * (4) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public void deleteRow() throws SQLException { + checkState(); + + rs.deleteRow(); + notifyRowChanged(); + } + + /** + * Refreshes the current row of this rowset's ResultSet + * object with its most recent value in the database. This method + * cannot be called when the cursor is on the insert row. + * + *

The refreshRow method provides a way for an + * application to explicitly tell the JDBC driver to refetch + * a row(s) from the database. An application may want to call + * refreshRow when caching or prefetching is being + * done by the JDBC driver to fetch the latest value of a row + * from the database. The JDBC driver may actually refresh multiple + * rows at once if the fetch size is greater than one. + * + *

All values are refetched subject to the transaction isolation + * level and cursor sensitivity. If refreshRow is called after + * calling an updateXXX method, but before calling + * the method updateRow, then the + * updates made to the row are lost. Calling the method + * refreshRow frequently will likely slow performance. + * + * @throws SQLException if (1) a database access error occurs, + * (2) this method is called when the cursor is + * on the insert row, or (3) this rowset does not + * currently have a valid connection, prepared statement, + * and result set + * + */ + public void refreshRow() throws SQLException { + checkState(); + + rs.refreshRow(); + } + + /** + * Cancels the updates made to the current row in this + * ResultSet object and notifies listeners that a row + * has changed. This method may be called after calling an + * updateXXX method(s) and before calling + * the method updateRow to roll back + * the updates made to a row. If no updates have been made or + * updateRow has already been called, this method has no + * effect. + * + * @throws SQLException if (1) a database access error occurs, + * (2) this method is called when the cursor is + * on the insert row, or (3) this rowset does not + * currently have a valid connection, prepared statement, + * and result set + */ + public void cancelRowUpdates() throws SQLException { + checkState(); + + rs.cancelRowUpdates(); + + notifyRowChanged(); + } + + /** + * Moves the cursor to the insert row. The current cursor position is + * remembered while the cursor is positioned on the insert row. + * + * The insert row is a special row associated with an updatable + * result set. It is essentially a buffer where a new row may + * be constructed by calling the updateXXX methods prior to + * inserting the row into the result set. + * + * Only the updateXXX, getXXX, + * and insertRow methods may be + * called when the cursor is on the insert row. All of the columns in + * a result set must be given a value each time this method is + * called before calling insertRow. + * An updateXXX method must be called before a + * getXXX method can be called on a column value. + * + * @throws SQLException if (1) a database access error occurs, + * (2) this rowset's ResultSet object is + * not updatable, or (3) this rowset does not + * currently have a valid connection, prepared statement, + * and result set + * + */ + public void moveToInsertRow() throws SQLException { + checkState(); + + rs.moveToInsertRow(); + } + + /** + * Moves the cursor to the remembered cursor position, usually the + * current row. This method has no effect if the cursor is not on + * the insert row. + * + * @throws SQLException if (1) a database access error occurs, + * (2) this rowset's ResultSet object is + * not updatable, or (3) this rowset does not + * currently have a valid connection, prepared statement, + * and result set + */ + public void moveToCurrentRow() throws SQLException { + checkState(); + + rs.moveToCurrentRow(); + } + + /** + * Returns the Statement object that produced this + * ResultSet object. + * If the result set was generated some other way, such as by a + * DatabaseMetaData method, this method returns + * null. + * + * @return the Statement object that produced + * this rowset's ResultSet object or null + * if the result set was produced some other way + * @throws SQLException if a database access error occurs + */ + public Statement getStatement() throws SQLException { + + if(rs != null) + { + return rs.getStatement(); + } else { + return null; + } + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as an Object. + * This method uses the given Map object + * for the custom mapping of the + * SQL structured or distinct type that is being retrieved. + * + * @param i the first column is 1, the second is 2, and so on + * @param map a java.util.Map object that contains the mapping + * from SQL type names to classes in the Java programming language + * @return an Object in the Java programming language + * representing the SQL value + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Object getObject(int i, Map> map) + throws SQLException + { + checkState(); + + return rs.getObject(i, map); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a Ref object. + * + * @param i the first column is 1, the second is 2, and so on + * @return a Ref object representing an SQL REF value + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Ref getRef(int i) throws SQLException { + checkState(); + + return rs.getRef(i); + } + + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a Blob object. + * + * @param i the first column is 1, the second is 2, and so on + * @return a Blob object representing the SQL BLOB + * value in the specified column + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Blob getBlob(int i) throws SQLException { + checkState(); + + return rs.getBlob(i); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a Clob object. + * + * @param i the first column is 1, the second is 2, and so on + * @return a Clob object representing the SQL CLOB + * value in the specified column + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Clob getClob(int i) throws SQLException { + checkState(); + + return rs.getClob(i); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as an Array object. + * + * @param i the first column is 1, the second is 2, and so on. + * @return an Array object representing the SQL ARRAY + * value in the specified column + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Array getArray(int i) throws SQLException { + checkState(); + + return rs.getArray(i); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as an Object. + * This method uses the specified Map object for + * custom mapping if appropriate. + * + * @param colName the name of the column from which to retrieve the value + * @param map a java.util.Map object that contains the mapping + * from SQL type names to classes in the Java programming language + * @return an Object representing the SQL + * value in the specified column + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Object getObject(String colName, Map> map) + throws SQLException + { + return getObject(findColumn(colName), map); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a Ref object. + * + * @param colName the column name + * @return a Ref object representing the SQL REF value in + * the specified column + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Ref getRef(String colName) throws SQLException { + return getRef(findColumn(colName)); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a Blob object. + * + * @param colName the name of the column from which to retrieve the value + * @return a Blob object representing the SQL BLOB + * value in the specified column + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Blob getBlob(String colName) throws SQLException { + return getBlob(findColumn(colName)); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a Clob object. + * + * @param colName the name of the column from which to retrieve the value + * @return a Clob object representing the SQL CLOB + * value in the specified column + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Clob getClob(String colName) throws SQLException { + return getClob(findColumn(colName)); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as an Array object. + * + * @param colName the name of the column from which to retrieve the value + * @return an Array object representing the SQL ARRAY + * value in the specified column + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Array getArray(String colName) throws SQLException { + return getArray(findColumn(colName)); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a java.sql.Date + * object. This method uses the given calendar to construct an appropriate + * millisecond value for the date if the underlying database does not store + * timezone information. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param cal the java.util.Calendar object + * to use in constructing the date + * @return the column value as a java.sql.Date object; + * if the value is SQL NULL, + * the value returned is null + * @throws SQLException if (1) a database access error occurs + * or (2) this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException { + checkState(); + + return rs.getDate(columnIndex, cal); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a java.sql.Date + * object. This method uses the given calendar to construct an appropriate + * millisecond value for the date if the underlying database does not store + * timezone information. + * + * @param columnName the SQL name of the column from which to retrieve the value + * @param cal the java.util.Calendar object + * to use in constructing the date + * @return the column value as a java.sql.Date object; + * if the value is SQL NULL, + * the value returned is null + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + * + */ + public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException { + return getDate(findColumn(columnName), cal); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a java.sql.Time + * object. This method uses the given calendar to construct an appropriate + * millisecond value for the date if the underlying database does not store + * timezone information. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param cal the java.util.Calendar object + * to use in constructing the time + * @return the column value as a java.sql.Time object; + * if the value is SQL NULL, + * the value returned is null in the Java programming language + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + checkState(); + + return rs.getTime(columnIndex, cal); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a java.sql.Time + * object. This method uses the given calendar to construct an appropriate + * millisecond value for the date if the underlying database does not store + * timezone information. + * + * @param columnName the SQL name of the column + * @param cal the java.util.Calendar object + * to use in constructing the time + * @return the column value as a java.sql.Time object; + * if the value is SQL NULL, + * the value returned is null in the Java programming language + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Time getTime(String columnName, Calendar cal) throws SQLException { + return getTime(findColumn(columnName), cal); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a + * java.sql.Timestamp object. + * This method uses the given calendar to construct an appropriate millisecond + * value for the timestamp if the underlying database does not store + * timezone information. + * + * @param columnIndex the first column is 1, the second is 2, and so on + * @param cal the java.util.Calendar object + * to use in constructing the timestamp + * @return the column value as a java.sql.Timestamp object; + * if the value is SQL NULL, + * the value returned is null + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + checkState(); + + return rs.getTimestamp(columnIndex, cal); + } + + /** + * Returns the value of the designated column in the current row + * of this rowset's ResultSet object as a + * java.sql.Timestamp object. + * This method uses the given calendar to construct an appropriate millisecond + * value for the timestamp if the underlying database does not store + * timezone information. + * + * @param columnName the SQL name of the column + * @param cal the java.util.Calendar object + * to use in constructing the timestamp + * @return the column value as a java.sql.Timestamp object; + * if the value is SQL NULL, + * the value returned is null + * @throws SQLException if a database access error occurs + * or this rowset does not currently have a valid connection, + * prepared statement, and result set + */ + public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException { + return getTimestamp(findColumn(columnName), cal); + } + + + /** + * Sets the designated column in either the current row or the insert + * row of this JdbcRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param ref the new Ref column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateRef(int columnIndex, Ref ref) + throws SQLException { + checkState(); + rs.updateRef(columnIndex, ref); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this JdbcRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param ref the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateRef(String columnName, Ref ref) + throws SQLException { + updateRef(findColumn(columnName), ref); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this JdbcRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param c the new column Clob value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateClob(int columnIndex, Clob c) throws SQLException { + checkState(); + rs.updateClob(columnIndex, c); + } + + + /** + * Sets the designated column in either the current row or the insert + * row of this JdbcRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param c the new column Clob value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateClob(String columnName, Clob c) throws SQLException { + updateClob(findColumn(columnName), c); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this JdbcRowSetImpl object with the given + * java.sql.Blob value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param b the new column Blob value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBlob(int columnIndex, Blob b) throws SQLException { + checkState(); + rs.updateBlob(columnIndex, b); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this JdbcRowSetImpl object with the given + * java.sql.Blob value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param b the new column Blob value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBlob(String columnName, Blob b) throws SQLException { + updateBlob(findColumn(columnName), b); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this JdbcRowSetImpl object with the given + * java.sql.Array values. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param a the new column Array value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateArray(int columnIndex, Array a) throws SQLException { + checkState(); + rs.updateArray(columnIndex, a); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this JdbcRowSetImpl object with the given + * java.sql.Array value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param a the new column Array value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateArray(String columnName, Array a) throws SQLException { + updateArray(findColumn(columnName), a); + } + + /** + * Provide interface coverage for getURL(int) in ResultSet->RowSet + */ + public java.net.URL getURL(int columnIndex) throws SQLException { + checkState(); + return rs.getURL(columnIndex); + } + + /** + * Provide interface coverage for getURL(String) in ResultSet->RowSet + */ + public java.net.URL getURL(String columnName) throws SQLException { + return getURL(findColumn(columnName)); + } + + /** + * Return the RowSetWarning object for the current row of a + * JdbcRowSetImpl + */ + public RowSetWarning getRowSetWarnings() throws SQLException { + return null; + } + /** + * Unsets the designated parameter to the given int array. + * This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnIdxes the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnIdx is + * not the same as set using setMatchColumn(int []) + */ + public void unsetMatchColumn(int[] columnIdxes) throws SQLException { + + int i_val; + for( int j= 0 ;j < columnIdxes.length; j++) { + i_val = (Integer.parseInt(iMatchColumns.get(j).toString())); + if(columnIdxes[j] != i_val) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols").toString()); + } + } + + for( int i = 0;i < columnIdxes.length ;i++) { + iMatchColumns.set(i,Integer.valueOf(-1)); + } + } + + /** + * Unsets the designated parameter to the given String array. + * This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnIdxes the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnName is + * not the same as set using setMatchColumn(String []) + */ + public void unsetMatchColumn(String[] columnIdxes) throws SQLException { + + for(int j = 0 ;j < columnIdxes.length; j++) { + if( !columnIdxes[j].equals(strMatchColumns.get(j)) ){ + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols").toString()); + } + } + + for(int i = 0 ; i < columnIdxes.length; i++) { + strMatchColumns.set(i,null); + } + } + + /** + * Retrieves the column name as String array + * that was set using setMatchColumn(String []) + * for this rowset. + * + * @return a String array object that contains the column names + * for the rowset which has this the match columns + * + * @throws SQLException if an error occurs or column name is not set + */ + public String[] getMatchColumnNames() throws SQLException { + + String []str_temp = new String[strMatchColumns.size()]; + + if( strMatchColumns.get(0) == null) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.setmatchcols").toString()); + } + + strMatchColumns.copyInto(str_temp); + return str_temp; + } + + /** + * Retrieves the column id as int array that was set using + * setMatchColumn(int []) for this rowset. + * + * @return a int array object that contains the column ids + * for the rowset which has this as the match columns. + * + * @throws SQLException if an error occurs or column index is not set + */ + public int[] getMatchColumnIndexes() throws SQLException { + + Integer []int_temp = new Integer[iMatchColumns.size()]; + int [] i_temp = new int[iMatchColumns.size()]; + int i_val; + + i_val = iMatchColumns.get(0); + + if( i_val == -1 ) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.setmatchcols").toString()); + } + + + iMatchColumns.copyInto(int_temp); + + for(int i = 0; i < int_temp.length; i++) { + i_temp[i] = (int_temp[i]).intValue(); + } + + return i_temp; + } + + /** + * Sets the designated parameter to the given int array. + * This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumnIndexes is called. + * + * @param columnIdxes the indexes into this rowset + * object's internal representation of parameter values; the + * first parameter is 0, the second is 1, and so on; must be + * 0 or greater + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(int[] columnIdxes) throws SQLException { + + for(int j = 0 ; j < columnIdxes.length; j++) { + if( columnIdxes[j] < 0 ) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols1").toString()); + } + } + for(int i = 0 ;i < columnIdxes.length; i++) { + iMatchColumns.add(i,Integer.valueOf(columnIdxes[i])); + } + } + + /** + * Sets the designated parameter to the given String array. + * This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumn is called. + * + * @param columnNames the name of the column into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(String[] columnNames) throws SQLException { + + for(int j = 0; j < columnNames.length; j++) { + if( columnNames[j] == null || columnNames[j].equals("")) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString()); + } + } + for( int i = 0; i < columnNames.length; i++) { + strMatchColumns.add(i,columnNames[i]); + } + } + + + /** + * Sets the designated parameter to the given int + * object. This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumn is called. + * + * @param columnIdx the index into this rowset + * object's internal representation of parameter values; the + * first parameter is 0, the second is 1, and so on; must be + * 0 or greater + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(int columnIdx) throws SQLException { + // validate, if col is ok to be set + if(columnIdx < 0) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols1").toString()); + } else { + // set iMatchColumn + iMatchColumns.set(0, Integer.valueOf(columnIdx)); + //strMatchColumn = null; + } + } + + /** + * Sets the designated parameter to the given String + * object. This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumn is called. + * + * @param columnName the name of the column into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(String columnName) throws SQLException { + // validate, if col is ok to be set + if(columnName == null || (columnName= columnName.trim()).equals("")) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.matchcols2").toString()); + } else { + // set strMatchColumn + strMatchColumns.set(0, columnName); + //iMatchColumn = -1; + } + } + + /** + * Unsets the designated parameter to the given int + * object. This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnIdx the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnIdx is + * not the same as set using setMatchColumn(int) + */ + public void unsetMatchColumn(int columnIdx) throws SQLException { + // check if we are unsetting the SAME column + if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.unsetmatch").toString()); + } else if(strMatchColumns.get(0) != null) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.usecolname").toString()); + } else { + // that is, we are unsetting it. + iMatchColumns.set(0, Integer.valueOf(-1)); + } + } + + /** + * Unsets the designated parameter to the given String + * object. This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnName the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnName is + * not the same as set using setMatchColumn(String) + * + */ + public void unsetMatchColumn(String columnName) throws SQLException { + // check if we are unsetting the same column + columnName = columnName.trim(); + + if(!((strMatchColumns.get(0)).equals(columnName))) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.unsetmatch").toString()); + } else if(iMatchColumns.get(0) > 0) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.usecolid").toString()); + } else { + strMatchColumns.set(0, null); // that is, we are unsetting it. + } + } + + /** + * Retrieves the DatabaseMetaData associated with + * the connection handle associated this this + * JdbcRowSet object. + * + * @return the DatabaseMetadata associated + * with the rowset's connection. + * @throws SQLException if a database access error occurs + */ + public DatabaseMetaData getDatabaseMetaData() throws SQLException { + Connection con = connect(); + return con.getMetaData(); + } + + /** + * Retrieves the ParameterMetaData associated with + * the connection handle associated this this + * JdbcRowSet object. + * + * @return the ParameterMetadata associated + * with the rowset's connection. + * @throws SQLException if a database access error occurs + */ + public ParameterMetaData getParameterMetaData() throws SQLException { + prepare(); + return (ps.getParameterMetaData()); + } + + /** + * Commits all updates in this JdbcRowSet object by + * wrapping the internal Connection object and calling + * its commit method. + * This method sets this JdbcRowSet object's private field + * rs to null after saving its value to another + * object, but only if the ResultSet + * constant HOLD_CURSORS_OVER_COMMIT has not been set. + * (The field rs is this JdbcRowSet object's + * ResultSet object.) + * + * @throws SQLException if autoCommit is set to true or if a database + * access error occurs + */ + public void commit() throws SQLException { + conn.commit(); + + // Checking the holadbility value and making the result set handle null + // Added as per Rave requirements + + if( conn.getHoldability() != HOLD_CURSORS_OVER_COMMIT) { + rs = null; + } + } + + /** + * Sets auto-commit on the internal Connection object with this + * JdbcRowSet + * + * @throws SQLException if a database access error occurs + */ + public void setAutoCommit(boolean autoCommit) throws SQLException { + // The connection object should be there + // in order to commit the connection handle on or off. + + if(conn != null) { + conn.setAutoCommit(autoCommit); + } else { + // Coming here means the connection object is null. + // So generate a connection handle internally, since + // a JdbcRowSet is always connected to a db, it is fine + // to get a handle to the connection. + + // Get hold of a connection handle + // and change the autcommit as passesd. + conn = connect(); + + // After setting the below the conn.getAutoCommit() + // should return the same value. + conn.setAutoCommit(autoCommit); + + } + } + + /** + * Returns the auto-commit status with this JdbcRowSet. + * + * @return true if auto commit is true; false otherwise + * @throws SQLException if a database access error occurs + */ + public boolean getAutoCommit() throws SQLException { + return conn.getAutoCommit(); + } + + /** + * Rolls back all the updates in this JdbcRowSet object by + * wrapping the internal Connection object and calling its + * rollback method. + * This method sets this JdbcRowSet object's private field + * rs to null after saving its value to another object. + * (The field rs is this JdbcRowSet object's + * internal ResultSet object.) + * + * @throws SQLException if autoCommit is set to true or a database + * access error occurs + */ + public void rollback() throws SQLException { + conn.rollback(); + + // Makes the result ste handle null after rollback + // Added as per Rave requirements + + rs = null; + } + + + /** + * Rollbacks all the updates in the JdbcRowSet back to the + * last Savepoint transaction marker. Wraps the internal + * Connection object and call it's rollback method + * + * @param s the Savepoint transaction marker to roll the + * transaction to. + * @throws SQLException if autoCommit is set to true; or ia a database + * access error occurs + */ + public void rollback(Savepoint s) throws SQLException { + conn.rollback(s); + } + + // Setting the ResultSet Type and Concurrency + protected void setParams() throws SQLException { + if(rs == null) { + setType(ResultSet.TYPE_SCROLL_INSENSITIVE); + setConcurrency(ResultSet.CONCUR_UPDATABLE); + } + else { + setType(rs.getType()); + setConcurrency(rs.getConcurrency()); + } + } + + + // Checking ResultSet Type and Concurrency + private void checkTypeConcurrency() throws SQLException { + if(rs.getType() == TYPE_FORWARD_ONLY || + rs.getConcurrency() == CONCUR_READ_ONLY) { + throw new SQLException(resBundle.handleGetObject("jdbcrowsetimpl.resnotupd").toString()); + } + } + + // Returns a Connection Handle + // Added as per Rave requirements + + /** + * Gets this JdbcRowSet object's Connection property + * + * + * @return the Connection object associated with this rowset; + */ + + protected Connection getConnection() { + return conn; + } + + // Sets the connection handle with the parameter + // Added as per rave requirements + + /** + * Sets this JdbcRowSet object's connection property + * to the given Connection object. + * + * @param connection the Connection object. + */ + + protected void setConnection(Connection connection) { + conn = connection; + } + + // Returns a PreparedStatement Handle + // Added as per Rave requirements + + /** + * Gets this JdbcRowSet object's PreparedStatement property + * + * + * @return the PreparedStatement object associated with this rowset; + */ + + protected PreparedStatement getPreparedStatement() { + return ps; + } + + //Sets the prepared statement handle to the parameter + // Added as per Rave requirements + + /** + * Sets this JdbcRowSet object's preparedtsatement property + * to the given PreparedStatemennt object. + * + * @param preparedStatement the PreparedStatement object + * + */ + protected void setPreparedStatement(PreparedStatement preparedStatement) { + ps = preparedStatement; + } + + // Returns a ResultSet handle + // Added as per Rave requirements + + /** + * Gets this JdbcRowSet object's ResultSet property + * + * + * @return the ResultSet object associated with this rowset; + */ + + protected ResultSet getResultSet() throws SQLException { + + checkState(); + + return rs; + } + + // Sets the result set handle to the parameter + // Added as per Rave requirements + + /** + * Sets this JdbcRowSet object's resultset property + * to the given ResultSet object. + * + * @param resultSet the ResultSet object + * + */ + protected void setResultSet(ResultSet resultSet) { + rs = resultSet; + } + + /** + * Sets this JdbcRowSet object's command property to + * the given String object and clears the parameters, if any, + * that were set for the previous command. In addition, + * if the command property has previously been set to a + * non-null value and it is + * different from the String object supplied, + * this method sets this JdbcRowSet object's private fields + * ps and rs to null. + * (The field ps is its PreparedStatement object, and + * the field rs is its ResultSet object.) + *

+ * The command property may not be needed if the RowSet + * object gets its data from a source that does not support commands, + * such as a spreadsheet or other tabular file. + * Thus, this property is optional and may be null. + * + * @param command a String object containing an SQL query + * that will be set as this RowSet object's command + * property; may be null but may not be an empty string + * @throws SQLException if an empty string is provided as the command value + * @see #getCommand + */ + public void setCommand(String command) throws SQLException { + + if (getCommand() != null) { + if(!getCommand().equals(command)) { + super.setCommand(command); + ps = null; + rs = null; + } + } + else { + super.setCommand(command); + } + } + + /** + * Sets the dataSourceName property for this JdbcRowSet + * object to the given logical name and sets this JdbcRowSet object's + * Url property to null. In addition, if the dataSourceName + * property has previously been set and is different from the one supplied, + * this method sets this JdbcRowSet object's private fields + * ps, rs, and conn to null. + * (The field ps is its PreparedStatement object, + * the field rs is its ResultSet object, and + * the field conn is its Connection object.) + *

+ * The name supplied to this method must have been bound to a + * DataSource object in a JNDI naming service so that an + * application can do a lookup using that name to retrieve the + * DataSource object bound to it. The DataSource + * object can then be used to establish a connection to the data source it + * represents. + *

+ * Users should set either the Url property or the dataSourceName property. + * If both properties are set, the driver will use the property set most recently. + * + * @param dsName a String object with the name that can be supplied + * to a naming service based on JNDI technology to retrieve the + * DataSource object that can be used to get a connection; + * may be null + * @throws SQLException if there is a problem setting the + * dataSourceName property + * @see #getDataSourceName + */ + public void setDataSourceName(String dsName) throws SQLException{ + + if(getDataSourceName() != null) { + if(!getDataSourceName().equals(dsName)) { + super.setDataSourceName(dsName); + conn = null; + ps = null; + rs = null; + } + } + else { + super.setDataSourceName(dsName); + } + } + + + /** + * Sets the Url property for this JdbcRowSet object + * to the given String object and sets the dataSource name + * property to null. In addition, if the Url property has + * previously been set to a non null value and its value + * is different from the value to be set, + * this method sets this JdbcRowSet object's private fields + * ps, rs, and conn to null. + * (The field ps is its PreparedStatement object, + * the field rs is its ResultSet object, and + * the field conn is its Connection object.) + *

+ * The Url property is a JDBC URL that is used when + * the connection is created using a JDBC technology-enabled driver + * ("JDBC driver") and the DriverManager. + * The correct JDBC URL for the specific driver to be used can be found + * in the driver documentation. Although there are guidelines for for how + * a JDBC URL is formed, + * a driver vendor can specify any String object except + * one with a length of 0 (an empty string). + *

+ * Setting the Url property is optional if connections are established using + * a DataSource object instead of the DriverManager. + * The driver will use either the URL property or the + * dataSourceName property to create a connection, whichever was + * specified most recently. If an application uses a JDBC URL, it + * must load a JDBC driver that accepts the JDBC URL before it uses the + * RowSet object to connect to a database. The RowSet + * object will use the URL internally to create a database connection in order + * to read or write data. + * + * @param url a String object that contains the JDBC URL + * that will be used to establish the connection to a database for this + * RowSet object; may be null but must not + * be an empty string + * @throws SQLException if an error occurs setting the Url property or the + * parameter supplied is a string with a length of 0 (an + * empty string) + * @see #getUrl + */ + + public void setUrl(String url) throws SQLException { + + if(getUrl() != null) { + if(!getUrl().equals(url)) { + super.setUrl(url); + conn = null; + ps = null; + rs = null; + } + } + else { + super.setUrl(url); + } + } + + /** + * Sets the username property for this JdbcRowSet object + * to the given user name. Because it + * is not serialized, the username property is set at run time before + * calling the method execute. In addition, + * if the username property is already set with a + * non-null value and that value is different from the String + * object to be set, + * this method sets this JdbcRowSet object's private fields + * ps, rs, and conn to null. + * (The field ps is its PreparedStatement object, + * rs is its ResultSet object, and + * conn is its Connection object.) + * Setting these fields to null ensures that only current + * values will be used. + * + * @param uname the String object containing the user name that + * is supplied to the data source to create a connection. It may be null. + * @see #getUsername + */ + public void setUsername(String uname) { + + if( getUsername() != null) { + if(!getUsername().equals(uname)) { + super.setUsername(uname); + conn = null; + ps = null; + rs = null; + } + } + else{ + super.setUsername(uname); + } + } + + /** + * Sets the password property for this JdbcRowSet object + * to the given String object. Because it + * is not serialized, the password property is set at run time before + * calling the method execute. Its default valus is + * null. In addition, + * if the password property is already set with a + * non-null value and that value is different from the one being set, + * this method sets this JdbcRowSet object's private fields + * ps, rs, and conn to null. + * (The field ps is its PreparedStatement object, + * rs is its ResultSet object, and + * conn is its Connection object.) + * Setting these fields to null ensures that only current + * values will be used. + * + * @param password the String object that represents the password + * that must be supplied to the database to create a connection + */ + public void setPassword(String password) { + + if ( getPassword() != null) { + if(!getPassword().equals(password)) { + super.setPassword(password); + conn = null; + ps = null; + rs = null; + } + } + else{ + super.setPassword(password); + } + } + + /** + * Sets the type for this RowSet object to the specified type. + * The default type is ResultSet.TYPE_SCROLL_INSENSITIVE. + * + * @param type one of the following constants: + * ResultSet.TYPE_FORWARD_ONLY, + * ResultSet.TYPE_SCROLL_INSENSITIVE, or + * ResultSet.TYPE_SCROLL_SENSITIVE + * @throws SQLException if the parameter supplied is not one of the + * following constants: + * ResultSet.TYPE_FORWARD_ONLY or + * ResultSet.TYPE_SCROLL_INSENSITIVE + * ResultSet.TYPE_SCROLL_SENSITIVE + * @see #getConcurrency + * @see #getType + */ + + public void setType(int type) throws SQLException { + + int oldVal; + + try { + oldVal = getType(); + }catch(SQLException ex) { + oldVal = 0; + } + + if(oldVal != type) { + super.setType(type); + } + + } + + /** + * Sets the concurrency for this RowSet object to + * the specified concurrency. The default concurrency for any RowSet + * object (connected or disconnected) is ResultSet.CONCUR_UPDATABLE, + * but this method may be called at any time to change the concurrency. + * + * @param concur one of the following constants: + * ResultSet.CONCUR_READ_ONLY or + * ResultSet.CONCUR_UPDATABLE + * @throws SQLException if the parameter supplied is not one of the + * following constants: + * ResultSet.CONCUR_UPDATABLE or + * ResultSet.CONCUR_READ_ONLY + * @see #getConcurrency + * @see #isReadOnly + */ + public void setConcurrency(int concur) throws SQLException { + + int oldVal; + + try { + oldVal = getConcurrency(); + }catch(NullPointerException ex) { + oldVal = 0; + } + + if(oldVal != concur) { + super.setConcurrency(concur); + } + + } + + /** + * Retrieves the value of the designated SQL XML parameter as a + * SQLXML object in the Java programming language. + * @param columnIndex the first column is 1, the second is 2, ... + * @return a SQLXML object that maps an SQL XML value + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public SQLXML getSQLXML(int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Retrieves the value of the designated SQL XML parameter as a + * SQLXML object in the Java programming language. + * @param colName the name of the column from which to retrieve the value + * @return a SQLXML object that maps an SQL XML value + * @throws SQLException if a database access error occurs + */ + public SQLXML getSQLXML(String colName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row of this + * ResultSet object as a java.sql.RowId object in the Java + * programming language. + * + * @param columnIndex the first column is 1, the second 2, ... + * @return the column value if the value is a SQL NULL the + * value returned is null + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public RowId getRowId(int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row of this + * ResultSet object as a java.sql.RowId object in the Java + * programming language. + * + * @param columnName the name of the column + * @return the column value if the value is a SQL NULL the + * value returned is null + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public RowId getRowId(String columnName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a RowId value. The updater + * methods are used to update column values in the current row or the insert + * row. The updater methods do not update the underlying database; instead + * the updateRow or insertRow methods are called + * to update the database. + * + * @param columnIndex the first column is 1, the second 2, ... + * @param x the column value + * @throws SQLException if a database access occurs + * @since 6.0 + */ + public void updateRowId(int columnIndex, RowId x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a RowId value. The updater + * methods are used to update column values in the current row or the insert + * row. The updater methods do not update the underlying database; instead + * the updateRow or insertRow methods are called + * to update the database. + * + * @param columnName the name of the column + * @param x the column value + * @throws SQLException if a database access occurs + * @since 6.0 + */ + public void updateRowId(String columnName, RowId x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Retrieves the holdability of this ResultSet object + * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT + * @throws SQLException if a database error occurs + * @since 6.0 + */ + public int getHoldability() throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Retrieves whether this ResultSet object has been closed. A ResultSet is closed if the + * method close has been called on it, or if it is automatically closed. + * @return true if this ResultSet object is closed; false if it is still open + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public boolean isClosed() throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * This method is used for updating columns that support National Character sets. + * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * @param columnIndex the first column is 1, the second 2, ... + * @param nString the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public void updateNString(int columnIndex, String nString) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * This method is used for updating columns that support National Character sets. + * It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * @param columnName name of the Column + * @param nString the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public void updateNString(String columnName, String nString) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /*o + * This method is used for updating SQL NCLOB type that maps + * to java.sql.Types.NCLOB + * @param columnIndex the first column is 1, the second 2, ... + * @param nClob the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public void updateNClob(int columnIndex, NClob nClob) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * This method is used for updating SQL NCLOB type that maps + * to java.sql.Types.NCLOB + * @param columnName name of the column + * @param nClob the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 6.0 + */ + public void updateNClob(String columnName, NClob nClob) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a NClob object + * in the Java programming language. + * + * @param i the first column is 1, the second is 2, ... + * @return a NClob object representing the SQL + * NCLOB value in the specified column + * @exception SQLException if a database access error occurs + * @since 6.0 + */ + public NClob getNClob(int i) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a NClob object + * in the Java programming language. + * + * @param colName the name of the column from which to retrieve the value + * @return a NClob object representing the SQL NCLOB + * value in the specified column + * @exception SQLException if a database access error occurs + * @since 6.0 + */ + public NClob getNClob(String colName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + public T unwrap(Class iface) throws SQLException{ + return null; + } + + public boolean isWrapperFor(Class interfaces) throws SQLException { + return false; + } + + /** + * Sets the designated parameter to the given java.sql.SQLXML object. The driver converts this to an + * SQL XML value when it sends it to the database. + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param xmlObject a SQLXML object that maps an SQL XML value + * @throws SQLException if a database access error occurs + * @since 1.6 + */ + public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given java.sql.SQLXML object. The driver converts this to an + * SQL XML value when it sends it to the database. + * @param parameterName the name of the parameter + * @param xmlObject a SQLXML object that maps an SQL XML value + * @throws SQLException if a database access error occurs + * @since 1.6 + */ + public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given java.sql.RowId object. The + * driver converts this to a SQL ROWID value when it sends it + * to the database + * + * @param parameterIndex the first parameter is 1, the second is 2, ... + * @param x the parameter value + * @throws SQLException if a database access error occurs + * + * @since 1.6 + */ + public void setRowId(int parameterIndex, RowId x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given java.sql.RowId object. The + * driver converts this to a SQL ROWID when it sends it to the + * database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @throws SQLException if a database access error occurs + * @since 1.6 + */ + public void setRowId(String parameterName, RowId x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given String object. + * The driver converts this to a SQL NCHAR or + * NVARCHAR or LONGNVARCHAR value + * (depending on the argument's + * size relative to the driver's limits on NVARCHAR values) + * when it sends it to the database. + * + * @param parameterIndex of the first parameter is 1, the second is 2, ... + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; or if a database access error occurs + * @since 1.6 + */ + public void setNString(int parameterIndex, String value) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter in this RowSet object's command + * to a Reader object. The + * Reader reads the data till end-of-file is reached. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setNCharacterStream which takes a length parameter. + * + * @param parameterIndex of the first parameter is 1, the second is 2, ... + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; if a database access error occurs; or + * this method is called on a closed PreparedStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a java.sql.NClob object. The object + * implements the java.sql.NClob interface. This NClob + * object maps to a SQL NCLOB. + * @param parameterName the name of the column to be set + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; or if a database access error occurs + * @since 1.6 + */ + public void setNClob(String parameterName, NClob value) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a + * java.io.Reader object. + * It is intended for use when + * accessing NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * @return a java.io.Reader object that contains the column + * value; if the value is SQL NULL, the value returned is + * null in the Java programming language. + * @param columnIndex the first column is 1, the second is 2, ... + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public Reader getNCharacterStream(int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as a + * java.io.Reader object. + * It is intended for use when + * accessing NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * @param columnName the name of the column + * @return a java.io.Reader object that contains the column + * value; if the value is SQL NULL, the value returned is + * null in the Java programming language + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public Reader getNCharacterStream(String columnName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a java.sql.SQLXML value. + * The updater + * methods are used to update column values in the current row or the insert + * row. The updater methods do not update the underlying database; instead + * the updateRow or insertRow methods are called + * to update the database. + * @param columnIndex the first column is 1, the second 2, ... + * @param xmlObject the value for the column to be updated + * @throws SQLException if a database access error occurs + * @since 1.6 + */ + public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a java.sql.SQLXML value. + * The updater + * methods are used to update column values in the current row or the insert + * row. The updater methods do not update the underlying database; instead + * the updateRow or insertRow methods are called + * to update the database. + * + * @param columnName the name of the column + * @param xmlObject the column value + * @throws SQLException if a database access occurs + * @since 1.6 + */ + public void updateSQLXML(String columnName, SQLXML xmlObject) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as + * a String in the Java programming language. + * It is intended for use when + * accessing NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public String getNString(int columnIndex) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Retrieves the value of the designated column in the current row + * of this ResultSet object as + * a String in the Java programming language. + * It is intended for use when + * accessing NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * @param columnName the SQL name of the column + * @return the column value; if the value is SQL NULL, the + * value returned is null + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public String getNString(String columnName) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value, which will + * have the specified number of bytes. The driver does the necessary conversion + * from Java character format to the national character set in the database. + * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * The updater methods are used to update column values in the current row or + * the insert row. The updater methods do not update the underlying database; + * instead the updateRow or insertRow methods are called to update the database. + * + * @param columnIndex - the first column is 1, the second is 2, ... + * @param x - the new column value + * @param length - the length of the stream + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public void updateNCharacterStream(int columnIndex, + Reader x, + long length) + throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value, which will + * have the specified number of bytes. The driver does the necessary conversion + * from Java character format to the national character set in the database. + * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * The updater methods are used to update column values in the current row or + * the insert row. The updater methods do not update the underlying database; + * instead the updateRow or insertRow methods are called to update the database. + * + * @param columnName - name of the Column + * @param x - the new column value + * @param length - the length of the stream + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public void updateNCharacterStream(String columnName, + Reader x, + long length) + throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + * It is intended for use when + * updating NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateNCharacterStream which takes a length parameter. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNCharacterStream(int columnIndex, + Reader x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + * It is intended for use when + * updating NCHAR,NVARCHAR + * and LONGNVARCHAR columns. + * + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateNCharacterStream which takes a length parameter. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param reader the java.io.Reader object containing + * the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNCharacterStream(String columnLabel, + Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given input stream, which + * will have the specified number of bytes. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param inputStream An object that contains the data to set the parameter + * value to. + * @param length the number of bytes in the parameter data. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given input stream, which + * will have the specified number of bytes. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param inputStream An object that contains the data to set the parameter + * value to. + * @param length the number of bytes in the parameter data. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given input stream. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateBlob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param inputStream An object that contains the data to set the parameter + * value to. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given input stream. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateBlob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param inputStream An object that contains the data to set the parameter + * value to. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateClob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateClob(int columnIndex, Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateClob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param reader An object that contains the data to set the parameter value to. + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateClob(String columnLabel, Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; this method is called on a closed result set, + * if a database access error occurs or + * the result set concurrency is CONCUR_READ_ONLY + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; this method is called on a closed result set; + * if a database access error occurs or + * the result set concurrency is CONCUR_READ_ONLY + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateNClob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; this method is called on a closed result set, + * if a database access error occurs or + * the result set concurrency is CONCUR_READ_ONLY + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column using the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateNClob which takes a length parameter. + *

+ * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; this method is called on a closed result set; + * if a database access error occurs or + * the result set concurrency is CONCUR_READ_ONLY + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Updates the designated column with an ascii stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateAsciiStream(int columnIndex, + InputStream x, + long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a binary stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBinaryStream(int columnIndex, + InputStream x, + long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateCharacterStream(int columnIndex, + Reader x, + long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with an ascii stream value, which will have + * the specified number of bytes.. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateAsciiStream(String columnLabel, + InputStream x, + long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with an ascii stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateAsciiStream which takes a length parameter. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateAsciiStream(int columnIndex, + InputStream x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with an ascii stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateAsciiStream which takes a length parameter. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateAsciiStream(String columnLabel, + InputStream x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Updates the designated column with a binary stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param x the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBinaryStream(String columnLabel, + InputStream x, + long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a binary stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateBinaryStream which takes a length parameter. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBinaryStream(int columnIndex, + InputStream x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Updates the designated column with a binary stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateBinaryStream which takes a length parameter. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateBinaryStream(String columnLabel, + InputStream x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Updates the designated column with a character stream value, which will have + * the specified number of bytes. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the label is the name of the column + * @param reader the java.io.Reader object containing + * the new column value + * @param length the length of the stream + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateCharacterStream(String columnLabel, + Reader reader, + long length) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateCharacterStream which takes a length parameter. + * + * @param columnIndex the first column is 1, the second is 2, ... + * @param x the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateCharacterStream(int columnIndex, + Reader x) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Updates the designated column with a character stream value. + * The updater methods are used to update column values in the + * current row or the insert row. The updater methods do not + * update the underlying database; instead the updateRow or + * insertRow methods are called to update the database. + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * updateCharacterStream which takes a length parameter. + * + * @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la +bel is the name of the column + * @param reader the java.io.Reader object containing + * the new column value + * @exception SQLException if a database access error occurs, + * the result set concurrency is CONCUR_READ_ONLY + * or this method is called on a closed result set + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void updateCharacterStream(String columnLabel, + Reader reader) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.net.URL value. + * The driver converts this to an SQL DATALINK value + * when it sends it to the database. + * + * @param parameterIndex the first parameter is 1, the second is 2, ... + * @param x the java.net.URL object to be set + * @exception SQLException if a database access error occurs or + * this method is called on a closed PreparedStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.4 + */ + public void setURL(int parameterIndex, java.net.URL x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a Reader object. + * This method differs from the setCharacterStream (int, Reader) method + * because it informs the driver that the parameter value should be sent to + * the server as a NCLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGNVARCHAR or a NCLOB + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setNClob which takes a length parameter. + * + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if parameterIndex does not correspond to a parameter + * marker in the SQL statement; + * if the driver does not support national character sets; + * if the driver can detect that a data conversion + * error could occur; if a database access error occurs or + * this method is called on a closed PreparedStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setNClob(int parameterIndex, Reader reader) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. The reader must contain the number + * of characters specified by length otherwise a SQLException will be + * generated when the CallableStatement is executed. + * This method differs from the setCharacterStream (int, Reader, int) method + * because it informs the driver that the parameter value should be sent to + * the server as a NCLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGNVARCHAR or a NCLOB + * + * @param parameterName the name of the parameter to be set + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if parameterIndex does not correspond to a parameter + * marker in the SQL statement; if the length specified is less than zero; + * if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void setNClob(String parameterName, Reader reader, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a Reader object. + * This method differs from the setCharacterStream (int, Reader) method + * because it informs the driver that the parameter value should be sent to + * the server as a NCLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGNVARCHAR or a NCLOB + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setNClob which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if the driver does not support national character sets; + * if the driver can detect that a data conversion + * error could occur; if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setNClob(String parameterName, Reader reader) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + ** of characters specified by length otherwise a SQLException will becontain the number + * generated when the PreparedStatement is executed. + * This method differs from the setCharacterStream (int, Reader, int) method + * because it informs the driver that the parameter value should be sent to + * the server as a NCLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGNVARCHAR or a NCLOB + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if parameterIndex does not correspond to a parameter + * marker in the SQL statement; if the length specified is less than zero; + * if the driver does not support national character sets; + * if the driver can detect that a data conversion + * error could occur; if a database access error occurs or + * this method is called on a closed PreparedStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setNClob(int parameterIndex, Reader reader, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a java.sql.NClob object. The driver converts this to +a + * SQL NCLOB value when it sends it to the database. + * @param parameterIndex of the first parameter is 1, the second is 2, ... + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; or if a database access error occurs + * @since 1.6 + */ + public void setNClob(int parameterIndex, NClob value) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given String object. + * The driver converts this to a SQL NCHAR or + * NVARCHAR or LONGNVARCHAR + * @param parameterName the name of the column to be set + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; or if a database access error occurs + * @since 1.6 + */ + public void setNString(String parameterName, String value) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. The + * Reader reads the data till end-of-file is reached. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + * @param parameterIndex of the first parameter is 1, the second is 2, ... + * @param value the parameter value + * @param length the number of characters in the parameter data. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; or if a database access error occurs + * @since 1.6 + */ + public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to a Reader object. The + * Reader reads the data till end-of-file is reached. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + * @param parameterName the name of the column to be set + * @param value the parameter value + * @param length the number of characters in the parameter data. + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur; or if a database access error occurs + * @since 1.6 + */ + public void setNCharacterStream(String parameterName, Reader value, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. The + * Reader reads the data till end-of-file is reached. The + * driver does the necessary conversion from Java character format to + * the national character set in the database. + + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setNCharacterStream which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param value the parameter value + * @throws SQLException if the driver does not support national + * character sets; if the driver can detect that a data conversion + * error could occur ; if a database access error occurs; or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setNCharacterStream(String parameterName, Reader value) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given java.sql.Timestamp value, + * using the given Calendar object. The driver uses + * the Calendar object to construct an SQL TIMESTAMP value, + * which the driver then sends to the database. With a + * a Calendar object, the driver can calculate the timestamp + * taking into account a custom timezone. If no + * Calendar object is specified, the driver uses the default + * timezone, which is that of the virtual machine running the application. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @param cal the Calendar object the driver will use + * to construct the timestamp + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getTimestamp + * @since 1.4 + */ + public void setTimestamp(String parameterName, Timestamp x, Calendar cal) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. The reader must contain the number + * of characters specified by length otherwise a SQLException will be + * generated when the CallableStatement is executed. + * This method differs from the setCharacterStream (int, Reader, int) method + * because it informs the driver that the parameter value should be sent to + * the server as a CLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGVARCHAR or a CLOB + * @param parameterName the name of the parameter to be set + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if parameterIndex does not correspond to a parameter + * marker in the SQL statement; if the length specified is less than zero; + * a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * + * @since 1.6 + */ + public void setClob(String parameterName, Reader reader, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given java.sql.Clob object. + * The driver converts this to an SQL CLOB value when it + * sends it to the database. + * + * @param parameterName the name of the parameter + * @param x a Clob object that maps an SQL CLOB value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void setClob (String parameterName, Clob x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. + * This method differs from the setCharacterStream (int, Reader) method + * because it informs the driver that the parameter value should be sent to + * the server as a CLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGVARCHAR or a CLOB + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setClob which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if a database access error occurs or this method is called on + * a closed CallableStatement + * + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setClob(String parameterName, Reader reader) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.Date value + * using the default time zone of the virtual machine that is running + * the application. + * The driver converts this + * to an SQL DATE value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getDate + * @since 1.4 + */ + public void setDate(String parameterName, java.sql.Date x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given java.sql.Date value, + * using the given Calendar object. The driver uses + * the Calendar object to construct an SQL DATE value, + * which the driver then sends to the database. With a + * a Calendar object, the driver can calculate the date + * taking into account a custom timezone. If no + * Calendar object is specified, the driver uses the default + * timezone, which is that of the virtual machine running the application. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @param cal the Calendar object the driver will use + * to construct the date + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getDate + * @since 1.4 + */ + public void setDate(String parameterName, java.sql.Date x, Calendar cal) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.Time value. + * The driver converts this + * to an SQL TIME value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getTime + * @since 1.4 + */ + public void setTime(String parameterName, Time x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given java.sql.Time value, + * using the given Calendar object. The driver uses + * the Calendar object to construct an SQL TIME value, + * which the driver then sends to the database. With a + * a Calendar object, the driver can calculate the time + * taking into account a custom timezone. If no + * Calendar object is specified, the driver uses the default + * timezone, which is that of the virtual machine running the application. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @param cal the Calendar object the driver will use + * to construct the time + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getTime + * @since 1.4 + */ + public void setTime(String parameterName, Time x, Calendar cal) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a Reader object. + * This method differs from the setCharacterStream (int, Reader) method + * because it informs the driver that the parameter value should be sent to + * the server as a CLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARCHAR or a CLOB + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setClob which takes a length parameter. + * + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @throws SQLException if a database access error occurs, this method is called on + * a closed PreparedStatementor if parameterIndex does not correspond to a parameter + * marker in the SQL statement + * + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setClob(int parameterIndex, Reader reader) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a Reader object. The reader must contain the number + * of characters specified by length otherwise a SQLException will be + * generated when the PreparedStatement is executed. + *This method differs from the setCharacterStream (int, Reader, int) method + * because it informs the driver that the parameter value should be sent to + * the server as a CLOB. When the setCharacterStream method is used, the + * driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARCHAR or a CLOB + * @param parameterIndex index of the first parameter is 1, the second is 2, ... + * @param reader An object that contains the data to set the parameter value to. + * @param length the number of characters in the parameter data. + * @throws SQLException if a database access error occurs, this method is called on + * a closed PreparedStatement, if parameterIndex does not correspond to a parameter + * marker in the SQL statement, or if the length specified is less than zero. + * + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setClob(int parameterIndex, Reader reader, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to a InputStream object. The inputstream must contain the number + * of characters specified by length otherwise a SQLException will be + * generated when the PreparedStatement is executed. + * This method differs from the setBinaryStream (int, InputStream, int) + * method because it informs the driver that the parameter value should be + * sent to the server as a BLOB. When the setBinaryStream method is used, + * the driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARBINARY or a BLOB + * @param parameterIndex index of the first parameter is 1, + * the second is 2, ... + * @param inputStream An object that contains the data to set the parameter + * value to. + * @param length the number of bytes in the parameter data. + * @throws SQLException if a database access error occurs, + * this method is called on a closed PreparedStatement, + * if parameterIndex does not correspond + * to a parameter marker in the SQL statement, if the length specified + * is less than zero or if the number of bytes in the inputstream does not match + * the specified length. + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setBlob(int parameterIndex, InputStream inputStream, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a InputStream object. + * This method differs from the setBinaryStream (int, InputStream) + * This method differs from the setBinaryStream (int, InputStream) + * method because it informs the driver that the parameter value should be + * sent to the server as a BLOB. When the setBinaryStream method is used, + * the driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARBINARY or a BLOB + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setBlob which takes a length parameter. + * + * @param parameterIndex index of the first parameter is 1, + * the second is 2, ... + + + * @param inputStream An object that contains the data to set the parameter + * value to. + * @throws SQLException if a database access error occurs, + * this method is called on a closed PreparedStatement or + * if parameterIndex does not correspond + * to a parameter marker in the SQL statement, + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setBlob(int parameterIndex, InputStream inputStream) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a InputStream object. The inputstream must contain the number + * of characters specified by length, otherwise a SQLException will be + * generated when the CallableStatement is executed. + * This method differs from the setBinaryStream (int, InputStream, int) + * method because it informs the driver that the parameter value should be + * sent to the server as a BLOB. When the setBinaryStream method is used, + * the driver may have to do extra work to determine whether the parameter + * data should be sent to the server as a LONGVARBINARY or a BLOB + * + * @param parameterName the name of the parameter to be set + * the second is 2, ... + * + * @param inputStream An object that contains the data to set the parameter + * value to. + * @param length the number of bytes in the parameter data. + * @throws SQLException if parameterIndex does not correspond + * to a parameter marker in the SQL statement, or if the length specified + * is less than zero; if the number of bytes in the inputstream does not match + * the specified length; if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * + * @since 1.6 + */ + public void setBlob(String parameterName, InputStream inputStream, long length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given java.sql.Blob object. + * The driver converts this to an SQL BLOB value when it + * sends it to the database. + * + * @param parameterName the name of the parameter + * @param x a Blob object that maps an SQL BLOB value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.6 + */ + public void setBlob (String parameterName, Blob x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to a InputStream object. + * This method differs from the setBinaryStream (int, InputStream) + * method because it informs the driver that the parameter value should be + * sent to the server as a BLOB. When the setBinaryStream method is used, + * the driver may have to do extra work to determine whether the parameter + * data should be send to the server as a LONGVARBINARY or a BLOB + * + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setBlob which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param inputStream An object that contains the data to set the parameter + * value to. + * @throws SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * + * @since 1.6 + */ + public void setBlob(String parameterName, InputStream inputStream) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the value of the designated parameter with the given object. The second + * argument must be an object type; for integral values, the + * java.lang equivalent objects should be used. + * + *

The given Java object will be converted to the given targetSqlType + * before being sent to the database. + * + * If the object has a custom mapping (is of a class implementing the + * interface SQLData), + * the JDBC driver should call the method SQLData.writeSQL to write it + * to the SQL data stream. + * If, on the other hand, the object is of a class implementing + * Ref, Blob, Clob, NClob, + * Struct, java.net.URL, + * or Array, the driver should pass it to the database as a + * value of the corresponding SQL type. + *

+ * Note that this method may be used to pass datatabase- + * specific abstract data types. + * + * @param parameterName the name of the parameter + * @param x the object containing the input parameter value + * @param targetSqlType the SQL type (as defined in java.sql.Types) to be + * sent to the database. The scale argument may further qualify this type. + * @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types, + * this is the number of digits after the decimal point. For all other + * types, this value will be ignored. + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if targetSqlType is + * a ARRAY, BLOB, CLOB, + * DATALINK, JAVA_OBJECT, NCHAR, + * NCLOB, NVARCHAR, LONGNVARCHAR, + * REF, ROWID, SQLXML + * or STRUCT data type and the JDBC driver does not support + * this data type + * @see Types + * @see #getObject + * @since 1.4 + */ + public void setObject(String parameterName, Object x, int targetSqlType, int scale) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the value of the designated parameter with the given object. + * This method is like the method setObject + * above, except that it assumes a scale of zero. + * + * @param parameterName the name of the parameter + * @param x the object containing the input parameter value + * @param targetSqlType the SQL type (as defined in java.sql.Types) to be + * sent to the database + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if targetSqlType is + * a ARRAY, BLOB, CLOB, + * DATALINK, JAVA_OBJECT, NCHAR, + * NCLOB, NVARCHAR, LONGNVARCHAR, + * REF, ROWID, SQLXML + * or STRUCT data type and the JDBC driver does not support + * this data type + * @see #getObject + * @since 1.4 + */ + public void setObject(String parameterName, Object x, int targetSqlType) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the value of the designated parameter with the given object. + * The second parameter must be of type Object; therefore, the + * java.lang equivalent objects should be used for built-in types. + * + *

The JDBC specification specifies a standard mapping from + * Java Object types to SQL types. The given argument + * will be converted to the corresponding SQL type before being + * sent to the database. + * + *

Note that this method may be used to pass datatabase- + * specific abstract data types, by using a driver-specific Java + * type. + * + * If the object is of a class implementing the interface SQLData, + * the JDBC driver should call the method SQLData.writeSQL + * to write it to the SQL data stream. + * If, on the other hand, the object is of a class implementing + * Ref, Blob, Clob, NClob, + * Struct, java.net.URL, + * or Array, the driver should pass it to the database as a + * value of the corresponding SQL type. + *

+ * This method throws an exception if there is an ambiguity, for example, if the + * object is of a class implementing more than one of the interfaces named above. + * + * @param parameterName the name of the parameter + * @param x the object containing the input parameter value + * @exception SQLException if a database access error occurs, + * this method is called on a closed CallableStatement or if the given + * Object parameter is ambiguous + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getObject + * @since 1.4 + */ + public void setObject(String parameterName, Object x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given input stream, which will have + * the specified number of bytes. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + * @param parameterName the name of the parameter + * @param x the Java input stream that contains the ASCII parameter value + * @param length the number of bytes in the stream + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setAsciiStream(String parameterName, InputStream x, int length) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + +/** + * Sets the designated parameter to the given input stream, which will have + * the specified number of bytes. + * When a very large binary value is input to a LONGVARBINARY + * parameter, it may be more practical to send it via a + * java.io.InputStream object. The data will be read from the stream + * as needed until end-of-file is reached. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + * @param parameterName the name of the parameter + * @param x the java input stream which contains the binary parameter value + * @param length the number of bytes in the stream + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setBinaryStream(String parameterName, InputStream x, + int length) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given Reader + * object, which is the given number of characters long. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + * + * @param parameterName the name of the parameter + * @param reader the java.io.Reader object that + * contains the UNICODE data used as the designated parameter + * @param length the number of characters in the stream + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setCharacterStream(String parameterName, + Reader reader, + int length) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given input stream. + * When a very large ASCII value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.InputStream. Data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from ASCII to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setAsciiStream which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param x the Java input stream that contains the ASCII parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setAsciiStream(String parameterName, InputStream x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given input stream. + * When a very large binary value is input to a LONGVARBINARY + * parameter, it may be more practical to send it via a + * java.io.InputStream object. The data will be read from the + * stream as needed until end-of-file is reached. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setBinaryStream which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param x the java input stream which contains the binary parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setBinaryStream(String parameterName, InputStream x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given Reader + * object. + * When a very large UNICODE value is input to a LONGVARCHAR + * parameter, it may be more practical to send it via a + * java.io.Reader object. The data will be read from the stream + * as needed until end-of-file is reached. The JDBC driver will + * do any necessary conversion from UNICODE to the database char format. + * + *

Note: This stream object can either be a standard + * Java stream object or your own subclass that implements the + * standard interface. + *

Note: Consult your JDBC driver documentation to determine if + * it might be more efficient to use a version of + * setCharacterStream which takes a length parameter. + * + * @param parameterName the name of the parameter + * @param reader the java.io.Reader object that contains the + * Unicode data + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method + * @since 1.6 + */ + public void setCharacterStream(String parameterName, + Reader reader) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given + * java.math.BigDecimal value. + * The driver converts this to an SQL NUMERIC value when + * it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getBigDecimal + * @since 1.4 + */ + public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given Java String value. + * The driver converts this + * to an SQL VARCHAR or LONGVARCHAR value + * (depending on the argument's + * size relative to the driver's limits on VARCHAR values) + * when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getString + * @since 1.4 + */ + public void setString(String parameterName, String x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given Java array of bytes. + * The driver converts this to an SQL VARBINARY or + * LONGVARBINARY (depending on the argument's size relative + * to the driver's limits on VARBINARY values) when it sends + * it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getBytes + * @since 1.4 + */ + public void setBytes(String parameterName, byte x[]) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given java.sql.Timestamp value. + * The driver + * converts this to an SQL TIMESTAMP value when it sends it to the + * database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getTimestamp + * @since 1.4 + */ + public void setTimestamp(String parameterName, Timestamp x) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to SQL NULL. + * + *

Note: You must specify the parameter's SQL type. + * + * @param parameterName the name of the parameter + * @param sqlType the SQL type code defined in java.sql.Types + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setNull(String parameterName, int sqlType) throws SQLException { + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to SQL NULL. + * This version of the method setNull should + * be used for user-defined types and REF type parameters. Examples + * of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and + * named array types. + * + *

Note: To be portable, applications must give the + * SQL type code and the fully-qualified SQL type name when specifying + * a NULL user-defined or REF parameter. In the case of a user-defined type + * the name is the type name of the parameter itself. For a REF + * parameter, the name is the type name of the referenced type. If + * a JDBC driver does not need the type code or type name information, + * it may ignore it. + * + * Although it is intended for user-defined and Ref parameters, + * this method may be used to set a null parameter of any JDBC type. + * If the parameter does not have a user-defined or REF type, the given + * typeName is ignored. + * + * + * @param parameterName the name of the parameter + * @param sqlType a value from java.sql.Types + * @param typeName the fully-qualified name of an SQL user-defined type; + * ignored if the parameter is not a user-defined type or + * SQL REF value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setNull (String parameterName, int sqlType, String typeName) + throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given Java boolean value. + * The driver converts this + * to an SQL BIT or BOOLEAN value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @see #getBoolean + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @since 1.4 + */ + public void setBoolean(String parameterName, boolean x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + + /** + * Sets the designated parameter to the given Java byte value. + * The driver converts this + * to an SQL TINYINT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getByte + * @since 1.4 + */ + public void setByte(String parameterName, byte x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given Java short value. + * The driver converts this + * to an SQL SMALLINT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getShort + * @since 1.4 + */ + public void setShort(String parameterName, short x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given Java int value. + * The driver converts this + * to an SQL INTEGER value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getInt + * @since 1.4 + */ + public void setInt(String parameterName, int x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given Java long value. + * The driver converts this + * to an SQL BIGINT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getLong + * @since 1.4 + */ + public void setLong(String parameterName, long x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + + /** + * Sets the designated parameter to the given Java float value. + * The driver converts this + * to an SQL FLOAT value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getFloat + * @since 1.4 + */ + public void setFloat(String parameterName, float x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * Sets the designated parameter to the given Java double value. + * The driver converts this + * to an SQL DOUBLE value when it sends it to the database. + * + * @param parameterName the name of the parameter + * @param x the parameter value + * @exception SQLException if a database access error occurs or + * this method is called on a closed CallableStatement + * @exception SQLFeatureNotSupportedException if the JDBC driver does not support + * this method + * @see #getDouble + * @since 1.4 + */ + public void setDouble(String parameterName, double x) throws SQLException{ + throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("jdbcrowsetimpl.featnotsupp").toString()); + } + + /** + * This method re populates the resBundle + * during the deserialization process + * + */ + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + // Default state initialization happens here + ois.defaultReadObject(); + // Initialization of transient Res Bundle happens here . + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) {} + + } + + static final long serialVersionUID = -3591946023893483003L; + + //------------------------- JDBC 4.1 ----------------------------------- + + public T getObject(int columnIndex, Class type) throws SQLException { + throw new SQLFeatureNotSupportedException("Not supported yet."); + } + + public T getObject(String columnLabel, Class type) throws SQLException { + throw new SQLFeatureNotSupportedException("Not supported yet."); + } +} diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/JdbcRowSetResourceBundle.java b/src/main/java/org/replicadb/rowset/sun/rowset/JdbcRowSetResourceBundle.java new file mode 100644 index 0000000..de088fc --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/JdbcRowSetResourceBundle.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Enumeration; +import java.util.Locale; +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; + +/** + * This class is used to help in localization of resources, + * especially the exception strings. + * + * @author Amit Handa + */ + +public class JdbcRowSetResourceBundle implements Serializable { + + /** + * This String variable stores the location + * of the resource bundle location. + */ + private static String fileName; + + /** + * This variable will hold the PropertyResourceBundle + * of the text to be internationalized. + */ + private transient PropertyResourceBundle propResBundle; + + /** + * The constructor initializes to this object + * + */ + private static volatile JdbcRowSetResourceBundle jpResBundle; + + /** + * The variable which will represent the properties + * the suffix or extension of the resource bundle. + **/ + private static final String PROPERTIES = "properties"; + + /** + * The variable to represent underscore + **/ + private static final String UNDERSCORE = "_"; + + /** + * The variable which will represent dot + **/ + private static final String DOT = "."; + + /** + * The variable which will represent the slash. + **/ + private static final String SLASH = "/"; + + /** + * The variable where the default resource bundle will + * be placed. + **/ + private static final String PATH = "com/sun/rowset/RowSetResourceBundle"; + + /** + * The constructor which initializes the resource bundle. + * Note this is a private constructor and follows Singleton + * Design Pattern. + * + * @throws IOException if unable to load the ResourceBundle + * according to locale or the default one. + */ + private JdbcRowSetResourceBundle () throws IOException { + // Try to load the resource bundle according + // to the locale. Else if no bundle found according + // to the locale load the default. + + // In default case the default locale resource bundle + // should always be loaded else it + // will be difficult to throw appropriate + // exception string messages. + Locale locale = Locale.getDefault(); + + // Load appropriate bundle according to locale + propResBundle = (PropertyResourceBundle) ResourceBundle.getBundle(PATH, + locale, Thread.currentThread().getContextClassLoader()); + + } + + /** + * This method is used to get a handle to the + * initialized instance of this class. Note that + * at any time there is only one instance of this + * class initialized which will be returned. + * + * @throws IOException if unable to find the RowSetResourceBundle.properties + */ + public static JdbcRowSetResourceBundle getJdbcRowSetResourceBundle() + throws IOException { + + if(jpResBundle == null){ + synchronized(JdbcRowSetResourceBundle.class) { + if(jpResBundle == null){ + jpResBundle = new JdbcRowSetResourceBundle(); + } //end if + } //end synchronized block + } //end if + return jpResBundle; + } + + /** + * This method returns an enumerated handle of the keys + * which correspond to values translated to various locales. + * + * @return an enumeration of keys which have messages tranlated to + * corresponding locales. + */ + @SuppressWarnings("rawtypes") + public Enumeration getKeys() { + return propResBundle.getKeys(); + } + + + /** + * This method takes the key as an argument and + * returns the corresponding value reading it + * from the Resource Bundle loaded earlier. + * + * @return value in locale specific language + * according to the key passed. + */ + public Object handleGetObject(String key) { + return propResBundle.handleGetObject(key); + } + + static final long serialVersionUID = 436199386225359954L; +} diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/internal/BaseRow.java b/src/main/java/org/replicadb/rowset/sun/rowset/internal/BaseRow.java new file mode 100644 index 0000000..ebe5ff7 --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/internal/BaseRow.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset.internal; + +import java.io.Serializable; +import java.sql.SQLException; +import java.util.Arrays; + +/** + * The abstract base class from which the classes Row + * The class BaseRow stores + * a row's original values as an array of Object + * values, which can be retrieved with the method getOrigRow. + * This class also provides methods for getting and setting individual + * values in the row. + *

+ * A row's original values are the values it contained before it was last + * modified. For example, when the CachedRowSetmethod + * acceptChanges is called, it will reset a row's original + * values to be the row's current values. Then, when the row is modified, + * the values that were previously the current values will become the row's + * original values (the values the row had immediately before it was modified). + * If a row has not been modified, its original values are its initial values. + *

+ * Subclasses of this class contain more specific details, such as + * the conditions under which an exception is thrown or the bounds for + * index parameters. + */ +public abstract class BaseRow implements Serializable, Cloneable { + +/** + * Specify the serialVersionUID + */ +private static final long serialVersionUID = 4152013523511412238L; + +/** + * The array containing the original values for this BaseRow + * object. + * @serial + */ + protected Object[] origVals; + +/** + * Retrieves the values that this row contained immediately + * prior to its last modification. + * + * @return an array of Object values containing this row's + * original values + */ + public Object[] getOrigRow() { + Object[] origRow = this.origVals; + return (origRow == null) ? null: Arrays.copyOf(origRow, origRow.length); + } + +/** + * Retrieves the array element at the given index, which is + * the original value of column number idx in this row. + * + * @param idx the index of the element to return + * @return the Object value at the given index into this + * row's array of original values + * @throws SQLException if there is an error + */ + public abstract Object getColumnObject(int idx) throws SQLException; + +/** + * Sets the element at the given index into this row's array of + * original values to the given value. Implementations of the classes + * Row and determine what happens + * when the cursor is on the insert row and when it is on any other row. + * + * @param idx the index of the element to be set + * @param obj the Object to which the element at index + * idx to be set + * @throws SQLException if there is an error + */ + public abstract void setColumnObject(int idx, Object obj) throws SQLException; +} diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/internal/CachedRowSetReader.java b/src/main/java/org/replicadb/rowset/sun/rowset/internal/CachedRowSetReader.java new file mode 100644 index 0000000..fd2d0d3 --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/internal/CachedRowSetReader.java @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset.internal; + +import org.replicadb.rowset.sun.rowset.CachedRowSetImpl; +import org.replicadb.rowset.sun.rowset.JdbcRowSetResourceBundle; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; +import javax.sql.RowSet; +import javax.sql.RowSetInternal; +import javax.sql.RowSetReader; +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.spi.SyncFactory; +import javax.sql.rowset.spi.SyncFactoryException; +import javax.sql.rowset.spi.SyncProvider; +import java.io.*; +import java.sql.*; + +/** + * The facility called by the RIOptimisticProvider object + * internally to read data into it. The calling RowSet object + * must have implemented the RowSetInternal interface + * and have the standard CachedRowSetReader object set as its + * reader. + *

+ * This implementation always reads all rows of the data source, + * and it assumes that the command property for the caller + * is set with a query that is appropriate for execution by a + * PreparedStatement object. + *

+ * Typically the SyncFactory manages the RowSetReader and + * the RowSetWriter implementations using SyncProvider objects. + * Standard JDBC RowSet implementations provide an object instance of this + * reader by invoking the SyncProvider.getRowSetReader() method. + * + * @author Jonathan Bruce + * @see SyncProvider + * @see SyncFactory + * @see SyncFactoryException + */ +public class CachedRowSetReader implements RowSetReader, Serializable { + + /** + * The field that keeps track of whether the writer associated with + * this CachedRowSetReader object's rowset has been called since + * the rowset was populated. + *

+ * When this CachedRowSetReader object reads data into + * its rowset, it sets the field writerCalls to 0. + * When the writer associated with the rowset is called to write + * data back to the underlying data source, its writeData + * method calls the method CachedRowSetReader.reset, + * which increments writerCalls and returns true + * if writerCalls is 1. Thus, writerCalls equals + * 1 after the first call to writeData that occurs + * after the rowset has had data read into it. + * + * @serial + */ + private int writerCalls = 0; + + private boolean userCon = false; + + private int startPosition; + + private JdbcRowSetResourceBundle resBundle; + + public CachedRowSetReader() { + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + } + + + /** + * Reads data from a data source and populates the given + * RowSet object with that data. + * This method is called by the rowset internally when + * the application invokes the method execute + * to read a new set of rows. + *

+ * After clearing the rowset of its contents, if any, and setting + * the number of writer calls to 0, this reader calls + * its connect method to make + * a connection to the rowset's data source. Depending on which + * of the rowset's properties have been set, the connect + * method will use a DataSource object or the + * DriverManager facility to make a connection to the + * data source. + *

+ * Once the connection to the data source is made, this reader + * executes the query in the calling CachedRowSet object's + * command property. Then it calls the rowset's + * populate method, which reads data from the + * ResultSet object produced by executing the rowset's + * command. The rowset is then populated with this data. + *

+ * This method's final act is to close the connection it made, thus + * leaving the rowset disconnected from its data source. + * + * @param caller a RowSet object that has implemented + * the RowSetInternal interface and had + * this CachedRowSetReader object set as + * its reader + * @throws SQLException if there is a database access error, there is a + * problem making the connection, or the command property has not + * been set + */ + public void readData(RowSetInternal caller) throws SQLException + { + Connection con = null; + try { + CachedRowSet crs = (CachedRowSet)caller; + + // Get rid of the current contents of the rowset. + + /** + * Checking added to verify whether page size has been set or not. + * If set then do not close the object as certain parameters need + * to be maintained. + */ + + if(crs.getPageSize() == 0 && crs.size() >0 ) { + // When page size is not set, + // crs.size() will show the total no of rows. + crs.close(); + } + + writerCalls = 0; + + // Get a connection. This reader assumes that the necessary + // properties have been set on the caller to let it supply a + // connection. + userCon = false; + + con = this.connect(caller); + + // Check our assumptions. + if (con == null || crs.getCommand() == null) + throw new SQLException(resBundle.handleGetObject("crsreader.connecterr").toString()); + + try { + con.setTransactionIsolation(crs.getTransactionIsolation()); + } catch (Exception ex) { + ; + } + // Use JDBC to read the data. + PreparedStatement pstmt = con.prepareStatement(crs.getCommand()); + // Pass any input parameters to JDBC. + + decodeParams(caller.getParams(), pstmt); + try { + pstmt.setMaxRows(crs.getMaxRows()); + pstmt.setMaxFieldSize(crs.getMaxFieldSize()); + pstmt.setEscapeProcessing(crs.getEscapeProcessing()); + pstmt.setQueryTimeout(crs.getQueryTimeout()); + } catch (Exception ex) { + /* + * drivers may not support the above - esp. older + * drivers being used by the bridge.. + */ + throw new SQLException(ex.getMessage()); + } + + if(crs.getCommand().toLowerCase().indexOf("select") != -1) { + // can be (crs.getCommand()).indexOf("select")) == 0 + // because we will be getting resultset when + // it may be the case that some false select query with + // select coming in between instead of first. + + // if ((crs.getCommand()).indexOf("?")) does not return -1 + // implies a Prepared Statement like query exists. + + ResultSet rs = pstmt.executeQuery(); + if(crs.getPageSize() == 0){ + crs.populate(rs); + } + else { + /** + * If page size has been set then create a ResultSet object that is scrollable using a + * PreparedStatement handle.Also call the populate(ResultSet,int) function to populate + * a page of data as specified by the page size. + */ + pstmt = con.prepareStatement(crs.getCommand(),ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); + decodeParams(caller.getParams(), pstmt); + try { + pstmt.setMaxRows(crs.getMaxRows()); + pstmt.setMaxFieldSize(crs.getMaxFieldSize()); + pstmt.setEscapeProcessing(crs.getEscapeProcessing()); + pstmt.setQueryTimeout(crs.getQueryTimeout()); + } catch (Exception ex) { + /* + * drivers may not support the above - esp. older + * drivers being used by the bridge.. + */ + throw new SQLException(ex.getMessage()); + } + rs = pstmt.executeQuery(); + crs.populate(rs,startPosition); + } + rs.close(); + } else { + pstmt.executeUpdate(); + } + + // Get the data. + pstmt.close(); + try { + con.commit(); + } catch (SQLException ex) { + ; + } + // only close connections we created... + if (getCloseConnection() == true) + con.close(); + } + catch (SQLException ex) { + // Throw an exception if reading fails for any reason. + throw ex; + } finally { + try { + // only close connections we created... + if (con != null && getCloseConnection() == true) { + try { + if (!con.getAutoCommit()) { + con.rollback(); + } + } catch (Exception dummy) { + /* + * not an error condition, we're closing anyway, but + * we'd like to clean up any locks if we can since + * it is not clear the connection pool will clean + * these connections in a timely manner + */ + } + con.close(); + con = null; + } + } catch (SQLException e) { + // will get exception if something already went wrong, but don't + // override that exception with this one + } + } + } + + /** + * Checks to see if the writer associated with this reader needs + * to reset its state. The writer will need to initialize its state + * if new contents have been read since the writer was last called. + * This method is called by the writer that was registered with + * this reader when components were being wired together. + * + * @return true if writer associated with this reader needs + * to reset the values of its fields; false otherwise + * @throws SQLException if an access error occurs + */ + public boolean reset() throws SQLException { + writerCalls++; + return writerCalls == 1; + } + + /** + * Establishes a connection with the data source for the given + * RowSet object. If the rowset's dataSourceName + * property has been set, this method uses the JNDI API to retrieve the + * DataSource object that it can use to make the connection. + * If the url, username, and password properties have been set, this + * method uses the DriverManager.getConnection method to + * make the connection. + *

+ * This method is used internally by the reader and writer associated with + * the calling RowSet object; an application never calls it + * directly. + * + * @param caller a RowSet object that has implemented + * the RowSetInternal interface and had + * this CachedRowSetReader object set as + * its reader + * @return a Connection object that represents a connection + * to the caller's data source + * @throws SQLException if an access error occurs + */ + public Connection connect(RowSetInternal caller) throws SQLException { + + // Get a JDBC connection. + if (caller.getConnection() != null) { + // A connection was passed to execute(), so use it. + // As we are using a connection the user gave us we + // won't close it. + userCon = true; + return caller.getConnection(); + } + else if (((RowSet)caller).getDataSourceName() != null) { + // Connect using JNDI. + try { + Context ctx = new InitialContext(); + DataSource ds = (DataSource)ctx.lookup + (((RowSet)caller).getDataSourceName()); + + // Check for username, password, + // if it exists try getting a Connection handle through them + // else try without these + // else throw SQLException + + if(((RowSet)caller).getUsername() != null) { + return ds.getConnection(((RowSet)caller).getUsername(), + ((RowSet)caller).getPassword()); + } else { + return ds.getConnection(); + } + } + catch (NamingException ex) { + SQLException sqlEx = new SQLException(resBundle.handleGetObject("crsreader.connect").toString()); + sqlEx.initCause(ex); + throw sqlEx; + } + } else if (((RowSet)caller).getUrl() != null) { + // Connect using the driver manager. + return DriverManager.getConnection(((RowSet)caller).getUrl(), + ((RowSet)caller).getUsername(), + ((RowSet)caller).getPassword()); + } + else { + return null; + } + } + + /** + * Sets the parameter placeholders + * in the rowset's command (the given PreparedStatement + * object) with the parameters in the given array. + * This method, called internally by the method + * CachedRowSetReader.readData, reads each parameter, and + * based on its type, determines the correct + * PreparedStatement.setXXX method to use for setting + * that parameter. + * + * @param params an array of parameters to be used with the given + * PreparedStatement object + * @param pstmt the PreparedStatement object that is the + * command for the calling rowset and into which + * the given parameters are to be set + * @throws SQLException if an access error occurs + */ + @SuppressWarnings("deprecation") + private void decodeParams(Object[] params, + PreparedStatement pstmt) throws SQLException { + // There is a corresponding decodeParams in JdbcRowSetImpl + // which does the same as this method. This is a design flaw. + // Update the JdbcRowSetImpl.decodeParams when you update + // this method. + + // Adding the same comments to JdbcRowSetImpl.decodeParams. + + int arraySize; + Object[] param = null; + + for (int i=0; i < params.length; i++) { + if (params[i] instanceof Object[]) { + param = (Object[])params[i]; + + if (param.length == 2) { + if (param[0] == null) { + pstmt.setNull(i + 1, ((Integer)param[1]).intValue()); + continue; + } + + if (param[0] instanceof Date || + param[0] instanceof Time || + param[0] instanceof Timestamp) { + System.err.println(resBundle.handleGetObject("crsreader.datedetected").toString()); + if (param[1] instanceof java.util.Calendar) { + System.err.println(resBundle.handleGetObject("crsreader.caldetected").toString()); + pstmt.setDate(i + 1, (Date)param[0], + (java.util.Calendar)param[1]); + continue; + } + else { + throw new SQLException(resBundle.handleGetObject("crsreader.paramtype").toString()); + } + } + + if (param[0] instanceof Reader) { + pstmt.setCharacterStream(i + 1, (Reader)param[0], + ((Integer)param[1]).intValue()); + continue; + } + + /* + * What's left should be setObject(int, Object, scale) + */ + if (param[1] instanceof Integer) { + pstmt.setObject(i + 1, param[0], ((Integer)param[1]).intValue()); + continue; + } + + } else if (param.length == 3) { + + if (param[0] == null) { + pstmt.setNull(i + 1, ((Integer)param[1]).intValue(), + (String)param[2]); + continue; + } + + if (param[0] instanceof InputStream) { + switch (((Integer)param[2]).intValue()) { + case CachedRowSetImpl.UNICODE_STREAM_PARAM: + pstmt.setUnicodeStream(i + 1, + (InputStream)param[0], + ((Integer)param[1]).intValue()); + break; + case CachedRowSetImpl.BINARY_STREAM_PARAM: + pstmt.setBinaryStream(i + 1, + (InputStream)param[0], + ((Integer)param[1]).intValue()); + break; + case CachedRowSetImpl.ASCII_STREAM_PARAM: + pstmt.setAsciiStream(i + 1, + (InputStream)param[0], + ((Integer)param[1]).intValue()); + break; + default: + throw new SQLException(resBundle.handleGetObject("crsreader.paramtype").toString()); + } + } + + /* + * no point at looking at the first element now; + * what's left must be the setObject() cases. + */ + if (param[1] instanceof Integer && param[2] instanceof Integer) { + pstmt.setObject(i + 1, param[0], ((Integer)param[1]).intValue(), + ((Integer)param[2]).intValue()); + continue; + } + + throw new SQLException(resBundle.handleGetObject("crsreader.paramtype").toString()); + + } else { + // common case - this catches all SQL92 types + pstmt.setObject(i + 1, params[i]); + continue; + } + } else { + // Try to get all the params to be set here + pstmt.setObject(i + 1, params[i]); + + } + } + } + + /** + * Assists in determining whether the current connection was created by this + * CachedRowSet to ensure incorrect connections are not prematurely terminated. + * + * @return a boolean giving the status of whether the connection has been closed. + */ + protected boolean getCloseConnection() { + if (userCon == true) + return false; + + return true; + } + + /** + * This sets the start position in the ResultSet from where to begin. This is + * called by the Reader in the CachedRowSetImpl to set the position on the page + * to begin populating from. + * @param pos integer indicating the position in the ResultSet to begin + * populating from. + */ + public void setStartPosition(int pos){ + startPosition = pos; + } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + // Default state initialization happens here + ois.defaultReadObject(); + // Initialization of Res Bundle happens here . + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + } + + static final long serialVersionUID =5049738185801363801L; +} diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/internal/CachedRowSetWriter.java b/src/main/java/org/replicadb/rowset/sun/rowset/internal/CachedRowSetWriter.java new file mode 100644 index 0000000..4e652b7 --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/internal/CachedRowSetWriter.java @@ -0,0 +1,1472 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset.internal; + +import org.replicadb.rowset.sun.rowset.CachedRowSetImpl; +import org.replicadb.rowset.sun.rowset.JdbcRowSetResourceBundle; +//import sun.reflect.misc.ReflectUtil; + +import javax.sql.RowSetInternal; +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.RowSetMetaDataImpl; +import javax.sql.rowset.serial.*; +import javax.sql.rowset.spi.*; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.sql.*; +import java.util.ArrayList; +import java.util.Map; +import java.util.Vector; + + +/** + * The facility called on internally by the RIOptimisticProvider implementation to + * propagate changes back to the data source from which the rowset got its data. + *

+ * A CachedRowSetWriter object, called a writer, has the public + * method writeData for writing modified data to the underlying data source. + * This method is invoked by the rowset internally and is never invoked directly by an application. + * A writer also has public methods for setting and getting + * the CachedRowSetReader object, called a reader, that is associated + * with the writer. The remainder of the methods in this class are private and + * are invoked internally, either directly or indirectly, by the method + * writeData. + *

+ * Typically the SyncFactory manages the RowSetReader and + * the RowSetWriter implementations using SyncProvider objects. + * Standard JDBC RowSet implementations provide an object instance of this + * writer by invoking the SyncProvider.getRowSetWriter() method. + * + * @version 0.2 + * @author Jonathan Bruce + * @see SyncProvider + * @see SyncFactory + * @see SyncFactoryException + */ +public class CachedRowSetWriter implements TransactionalWriter, Serializable { + +/** + * The Connection object that this writer will use to make a + * connection to the data source to which it will write data. + * + */ + private transient Connection con; + +/** + * The SQL SELECT command that this writer will call + * internally. The method initSQLStatements builds this + * command by supplying the words "SELECT" and "FROM," and using + * metadata to get the table name and column names . + * + * @serial + */ + private String selectCmd; + +/** + * The SQL UPDATE command that this writer will call + * internally to write data to the rowset's underlying data source. + * The method initSQLStatements builds this String + * object. + * + * @serial + */ + private String updateCmd; + +/** + * The SQL WHERE clause the writer will use for update + * statements in the PreparedStatement object + * it sends to the underlying data source. + * + * @serial + */ + private String updateWhere; + +/** + * The SQL DELETE command that this writer will call + * internally to delete a row in the rowset's underlying data source. + * + * @serial + */ + private String deleteCmd; + +/** + * The SQL WHERE clause the writer will use for delete + * statements in the PreparedStatement object + * it sends to the underlying data source. + * + * @serial + */ + private String deleteWhere; + +/** + * The SQL INSERT INTO command that this writer will internally use + * to insert data into the rowset's underlying data source. The method + * initSQLStatements builds this command with a question + * mark parameter placeholder for each column in the rowset. + * + * @serial + */ + private String insertCmd; + +/** + * An array containing the column numbers of the columns that are + * needed to uniquely identify a row in the CachedRowSet object + * for which this CachedRowSetWriter object is the writer. + * + * @serial + */ + private int[] keyCols; + +/** + * An array of the parameters that should be used to set the parameter + * placeholders in a PreparedStatement object that this + * writer will execute. + * + * @serial + */ + private Object[] params; + +/** + * The CachedRowSetReader object that has been + * set as the reader for the CachedRowSet object + * for which this CachedRowSetWriter object is the writer. + * + * @serial + */ + private CachedRowSetReader reader; + +/** + * The ResultSetMetaData object that contains information + * about the columns in the CachedRowSet object + * for which this CachedRowSetWriter object is the writer. + * + * @serial + */ + private ResultSetMetaData callerMd; + +/** + * The number of columns in the CachedRowSet object + * for which this CachedRowSetWriter object is the writer. + * + * @serial + */ + private int callerColumnCount; + +/** + * This CachedRowSet will hold the conflicting values + * retrieved from the db and hold it. + */ + private CachedRowSetImpl crsResolve; + +/** + * This ArrayList will hold the values of SyncResolver.* + */ + private ArrayList status; + +/** + * This will check whether the same field value has changed both + * in database and CachedRowSet. + */ + private int iChangedValsInDbAndCRS; + +/** + * This will hold the number of cols for which the values have + * changed only in database. + */ + private int iChangedValsinDbOnly ; + + private JdbcRowSetResourceBundle resBundle; + + public CachedRowSetWriter() { + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + } + +/** + * Propagates changes in the given RowSet object + * back to its underlying data source and returns true + * if successful. The writer will check to see if + * the data in the pre-modified rowset (the original values) differ + * from the data in the underlying data source. If data in the data + * source has been modified by someone else, there is a conflict, + * and in that case, the writer will not write to the data source. + * In other words, the writer uses an optimistic concurrency algorithm: + * It checks for conflicts before making changes rather than restricting + * access for concurrent users. + *

+ * This method is called by the rowset internally when + * the application invokes the method acceptChanges. + * The writeData method in turn calls private methods that + * it defines internally. + * The following is a general summary of what the method + * writeData does, much of which is accomplished + * through calls to its own internal methods. + *

    + *
  1. Creates a CachedRowSet object from the given + * RowSet object + *
  2. Makes a connection with the data source + *
      + *
    • Disables autocommit mode if it is not already disabled + *
    • Sets the transaction isolation level to that of the rowset + *
    + *
  3. Checks to see if the reader has read new data since the writer + * was last called and, if so, calls the method + * initSQLStatements to initialize new SQL statements + *
      + *
    • Builds new SELECT, UPDATE, + * INSERT, and DELETE statements + *
    • Uses the CachedRowSet object's metadata to + * determine the table name, column names, and the columns + * that make up the primary key + *
    + *
  4. When there is no conflict, propagates changes made to the + * CachedRowSet object back to its underlying data source + *
      + *
    • Iterates through each row of the CachedRowSet object + * to determine whether it has been updated, inserted, or deleted + *
    • If the corresponding row in the data source has not been changed + * since the rowset last read its + * values, the writer will use the appropriate command to update, + * insert, or delete the row + *
    • If any data in the data source does not match the original values + * for the CachedRowSet object, the writer will roll + * back any changes it has made to the row in the data source. + *
    + *
+ * + * @return true if changes to the rowset were successfully + * written to the rowset's underlying data source; + * false otherwise + */ + public boolean writeData(RowSetInternal caller) throws SQLException { + long conflicts = 0; + boolean showDel = false; + PreparedStatement pstmtIns = null; + iChangedValsInDbAndCRS = 0; + iChangedValsinDbOnly = 0; + + // We assume caller is a CachedRowSet + CachedRowSetImpl crs = (CachedRowSetImpl)caller; + // crsResolve = new CachedRowSetImpl(); + this.crsResolve = new CachedRowSetImpl();; + + // The reader is registered with the writer at design time. + // This is not required, in general. The reader has logic + // to get a JDBC connection, so call it. + + con = reader.connect(caller); + + + if (con == null) { + throw new SQLException(resBundle.handleGetObject("crswriter.connect").toString()); + } + + /* + // Fix 6200646. + // Don't change the connection or transaction properties. This will fail in a + // J2EE container. + if (con.getAutoCommit() == true) { + con.setAutoCommit(false); + } + + con.setTransactionIsolation(crs.getTransactionIsolation()); + */ + + initSQLStatements(crs); + int iColCount; + + RowSetMetaDataImpl rsmdWrite = (RowSetMetaDataImpl)crs.getMetaData(); + RowSetMetaDataImpl rsmdResolv = new RowSetMetaDataImpl(); + + iColCount = rsmdWrite.getColumnCount(); + int sz= crs.size()+1; + status = new ArrayList<>(sz); + + status.add(0,null); + rsmdResolv.setColumnCount(iColCount); + + for(int i =1; i <= iColCount; i++) { + rsmdResolv.setColumnType(i, rsmdWrite.getColumnType(i)); + rsmdResolv.setColumnName(i, rsmdWrite.getColumnName(i)); + rsmdResolv.setNullable(i, ResultSetMetaData.columnNullableUnknown); + } + this.crsResolve.setMetaData(rsmdResolv); + + // moved outside the insert inner loop + //pstmtIns = con.prepareStatement(insertCmd); + + if (callerColumnCount < 1) { + // No data, so return success. + if (reader.getCloseConnection() == true) + con.close(); + return true; + } + // We need to see rows marked for deletion. + showDel = crs.getShowDeleted(); + crs.setShowDeleted(true); + + // Look at all the rows. + crs.beforeFirst(); + + int rows =1; + while (crs.next()) { + if (crs.rowDeleted()) { + // The row has been deleted. + if (deleteOriginalRow(crs, this.crsResolve)) { + status.add(rows, SyncResolver.DELETE_ROW_CONFLICT); + conflicts++; + } else { + // delete happened without any occurrence of conflicts + // so update status accordingly + status.add(rows, SyncResolver.NO_ROW_CONFLICT); + } + + } else if (crs.rowInserted()) { + // The row has been inserted. + + pstmtIns = con.prepareStatement(insertCmd); + if (insertNewRow(crs, pstmtIns, this.crsResolve)) { + status.add(rows, SyncResolver.INSERT_ROW_CONFLICT); + conflicts++; + } else { + // insert happened without any occurrence of conflicts + // so update status accordingly + status.add(rows, SyncResolver.NO_ROW_CONFLICT); + } + } else if (crs.rowUpdated()) { + // The row has been updated. + if (updateOriginalRow(crs)) { + status.add(rows, SyncResolver.UPDATE_ROW_CONFLICT); + conflicts++; + } else { + // update happened without any occurrence of conflicts + // so update status accordingly + status.add(rows, SyncResolver.NO_ROW_CONFLICT); + } + + } else { + /** The row is neither of inserted, updated or deleted. + * So set nulls in the this.crsResolve for this row, + * as nothing is to be done for such rows. + * Also note that if such a row has been changed in database + * and we have not changed(inserted, updated or deleted) + * that is fine. + **/ + int icolCount = crs.getMetaData().getColumnCount(); + status.add(rows, SyncResolver.NO_ROW_CONFLICT); + + this.crsResolve.moveToInsertRow(); + for(int cols=0;colsCachedRowSet object's underlying data + * source so that updates to the rowset are reflected in the original + * data source, and returns false if the update was successful. + * A return value of true indicates that there is a conflict, + * meaning that a value updated in the rowset has already been changed by + * someone else in the underlying data source. A conflict can also exist + * if, for example, more than one row in the data source would be affected + * by the update or if no rows would be affected. In any case, if there is + * a conflict, this method does not update the underlying data source. + *

+ * This method is called internally by the method writeData + * if a row in the CachedRowSet object for which this + * CachedRowSetWriter object is the writer has been updated. + * + * @return false if the update to the underlying data source is + * successful; true otherwise + * @throws SQLException if a database access error occurs + */ + private boolean updateOriginalRow(CachedRowSet crs) + throws SQLException { + PreparedStatement pstmt; + int i = 0; + int idx = 0; + + // Select the row from the database. + ResultSet origVals = crs.getOriginalRow(); + origVals.next(); + + try { + updateWhere = buildWhereClause(updateWhere, origVals); + + + /** + * The following block of code is for checking a particular type of + * query where in there is a where clause. Without this block, if a + * SQL statement is built the "where" clause will appear twice hence + * the DB errors out and a SQLException is thrown. This code also + * considers that the where clause is in the right place as the + * CachedRowSet object would already have been populated with this + * query before coming to this point. + **/ + + + String tempselectCmd = selectCmd.toLowerCase(); + + int idxWhere = tempselectCmd.indexOf("where"); + + if(idxWhere != -1) + { + String tempSelect = selectCmd.substring(0,idxWhere); + selectCmd = tempSelect; + } + + pstmt = con.prepareStatement(selectCmd + updateWhere, + ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + + for (i = 0; i < keyCols.length; i++) { + if (params[i] != null) { + pstmt.setObject(++idx, params[i]); + } else { + continue; + } + } + + try { + pstmt.setMaxRows(crs.getMaxRows()); + pstmt.setMaxFieldSize(crs.getMaxFieldSize()); + pstmt.setEscapeProcessing(crs.getEscapeProcessing()); + pstmt.setQueryTimeout(crs.getQueryTimeout()); + } catch (Exception ex) { + // Older driver don't support these operations. + } + + ResultSet rs = null; + rs = pstmt.executeQuery(); + ResultSetMetaData rsmd = rs.getMetaData(); + + if (rs.next()) { + if (rs.next()) { + /** More than one row conflict. + * If rs has only one row we are able to + * uniquely identify the row where update + * have to happen else if more than one + * row implies we cannot uniquely identify the row + * where we have to do updates. + * crs.setKeyColumns needs to be set to + * come out of this situation. + */ + + return true; + } + + // don't close the rs + // we require the record in rs to be used. + // rs.close(); + // pstmt.close(); + rs.first(); + + // how many fields need to be updated + int colsNotChanged = 0; + Vector cols = new Vector<>(); + String updateExec = updateCmd; + Object orig; + Object curr; + Object rsval; + boolean boolNull = true; + Object objVal = null; + + // There's only one row and the cursor + // needs to be on that row. + + boolean first = true; + boolean flag = true; + + this.crsResolve.moveToInsertRow(); + + for (i = 1; i <= callerColumnCount; i++) { + orig = origVals.getObject(i); + curr = crs.getObject(i); + rsval = rs.getObject(i); + /* + * the following block creates equivalent objects + * that would have been created if this rs is populated + * into a CachedRowSet so that comparison of the column values + * from the ResultSet and CachedRowSet are possible + */ + Map> map = (crs.getTypeMap() == null)?con.getTypeMap():crs.getTypeMap(); + if (rsval instanceof Struct) { + + Struct s = (Struct)rsval; + + // look up the class in the map + Class c = null; + c = map.get(s.getSQLTypeName()); + if (c != null) { + // create new instance of the class + SQLData obj = null; + throw new SQLException("Unable to Instantiate: TODO from ReplicaDB"); + /*try { + //obj = (SQLData)ReflectUtil.newInstance(c); + } catch (Exception ex) { + throw new SQLException("Unable to Instantiate: ", ex); + } + // get the attributes from the struct + Object attribs[] = s.getAttributes(map); + // create the SQLInput "stream" + SQLInputImpl sqlInput = new SQLInputImpl(attribs, map); + // read the values... + obj.readSQL(sqlInput, s.getSQLTypeName()); + rsval = obj;*/ + } + } else if (rsval instanceof SQLData) { + rsval = new SerialStruct((SQLData)rsval, map); + } else if (rsval instanceof Blob) { + rsval = new SerialBlob((Blob)rsval); + } else if (rsval instanceof Clob) { + rsval = new SerialClob((Clob)rsval); + } else if (rsval instanceof Array) { + rsval = new SerialArray((Array)rsval, map); + } + + // reset boolNull if it had been set + boolNull = true; + + /** This addtional checking has been added when the current value + * in the DB is null, but the DB had a different value when the + * data was actaully fetched into the CachedRowSet. + **/ + + if(rsval == null && orig != null) { + // value in db has changed + // don't proceed with synchronization + // get the value in db and pass it to the resolver. + + iChangedValsinDbOnly++; + // Set the boolNull to false, + // in order to set the actual value; + boolNull = false; + objVal = rsval; + } + + /** Adding the checking for rsval to be "not" null or else + * it would through a NullPointerException when the values + * are compared. + **/ + + else if(rsval != null && (!rsval.equals(orig))) + { + // value in db has changed + // don't proceed with synchronization + // get the value in db and pass it to the resolver. + + iChangedValsinDbOnly++; + // Set the boolNull to false, + // in order to set the actual value; + boolNull = false; + objVal = rsval; + } else if ( (orig == null || curr == null) ) { + + /** Adding the additonal condition of checking for "flag" + * boolean variable, which would otherwise result in + * building a invalid query, as the comma would not be + * added to the query string. + **/ + + if (first == false || flag == false) { + updateExec += ", "; + } + updateExec += crs.getMetaData().getColumnName(i); + cols.add(i); + updateExec += " = ? "; + first = false; + + /** Adding the extra condition for orig to be "not" null as the + * condition for orig to be null is take prior to this, if this + * is not added it will result in a NullPointerException when + * the values are compared. + **/ + + } else if (orig.equals(curr)) { + colsNotChanged++; + //nothing to update in this case since values are equal + + /** Adding the extra condition for orig to be "not" null as the + * condition for orig to be null is take prior to this, if this + * is not added it will result in a NullPointerException when + * the values are compared. + **/ + + } else if(orig.equals(curr) == false) { + // When values from db and values in CachedRowSet are not equal, + // if db value is same as before updation for each col in + // the row before fetching into CachedRowSet, + // only then we go ahead with updation, else we + // throw SyncProviderException. + + // if value has changed in db after fetching from db + // for some cols of the row and at the same time, some other cols + // have changed in CachedRowSet, no synchronization happens + + // Synchronization happens only when data when fetching is + // same or at most has changed in cachedrowset + + // check orig value with what is there in crs for a column + // before updation in crs. + + if(crs.columnUpdated(i)) { + if(rsval.equals(orig)) { + // At this point we are sure that + // the value updated in crs was from + // what is in db now and has not changed + if (flag == false || first == false) { + updateExec += ", "; + } + updateExec += crs.getMetaData().getColumnName(i); + cols.add(i); + updateExec += " = ? "; + flag = false; + } else { + // Here the value has changed in the db after + // data was fetched + // Plus store this row from CachedRowSet and keep it + // in a new CachedRowSet + boolNull= false; + objVal = rsval; + iChangedValsInDbAndCRS++; + } + } + } + + if(!boolNull) { + this.crsResolve.updateObject(i,objVal); + } else { + this.crsResolve.updateNull(i); + } + } //end for + + rs.close(); + pstmt.close(); + + this.crsResolve.insertRow(); + this.crsResolve.moveToCurrentRow(); + + /** + * if nothing has changed return now - this can happen + * if column is updated to the same value. + * if colsNotChanged == callerColumnCount implies we are updating + * the database with ALL COLUMNS HAVING SAME VALUES, + * so skip going to database, else do as usual. + **/ + if ( (first == false && cols.size() == 0) || + colsNotChanged == callerColumnCount ) { + return false; + } + + if(iChangedValsInDbAndCRS != 0 || iChangedValsinDbOnly != 0) { + return true; + } + + + updateExec += updateWhere; + + pstmt = con.prepareStatement(updateExec); + + // Comments needed here + for (i = 0; i < cols.size(); i++) { + Object obj = crs.getObject(cols.get(i)); + if (obj != null) + pstmt.setObject(i + 1, obj); + else + pstmt.setNull(i + 1,crs.getMetaData().getColumnType(i + 1)); + } + idx = i; + + // Comments needed here + for (i = 0; i < keyCols.length; i++) { + if (params[i] != null) { + pstmt.setObject(++idx, params[i]); + } else { + continue; + } + } + + i = pstmt.executeUpdate(); + + /** + * i should be equal to 1(row count), because we update + * one row(returned as row count) at a time, if all goes well. + * if 1 != 1, this implies we have not been able to + * do updations properly i.e there is a conflict in database + * versus what is in CachedRowSet for this particular row. + **/ + + return false; + + } else { + /** + * Cursor will be here, if the ResultSet may not return even a single row + * i.e. we can't find the row where to update because it has been deleted + * etc. from the db. + * Present the whole row as null to user, to force null to be sync'ed + * and hence nothing to be synced. + * + * NOTE: + * ------ + * In the database if a column that is mapped to java.sql.Types.REAL stores + * a Double value and is compared with value got from ResultSet.getFloat() + * no row is retrieved and will throw a SyncProviderException. For details + * see bug Id 5053830 + **/ + return true; + } + } catch (SQLException ex) { + ex.printStackTrace(); + // if executeUpdate fails it will come here, + // update crsResolve with null rows + this.crsResolve.moveToInsertRow(); + + for(i = 1; i <= callerColumnCount; i++) { + this.crsResolve.updateNull(i); + } + + this.crsResolve.insertRow(); + this.crsResolve.moveToCurrentRow(); + + return true; + } + } + + /** + * Inserts a row that has been inserted into the given + * CachedRowSet object into the data source from which + * the rowset is derived, returning false if the insertion + * was successful. + * + * @param crs the CachedRowSet object that has had a row inserted + * and to whose underlying data source the row will be inserted + * @param pstmt the PreparedStatement object that will be used + * to execute the insertion + * @return false to indicate that the insertion was successful; + * true otherwise + * @throws SQLException if a database access error occurs + */ + private boolean insertNewRow(CachedRowSet crs, + PreparedStatement pstmt, CachedRowSetImpl crsRes) throws SQLException { + + boolean returnVal = false; + + try (PreparedStatement pstmtSel = con.prepareStatement(selectCmd, + ResultSet.TYPE_SCROLL_SENSITIVE, + ResultSet.CONCUR_READ_ONLY); + ResultSet rs = pstmtSel.executeQuery(); + ResultSet rs2 = con.getMetaData().getPrimaryKeys(null, null, + crs.getTableName()) + ) { + + ResultSetMetaData rsmd = crs.getMetaData(); + int icolCount = rsmd.getColumnCount(); + String[] primaryKeys = new String[icolCount]; + int k = 0; + while (rs2.next()) { + primaryKeys[k] = rs2.getString("COLUMN_NAME"); + k++; + } + + if (rs.next()) { + for (String pkName : primaryKeys) { + if (!isPKNameValid(pkName, rsmd)) { + + /* We came here as one of the the primary keys + * of the table is not present in the cached + * rowset object, it should be an autoincrement column + * and not included while creating CachedRowSet + * Object, proceed to check for other primary keys + */ + continue; + } + + Object crsPK = crs.getObject(pkName); + if (crsPK == null) { + /* + * It is possible that the PK is null on some databases + * and will be filled in at insert time (MySQL for example) + */ + break; + } + + String rsPK = rs.getObject(pkName).toString(); + if (crsPK.toString().equals(rsPK)) { + returnVal = true; + this.crsResolve.moveToInsertRow(); + for (int i = 1; i <= icolCount; i++) { + String colname = (rs.getMetaData()).getColumnName(i); + if (colname.equals(pkName)) + this.crsResolve.updateObject(i,rsPK); + else + this.crsResolve.updateNull(i); + } + this.crsResolve.insertRow(); + this.crsResolve.moveToCurrentRow(); + } + } + } + + if (returnVal) { + return returnVal; + } + + try { + for (int i = 1; i <= icolCount; i++) { + Object obj = crs.getObject(i); + if (obj != null) { + pstmt.setObject(i, obj); + } else { + pstmt.setNull(i,crs.getMetaData().getColumnType(i)); + } + } + + pstmt.executeUpdate(); + return false; + + } catch (SQLException ex) { + /* + * Cursor will come here if executeUpdate fails. + * There can be many reasons why the insertion failed, + * one can be violation of primary key. + * Hence we cannot exactly identify why the insertion failed, + * present the current row as a null row to the caller. + */ + this.crsResolve.moveToInsertRow(); + + for (int i = 1; i <= icolCount; i++) { + this.crsResolve.updateNull(i); + } + + this.crsResolve.insertRow(); + this.crsResolve.moveToCurrentRow(); + + return true; + } + } + } + +/** + * Deletes the row in the underlying data source that corresponds to + * a row that has been deleted in the given CachedRowSet object + * and returns false if the deletion was successful. + *

+ * This method is called internally by this writer's writeData + * method when a row in the rowset has been deleted. The values in the + * deleted row are the same as those that are stored in the original row + * of the given CachedRowSet object. If the values in the + * original row differ from the row in the underlying data source, the row + * in the data source is not deleted, and deleteOriginalRow + * returns true to indicate that there was a conflict. + * + * + * @return false if the deletion was successful, which means that + * there was no conflict; true otherwise + * @throws SQLException if there was a database access error + */ + private boolean deleteOriginalRow(CachedRowSet crs, CachedRowSetImpl crsRes) throws SQLException { + PreparedStatement pstmt; + int i; + int idx = 0; + String strSelect; + // Select the row from the database. + ResultSet origVals = crs.getOriginalRow(); + origVals.next(); + + deleteWhere = buildWhereClause(deleteWhere, origVals); + pstmt = con.prepareStatement(selectCmd + deleteWhere, + ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + + for (i = 0; i < keyCols.length; i++) { + if (params[i] != null) { + pstmt.setObject(++idx, params[i]); + } else { + continue; + } + } + + try { + pstmt.setMaxRows(crs.getMaxRows()); + pstmt.setMaxFieldSize(crs.getMaxFieldSize()); + pstmt.setEscapeProcessing(crs.getEscapeProcessing()); + pstmt.setQueryTimeout(crs.getQueryTimeout()); + } catch (Exception ex) { + /* + * Older driver don't support these operations... + */ + ; + } + + ResultSet rs = pstmt.executeQuery(); + + if (rs.next() == true) { + if (rs.next()) { + // more than one row + return true; + } + rs.first(); + + // Now check all the values in rs to be same in + // db also before actually going ahead with deleting + boolean boolChanged = false; + + crsRes.moveToInsertRow(); + + for (i = 1; i <= crs.getMetaData().getColumnCount(); i++) { + + Object original = origVals.getObject(i); + Object changed = rs.getObject(i); + + if(original != null && changed != null ) { + if(! (original.toString()).equals(changed.toString()) ) { + boolChanged = true; + crsRes.updateObject(i,origVals.getObject(i)); + } + } else { + crsRes.updateNull(i); + } + } + + crsRes.insertRow(); + crsRes.moveToCurrentRow(); + + if(boolChanged) { + // do not delete as values in db have changed + // deletion will not happen for this row from db + // exit now returning true. i.e. conflict + return true; + } else { + // delete the row. + // Go ahead with deleting, + // don't do anything here + } + + String cmd = deleteCmd + deleteWhere; + pstmt = con.prepareStatement(cmd); + + idx = 0; + for (i = 0; i < keyCols.length; i++) { + if (params[i] != null) { + pstmt.setObject(++idx, params[i]); + } else { + continue; + } + } + + if (pstmt.executeUpdate() != 1) { + return true; + } + pstmt.close(); + } else { + // didn't find the row + return true; + } + + // no conflict + return false; + } + + /** + * Sets the reader for this writer to the given reader. + * + * @throws SQLException if a database access error occurs + */ + public void setReader(CachedRowSetReader reader) throws SQLException { + this.reader = reader; + } + + /** + * Gets the reader for this writer. + * + * @throws SQLException if a database access error occurs + */ + public CachedRowSetReader getReader() throws SQLException { + return reader; + } + + /** + * Composes a SELECT, UPDATE, INSERT, + * and DELETE statement that can be used by this writer to + * write data to the data source backing the given CachedRowSet + * object. + * + * @ param caller a CachedRowSet object for which this + * CachedRowSetWriter object is the writer + * @throws SQLException if a database access error occurs + */ + private void initSQLStatements(CachedRowSet caller) throws SQLException { + + int i; + + callerMd = caller.getMetaData(); + callerColumnCount = callerMd.getColumnCount(); + if (callerColumnCount < 1) + // No data, so return. + return; + + /* + * If the RowSet has a Table name we should use it. + * This is really a hack to get round the fact that + * a lot of the jdbc drivers can't provide the tab. + */ + String table = caller.getTableName(); + if (table == null) { + /* + * attempt to build a table name using the info + * that the driver gave us for the first column + * in the source result set. + */ + table = callerMd.getTableName(1); + if (table == null || table.length() == 0) { + throw new SQLException(resBundle.handleGetObject("crswriter.tname").toString()); + } + } + String catalog = callerMd.getCatalogName(1); + String schema = callerMd.getSchemaName(1); + DatabaseMetaData dbmd = con.getMetaData(); + + /* + * Compose a SELECT statement. There are three parts. + */ + + // Project List + selectCmd = "SELECT "; + for (i=1; i <= callerColumnCount; i++) { + selectCmd += callerMd.getColumnName(i); + if ( i < callerMd.getColumnCount() ) + selectCmd += ", "; + else + selectCmd += " "; + } + + // FROM clause. + selectCmd += "FROM " + buildTableName(dbmd, catalog, schema, table); + + /* + * Compose an UPDATE statement. + */ + updateCmd = "UPDATE " + buildTableName(dbmd, catalog, schema, table); + + + /** + * The following block of code is for checking a particular type of + * query where in there is a where clause. Without this block, if a + * SQL statement is built the "where" clause will appear twice hence + * the DB errors out and a SQLException is thrown. This code also + * considers that the where clause is in the right place as the + * CachedRowSet object would already have been populated with this + * query before coming to this point. + **/ + + String tempupdCmd = updateCmd.toLowerCase(); + + int idxupWhere = tempupdCmd.indexOf("where"); + + if(idxupWhere != -1) + { + updateCmd = updateCmd.substring(0,idxupWhere); + } + updateCmd += "SET "; + + /* + * Compose an INSERT statement. + */ + insertCmd = "INSERT INTO " + buildTableName(dbmd, catalog, schema, table); + // Column list + insertCmd += "("; + for (i=1; i <= callerColumnCount; i++) { + insertCmd += callerMd.getColumnName(i); + if ( i < callerMd.getColumnCount() ) + insertCmd += ", "; + else + insertCmd += ") VALUES ("; + } + for (i=1; i <= callerColumnCount; i++) { + insertCmd += "?"; + if (i < callerColumnCount) + insertCmd += ", "; + else + insertCmd += ")"; + } + + /* + * Compose a DELETE statement. + */ + deleteCmd = "DELETE FROM " + buildTableName(dbmd, catalog, schema, table); + + /* + * set the key desriptors that will be + * needed to construct where clauses. + */ + buildKeyDesc(caller); + } + + /** + * Returns a fully qualified table name built from the given catalog and + * table names. The given metadata object is used to get the proper order + * and separator. + * + * @param dbmd a DatabaseMetaData object that contains metadata + * about this writer's CachedRowSet object + * @param catalog a String object with the rowset's catalog + * name + * @param table a String object with the name of the table from + * which this writer's rowset was derived + * @return a String object with the fully qualified name of the + * table from which this writer's rowset was derived + * @throws SQLException if a database access error occurs + */ + private String buildTableName(DatabaseMetaData dbmd, + String catalog, String schema, String table) throws SQLException { + + // trim all the leading and trailing whitespaces, + // white spaces can never be catalog, schema or a table name. + + String cmd = ""; + + catalog = catalog.trim(); + schema = schema.trim(); + table = table.trim(); + + if (dbmd.isCatalogAtStart() == true) { + if (catalog != null && catalog.length() > 0) { + cmd += catalog + dbmd.getCatalogSeparator(); + } + if (schema != null && schema.length() > 0) { + cmd += schema + "."; + } + cmd += table; + } else { + if (schema != null && schema.length() > 0) { + cmd += schema + "."; + } + cmd += table; + if (catalog != null && catalog.length() > 0) { + cmd += dbmd.getCatalogSeparator() + catalog; + } + } + cmd += " "; + return cmd; + } + + /** + * Assigns to the given CachedRowSet object's + * params + * field an array whose length equals the number of columns needed + * to uniquely identify a row in the rowset. The array is given + * values by the method buildWhereClause. + *

+ * If the CachedRowSet object's keyCols + * field has length 0 or is null, the array + * is set with the column number of every column in the rowset. + * Otherwise, the array in the field keyCols is set with only + * the column numbers of the columns that are required to form a unique + * identifier for a row. + * + * @param crs the CachedRowSet object for which this + * CachedRowSetWriter object is the writer + * + * @throws SQLException if a database access error occurs + */ + private void buildKeyDesc(CachedRowSet crs) throws SQLException { + + keyCols = crs.getKeyColumns(); + ResultSetMetaData resultsetmd = crs.getMetaData(); + if (keyCols == null || keyCols.length == 0) { + ArrayList listKeys = new ArrayList(); + + for (int i = 0; i < callerColumnCount; i++ ) { + if(resultsetmd.getColumnType(i+1) != Types.CLOB && + resultsetmd.getColumnType(i+1) != Types.STRUCT && + resultsetmd.getColumnType(i+1) != Types.SQLXML && + resultsetmd.getColumnType(i+1) != Types.BLOB && + resultsetmd.getColumnType(i+1) != Types.ARRAY && + resultsetmd.getColumnType(i+1) != Types.OTHER ) + listKeys.add(i+1); + } + keyCols = new int[listKeys.size()]; + for (int i = 0; i < listKeys.size(); i++ ) + keyCols[i] = listKeys.get(i); + } + params = new Object[keyCols.length]; + } + + /** + * Constructs an SQL WHERE clause using the given + * string as a starting point. The resulting clause will contain + * a column name and " = ?" for each key column, that is, each column + * that is needed to form a unique identifier for a row in the rowset. + * This WHERE clause can be added to + * a PreparedStatement object that updates, inserts, or + * deletes a row. + *

+ * This method uses the given result set to access values in the + * CachedRowSet object that called this writer. These + * values are used to build the array of parameters that will serve as + * replacements for the "?" parameter placeholders in the + * PreparedStatement object that is sent to the + * CachedRowSet object's underlying data source. + * + * @param whereClause a String object that is an empty + * string ("") + * @param rs a ResultSet object that can be used + * to access the CachedRowSet object's data + * @return a WHERE clause of the form "WHERE + * columnName = ? AND columnName = ? AND columnName = ? ..." + * @throws SQLException if a database access error occurs + */ + private String buildWhereClause(String whereClause, + ResultSet rs) throws SQLException { + whereClause = "WHERE "; + + for (int i = 0; i < keyCols.length; i++) { + if (i > 0) { + whereClause += "AND "; + } + whereClause += callerMd.getColumnName(keyCols[i]); + params[i] = rs.getObject(keyCols[i]); + if (rs.wasNull() == true) { + whereClause += " IS NULL "; + } else { + whereClause += " = ? "; + } + } + return whereClause; + } + + void updateResolvedConflictToDB(CachedRowSet crs, Connection con) throws SQLException { + //String updateExe = ; + PreparedStatement pStmt ; + String strWhere = "WHERE " ; + String strExec =" "; + String strUpdate = "UPDATE "; + int icolCount = crs.getMetaData().getColumnCount(); + int keyColumns[] = crs.getKeyColumns(); + Object param[]; + String strSet=""; + + strWhere = buildWhereClause(strWhere, crs); + + if (keyColumns == null || keyColumns.length == 0) { + keyColumns = new int[icolCount]; + for (int i = 0; i < keyColumns.length; ) { + keyColumns[i] = ++i; + } + } + param = new Object[keyColumns.length]; + + strUpdate = "UPDATE " + buildTableName(con.getMetaData(), + crs.getMetaData().getCatalogName(1), + crs.getMetaData().getSchemaName(1), + crs.getTableName()); + + // changed or updated values will become part of + // set clause here + strUpdate += "SET "; + + boolean first = true; + + for (int i=1; i<=icolCount;i++) { + if (crs.columnUpdated(i)) { + if (first == false) { + strSet += ", "; + } + strSet += crs.getMetaData().getColumnName(i); + strSet += " = ? "; + first = false; + } //end if + } //end for + + // keycols will become part of where clause + strUpdate += strSet; + strWhere = "WHERE "; + + for (int i = 0; i < keyColumns.length; i++) { + if (i > 0) { + strWhere += "AND "; + } + strWhere += crs.getMetaData().getColumnName(keyColumns[i]); + param[i] = crs.getObject(keyColumns[i]); + if (crs.wasNull() == true) { + strWhere += " IS NULL "; + } else { + strWhere += " = ? "; + } + } + strUpdate += strWhere; + + pStmt = con.prepareStatement(strUpdate); + + int idx =0; + for (int i = 0; i < icolCount; i++) { + if(crs.columnUpdated(i+1)) { + Object obj = crs.getObject(i+1); + if (obj != null) { + pStmt.setObject(++idx, obj); + } else { + pStmt.setNull(i + 1,crs.getMetaData().getColumnType(i + 1)); + } //end if ..else + } //end if crs.column... + } //end for + + // Set the key cols for after WHERE =? clause + for (int i = 0; i < keyColumns.length; i++) { + if (param[i] != null) { + pStmt.setObject(++idx, param[i]); + } + } + + int id = pStmt.executeUpdate(); + } + + + /** + * + */ + public void commit() throws SQLException { + con.commit(); + if (reader.getCloseConnection() == true) { + con.close(); + } + } + + public void commit(CachedRowSetImpl crs, boolean updateRowset) throws SQLException { + con.commit(); + if(updateRowset) { + if(crs.getCommand() != null) + crs.execute(con); + } + + if (reader.getCloseConnection() == true) { + con.close(); + } + } + + /** + * + */ + public void rollback() throws SQLException { + con.rollback(); + if (reader.getCloseConnection() == true) { + con.close(); + } + } + + /** + * + */ + public void rollback(Savepoint s) throws SQLException { + con.rollback(s); + if (reader.getCloseConnection() == true) { + con.close(); + } + } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + // Default state initialization happens here + ois.defaultReadObject(); + // Initialization of Res Bundle happens here . + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + } + + static final long serialVersionUID =-8506030970299413976L; + + /** + * Validate whether the Primary Key is known to the CachedRowSet. If it is + * not, it is an auto-generated key + * @param pk - Primary Key to validate + * @param rsmd - ResultSetMetadata for the RowSet + * @return true if found, false otherwise (auto generated key) + */ + private boolean isPKNameValid(String pk, ResultSetMetaData rsmd) throws SQLException { + boolean isValid = false; + int cols = rsmd.getColumnCount(); + for(int i = 1; i<= cols; i++) { + String colName = rsmd.getColumnClassName(i); + if(colName.equalsIgnoreCase(pk)) { + isValid = true; + break; + } + } + + return isValid; + } +} diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/internal/InsertRow.java b/src/main/java/org/replicadb/rowset/sun/rowset/internal/InsertRow.java new file mode 100644 index 0000000..37d3ca7 --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/internal/InsertRow.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset.internal; + +import org.replicadb.rowset.sun.rowset.JdbcRowSetResourceBundle; + +import javax.sql.RowSetMetaData; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.BitSet; + +/** + * A class used internally to manage a CachedRowSet object's + * insert row. This class keeps track of the number of columns in the + * insert row and which columns have had a value inserted. It provides + * methods for retrieving a column value, setting a column value, and finding + * out whether the insert row is complete. + */ +public class InsertRow extends BaseRow implements Serializable, Cloneable { + +/** + * An internal BitSet object used to keep track of the + * columns in this InsertRow object that have had a value + * inserted. + */ + private BitSet colsInserted; + +/** + * The number of columns in this InsertRow object. + */ + private int cols; + + private JdbcRowSetResourceBundle resBundle; + +/** + * Creates an InsertRow object initialized with the + * given number of columns, an array for keeping track of the + * original values in this insert row, and a + * BitSet object with the same number of bits as + * there are columns. + * + * @param numCols an int indicating the number of columns + * in this InsertRow object + */ + public InsertRow(int numCols) { + origVals = new Object[numCols]; + colsInserted = new BitSet(numCols); + cols = numCols; + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + } + +/** + * Sets the bit in this InsertRow object's internal + * BitSet object that corresponds to the specified column + * in this InsertRow object. Setting a bit indicates + * that a value has been set. + * + * @param col the number of the column to be marked as inserted; + * the first column is 1 + */ + protected void markColInserted(int col) { + colsInserted.set(col); + } + +/** + * Indicates whether this InsertRow object has a value + * for every column that cannot be null. + * @param RowSetMD the RowSetMetaData object for the + * CachedRowSet object that maintains this + * InsertRow object + * @return true if this InsertRow object is + * complete; false otherwise + * @throws SQLException if there is an error accessing data + */ + public boolean isCompleteRow(RowSetMetaData RowSetMD) throws SQLException { + for (int i = 0; i < cols; i++) { + if (colsInserted.get(i) == false && + RowSetMD.isNullable(i + 1) == + ResultSetMetaData.columnNoNulls) { + return false; + } + + } + return true; + } + +/** + * Clears all the bits in the internal BitSet object + * maintained by this InsertRow object. Clearing all the bits + * indicates that none of the columns have had a value inserted. + */ + public void initInsertRow() { + for (int i = 0; i < cols; i++) { + colsInserted.clear(i); + } + } + +/** + * Retrieves the value of the designated column in this + * InsertRow object. If no value has been inserted + * into the designated column, this method throws an + * SQLException. + * + * @param idx the column number of the value to be retrieved; + * the first column is 1 + * @throws SQLException if no value has been inserted into + * the designated column + */ + public Object getColumnObject(int idx) throws SQLException { + if (colsInserted.get(idx - 1) == false) { + throw new SQLException(resBundle.handleGetObject("insertrow.novalue").toString()); + } + return (origVals[idx - 1]); + } + +/** + * Sets the element in this InsertRow object's + * internal array of original values that corresponds to the + * designated column with the given value. If the third + * argument is true, + * which means that the cursor is on the insert row, this + * InsertRow object's internal BitSet object + * is set so that the bit corresponding to the column being set is + * turned on. + * + * @param idx the number of the column in the insert row to be set; + * the first column is 1 + * @param val the value to be set + */ + public void setColumnObject(int idx, Object val) { + origVals[idx - 1] = val; + markColInserted(idx - 1); + } + + /** + * This method re populates the resBundle + * during the deserialization process + * + */ + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + // Default state initialization happens here + ois.defaultReadObject(); + // Initialization of transient Res Bundle happens here . + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + } + + static final long serialVersionUID = 1066099658102869344L; +} diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/internal/Row.java b/src/main/java/org/replicadb/rowset/sun/rowset/internal/Row.java new file mode 100644 index 0000000..f9bb65f --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/internal/Row.java @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset.internal; + +import java.io.Serializable; +import java.sql.SQLException; +import java.util.BitSet; + +/** + * A class that keeps track of a row's values. A Row object + * maintains an array of current column values and an array of original + * column values, and it provides methods for getting and setting the + * value of a column. It also keeps track of which columns have + * changed and whether the change was a delete, insert, or update. + *

+ * Note that column numbers for rowsets start at 1, + * whereas the first element of an array or bitset is 0. + * The argument for the method getColumnUpdated refers to + * the column number in the rowset (the first column is 1); + * the argument for setColumnUpdated refers to the index + * into the rowset's internal bitset (the first bit is 0). + */ +public class Row extends BaseRow implements Serializable, Cloneable { + +static final long serialVersionUID = 5047859032611314762L; + +/** + * An array containing the current column values for this Row + * object. + * @serial + */ + private Object[] currentVals; + +/** + * A BitSet object containing a flag for each column in + * this Row object, with each flag indicating whether or + * not the value in the column has been changed. + * @serial + */ + private BitSet colsChanged; + +/** + * A boolean indicating whether or not this Row + * object has been deleted. true indicates that it has + * been deleted; false indicates that it has not. + * @serial + */ + private boolean deleted; + +/** + * A boolean indicating whether or not this Row + * object has been updated. true indicates that it has + * been updated; false indicates that it has not. + * @serial + */ + private boolean updated; + +/** + * A boolean indicating whether or not this Row + * object has been inserted. true indicates that it has + * been inserted; false indicates that it has not. + * @serial + */ + private boolean inserted; + +/** + * The number of columns in this Row object. + * @serial + */ + private int numCols; + +/** + * Creates a new Row object with the given number of columns. + * The newly-created row includes an array of original values, + * an array for storing its current values, and a BitSet + * object for keeping track of which column values have been changed. + */ + public Row(int numCols) { + origVals = new Object[numCols]; + currentVals = new Object[numCols]; + colsChanged = new BitSet(numCols); + this.numCols = numCols; + } + +/** + * Creates a new Row object with the given number of columns + * and with its array of original values initialized to the given array. + * The new Row object also has an array for storing its + * current values and a BitSet object for keeping track + * of which column values have been changed. + */ + public Row(int numCols, Object[] vals) { + origVals = new Object[numCols]; + System.arraycopy(vals, 0, origVals, 0, numCols); + currentVals = new Object[numCols]; + colsChanged = new BitSet(numCols); + this.numCols = numCols; + } + +/** + * + * This method is called internally by the CachedRowSet.populate + * methods. + * + * @param idx the number of the column in this Row object + * that is to be set; the index of the first column is + * 1 + * @param val the new value to be set + */ + public void initColumnObject(int idx, Object val) { + origVals[idx - 1] = val; + } + + +/** + * + * This method is called internally by the CachedRowSet.updateXXX + * methods. + * + * @param idx the number of the column in this Row object + * that is to be set; the index of the first column is + * 1 + * @param val the new value to be set + */ + public void setColumnObject(int idx, Object val) { + currentVals[idx - 1] = val; + setColUpdated(idx - 1); + } + +/** + * Retrieves the column value stored in the designated column of this + * Row object. + * + * @param columnIndex the index of the column value to be retrieved; + * the index of the first column is 1 + * @return an Object in the Java programming language that + * represents the value stored in the designated column + * @throws SQLException if there is a database access error + */ + public Object getColumnObject(int columnIndex) throws SQLException { + if (getColUpdated(columnIndex - 1)) { + return(currentVals[columnIndex - 1]); // maps to array!! + } else { + return(origVals[columnIndex - 1]); // maps to array!! + } + } + +/** + * Indicates whether the designated column of this Row object + * has been changed. + * @param idx the index into the BitSet object maintained by + * this Row object to keep track of which column + * values have been modified; the index of the first bit is + * 0 + * @return true if the designated column value has been changed; + * false otherwise + * + */ + public boolean getColUpdated(int idx) { + return colsChanged.get(idx); + } + +/** + * Sets this Row object's deleted field + * to true. + * + * @see #getDeleted + */ + public void setDeleted() { // %%% was public + deleted = true; + } + + +/** + * Retrieves the value of this Row object's deleted field, + * which will be true if one or more of its columns has been + * deleted. + * @return true if a column value has been deleted; false + * otherwise + * + * @see #setDeleted + */ + public boolean getDeleted() { + return(deleted); + } + +/** + * Sets the deleted field for this Row object to + * false. + */ + public void clearDeleted() { + deleted = false; + } + + +/** + * Sets the value of this Row object's inserted field + * to true. + * + * @see #getInserted + */ + public void setInserted() { + inserted = true; + } + + +/** + * Retrieves the value of this Row object's inserted field, + * which will be true if this row has been inserted. + * @return true if this row has been inserted; false + * otherwise + * + * @see #setInserted + */ + public boolean getInserted() { + return(inserted); + } + + +/** + * Sets the inserted field for this Row object to + * false. + */ + public void clearInserted() { // %%% was public + inserted = false; + } + +/** + * Retrieves the value of this Row object's + * updated field. + * @return true if this Row object has been + * updated; false if it has not + * + * @see #setUpdated + */ + public boolean getUpdated() { + return(updated); + } + +/** + * Sets the updated field for this Row object to + * true if one or more of its column values has been changed. + * + * @see #getUpdated + */ + public void setUpdated() { + // only mark something as updated if one or + // more of the columns has been changed. + for (int i = 0; i < numCols; i++) { + if (getColUpdated(i) == true) { + updated = true; + return; + } + } + } + +/** + * Sets the bit at the given index into this Row object's internal + * BitSet object, indicating that the corresponding column value + * (column idx + 1) has been changed. + * + * @param idx the index into the BitSet object maintained by + * this Row object; the first bit is at index + * 0 + * + */ + private void setColUpdated(int idx) { + colsChanged.set(idx); + } + +/** + * Sets the updated field for this Row object to + * false, sets all the column values in this Row + * object's internal array of current values to null, and clears + * all of the bits in the BitSet object maintained by this + * Row object. + */ + public void clearUpdated() { + updated = false; + for (int i = 0; i < numCols; i++) { + currentVals[i] = null; + colsChanged.clear(i); + } + } + + /** + * Sets the column values in this Row object's internal + * array of original values with the values in its internal array of + * current values, sets all the values in this Row + * object's internal array of current values to null, + * clears all the bits in this Row object's internal bitset, + * and sets its updated field to false. + *

+ * This method is called internally by the CachedRowSet + * method makeRowOriginal. + */ + public void moveCurrentToOrig() { + for (int i = 0; i < numCols; i++) { + if (getColUpdated(i) == true) { + origVals[i] = currentVals[i]; + currentVals[i] = null; + colsChanged.clear(i); + } + } + updated = false; + } + + /** + * Returns the row on which the cursor is positioned. + * + * @return the Row object on which the CachedRowSet + * implementation objects's cursor is positioned + */ + public BaseRow getCurrentRow() { + return null; + } +} diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/internal/SyncResolverImpl.java b/src/main/java/org/replicadb/rowset/sun/rowset/internal/SyncResolverImpl.java new file mode 100644 index 0000000..78ca3ca --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/internal/SyncResolverImpl.java @@ -0,0 +1,4873 @@ +/* + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset.internal; + +import org.replicadb.rowset.sun.rowset.CachedRowSetImpl; +import org.replicadb.rowset.sun.rowset.JdbcRowSetResourceBundle; + +import javax.sql.*; +import javax.sql.rowset.CachedRowSet; +import javax.sql.rowset.RowSetMetaDataImpl; +import javax.sql.rowset.RowSetWarning; +import javax.sql.rowset.spi.SyncFactory; +import javax.sql.rowset.spi.SyncProvider; +import javax.sql.rowset.spi.SyncProviderException; +import javax.sql.rowset.spi.SyncResolver; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.math.BigDecimal; +import java.sql.*; +import java.util.*; + +/** + * There will be two sets of data which will be maintained by the rowset at the + * time of synchronization. The SyncProvider will utilize the + * SyncResolver to synchronize the changes back to database. + */ +public class SyncResolverImpl extends CachedRowSetImpl implements SyncResolver { + /** + * This CachedRowSet object will encapsulate a rowset + * which will be sync'ed with the datasource but will + * contain values in rows where there is conflict. + * For rows other than conflict, it will *not* contain + * any data. For rows containing conflict it will + * return either of the three values set by SyncResolver.*_CONFLICT + * from getStatus() + */ + private CachedRowSetImpl crsRes; + + /** + * This is the actual CachedRowSet object + * which is being synchronized back to + * datasource. + */ + private CachedRowSetImpl crsSync; + + /** + * This ArrayList will contain the status of a row + * from the SyncResolver.* values else it will be null. + */ + private ArrayList stats; + + /** + * The RowSetWriter associated with the original + * CachedRowSet object which is being synchronized. + */ + private CachedRowSetWriter crw; + + /** + * Row number identifier + */ + private int rowStatus; + + /** + * This will contain the size of the CachedRowSet object + */ + private int sz; + + /** + * The Connection handle used to synchronize the changes + * back to datasource. This is the same connection handle as was passed + * to the CachedRowSet while fetching the data. + */ + private transient Connection con; + + /** + * The CachedRowSet object which will encapsulate + * a row at any time. This will be built from CachedRowSet and + * SyncResolver values. Synchronization takes place on a row by + * row basis encapsulated as a CahedRowSet. + */ + private CachedRowSet row; + + private JdbcRowSetResourceBundle resBundle; + + /** + * Public constructor + */ + public SyncResolverImpl() throws SQLException { + try { + crsSync = new CachedRowSetImpl(); + crsRes = new CachedRowSetImpl(); + crw = new CachedRowSetWriter(); + row = new CachedRowSetImpl(); + rowStatus = 1; + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + } catch(SQLException sqle) { + } + } + + + /** + * Retrieves the conflict status of the current row of this + * SyncResolver, which indicates the operationthe RowSet + * object was attempting when the conflict occurred. + * + * @return one of the following constants: + * SyncResolver.UPDATE_ROW_CONFLICT, + * SyncResolver.DELETE_ROW_CONFLICT, or + * SyncResolver.INSERT_ROW_CONFLICT + */ + public int getStatus() { + return ((Integer)stats.get(rowStatus-1)).intValue(); + } + + /** + * Retrieves the value in the designated column in the current row of this + * SyncResolver object, which is the value that caused a conflict. + * + * @param index int designating the column in this row of this + * SyncResolver object from which to retrieve the value + * causing a conflict + */ + public Object getConflictValue(int index) throws SQLException { + try { + return crsRes.getObject(index); + } catch(SQLException sqle) { + throw new SQLException(sqle.getMessage()); + } + } + + /** + * Retrieves the value in the designated column in the current row of this + * SyncResolver object, which is the value that caused a conflict. + * + * @param columnName a String object designating the column in this row of this + * SyncResolver object from which to retrieve the value + * causing a conflict + */ + public Object getConflictValue(String columnName) throws SQLException { + try { + return crsRes.getObject(columnName); + } catch(SQLException sqle) { + throw new SQLException(sqle.getMessage()); + } + } + + /** + * Sets obj as the value in column index in the current row of the + * RowSet object. This value is the resolved value that is to be + * persisted in the data source. + * + * @param index an int giving the number of the column into which to + * set the value to be persisted + * @param obj an Object that is the value to be set in the data source + */ + public void setResolvedValue(int index, Object obj) throws SQLException { + // modify method to throw SQLException in spec + + /** + * When a value is resolved properly make it to null + * inside crsRes for that column. + * + * For more than one conflicts in the row, + * check for the last resolved value of the current row + * (Note: it can be resolved randomly for same row) + * then sync back immediately. + **/ + try { + // check whether the index is in range + if(index<=0 || index > crsSync.getMetaData().getColumnCount() ) { + throw new SQLException(resBundle.handleGetObject("syncrsimpl.indexval").toString()+ index); + } + // check whether index col is in conflict + if(crsRes.getObject(index) == null) { + throw new SQLException(resBundle.handleGetObject("syncrsimpl.noconflict").toString()); + } + } catch (SQLException sqle) { + // modify method to throw for SQLException + throw new SQLException(sqle.getMessage()); + } + try { + boolean bool = true; + /** Check resolved value to be either of conflict + * or in rowset else throw sql exception. + * If we allow a value other than that in CachedRowSet or + * datasource we will end up in looping the loop of exceptions. + **/ + + if( ((crsSync.getObject(index)).toString()).equals(obj.toString()) || + ((crsRes.getObject(index)).toString()).equals(obj.toString()) ) { + + /** + * Check whether this is the only conflict in the row. + * If yes, synchronize this row back + * which has been resolved, else wait + * for all conflicts of current row to be resolved + * + * Step 1: Update crsRes and make the index col as null + * i.e. resolved + * crsRes.updateObject(index, obj); + **/ + crsRes.updateNull(index); + crsRes.updateRow(); + + /** + * Step 2: Change the value in the CachedRowSetImpl object + * crsSync.updateObject(index, obj); + * crsSync.updateRow(); + **/ + if(row.size() != 1) { + row = buildCachedRow(); + } + + row.updateObject(index, obj); + row.updateRow(); + + for(int j=1; j < crsRes.getMetaData().getColumnCount(); j++) { + if(crsRes.getObject(j) != null) { + bool = false; + break; + // break out of loop and wait for other cols + // in same row to get resolved + } //end if + + } //end for + + if(bool) { + /** + * sync data back using CachedRowSetWriter + * construct the present row and pass it to the writer + * to write back to db. + **/ + try { + /** + * Note : The use of CachedRowSetWriter to get *same* Connection handle. + * The CachedRowSetWriter uses the connection handle + * from the reader, Hence will use the same connection handle + * as of original CachedRowSetImpl + **/ + + writeData(row); + + //crw.writeData( (RowSetInternal)crsRow); + //System.out.printlnt.println("12"); + + } catch(SyncProviderException spe) { + /** + * This will occur if db is not allowing + * even after resolving the conflicts + * due to some reasons. + * Also will prevent from going into a loop of SPE's + **/ + throw new SQLException(resBundle.handleGetObject("syncrsimpl.syncnotpos").toString()); + } + } //end if(bool) + + } else { + throw new SQLException(resBundle.handleGetObject("syncrsimpl.valtores").toString()); + } //end if (crs.getObject ...) block + + + } catch(SQLException sqle) { + throw new SQLException(sqle.getMessage()); + } + } + + /** + * This passes a CachedRowSet as a row the the CachedRowSetWriter + * after the values have been resolved, back to the datasource. + * + * @param row a CachedRowSet object which will hold the + * values of a particular row after they have been resolved by + * the user to synchronize back to datasource. + * @throws SQLException if synchronization does not happen properly + * maybe beacuse Connection has timed out. + **/ + private void writeData(CachedRowSet row) throws SQLException { + crw.updateResolvedConflictToDB(row, crw.getReader().connect((RowSetInternal)crsSync)); + } + + /** + * This function builds a row as a CachedRowSet object + * which has been resolved and is ready to be synchrinized to the datasource + * + * @throws SQLException if there is problem in building + * the metadata of the row. + **/ + private CachedRowSet buildCachedRow() throws SQLException { + int iColCount; + CachedRowSetImpl crsRow = new CachedRowSetImpl(); + + RowSetMetaDataImpl rsmd = new RowSetMetaDataImpl(); + RowSetMetaDataImpl rsmdWrite = (RowSetMetaDataImpl)crsSync.getMetaData(); + RowSetMetaDataImpl rsmdRow = new RowSetMetaDataImpl(); + + iColCount = rsmdWrite.getColumnCount(); + rsmdRow.setColumnCount(iColCount); + + for(int i =1;i<=iColCount;i++) { + rsmdRow.setColumnType(i,rsmdWrite.getColumnType(i)); + rsmdRow.setColumnName(i,rsmdWrite.getColumnName(i)); + rsmdRow.setNullable(i,ResultSetMetaData.columnNullableUnknown); + + try { + rsmdRow.setCatalogName(i, rsmdWrite.getCatalogName(i)); + rsmdRow.setSchemaName(i, rsmdWrite.getSchemaName(i)); + } catch(SQLException e) { + e.printStackTrace(); + } + } //end for + + crsRow.setMetaData(rsmdRow); + + crsRow.moveToInsertRow(); + + for(int col=1;col<=crsSync.getMetaData().getColumnCount();col++) { + crsRow.updateObject(col, crsSync.getObject(col)); + } + + crsRow.insertRow(); + crsRow.moveToCurrentRow(); + + crsRow.absolute(1); + crsRow.setOriginalRow(); + + try { + crsRow.setUrl(crsSync.getUrl()); + } catch(SQLException sqle) { + + } + + try { + crsRow.setDataSourceName(crsSync.getCommand()); + } catch(SQLException sqle) { + + } + + try { + if(crsSync.getTableName()!= null){ + crsRow.setTableName(crsSync.getTableName()); + } + } catch(SQLException sqle) { + + } + + try { + if(crsSync.getCommand() != null) + crsRow.setCommand(crsSync.getCommand()); + } catch(SQLException sqle) { + + } + + try { + crsRow.setKeyColumns(crsSync.getKeyColumns()); + } catch(SQLException sqle) { + + } + return crsRow; + } + + + + /** + * Sets obj as the value in column columnName in the current row of the + * RowSet object. This value is the resolved value that is to be + * persisted in the data source. + * + * @param columnName a String object giving the name of the column + * into which to set the value to be persisted + * @param obj an Object that is the value to be set in the data source + */ + public void setResolvedValue(String columnName, Object obj) throws SQLException { + // modify method to throw SQLException in spec + // %%% Missing implementation! + } + + /** + * This function is package private, + * i.e. cannot be accesses outside this package. + * This is used to set the actual CachedRowSet + * which is being synchronized to the database + **/ + void setCachedRowSet(CachedRowSet crs) { + crsSync = (CachedRowSetImpl)crs; + } + + /** + * This function is package private, + * i.e. cannot be accesses outside this package. + * This is used to set the CachedRowSet formed + * with conflict values. + **/ + void setCachedRowSetResolver(CachedRowSet crs){ + try { + crsRes = (CachedRowSetImpl)crs; + crsRes.afterLast(); + sz = crsRes.size(); + } catch (SQLException sqle) { + // do nothing + } + } + + /** + * This function is package private, + * i.e. cannot be accesses outside this package. + * This is used to set the status of each row + * to either of the values SyncResolver.*_CONFLICT + **/ + @SuppressWarnings("rawtypes") + void setStatus(ArrayList status){ + stats = status; + } + + /** + * This function is package private, + * i.e. cannot be accesses outside this package. + * This is used to set the handle to the writer object + * which will write the resolved values back to datasource + **/ + void setCachedRowSetWriter(CachedRowSetWriter CRWriter) { + crw = CRWriter; + } + + /** + * Moves the cursor down one row from its current position. A SyncResolver + * cursor is initially positioned before the first conflict row; the first call to the + * method nextConflict() makes the first conflict row the current row; + * the second call makes the second conflict row the current row, and so on. + *

+ * If an input stream is open for the current row, a call to the method next will + * implicitly close it. A SyncResolver object's warning chain is cleared + * when a new row + * + * @return true if the new current row is valid; false if there are no more rows + * @throws SQLException if a database access occurs + * + */ + public boolean nextConflict() throws SQLException { + /** + * The next() method will hop from + * one conflict to another + * + * Internally do a crs.next() until + * next conflict. + **/ + boolean bool = false; + + crsSync.setShowDeleted(true); + while(crsSync.next()) { + crsRes.previous(); + rowStatus++; //sz--; + + if((rowStatus-1) >= stats.size()) { + bool = false; + break; + } + + if(((Integer)stats.get(rowStatus-1)).intValue() == SyncResolver.NO_ROW_CONFLICT) { + // do nothing + // bool remains as false + ; + } else { + bool = true; + break; + } //end if + + } //end while + + crsSync.setShowDeleted(false); + return bool; + } // end next() method + + + /** + * Moves the cursor to the previous conflict row in this SyncResolver object. + * + * @return true if the cursor is on a valid row; false + * if it is off the result set + * @throws SQLException if a database access error occurs or the result set type + * is TYPE_FORWARD_ONLY + */ + public boolean previousConflict() throws SQLException { + throw new UnsupportedOperationException(); + } + + //----------------------------------------------------------------------- + // Properties + //----------------------------------------------------------------------- + + /** + * Sets this CachedRowSetImpl object's command property + * to the given String object and clears the parameters, + * if any, that were set for the previous command. + *

+ * The command property may not be needed + * if the rowset is produced by a data source, such as a spreadsheet, + * that does not support commands. Thus, this property is optional + * and may be null. + * + * @param cmd a String object containing an SQL query + * that will be set as the command; may be null + * @throws SQLException if an error occurs + */ + public void setCommand(String cmd) throws SQLException { + throw new UnsupportedOperationException(); + } + + + //--------------------------------------------------------------------- + // Reading and writing data + //--------------------------------------------------------------------- + + /** + * Populates this CachedRowSetImpl object with data from + * the given ResultSet object. This + * method is an alternative to the method execute + * for filling the rowset with data. The method populate + * does not require that the properties needed by the method + * execute, such as the command property, + * be set. This is true because the method populate + * is given the ResultSet object from + * which to get data and thus does not need to use the properties + * required for setting up a connection and executing this + * CachedRowSetImpl object's command. + *

+ * After populating this rowset with data, the method + * populate sets the rowset's metadata and + * then sends a RowSetChangedEvent object + * to all registered listeners prior to returning. + * + * @param data the ResultSet object containing the data + * to be read into this CachedRowSetImpl object + * @throws SQLException if an error occurs; or the max row setting is + * violated while populating the RowSet + * @see #execute + */ + public void populate(ResultSet data) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Populates this CachedRowSetImpl object with data, + * using the given connection to produce the result set from + * which data will be read. A second form of this method, + * which takes no arguments, uses the values from this rowset's + * user, password, and either url or data source properties to + * create a new database connection. The form of execute + * that is given a connection ignores these properties. + * + * @param conn A standard JDBC Connection object that this + * CachedRowSet object can pass to a synchronization provider + * to establish a connection to the data source + * @throws SQLException if an invalid Connection is supplied + * or an error occurs in establishing the connection to the + * data source + * @see #populate + * @see Connection + */ + public void execute(Connection conn) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Propagates all row update, insert, and delete changes to the + * underlying data source backing this CachedRowSetImpl + * object. + *

+ * NoteIn the reference implementation an optimistic concurrency implementation + * is provided as a sample implementation of a the SyncProvider + * abstract class. + *

+ * This method fails if any of the updates cannot be propagated back + * to the data source. When it fails, the caller can assume that + * none of the updates are reflected in the data source. + * When an exception is thrown, the current row + * is set to the first "updated" row that resulted in an exception + * unless the row that caused the exception is a "deleted" row. + * In that case, when deleted rows are not shown, which is usually true, + * the current row is not affected. + *

+ * If no SyncProvider is configured, the reference implementation + * leverages the RIOptimisticProvider available which provides the + * default and reference synchronization capabilities for disconnected + * RowSets. + * + * @throws SQLException if the cursor is on the insert row or the underlying + * reference synchronization provider fails to commit the updates + * to the datasource + * @throws SyncProviderException if an internal error occurs within the + * SyncProvider instance during either during the + * process or at any time when the SyncProvider + * instance touches the data source. + * @see #acceptChanges(Connection) + * @see RowSetWriter + * @see SyncProvider + */ + public void acceptChanges() throws SyncProviderException { + throw new UnsupportedOperationException(); + } + + /** + * Propagates all row update, insert, and delete changes to the + * data source backing this CachedRowSetImpl object + * using the given Connection object. + *

+ * The reference implementation RIOptimisticProvider + * modifies its synchronization to a write back function given + * the updated connection + * The reference implementation modifies its synchronization behaviour + * via the SyncProvider to ensure the synchronization + * occurs according to the updated JDBC Connection + * properties. + * + * @param con a standard JDBC Connection object + * @throws SQLException if the cursor is on the insert row or the underlying + * synchronization provider fails to commit the updates + * back to the data source + * @see #acceptChanges + * @see RowSetWriter + * @see SyncFactory + * @see SyncProvider + */ + public void acceptChanges(Connection con) throws SyncProviderException{ + throw new UnsupportedOperationException(); + } + + /** + * Restores this CachedRowSetImpl object to its original state, + * that is, its state before the last set of changes. + *

+ * Before returning, this method moves the cursor before the first row + * and sends a rowSetChanged event to all registered + * listeners. + * @throws SQLException if an error is occurs rolling back the RowSet + * state to the definied original value. + * @see RowSetListener#rowSetChanged + */ + public void restoreOriginal() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Releases the current contents of this CachedRowSetImpl + * object and sends a rowSetChanged event object to all + * registered listeners. + * + * @throws SQLException if an error occurs flushing the contents of + * RowSet. + * @see RowSetListener#rowSetChanged + */ + public void release() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Cancels deletion of the current row and notifies listeners that + * a row has changed. + *

+ * Note: This method can be ignored if deleted rows are not being shown, + * which is the normal case. + * + * @throws SQLException if the cursor is not on a valid row + */ + public void undoDelete() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Immediately removes the current row from this + * CachedRowSetImpl object if the row has been inserted, and + * also notifies listeners the a row has changed. An exception is thrown + * if the row is not a row that has been inserted or the cursor is before + * the first row, after the last row, or on the insert row. + *

+ * This operation cannot be undone. + * + * @throws SQLException if an error occurs, + * the cursor is not on a valid row, + * or the row has not been inserted + */ + public void undoInsert() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Immediately reverses the last update operation if the + * row has been modified. This method can be + * called to reverse updates on a all columns until all updates in a row have + * been rolled back to their originating state since the last synchronization + * (acceptChanges) or population. This method may also be called + * while performing updates to the insert row. + *

+ * undoUpdateRowSet object backed by the same data as + * that of this CachedRowSetImpl object and sharing a set of cursors + * with it. This allows cursors to interate over a shared set of rows, providing + * multiple views of the underlying data. + * + * @return a RowSet object that is a copy of this CachedRowSetImpl + * object and shares a set of cursors with it + * @throws SQLException if an error occurs or cloning is + * not supported + * @see RowSetEvent + * @see RowSetListener + */ + public RowSet createShared() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns a new RowSet object containing by the same data + * as this CachedRowSetImpl object. This method + * differs from the method createCopy in that it throws a + * CloneNotSupportedException object instead of an + * SQLException object, as the method createShared + * does. This clone + * method is called internally by the method createShared, + * which catches the CloneNotSupportedException object + * and in turn throws a new SQLException object. + * + * @return a copy of this CachedRowSetImpl object + * @throws CloneNotSupportedException if an error occurs when + * attempting to clone this CachedRowSetImpl object + * @see #createShared + */ + protected Object clone() throws CloneNotSupportedException { + throw new UnsupportedOperationException(); + } + + /** + * Creates a RowSet object that is a deep copy of + * this CachedRowSetImpl object's data, including + * constraints. Updates made + * on a copy are not visible to the original rowset; + * a copy of a rowset is completely independent from the original. + *

+ * Making a copy saves the cost of creating an identical rowset + * from first principles, which can be quite expensive. + * For example, it can eliminate the need to query a + * remote database server. + * @return a new CachedRowSet object that is a deep copy + * of this CachedRowSet object and is + * completely independent from this CachedRowSetImpl + * object. + * @throws SQLException if an error occurs in generating the copy of this + * of the CachedRowSetImpl + * @see #createShared + * @see RowSetEvent + * @see RowSetListener + */ + public CachedRowSet createCopy() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Creates a RowSet object that is a copy of + * this CachedRowSetImpl object's table structure + * and the constraints only. + * There will be no data in the object being returned. + * Updates made on a copy are not visible to the original rowset. + *

+ * This helps in getting the underlying XML schema which can + * be used as the basis for populating a WebRowSet. + * + * @return a new CachedRowSet object that is a copy + * of this CachedRowSetImpl object's schema and + * retains all the constraints on the original rowset but contains + * no data + * @throws SQLException if an error occurs in generating the copy + * of the CachedRowSet object + * @see #createShared + * @see #createCopy + * @see #createCopyNoConstraints + * @see RowSetEvent + * @see RowSetListener + */ + public CachedRowSet createCopySchema() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Creates a CachedRowSet object that is a copy of + * this CachedRowSetImpl object's data only. + * All constraints set in this object will not be there + * in the returning object. Updates made + * on a copy are not visible to the original rowset. + * + * @return a new CachedRowSet object that is a deep copy + * of this CachedRowSetImpl object and is + * completely independent from this CachedRowSetImpl object + * @throws SQLException if an error occurs in generating the copy of the + * of the CachedRowSet + * @see #createShared + * @see #createCopy + * @see #createCopySchema + * @see RowSetEvent + * @see RowSetListener + */ + public CachedRowSet createCopyNoConstraints() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Converts this CachedRowSetImpl object to a collection + * of tables. The sample implementation utilitizes the TreeMap + * collection type. + * This class guarantees that the map will be in ascending key order, + * sorted according to the natural order for the key's class. + * + * @return a Collection object consisting of tables, + * each of which is a copy of a row in this + * CachedRowSetImpl object + * @throws SQLException if an error occurs in generating the collection + * @see #toCollection(int) + * @see #toCollection(String) + * @see TreeMap + */ + @SuppressWarnings("rawtypes") + public Collection toCollection() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns the specified column of this CachedRowSetImpl object + * as a Collection object. This method makes a copy of the + * column's data and utilitizes the Vector to establish the + * collection. The Vector class implements a growable array + * objects allowing the individual components to be accessed using an + * an integer index similar to that of an array. + * + * @return a Collection object that contains the value(s) + * stored in the specified column of this + * CachedRowSetImpl + * object + * @throws SQLException if an error occurs generated the collection; or + * an invalid column is provided. + * @see #toCollection() + * @see #toCollection(String) + * @see Vector + */ + @SuppressWarnings("rawtypes") + public Collection toCollection(int column) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns the specified column of this CachedRowSetImpl object + * as a Collection object. This method makes a copy of the + * column's data and utilitizes the Vector to establish the + * collection. The Vector class implements a growable array + * objects allowing the individual components to be accessed using an + * an integer index similar to that of an array. + * + * @return a Collection object that contains the value(s) + * stored in the specified column of this + * CachedRowSetImpl + * object + * @throws SQLException if an error occurs generated the collection; or + * an invalid column is provided. + * @see #toCollection() + * @see #toCollection(int) + * @see Vector + */ + @SuppressWarnings("rawtypes") + public Collection toCollection(String column) throws SQLException { + throw new UnsupportedOperationException(); + } + + //-------------------------------------------------------------------- + // Advanced features + //-------------------------------------------------------------------- + + + /** + * Returns the SyncProvider implementation being used + * with this CachedRowSetImpl implementation rowset. + * + * @return the SyncProvider used by the rowset. If not provider was + * set when the rowset was instantiated, the reference + * implementation (default) provider is returned. + * @throws SQLException if error occurs while return the + * SyncProvider instance. + */ + public SyncProvider getSyncProvider() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the active SyncProvider and attempts to load + * load the new provider using the SyncFactory SPI. + * + * @throws SQLException if an error occurs while resetting the + * SyncProvider. + */ + public void setSyncProvider(String providerStr) throws SQLException { + throw new UnsupportedOperationException(); + } + + + //----------------- + // methods inherited from RowSet + //----------------- + + + + + + + //--------------------------------------------------------------------- + // Reading and writing data + //--------------------------------------------------------------------- + + /** + * Populates this CachedRowSetImpl object with data. + * This form of the method uses the rowset's user, password, and url or + * data source name properties to create a database + * connection. If properties that are needed + * have not been set, this method will throw an exception. + *

+ * Another form of this method uses an existing JDBC Connection + * object instead of creating a new one; therefore, it ignores the + * properties used for establishing a new connection. + *

+ * The query specified by the command property is executed to create a + * ResultSet object from which to retrieve data. + * The current contents of the rowset are discarded, and the + * rowset's metadata is also (re)set. If there are outstanding updates, + * they are also ignored. + *

+ * The method execute closes any database connections that it + * creates. + * + * @throws SQLException if an error occurs or the + * necessary properties have not been set + */ + public void execute() throws SQLException { + throw new UnsupportedOperationException(); + } + + + + //----------------------------------- + // Methods inherited from ResultSet + //----------------------------------- + + /** + * Moves the cursor down one row from its current position and + * returns true if the new cursor position is a + * valid row. + * The cursor for a new ResultSet object is initially + * positioned before the first row. The first call to the method + * next moves the cursor to the first row, making it + * the current row; the second call makes the second row the + * current row, and so on. + * + *

If an input stream from the previous row is open, it is + * implicitly closed. The ResultSet object's warning + * chain is cleared when a new row is read. + * + * @return true if the new current row is valid; + * false if there are no more rows + * @throws SQLException if an error occurs or + * the cursor is not positioned in the rowset, before + * the first row, or after the last row + */ + public boolean next() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the next + * row and returns true if the cursor is still in the rowset; + * returns false if the cursor has moved to the position after + * the last row. + *

+ * This method handles the cases where the cursor moves to a row that + * has been deleted. + * If this rowset shows deleted rows and the cursor moves to a row + * that has been deleted, this method moves the cursor to the next + * row until the cursor is on a row that has not been deleted. + *

+ * The method internalNext is called by methods such as + * next, absolute, and relative, + * and, as its name implies, is only called internally. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @return true if the cursor is on a valid row in this + * rowset; false if it is after the last row + * @throws SQLException if an error occurs + */ + protected boolean internalNext() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Closes this CachedRowSetImpl objecy and releases any resources + * it was using. + * + * @throws SQLException if an error occurs when releasing any resources in use + * by this CachedRowSetImpl object + */ + public void close() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Reports whether the last column read was SQL NULL. + * Note that you must first call the method getXXX + * on a column to try to read its value and then call the method + * wasNull to determine whether the value was + * SQL NULL. + * + * @return true if the value in the last column read + * was SQL NULL; false otherwise + * @throws SQLException if an error occurs + */ + public boolean wasNull() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns the insert row or the current row of this + * CachedRowSetImplobject. + * + * @return the Row object on which this CachedRowSetImpl + * objects's cursor is positioned + */ + protected BaseRow getCurrentRow() { + throw new UnsupportedOperationException(); + } + + /** + * Removes the row on which the cursor is positioned. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @throws SQLException if the cursor is positioned on the insert + * row + */ + protected void removeCurrentRow() { + throw new UnsupportedOperationException(); + } + + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * String object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is null + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + */ + public String getString(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * boolean value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value as a boolean in the Java progamming language; + * if the value is SQL NULL, the result is false + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BOOLEAN value + * @see #getBoolean(String) + */ + public boolean getBoolean(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * byte value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value as a byte in the Java programming + * language; if the value is SQL NULL, the result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type + * designates the recommended return type. + * @see #getByte(String) + */ + public byte getByte(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * short value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + * @see #getShort(String) + */ + public short getShort(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as an + * int value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + */ + public int getInt(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * long value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + * @see #getLong(String) + */ + public long getLong(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * float value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + * @see #getFloat(String) + */ + public float getFloat(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * double value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is 0 + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + * @see #getDouble(String) + * + */ + public double getDouble(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.math.BigDecimal object. + *

+ * This method is deprecated; use the version of getBigDecimal + * that does not take a scale parameter and returns a value with full + * precision. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @param scale the number of digits to the right of the decimal point in the + * value returned + * @return the column value with the specified number of digits to the right + * of the decimal point; if the value is SQL NULL, the + * result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or this method fails + * @deprecated + */ + @Deprecated + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * byte array value. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value as a byte array in the Java programming + * language; if the value is SQL NULL, the + * result is null + * + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BINARY, VARBINARY or + * LONGVARBINARY value. + * The bold SQL type designates the recommended return type. + * @see #getBytes(String) + */ + public byte[] getBytes(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.sql.Date object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value as a java.sql.Data object; if + * the value is SQL NULL, the + * result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or this method fails + */ + public java.sql.Date getDate(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.sql.Time object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or this method fails + */ + public Time getTime(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.sql.Timestamp object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return the column value; if the value is SQL NULL, the + * result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or this method fails + */ + public Timestamp getTimestamp(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row of this + * CachedRowSetImpl object as a java.io.InputStream + * object. + * + * A column value can be retrieved as a stream of ASCII characters + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. The JDBC + * driver will do any necessary conversion from the database format into ASCII. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a get method implicitly closes the stream. . Also, a + * stream may return 0 for CachedRowSetImpl.available() + * whether there is data available or not. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Java input stream that delivers the database column value + * as a stream of one-byte ASCII characters. If the value is SQL + * NULL, the result is null. + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL CHAR, VARCHAR, LONGVARCHAR + * BINARY, VARBINARY or LONGVARBINARY value. The + * bold SQL type designates the recommended return types that this method is + * used to retrieve. + * @see #getAsciiStream(String) + */ + public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * A column value can be retrieved as a stream of Unicode characters + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. The JDBC driver will + * do any necessary conversion from the database format into Unicode. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a get method implicitly closes the stream. . Also, a + * stream may return 0 for available() whether there is data + * available or not. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Java input stream that delivers the database column value + * as a stream of two byte Unicode characters. If the value is SQL NULL + * then the result is null. + * @throws SQLException if an error occurs + * @deprecated + */ + @Deprecated + public java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row of this + * CachedRowSetImpl object as a java.io.InputStream + * object. + *

+ * A column value can be retrieved as a stream of uninterpreted bytes + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARBINARY values. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a get method implicitly closes the stream. Also, a + * stream may return 0 for + * CachedRowSetImpl.available() whether there is data + * available or not. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return a Java input stream that delivers the database column value + * as a stream of uninterpreted bytes. If the value is SQL NULL + * then the result is null. + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BINARY, VARBINARY or LONGVARBINARY + * The bold type indicates the SQL type that this method is recommened + * to retrieve. + * @see #getBinaryStream(String) + */ + public java.io.InputStream getBinaryStream(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + + } + + + //====================================================================== + // Methods for accessing results by column name + //====================================================================== + + /** + * Retrieves the value stored in the designated column + * of the current row as a String object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR< value. The bold SQL type + * designates the recommended return type. + */ + public String getString(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a boolean value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value as a boolean in the Java programming + * language; if the value is SQL NULL, + * the result is false + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL BOOLEAN value + * @see #getBoolean(int) + */ + public boolean getBoolean(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a byte value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value as a byte in the Java programming + * language; if the value is SQL NULL, the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER, + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The + * bold type designates the recommended return type + */ + public byte getByte(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a short value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type. + * @see #getShort(int) + */ + public short getShort(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as an int value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name + * of a column in this rowset, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return type. + */ + public int getInt(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a long value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type. + * @see #getLong(int) + */ + public long getLong(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a float value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type. + * @see #getFloat(String) + */ + public float getFloat(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row of this CachedRowSetImpl object + * as a double value. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is 0 + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return types. + * @see #getDouble(int) + */ + public double getDouble(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.math.BigDecimal object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @param scale the number of digits to the right of the decimal point + * @return a java.math.BugDecimal object with scale + * number of digits to the right of the decimal point. + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type that this method is used to + * retrieve. + * @deprecated Use the getBigDecimal(String columnName) + * method instead + */ + @Deprecated + public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a byte array. + * The bytes represent the raw values returned by the driver. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value as a byte array in the Java programming + * language; if the value is SQL NULL, the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL BINARY, VARBINARY + * or LONGVARBINARY values + * The bold SQL type designates the recommended return type. + * @see #getBytes(int) + */ + public byte[] getBytes(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.sql.Date object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL DATE or + * TIMESTAMP value + */ + public java.sql.Date getDate(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.sql.Time object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if the given column name does not match one of + * this rowset's column names or the cursor is not on one of + * this rowset's rows or its insert row + */ + public Time getTime(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.sql.Timestamp object. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if the given column name does not match one of + * this rowset's column names or the cursor is not on one of + * this rowset's rows or its insert row + */ + public Timestamp getTimestamp(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row of this + * CachedRowSetImpl object as a java.io.InputStream + * object. + * + * A column value can be retrieved as a stream of ASCII characters + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. The + * SyncProvider will rely on the JDBC driver to do any necessary + * conversion from the database format into ASCII format. + * + *

Note: All the data in the returned stream must + * be read prior to getting the value of any other column. The + * next call to a getXXX method implicitly closes the stream. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return a Java input stream that delivers the database column value + * as a stream of one-byte ASCII characters. If the value is SQL + * NULL, the result is null. + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL CHAR, VARCHAR, LONGVARCHAR + * BINARY, VARBINARY or LONGVARBINARY value. The + * bold SQL type designates the recommended return types that this method is + * used to retrieve. + * @see #getAsciiStream(int) + */ + public java.io.InputStream getAsciiStream(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + + } + + /** + * A column value can be retrieved as a stream of Unicode characters + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARCHAR values. + * The JDBC driver will do any necessary conversion from the database + * format into Unicode. + * + *

Note: All the data in the returned stream must + * be read prior to getting the value of any other column. The + * next call to a getXXX method implicitly closes the stream. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return a Java input stream that delivers the database column value + * as a stream of two-byte Unicode characters. If the value is + * SQL NULL, the result is null. + * @throws SQLException if the given column name does not match one of + * this rowset's column names or the cursor is not on one of + * this rowset's rows or its insert row + * @deprecated use the method getCharacterStream instead + */ + @Deprecated + public java.io.InputStream getUnicodeStream(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row of this + * CachedRowSetImpl object as a java.io.InputStream + * object. + *

+ * A column value can be retrieved as a stream of uninterpreted bytes + * and then read in chunks from the stream. This method is particularly + * suitable for retrieving large LONGVARBINARY values. + * + *

Note: All the data in the returned stream must be + * read prior to getting the value of any other column. The next + * call to a get method implicitly closes the stream. Also, a + * stream may return 0 for CachedRowSetImpl.available() + * whether there is data available or not. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return a Java input stream that delivers the database column value + * as a stream of uninterpreted bytes. If the value is SQL + * NULL, the result is null. + * @throws SQLException if (1) the given column name is unknown, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BINARY, VARBINARY or LONGVARBINARY + * The bold type indicates the SQL type that this method is recommened + * to retrieve. + * @see #getBinaryStream(int) + * + */ + public java.io.InputStream getBinaryStream(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + + //===================================================================== + // Advanced features: + //===================================================================== + + /** + * The first warning reported by calls on this CachedRowSetImpl + * object is returned. Subsequent CachedRowSetImpl warnings will + * be chained to this SQLWarning. + * + *

The warning chain is automatically cleared each time a new + * row is read. + * + *

Note: This warning chain only covers warnings caused + * by ResultSet methods. Any warning caused by statement + * methods (such as reading OUT parameters) will be chained on the + * Statement object. + * + * @return the first SQLWarning or null + */ + public SQLWarning getWarnings() { + throw new UnsupportedOperationException(); + } + + /** + * Clears all the warnings reporeted for the CachedRowSetImpl + * object. After a call to this method, the getWarnings method + * returns null until a new warning is reported for this + * CachedRowSetImpl object. + */ + public void clearWarnings() { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the name of the SQL cursor used by this + * CachedRowSetImpl object. + * + *

In SQL, a result table is retrieved through a cursor that is + * named. The current row of a ResultSet can be updated or deleted + * using a positioned update/delete statement that references the + * cursor name. To ensure that the cursor has the proper isolation + * level to support an update operation, the cursor's SELECT + * statement should be of the form select for update. + * If the for update clause + * is omitted, positioned updates may fail. + * + *

JDBC supports this SQL feature by providing the name of the + * SQL cursor used by a ResultSet object. The current row + * of a result set is also the current row of this SQL cursor. + * + *

Note: If positioned updates are not supported, an + * SQLException is thrown. + * + * @return the SQL cursor name for this CachedRowSetImpl object's + * cursor + * @throws SQLException if an error occurs + */ + public String getCursorName() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves a ResultSetMetaData object instance that + * contains information about the CachedRowSet object. + * However, applications should cast the returned object to a + * RowSetMetaData interface implementation. In the + * reference implementation, this cast can be done on the + * RowSetMetaDataImpl class. + *

+ * For example: + *

+     * CachedRowSet crs = new CachedRowSetImpl();
+     * RowSetMetaDataImpl metaData =
+     *     (RowSetMetaDataImpl)crs.getMetaData();
+     * // Set the number of columns in the RowSet object for
+     * // which this RowSetMetaDataImpl object was created to the
+     * // given number.
+     * metaData.setColumnCount(3);
+     * crs.setMetaData(metaData);
+     * 
+ * + * @return the ResultSetMetaData object that describes this + * CachedRowSetImpl object's columns + * @throws SQLException if an error occurs in generating the RowSet + * meta data; or if the CachedRowSetImpl is empty. + * @see RowSetMetaData + */ + public ResultSetMetaData getMetaData() throws SQLException { + throw new UnsupportedOperationException(); + } + + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as an + * Object value. + *

+ * The type of the Object will be the default + * Java object type corresponding to the column's SQL type, + * following the mapping for built-in types specified in the JDBC 3.0 + * specification. + *

+ * This method may also be used to read datatabase-specific + * abstract data types. + *

+ * This implementation of the method getObject extends its + * behavior so that it gets the attributes of an SQL structured type + * as an array of Object values. This method also custom + * maps SQL user-defined types to classes in the Java programming language. + * When the specified column contains + * a structured or distinct value, the behavior of this method is as + * if it were a call to the method getObject(columnIndex, + * this.getStatement().getConnection().getTypeMap()). + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return a java.lang.Object holding the column value; + * if the value is SQL NULL, the result is null + * @throws SQLException if the given column index is out of bounds, + * the cursor is not on a valid row, or there is a problem getting + * the Class object for a custom mapping + * @see #getObject(String) + */ + public Object getObject(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as an + * Object value. + *

+ * The type of the Object will be the default + * Java object type corresponding to the column's SQL type, + * following the mapping for built-in types specified in the JDBC 3.0 + * specification. + *

+ * This method may also be used to read datatabase-specific + * abstract data types. + *

+ * This implementation of the method getObject extends its + * behavior so that it gets the attributes of an SQL structured type + * as an array of Object values. This method also custom + * maps SQL user-defined types to classes + * in the Java programming language. When the specified column contains + * a structured or distinct value, the behavior of this method is as + * if it were a call to the method getObject(columnIndex, + * this.getStatement().getConnection().getTypeMap()). + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a java.lang.Object holding the column value; + * if the value is SQL NULL, the result is null + * @throws SQLException if (1) the given column name does not match one of + * this rowset's column names, (2) the cursor is not + * on a valid row, or (3) there is a problem getting + * the Class object for a custom mapping + * @see #getObject(int) + */ + public Object getObject(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + //---------------------------------------------------------------- + + /** + * Maps the given column name for one of this CachedRowSetImpl + * object's columns to its column number. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return the column index of the given column name + * @throws SQLException if the given column name does not match one + * of this rowset's column names + */ + public int findColumn(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + //--------------------------JDBC 2.0----------------------------------- + + //--------------------------------------------------------------------- + // Getter's and Setter's + //--------------------------------------------------------------------- + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.io.Reader object. + * + *

Note: All the data in the returned stream must + * be read prior to getting the value of any other column. The + * next call to a getXXX method implicitly closes the stream. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return a Java character stream that delivers the database column value + * as a stream of two-byte unicode characters in a + * java.io.Reader object. If the value is + * SQL NULL, the result is null. + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL CHAR, VARCHAR, LONGVARCHAR, BINARY, VARBINARY or + * LONGVARBINARY value. + * The bold SQL type designates the recommended return type. + * @see #getCharacterStream(String) + */ + public java.io.Reader getCharacterStream(int columnIndex) throws SQLException{ + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value stored in the designated column + * of the current row as a java.io.Reader object. + * + *

Note: All the data in the returned stream must + * be read prior to getting the value of any other column. The + * next call to a getXXX method implicitly closes the stream. + * + * @param columnName a String object giving the SQL name of + * a column in this CachedRowSetImpl object + * @return a Java input stream that delivers the database column value + * as a stream of two-byte Unicode characters. If the value is + * SQL NULL, the result is null. + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL CHAR, VARCHAR, LONGVARCHAR, + * BINARY, VARYBINARY or LONGVARBINARY value. + * The bold SQL type designates the recommended return type. + */ + public java.io.Reader getCharacterStream(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.math.BigDecimal object. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @return a java.math.BigDecimal value with full precision; + * if the value is SQL NULL, the result is null + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL TINYINT, SMALLINT, INTEGER, BIGINT, REAL, + * FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR + * or LONGVARCHAR value. The bold SQL type designates the + * recommended return types that this method is used to retrieve. + * @see #getBigDecimal(String) + */ + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.math.BigDecimal object. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a java.math.BigDecimal value with full precision; + * if the value is SQL NULL, the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TINYINT, SMALLINT, INTEGER + * BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT CHAR, + * VARCHAR or LONGVARCHAR value. The bold SQL type + * designates the recommended return type that this method is used to + * retrieve + * @see #getBigDecimal(int) + */ + public BigDecimal getBigDecimal(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + //--------------------------------------------------------------------- + // Traversal/Positioning + //--------------------------------------------------------------------- + + /** + * Returns the number of rows in this CachedRowSetImpl object. + * + * @return number of rows in the rowset + */ + public int size() { + throw new UnsupportedOperationException(); + } + + /** + * Indicates whether the cursor is before the first row in this + * CachedRowSetImpl object. + * + * @return true if the cursor is before the first row; + * false otherwise or if the rowset contains no rows + * @throws SQLException if an error occurs + */ + public boolean isBeforeFirst() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Indicates whether the cursor is after the last row in this + * CachedRowSetImpl object. + * + * @return true if the cursor is after the last row; + * false otherwise or if the rowset contains no rows + * @throws SQLException if an error occurs + */ + public boolean isAfterLast() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Indicates whether the cursor is on the first row in this + * CachedRowSetImpl object. + * + * @return true if the cursor is on the first row; + * false otherwise or if the rowset contains no rows + * @throws SQLException if an error occurs + */ + public boolean isFirst() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Indicates whether the cursor is on the last row in this + * CachedRowSetImpl object. + *

+ * Note: Calling the method isLast may be expensive + * because the JDBC driver might need to fetch ahead one row in order + * to determine whether the current row is the last row in this rowset. + * + * @return true if the cursor is on the last row; + * false otherwise or if this rowset contains no rows + * @throws SQLException if an error occurs + */ + public boolean isLast() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the front of + * the rowset, just before the first row. This method has no effect if + * this rowset contains no rows. + * + * @throws SQLException if an error occurs or the type of this rowset + * is ResultSet.TYPE_FORWARD_ONLY + */ + public void beforeFirst() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the end of + * the rowset, just after the last row. This method has no effect if + * this rowset contains no rows. + * + * @throws SQLException if an error occurs + */ + public void afterLast() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the first row + * and returns true if the operation was successful. This + * method also notifies registered listeners that the cursor has moved. + * + * @return true if the cursor is on a valid row; + * false otherwise or if there are no rows in this + * CachedRowSetImpl object + * @throws SQLException if the type of this rowset + * is ResultSet.TYPE_FORWARD_ONLY + */ + public boolean first() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the first + * row and returns true if the operation is successful. + *

+ * This method is called internally by the methods first, + * isFirst, and absolute. + * It in turn calls the method internalNext in order to + * handle the case where the first row is a deleted row that is not visible. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @return true if the cursor moved to the first row; + * false otherwise + * @throws SQLException if an error occurs + */ + protected boolean internalFirst() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the last row + * and returns true if the operation was successful. This + * method also notifies registered listeners that the cursor has moved. + * + * @return true if the cursor is on a valid row; + * false otherwise or if there are no rows in this + * CachedRowSetImpl object + * @throws SQLException if the type of this rowset + * is ResultSet.TYPE_FORWARD_ONLY + */ + public boolean last() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the last + * row and returns true if the operation is successful. + *

+ * This method is called internally by the method last + * when rows have been deleted and the deletions are not visible. + * The method internalLast handles the case where the + * last row is a deleted row that is not visible by in turn calling + * the method internalPrevious. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @return true if the cursor moved to the last row; + * false otherwise + * @throws SQLException if an error occurs + */ + protected boolean internalLast() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns the number of the current row in this CachedRowSetImpl + * object. The first row is number 1, the second number 2, and so on. + * + * @return the number of the current row; 0 if there is no + * current row + * @throws SQLException if an error occurs; or if the CacheRowSetImpl + * is empty + */ + public int getRow() throws SQLException { + return crsSync.getRow(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the row number + * specified. + * + *

If the number is positive, the cursor moves to an absolute row with + * respect to the beginning of the rowset. The first row is row 1, the second + * is row 2, and so on. For example, the following command, in which + * crs is a CachedRowSetImpl object, moves the cursor + * to the fourth row, starting from the beginning of the rowset. + *


+     *
+     *    crs.absolute(4);
+     *
+     *  
+ *

+ * If the number is negative, the cursor moves to an absolute row position + * with respect to the end of the rowset. For example, calling + * absolute(-1) positions the cursor on the last row, + * absolute(-2) moves it on the next-to-last row, and so on. + * If the CachedRowSetImpl object crs has five rows, + * the following command moves the cursor to the fourth-to-last row, which + * in the case of a rowset with five rows, is also the second row, counting + * from the beginning. + *


+     *
+     *    crs.absolute(-4);
+     *
+     *  
+ * + * If the number specified is larger than the number of rows, the cursor + * will move to the position after the last row. If the number specified + * would move the cursor one or more rows before the first row, the cursor + * moves to the position before the first row. + *

+ * Note: Calling absolute(1) is the same as calling the + * method first(). Calling absolute(-1) is the + * same as calling last(). + * + * @param row a positive number to indicate the row, starting row numbering from + * the first row, which is 1; a negative number to indicate + * the row, starting row numbering from the last row, which is + * -1; it must not be 0 + * @return true if the cursor is on the rowset; false + * otherwise + * @throws SQLException if the given cursor position is 0 or the + * type of this rowset is ResultSet.TYPE_FORWARD_ONLY + */ + public boolean absolute( int row ) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves the cursor the specified number of rows from the current + * position, with a positive number moving it forward and a + * negative number moving it backward. + *

+ * If the number is positive, the cursor moves the specified number of + * rows toward the end of the rowset, starting at the current row. + * For example, the following command, in which + * crs is a CachedRowSetImpl object with 100 rows, + * moves the cursor forward four rows from the current row. If the + * current row is 50, the cursor would move to row 54. + *


+     *
+     *    crs.relative(4);
+     *
+     *  
+ *

+ * If the number is negative, the cursor moves back toward the beginning + * the specified number of rows, starting at the current row. + * For example, calling the method + * absolute(-1) positions the cursor on the last row, + * absolute(-2) moves it on the next-to-last row, and so on. + * If the CachedRowSetImpl object crs has five rows, + * the following command moves the cursor to the fourth-to-last row, which + * in the case of a rowset with five rows, is also the second row + * from the beginning. + *


+     *
+     *    crs.absolute(-4);
+     *
+     *  
+ * + * If the number specified is larger than the number of rows, the cursor + * will move to the position after the last row. If the number specified + * would move the cursor one or more rows before the first row, the cursor + * moves to the position before the first row. In both cases, this method + * throws an SQLException. + *

+ * Note: Calling absolute(1) is the same as calling the + * method first(). Calling absolute(-1) is the + * same as calling last(). Calling relative(0) + * is valid, but it does not change the cursor position. + * + * @param rows an int indicating the number of rows to move + * the cursor, starting at the current row; a positive number + * moves the cursor forward; a negative number moves the cursor + * backward; must not move the cursor past the valid + * rows + * @return true if the cursor is on a row in this + * CachedRowSetImpl object; false + * otherwise + * @throws SQLException if there are no rows in this rowset, the cursor is + * positioned either before the first row or after the last row, or + * the rowset is type ResultSet.TYPE_FORWARD_ONLY + */ + public boolean relative(int rows) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves this CachedRowSetImpl object's cursor to the + * previous row and returns true if the cursor is on + * a valid row or false if it is not. + * This method also notifies all listeners registered with this + * CachedRowSetImpl object that its cursor has moved. + *

+ * Note: calling the method previous() is not the same + * as calling the method relative(-1). This is true + * because it is possible to call previous() from the insert + * row, from after the last row, or from the current row, whereas + * relative may only be called from the current row. + *

+ * The method previous may used in a while + * loop to iterate through a rowset starting after the last row + * and moving toward the beginning. The loop ends when previous + * returns false, meaning that there are no more rows. + * For example, the following code fragment retrieves all the data in + * the CachedRowSetImpl object crs, which has + * three columns. Note that the cursor must initially be positioned + * after the last row so that the first call to the method + * previous places the cursor on the last line. + *

 
+     *
+     *     crs.afterLast();
+     *     while (previous()) {
+     *         String name = crs.getString(1);
+     *         int age = crs.getInt(2);
+     *         short ssn = crs.getShort(3);
+     *         System.out.println(name + "   " + age + "   " + ssn);
+     *     }
+     *
+     *  
+ * This method throws an SQLException if the cursor is not + * on a row in the rowset, before the first row, or after the last row. + * + * @return true if the cursor is on a valid row; + * false if it is before the first row or after the + * last row + * @throws SQLException if the cursor is not on a valid position or the + * type of this rowset is ResultSet.TYPE_FORWARD_ONLY + */ + public boolean previous() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves the cursor to the previous row in this CachedRowSetImpl + * object, skipping past deleted rows that are not visible; returns + * true if the cursor is on a row in this rowset and + * false when the cursor goes before the first row. + *

+ * This method is called internally by the method previous. + *

+ * This is a implementation only method and is not required as a standard + * implementation of the CachedRowSet interface. + * + * @return true if the cursor is on a row in this rowset; + * false when the cursor reaches the position before + * the first row + * @throws SQLException if an error occurs + */ + protected boolean internalPrevious() throws SQLException { + throw new UnsupportedOperationException(); + } + + + //--------------------------------------------------------------------- + // Updates + //--------------------------------------------------------------------- + + /** + * Indicates whether the current row of this CachedRowSetImpl + * object has been updated. The value returned + * depends on whether this rowset can detect updates: false + * will always be returned if it does not detect updates. + * + * @return true if the row has been visibly updated + * by the owner or another and updates are detected; + * false otherwise + * @throws SQLException if the cursor is on the insert row or not + * not on a valid row + * + * @see DatabaseMetaData#updatesAreDetected + */ + public boolean rowUpdated() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Indicates whether the designated column of the current row of + * this CachedRowSetImpl object has been updated. The + * value returned depends on whether this rowset can detcted updates: + * false will always be returned if it does not detect updates. + * + * @param idx the index identifier of the column that may be have been updated. + * @return true is the designated column has been updated + * and the rowset detects updates; false if the rowset has not + * been updated or the rowset does not detect updates + * @throws SQLException if the cursor is on the insert row or not + * on a valid row + * @see DatabaseMetaData#updatesAreDetected + */ + public boolean columnUpdated(int idx) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Indicates whether the designated column of the current row of + * this CachedRowSetImpl object has been updated. The + * value returned depends on whether this rowset can detcted updates: + * false will always be returned if it does not detect updates. + * + * @param columnName the String column name column that may be have + * been updated. + * @return true is the designated column has been updated + * and the rowset detects updates; false if the rowset has not + * been updated or the rowset does not detect updates + * @throws SQLException if the cursor is on the insert row or not + * on a valid row + * @see DatabaseMetaData#updatesAreDetected + */ + public boolean columnUpdated(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Indicates whether the current row has been inserted. The value returned + * depends on whether or not the rowset can detect visible inserts. + * + * @return true if a row has been inserted and inserts are detected; + * false otherwise + * @throws SQLException if the cursor is on the insert row or not + * not on a valid row + * + * @see DatabaseMetaData#insertsAreDetected + */ + public boolean rowInserted() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Indicates whether the current row has been deleted. A deleted row + * may leave a visible "hole" in a rowset. This method can be used to + * detect such holes if the rowset can detect deletions. This method + * will always return false if this rowset cannot detect + * deletions. + * + * @return true if (1)the current row is blank, indicating that + * the row has been deleted, and (2)deletions are detected; + * false otherwise + * @throws SQLException if the cursor is on a valid row in this rowset + * @see DatabaseMetaData#deletesAreDetected + */ + public boolean rowDeleted() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated nullable column in the current row or the + * insert row of this CachedRowSetImpl object with + * null value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset; however, another method must be called to complete + * the update process. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to mark the row as updated + * and to notify listeners that the row has changed. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called to insert the new row into this rowset and to notify + * listeners that a row has changed. + *

+ * In order to propagate updates in this rowset to the underlying + * data source, an application must call the method {@link #acceptChanges} + * after it calls either updateRow or insertRow. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateNull(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * boolean value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * byte value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateByte(int columnIndex, byte x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * short value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateShort(int columnIndex, short x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * int value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateInt(int columnIndex, int x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * long value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateLong(int columnIndex, long x) throws SQLException { + throw new UnsupportedOperationException(); + + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * float value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateFloat(int columnIndex, float x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateDouble(int columnIndex, double x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.math.BigDecimal object. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * String object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to mark the row as updated. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called to insert the new row into this rowset and mark it + * as inserted. Both of these methods must be called before the + * cursor moves to another row. + *

+ * The method acceptChanges must be called if the + * updated values are to be written back to the underlying database. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateString(int columnIndex, String x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * byte array. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBytes(int columnIndex, byte x[]) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Date object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the type of the designated column is not + * an SQL DATE or TIMESTAMP, or + * (4) this rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateDate(int columnIndex, java.sql.Date x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Time object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the type of the designated column is not + * an SQL TIME or TIMESTAMP, or + * (4) this rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateTime(int columnIndex, Time x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Timestamp object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the type of the designated column is not + * an SQL DATE, TIME, or + * TIMESTAMP, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * ASCII stream value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @param length the number of one-byte ASCII characters in the stream + * @throws SQLException if this method is invoked + */ + public void updateAsciiStream(int columnIndex, java.io.InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.io.InputStream object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value; must be a java.io.InputStream + * containing BINARY, VARBINARY, or + * LONGVARBINARY data + * @param length the length of the stream in bytes + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the data in the stream is not binary, or + * (4) this rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBinaryStream(int columnIndex, java.io.InputStream x,int length) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.io.Reader object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value; must be a java.io.Reader + * containing BINARY, VARBINARY, + * LONGVARBINARY, CHAR, VARCHAR, + * or LONGVARCHAR data + * @param length the length of the stream in characters + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, (3) the data in the stream is not a binary or + * character type, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Object value. The scale parameter indicates + * the number of digits to the right of the decimal point and is ignored + * if the new column value is not a type that will be mapped to an SQL + * DECIMAL or NUMERIC value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @param scale the number of digits to the right of the decimal point (for + * DECIMAL and NUMERIC types only) + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateObject(int columnIndex, Object x, int scale) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Object value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param x the new column value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateObject(int columnIndex, Object x) throws SQLException { + throw new UnsupportedOperationException(); + } + + + /** + * Sets the designated nullable column in the current row or the + * insert row of this CachedRowSetImpl object with + * null value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateNull(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * boolean value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBoolean(String columnName, boolean x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * byte value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateByte(String columnName, byte x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * short value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateShort(String columnName, short x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * int value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateInt(String columnName, int x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * long value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateLong(String columnName, long x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * float value. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateFloat(String columnName, float x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateDouble(String columnName, double x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.math.BigDecimal object. + *

+ * This method updates a column value in the current row or the insert + * row of this rowset, but it does not update the database. + * If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * String object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateString(String columnName, String x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * byte array. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBytes(String columnName, byte x[]) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Date object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the type + * of the designated column is not an SQL DATE or + * TIMESTAMP, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateDate(String columnName, java.sql.Date x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Time object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the type + * of the designated column is not an SQL TIME or + * TIMESTAMP, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateTime(String columnName, Time x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Timestamp object. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if the given column index is out of bounds or + * the cursor is not on one of this rowset's rows or its + * insert row + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the type + * of the designated column is not an SQL DATE, + * TIME, or TIMESTAMP, or (4) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateTimestamp(String columnName, Timestamp x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * ASCII stream value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @param length the number of one-byte ASCII characters in the stream + */ + public void updateAsciiStream(String columnName, + java.io.InputStream x, + int length) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.io.InputStream object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value; must be a java.io.InputStream + * containing BINARY, VARBINARY, or + * LONGVARBINARY data + * @param length the length of the stream in bytes + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the data + * in the stream is not binary, or (4) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.io.Reader object. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param reader the new column value; must be a + * java.io.Reader containing BINARY, + * VARBINARY, LONGVARBINARY, CHAR, + * VARCHAR, or LONGVARCHAR data + * @param length the length of the stream in characters + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, (3) the data + * in the stream is not a binary or character type, or (4) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateCharacterStream(String columnName, + java.io.Reader reader, + int length) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Object value. The scale parameter + * indicates the number of digits to the right of the decimal point + * and is ignored if the new column value is not a type that will be + * mapped to an SQL DECIMAL or NUMERIC value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @param scale the number of digits to the right of the decimal point (for + * DECIMAL and NUMERIC types only) + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateObject(String columnName, Object x, int scale) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * Object value. + *

+ * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param x the new column value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateObject(String columnName, Object x) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Inserts the contents of this CachedRowSetImpl object's insert + * row into this rowset immediately following the current row. + * If the current row is the + * position after the last row or before the first row, the new row will + * be inserted at the end of the rowset. This method also notifies + * listeners registered with this rowset that the row has changed. + *

+ * The cursor must be on the insert row when this method is called. + * + * @throws SQLException if (1) the cursor is not on the insert row, + * (2) one or more of the non-nullable columns in the insert + * row has not been given a value, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void insertRow() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Marks the current row of this CachedRowSetImpl object as + * updated and notifies listeners registered with this rowset that the + * row has changed. + *

+ * This method cannot be called when the cursor is on the insert row, and + * it should be called before the cursor moves to another row. If it is + * called after the cursor moves to another row, this method has no effect, + * and the updates made before the cursor moved will be lost. + * + * @throws SQLException if the cursor is on the insert row or this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateRow() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Deletes the current row from this CachedRowSetImpl object and + * notifies listeners registered with this rowset that a row has changed. + * This method cannot be called when the cursor is on the insert row. + *

+ * This method marks the current row as deleted, but it does not delete + * the row from the underlying data source. The method + * acceptChanges must be called to delete the row in + * the data source. + * + * @throws SQLException if (1) this method is called when the cursor + * is on the insert row, before the first row, or after the + * last row or (2) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void deleteRow() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the current row with its original value and marks the row as + * not updated, thus undoing any changes made to the row since the + * last call to the methods updateRow or deleteRow. + * This method should be called only when the cursor is on a row in + * this rowset. + * + * @throws SQLException if the cursor is on the insert row, before the + * first row, or after the last row + */ + public void refreshRow() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Rolls back any updates made to the current row of this + * CachedRowSetImpl object and notifies listeners that + * a row has changed. To have an effect, this method + * must be called after an updateXXX method has been + * called and before the method updateRow has been called. + * If no updates have been made or the method updateRow + * has already been called, this method has no effect. + * + * @throws SQLException if the cursor is on the insert row, before the + * first row, or after the last row + */ + public void cancelRowUpdates() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves the cursor for this CachedRowSetImpl object + * to the insert row. The current row in the rowset is remembered + * while the cursor is on the insert row. + *

+ * The insert row is a special row associated with an updatable + * rowset. It is essentially a buffer where a new row may + * be constructed by calling the appropriate updateXXX + * methods to assign a value to each column in the row. A complete + * row must be constructed; that is, every column that is not nullable + * must be assigned a value. In order for the new row to become part + * of this rowset, the method insertRow must be called + * before the cursor is moved back to the rowset. + *

+ * Only certain methods may be invoked while the cursor is on the insert + * row; many methods throw an exception if they are called while the + * cursor is there. In addition to the updateXXX + * and insertRow methods, only the getXXX methods + * may be called when the cursor is on the insert row. A getXXX + * method should be called on a column only after an updateXXX + * method has been called on that column; otherwise, the value returned is + * undetermined. + * + * @throws SQLException if this CachedRowSetImpl object is + * ResultSet.CONCUR_READ_ONLY + */ + public void moveToInsertRow() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Moves the cursor for this CachedRowSetImpl object to + * the current row. The current row is the row the cursor was on + * when the method moveToInsertRow was called. + *

+ * Calling this method has no effect unless it is called while the + * cursor is on the insert row. + * + * @throws SQLException if an error occurs + */ + public void moveToCurrentRow() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns null. + * + * @return null + * @throws SQLException if an error occurs + */ + public Statement getStatement() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as an Object in + * the Java programming language, using the given + * java.util.Map object to custom map the value if + * appropriate. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param map a java.util.Map object showing the mapping + * from SQL type names to classes in the Java programming + * language + * @return an Object representing the SQL value + * @throws SQLException if the given column index is out of bounds or + * the cursor is not on one of this rowset's rows or its + * insert row + */ + public Object getObject(int columnIndex, + Map> map) + throws SQLException + { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Ref object + * in the Java programming language. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Ref object representing an SQL REF value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL REF value + * @see #getRef(String) + */ + public Ref getRef(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Blob object + * in the Java programming language. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Blob object representing an SQL BLOB value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL BLOB value + * @see #getBlob(String) + */ + public Blob getBlob(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Clob object + * in the Java programming language. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return a Clob object representing an SQL CLOB value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL CLOB value + * @see #getClob(String) + */ + public Clob getClob(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as an Array object + * in the Java programming language. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @return an Array object representing an SQL + * ARRAY value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL ARRAY value + * @see #getArray(String) + */ + public Array getArray(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as an Object in + * the Java programming language, using the given + * java.util.Map object to custom map the value if + * appropriate. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param map a java.util.Map object showing the mapping + * from SQL type names to classes in the Java programming + * language + * @return an Object representing the SQL value + * @throws SQLException if the given column name is not the name of + * a column in this rowset or the cursor is not on one of + * this rowset's rows or its insert row + */ + public Object getObject(String columnName, + Map> map) + throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Ref object + * in the Java programming language. + * + * @param colName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a Ref object representing an SQL REF value + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the column value + * is not an SQL REF value + * @see #getRef(int) + */ + public Ref getRef(String colName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Blob object + * in the Java programming language. + * + * @param colName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a Blob object representing an SQL BLOB value + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL BLOB value + * @see #getBlob(int) + */ + public Blob getBlob(String colName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a Clob object + * in the Java programming language. + * + * @param colName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return a Clob object representing an SQL + * CLOB value + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL CLOB value + * @see #getClob(int) + */ + public Clob getClob(String colName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as an Array object + * in the Java programming langugage. + * + * @param colName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @return an Array object representing an SQL + * ARRAY value + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL ARRAY value + * @see #getArray(int) + */ + public Array getArray(String colName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Date + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL DATE or + * TIMESTAMP value + */ + public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Date + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL DATE or + * TIMESTAMP value + */ + public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Time + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TIME or + * TIMESTAMP value + */ + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Time + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TIME or + * TIMESTAMP value + */ + public Time getTime(String columnName, Calendar cal) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a java.sql.Timestamp + * object, using the given Calendar object to construct an + * appropriate millisecond value for the date. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in the rowset + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL TIME or + * TIMESTAMP value + */ + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in the current row + * of this CachedRowSetImpl object as a + * java.sql.Timestamp object, using the given + * Calendar object to construct an appropriate + * millisecond value for the date. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param cal the java.util.Calendar object to use in + * constructing the date + * @return the column value; if the value is SQL NULL, + * the result is null + * @throws SQLException if (1) the given column name is not the name of + * a column in this rowset, (2) the cursor is not on one of + * this rowset's rows or its insert row, or (3) the designated + * column does not store an SQL DATE, + * TIME, or TIMESTAMP value + */ + public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException { + throw new UnsupportedOperationException(); + } + + /* + * RowSetInternal Interface + */ + + /** + * Retrieves the Connection object passed to this + * CachedRowSetImpl object. This connection may be + * used to populate this rowset with data or to write data back + * to its underlying data source. + * + * @return the Connection object passed to this rowset; + * may be null if there is no connection + * @throws SQLException if an error occurs + */ + public Connection getConnection() throws SQLException{ + throw new UnsupportedOperationException(); + } + + /** + * Sets the metadata for this CachedRowSetImpl object + * with the given RowSetMetaData object. + * + * @param md a RowSetMetaData object instance containing + * metadata about the columsn in the rowset + * @throws SQLException if invalid meta data is supplied to the + * rowset + */ + public void setMetaData(RowSetMetaData md) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns a result set containing the original value of the rowset. The + * original value is the state of the CachedRowSetImpl after the + * last population or synchronization (whichever occurred most recently) with + * the data source. + *

+ * The cursor is positioned before the first row in the result set. + * Only rows contained in the result set returned by getOriginal() + * are said to have an original value. + * + * @return the original result set of the rowset + * @throws SQLException if an error occurs produce the + * ResultSet object + */ + public ResultSet getOriginal() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns a result set containing the original value of the current + * row only. + * The original value is the state of the CachedRowSetImpl after + * the last population or synchronization (whichever occurred most recently) + * with the data source. + * + * @return the original result set of the row + * @throws SQLException if there is no current row + * @see #setOriginalRow + */ + public ResultSet getOriginalRow() throws SQLException { + throw new UnsupportedOperationException(); + + } + + /** + * Marks the current row in this rowset as being an original row. + * + * @throws SQLException if there is no current row + * @see #getOriginalRow + */ + public void setOriginalRow() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Marks all rows in this rowset as being original rows. Any updates + * made to the rows become the original values for the rowset. + * Calls to the method setOriginal connot be reversed. + * + * @throws SQLException if an error occurs + */ + public void setOriginal() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns an identifier for the object (table) that was used to create this + * rowset. + * + * @return a String object that identifies the table from + * which this CachedRowSetImpl object was derived + * @throws SQLException if an error occurs + */ + public String getTableName() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the identifier for the table from which this rowset was derived + * to the given table name. + * + * @param tabName a String object that identifies the + * table from which this CachedRowSetImpl object + * was derived + * @throws SQLException if an error occurs + */ + public void setTableName(String tabName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Returns the columns that make a key to uniquely identify a + * row in this CachedRowSetImpl object. + * + * @return an array of column numbers that constitutes a primary + * key for this rowset. This array should be empty + * if no column is representitive of a primary key + * @throws SQLException if the rowset is empty or no columns + * are designated as primary keys + * @see #setKeyColumns + */ + public int[] getKeyColumns() throws SQLException { + throw new UnsupportedOperationException(); + } + + + /** + * Sets this CachedRowSetImpl object's + * keyCols field with the given array of column + * numbers, which forms a key for uniquely identifying a row + * in this rowset. + * + * @param keys an array of int indicating the + * columns that form a primary key for this + * CachedRowSetImpl object; every + * element in the array must be greater than + * 0 and less than or equal to the number + * of columns in this rowset + * @throws SQLException if any of the numbers in the + * given array is not valid for this rowset + * @see #getKeyColumns + */ + public void setKeyColumns(int [] keys) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param ref the new column java.sql.Ref value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateRef(int columnIndex, Ref ref) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param ref the new column java.sql.Ref value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateRef(String columnName, Ref ref) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param c the new column Clob value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateClob(int columnIndex, Clob c) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * double value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param c the new column Clobvalue + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateClob(String columnName, Clob c) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.sql.Blob value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param b the new column Blob value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateBlob(int columnIndex, Blob b) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.sql.Blob value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param b the new column Blob value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateBlob(String columnName, Blob b) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.sql.Array values. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnIndex the first column is 1, the second + * is 2, and so on; must be 1 or larger + * and equal to or less than the number of columns in this rowset + * @param a the new column Array value + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) this rowset is + * ResultSet.CONCUR_READ_ONLY + */ + public void updateArray(int columnIndex, Array a) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated column in either the current row or the insert + * row of this CachedRowSetImpl object with the given + * java.sql.Array value. + * + * This method updates a column value in either the current row or + * the insert row of this rowset, but it does not update the + * database. If the cursor is on a row in the rowset, the + * method {@link #updateRow} must be called to update the database. + * If the cursor is on the insert row, the method {@link #insertRow} + * must be called, which will insert the new row into both this rowset + * and the database. Both of these methods must be called before the + * cursor moves to another row. + * + * @param columnName a String object that must match the + * SQL name of a column in this rowset, ignoring case + * @param a the new column Array value + * @throws SQLException if (1) the given column name does not match the + * name of a column in this rowset, (2) the cursor is not on + * one of this rowset's rows or its insert row, or (3) this + * rowset is ResultSet.CONCUR_READ_ONLY + */ + public void updateArray(String columnName, Array a) throws SQLException { + throw new UnsupportedOperationException(); + } + + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a java.net.URL object + * in the Java programming language. + * + * @return a java.net.URL object containing the resource reference described by + * the URL + * @throws SQLException if (1) the given column index is out of bounds, + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL DATALINK value. + * @see #getURL(String) + */ + public java.net.URL getURL(int columnIndex) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the value of the designated column in this + * CachedRowSetImpl object as a java.net.URL object + * in the Java programming language. + * + * @return a java.net.URL object containing the resource reference described by + * the URL + * @throws SQLException if (1) the given column name not the name of a column + * in this rowset, or + * (2) the cursor is not on one of this rowset's rows or its + * insert row, or (3) the designated column does not store an + * SQL DATALINK value. + * @see #getURL(int) + */ + public java.net.URL getURL(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + + } + + /** + * The first warning reported by calls on this CachedRowSetImpl + * object is returned. Subsequent CachedRowSetImpl warnings will + * be chained to this SQLWarning. All RowSetWarnings + * warnings are generated in the disconnected environment and remain a + * seperate warning chain to that provided by the getWarnings + * method. + * + *

The warning chain is automatically cleared each time a new + * row is read. + * + *

Note: This warning chain only covers warnings caused + * by CachedRowSet (and their child interface) + * methods. All SQLWarnings can be obtained using the + * getWarnings method which tracks warnings generated + * by the underlying JDBC driver. + * @return the first SQLWarning or null + * + */ + public RowSetWarning getRowSetWarnings() { + throw new UnsupportedOperationException(); + } + + /** + * Commits all changes performed by the acceptChanges() + * methods + * + * @see Connection#commit + */ + public void commit() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Rolls back all changes performed by the acceptChanges() + * methods + * + * @see Connection#rollback + */ + public void rollback() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Rolls back all changes performed by the acceptChanges() + * to the last Savepoint transaction marker. + * + * @see Connection#rollback(Savepoint) + */ + public void rollback(Savepoint s) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Unsets the designated parameter to the given int array. + * This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnIdxes the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnIdx is + * not the same as set using setMatchColumn(int []) + */ + public void unsetMatchColumn(int[] columnIdxes) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Unsets the designated parameter to the given String array. + * This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnIdxes the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnName is + * not the same as set using setMatchColumn(String []) + */ + public void unsetMatchColumn(String[] columnIdxes) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the column name as String array + * that was set using setMatchColumn(String []) + * for this rowset. + * + * @return a String array object that contains the column names + * for the rowset which has this the match columns + * + * @throws SQLException if an error occurs or column name is not set + */ + public String[] getMatchColumnNames() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves the column id as int array that was set using + * setMatchColumn(int []) for this rowset. + * + * @return a int array object that contains the column ids + * for the rowset which has this as the match columns. + * + * @throws SQLException if an error occurs or column index is not set + */ + public int[] getMatchColumnIndexes() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated parameter to the given int array. + * This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumnIndexes is called. + * + * @param columnIdxes the indexes into this rowset + * object's internal representation of parameter values; the + * first parameter is 0, the second is 1, and so on; must be + * 0 or greater + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(int[] columnIdxes) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated parameter to the given String array. + * This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumn is called. + * + * @param columnNames the name of the column into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(String[] columnNames) throws SQLException { + throw new UnsupportedOperationException(); + } + + + /** + * Sets the designated parameter to the given int + * object. This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumn is called. + * + * @param columnIdx the index into this rowset + * object's internal representation of parameter values; the + * first parameter is 0, the second is 1, and so on; must be + * 0 or greater + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(int columnIdx) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the designated parameter to the given String + * object. This forms the basis of the join for the + * JoinRowSet as the column which will form the basis of the + * join. + *

+ * The parameter value set by this method is stored internally and + * will be supplied as the appropriate parameter in this rowset's + * command when the method getMatchColumn is called. + * + * @param columnName the name of the column into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds + */ + public void setMatchColumn(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Unsets the designated parameter to the given int + * object. This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnIdx the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnIdx is + * not the same as set using setMatchColumn(int) + */ + public void unsetMatchColumn(int columnIdx) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Unsets the designated parameter to the given String + * object. This was set using setMatchColumn + * as the column which will form the basis of the join. + *

+ * The parameter value unset by this method should be same + * as was set. + * + * @param columnName the index into this rowset + * object's internal representation of parameter values + * @throws SQLException if an error occurs or the + * parameter index is out of bounds or if the columnName is + * not the same as set using setMatchColumn(String) + */ + public void unsetMatchColumn(String columnName) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Notifies registered listeners that a RowSet object in the given RowSetEvent + * object has populated a number of additional rows. The numRows parameter + * ensures that this event will only be fired every numRow. + *

+ * The source of the event can be retrieved with the method event.getSource. + * + * @param event a RowSetEvent object that contains the + * RowSet object that is the source of the events + * @param numRows when populating, the number of rows interval on which the + * CachedRowSet populated should fire; the default value + * is zero; cannot be less than fetchSize or zero + */ + public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Populates this CachedRowSet object with data from + * the given ResultSet object. While related to the populate(ResultSet) + * method, an additional parameter is provided to allow starting position within + * the ResultSet from where to populate the CachedRowSet + * instance. + * + * This method is an alternative to the method execute + * for filling the rowset with data. The method populate + * does not require that the properties needed by the method + * execute, such as the command property, + * be set. This is true because the method populate + * is given the ResultSet object from + * which to get data and thus does not need to use the properties + * required for setting up a connection and executing this + * CachedRowSetImpl object's command. + *

+ * After populating this rowset with data, the method + * populate sets the rowset's metadata and + * then sends a RowSetChangedEvent object + * to all registered listeners prior to returning. + * + * @param data the ResultSet object containing the data + * to be read into this CachedRowSetImpl object + * @param start the integer specifing the position in the + * ResultSet object to popultate the + * CachedRowSetImpl object. + * @throws SQLException if an error occurs; or the max row setting is + * violated while populating the RowSet.Also id the start position + * is negative. + * @see #execute + */ + public void populate(ResultSet data, int start) throws SQLException{ + throw new UnsupportedOperationException(); + + } + + /** + * The nextPage gets the next page, that is a CachedRowSetImpl object + * containing the number of rows specified by page size. + * @return boolean value true indicating whether there are more pages to come and + * false indicating that this is the last page. + * @throws SQLException if an error occurs or this called before calling populate. + */ + public boolean nextPage() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * This is the setter function for setting the size of the page, which specifies + * how many rows have to be retrived at a time. + * + * @param size which is the page size + * @throws SQLException if size is less than zero or greater than max rows. + */ + public void setPageSize (int size) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * This is the getter function for the size of the page. + * + * @return an integer that is the page size. + */ + public int getPageSize() { + throw new UnsupportedOperationException(); + } + + + /** + * Retrieves the data present in the page prior to the page from where it is + * called. + * @return boolean value true if it retrieves the previous page, flase if it + * is on the first page. + * @throws SQLException if it is called before populate is called or ResultSet + * is of type ResultSet.TYPE_FORWARD_ONLY or if an error + * occurs. + */ + public boolean previousPage() throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Updates the designated column with a character stream value, which will + * have the specified number of bytes. The driver does the necessary conversion + * from Java character format to the national character set in the database. + * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * The updater methods are used to update column values in the current row or + * the insert row. The updater methods do not update the underlying database; + * instead the updateRow or insertRow methods are called to update the database. + * + * @param columnIndex - the first column is 1, the second is 2, ... + * @param x - the new column value + * @param length - the length of the stream + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public void updateNCharacterStream(int columnIndex, + java.io.Reader x, + int length) + throws SQLException { + throw new UnsupportedOperationException("Operation not yet supported"); + } + + /** + * Updates the designated column with a character stream value, which will + * have the specified number of bytes. The driver does the necessary conversion + * from Java character format to the national character set in the database. + * It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns. + * The updater methods are used to update column values in the current row or + * the insert row. The updater methods do not update the underlying database; + * instead the updateRow or insertRow methods are called to update the database. + * + * @param columnName - name of the Column + * @param x - the new column value + * @param length - the length of the stream + * @exception SQLException if a database access error occurs + * @since 1.6 + */ + public void updateNCharacterStream(String columnName, + java.io.Reader x, + int length) + throws SQLException { + throw new UnsupportedOperationException("Operation not yet supported"); + } + + /** + * This method re populates the resBundle + * during the deserialization process + * + */ + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + // Default state initialization happens here + ois.defaultReadObject(); + // Initialization of transient Res Bundle happens here . + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + } + + static final long serialVersionUID = -3345004441725080251L; +} //end class diff --git a/src/main/java/org/replicadb/rowset/sun/rowset/providers/RIOptimisticProvider.java b/src/main/java/org/replicadb/rowset/sun/rowset/providers/RIOptimisticProvider.java new file mode 100644 index 0000000..46cc668 --- /dev/null +++ b/src/main/java/org/replicadb/rowset/sun/rowset/providers/RIOptimisticProvider.java @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.replicadb.rowset.sun.rowset.providers; + +import org.replicadb.rowset.sun.rowset.JdbcRowSetResourceBundle; +import org.replicadb.rowset.sun.rowset.internal.CachedRowSetReader; +import org.replicadb.rowset.sun.rowset.internal.CachedRowSetWriter; + +import javax.sql.RowSetReader; +import javax.sql.RowSetWriter; +import javax.sql.rowset.spi.SyncFactory; +import javax.sql.rowset.spi.SyncFactoryException; +import javax.sql.rowset.spi.SyncProvider; +import javax.sql.rowset.spi.SyncProviderException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; + +/** + * The reference implementation of a JDBC Rowset synchronization provider + * providing optimistic synchronization with a relational datastore + * using any JDBC technology-enabled driver. + *

+ *

1.0 Backgroud

+ * This synchronization provider is registered with the + * SyncFactory by default as the + * com.sun.rowset.providers.RIOptimisticProvider. + * As an extension of the SyncProvider abstract + * class, it provides the reader and writer classes required by disconnected + * rowsets as javax.sql.RowSetReader and javax.sql.RowSetWriter + * interface implementations. As a reference implementation, + * RIOptimisticProvider provides a + * fully functional implementation offering a medium grade classification of + * syncrhonization, namely GRADE_CHECK_MODIFIED_AT_COMMIT. A + * disconnected RowSet implementation using the + * RIOptimisticProvider can expect the writer to + * check only rows that have been modified in the RowSet against + * the values in the data source. If there is a conflict, that is, if a value + * in the data source has been changed by another party, the + * RIOptimisticProvider will not write any of the changes to the data + * source and will throw a SyncProviderException object. + * + *

2.0 Usage

+ * Standard disconnected RowSet implementations may opt to use this + * SyncProvider implementation in one of two ways: + *
    + *
  1. By specifically calling the setSyncProvider method + defined in the CachedRowSet interface + *
    + *     CachedRowset crs = new FooCachedRowSetImpl();
    + *     crs.setSyncProvider("com.sun.rowset.providers.RIOptimisticProvider");
    + * 
    + *
  2. By specifying it in the constructor of the RowSet + * implementation + *
    + *     CachedRowset crs = new FooCachedRowSetImpl(
    + *                         "com.sun.rowset.providers.RIOptimisticProvider");
    + * 
    + *
+ * Note that because the RIOptimisticProvider implementation is + * the default provider, it will always be the provider when no provider ID is + * specified to the constructor. + *

+ * See the standard RowSet reference implementations in the + * com.sun.rowset package for more details. + * + * @author Jonathan Bruce + * @see SyncProvider + * @see SyncProviderException + * @see SyncFactory + * @see SyncFactoryException + * + */ +public final class RIOptimisticProvider extends SyncProvider implements Serializable { + + private CachedRowSetReader reader; + private CachedRowSetWriter writer; + + /** + * The unique provider identifier. + */ + private String providerID = "com.sun.rowset.providers.RIOptimisticProvider"; + + /** + * The vendor name of this SyncProvider implementation + */ + private String vendorName = "Oracle Corporation"; + + /** + * The version number of this SyncProvider implementation + */ + private String versionNumber = "1.0"; + + /** + * ResourceBundle + */ + private JdbcRowSetResourceBundle resBundle; + + /** + * Creates an RIOptimisticProvider object initialized with the + * fully qualified class name of this SyncProvider implementation + * and a default reader and writer. + *

+ * This provider is available to all disconnected RowSet implementations + * as the default persistence provider. + */ + public RIOptimisticProvider() { + providerID = this.getClass().getName(); + reader = new CachedRowSetReader(); + writer = new CachedRowSetWriter(); + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + } + + /** + * Returns the 'javax.sql.rowset.providers.RIOptimisticProvider' + * provider identification string. + * + * @return String Provider ID of this persistence provider + */ + public String getProviderID() { + return providerID; + } + + /** + * Returns the javax.sql.RowSetWriter object for this + * RIOptimisticProvider object. This is the writer that will + * write changes made to the Rowset object back to the data source. + * + * @return the javax.sql.RowSetWriter object for this + * RIOptimisticProvider object + */ + public RowSetWriter getRowSetWriter() { + try { + writer.setReader(reader); + } catch (java.sql.SQLException e) {} + return writer; + } + + /** + * Returns the javax.sql.RowSetReader object for this + * RIOptimisticProvider object. This is the reader that will + * populate a RowSet object using this RIOptimisticProvider. + * + * @return the javax.sql.RowSetReader object for this + * RIOptimisticProvider object + */ + public RowSetReader getRowSetReader() { + return reader; + } + + /** + * Returns the SyncProvider grade of synchronization that + * RowSet objects can expect when using this + * implementation. As an optimisic synchonization provider, the writer + * will only check rows that have been modified in the RowSet + * object. + */ + public int getProviderGrade() { + return SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT; + } + + /** + * Modifies the data source lock severity according to the standard + * SyncProvider classifications. + * + * @param datasource_lock An int indicating the level of locking to be + * set; must be one of the following constants: + *

+     *       SyncProvider.DATASOURCE_NO_LOCK,
+     *       SyncProvider.DATASOURCE_ROW_LOCK,
+     *       SyncProvider.DATASOURCE_TABLE_LOCK,
+     *       SyncProvider.DATASOURCE_DB_LOCk
+     * 
+ * @throws SyncProviderException if the parameter specified is not + * SyncProvider.DATASOURCE_NO_LOCK + */ + public void setDataSourceLock(int datasource_lock) throws SyncProviderException { + if(datasource_lock != SyncProvider.DATASOURCE_NO_LOCK ) { + throw new SyncProviderException(resBundle.handleGetObject("riop.locking").toString()); + } + } + + /** + * Returns the active data source lock severity in this + * reference implementation of the SyncProvider + * abstract class. + * + * @return SyncProvider.DATASOURCE_NO_LOCK. + * The reference implementation does not support data source locks. + */ + public int getDataSourceLock() throws SyncProviderException { + return SyncProvider.DATASOURCE_NO_LOCK; + } + + /** + * Returns the supported updatable view abilities of the + * reference implementation of the SyncProvider + * abstract class. + * + * @return SyncProvider.NONUPDATABLE_VIEW_SYNC. The + * the reference implementation does not support updating tables + * that are the source of a view. + */ + public int supportsUpdatableView() { + return SyncProvider.NONUPDATABLE_VIEW_SYNC; + } + + /** + * Returns the release version ID of the Reference Implementation Optimistic + * Synchronization Provider. + * + * @return the String detailing the version number of this SyncProvider + */ + public String getVersion() { + return this.versionNumber; + } + + /** + * Returns the vendor name of the Reference Implementation Optimistic + * Synchronization Provider + * + * @return the String detailing the vendor name of this + * SyncProvider + */ + public String getVendor() { + return this.vendorName; + } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + // Default state initialization happens here + ois.defaultReadObject(); + // Initialization of transient Res Bundle happens here . + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + + } + static final long serialVersionUID =-3143367176751761936L; + +} From c245081a1cb571608f159e4560b9bc242685ae5a Mon Sep 17 00:00:00 2001 From: = Date: Sat, 21 Oct 2023 12:25:40 +0200 Subject: [PATCH 2/7] Change version (8->9) for UBI Image --- .gitignore | 1 + Containerfile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e831a94..5c8dc60 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ data/* create_db.log create_db_error.log .DS_Store +.vscode \ No newline at end of file diff --git a/Containerfile b/Containerfile index 7394916..04ccf87 100644 --- a/Containerfile +++ b/Containerfile @@ -1,4 +1,4 @@ -FROM registry.access.redhat.com/ubi8/openjdk-11-runtime +FROM registry.access.redhat.com/ubi9/openjdk-11-runtime LABEL maintainer Oscar Salvador Magallanes LABEL maintainer Francesco Zanti From 67af077cc253ac9c766e57f4d512dd4eb96903a7 Mon Sep 17 00:00:00 2001 From: = Date: Sat, 21 Oct 2023 12:31:30 +0200 Subject: [PATCH 3/7] Change version (8->9) for UBI Image (Fix readme + Fix Github actions --- .github/workflows/CI_Release.yml | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI_Release.yml b/.github/workflows/CI_Release.yml index 456fc0c..911514e 100644 --- a/.github/workflows/CI_Release.yml +++ b/.github/workflows/CI_Release.yml @@ -92,7 +92,7 @@ jobs: context: . file: Containerfile push: ${{ github.event_name != 'pull_request' }} - tags: osalvador/replicadb:ubi8-${{ env.version }}, osalvador/replicadb:ubi8-latest + tags: osalvador/replicadb:ubi9-${{ env.version }}, osalvador/replicadb:ubi9-latest build-args: REPLICADB_RELEASE_VERSION=${{ env.version }} diff --git a/README.md b/README.md index 49b6fd5..8f94606 100644 --- a/README.md +++ b/README.md @@ -96,12 +96,12 @@ Visit the [project homepage on Docker Hub](https://hub.docker.com/r/osalvador/re ## Podman -Based on Red Hat UBI 8 +Based on Red Hat UBI 9 ```bash $ podman run \ -v /tmp/replicadb.conf:/home/replicadb/conf/replicadb.conf:Z \ - osalvador/replicadb:ubi8-latest + osalvador/replicadb:ubi9-latest ``` # Full Documentation From cec66cc417cc58f8d3af1d5233a8c4b7bdb09d38 Mon Sep 17 00:00:00 2001 From: Oscar Salvador Magallanes Date: Wed, 31 Jan 2024 16:12:38 +0100 Subject: [PATCH 4/7] feat: upgrade to jdk11 --- .github/workflows/CT_PushJDK11.yml | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 .github/workflows/CT_PushJDK11.yml diff --git a/.github/workflows/CT_PushJDK11.yml b/.github/workflows/CT_PushJDK11.yml new file mode 100644 index 0000000..b3d97a9 --- /dev/null +++ b/.github/workflows/CT_PushJDK11.yml @@ -0,0 +1,45 @@ +# This workflow will build a Java project with Maven +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven + +name: Only CI/CT + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + java-version: '11' + distribution: 'adopt' + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + settings-path: ${{ github.workspace }} # location for the settings.xml file + + - name: Get version + run: echo "version=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec) " >> $GITHUB_ENV + + - name: Build and Integration Tests + run: mvn -B package --file pom.xml + + - name: Clean Install + run: | + export REPLICADB_RELEASE_VERSION=${{ env.version }} + echo ${REPLICADB_RELEASE_VERSION} + mvn clean install -Dmaven.javadoc.skip=true -DskipTests -B -V -P release + cp ./target/ReplicaDB-*.jar . + mkdir lib + echo ${REPLICADB_RELEASE_VERSION} + cp ./target/lib/* ./lib + tar -zcvf ReplicaDB-v${REPLICADB_RELEASE_VERSION}.tar.gz ReplicaDB-*.jar README.md lib conf bin LICENSE + zip -r -X ReplicaDB-v${REPLICADB_RELEASE_VERSION}.zip ReplicaDB-*.jar README.md lib conf bin LICENSE + ls -lahtr + From 8e45f0f372023dd830026beb3cc3bc92f3a4e373 Mon Sep 17 00:00:00 2001 From: Oscar Salvador Magallanes Date: Wed, 31 Jan 2024 17:55:00 +0100 Subject: [PATCH 5/7] feat: refactor --- .github/workflows/CT_PushJDK11.yml | 2 +- src/main/java/org/replicadb/cli/ToolOptions.java | 16 ++++++++-------- src/main/java/org/replicadb/config/Sentry.java | 2 +- .../manager/file/FileManagerFactory.java | 2 +- .../replicadb/postgres/Postgres2CsvFileTest.java | 5 +++++ 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/workflows/CT_PushJDK11.yml b/.github/workflows/CT_PushJDK11.yml index b3d97a9..78c7322 100644 --- a/.github/workflows/CT_PushJDK11.yml +++ b/.github/workflows/CT_PushJDK11.yml @@ -1,7 +1,7 @@ # This workflow will build a Java project with Maven # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven -name: Only CI/CT +name: Only CI/CT JDK11 on: push: diff --git a/src/main/java/org/replicadb/cli/ToolOptions.java b/src/main/java/org/replicadb/cli/ToolOptions.java index 6bef077..e7d100b 100644 --- a/src/main/java/org/replicadb/cli/ToolOptions.java +++ b/src/main/java/org/replicadb/cli/ToolOptions.java @@ -32,7 +32,7 @@ public class ToolOptions { private String sinkStagingTableAlias; private String sinkStagingSchema; private String sinkColumns; - private String sinkFileformat; + private String sinkFileFormat; private Boolean sinkDisableEscape = false; private Boolean sinkDisableIndex = false; private Boolean sinkDisableTruncate = false; @@ -476,7 +476,7 @@ private void loadOptionsFile() throws IOException { setBandwidthThrottling(prop.getProperty("bandwidth.throttling")); setQuotedIdentifiers(Boolean.parseBoolean(prop.getProperty("quoted.identifiers"))); setSourceFileFormat(prop.getProperty("source.file.format")); - setSinkFileformat(prop.getProperty("sink.file.format")); + setSinkFileFormat(prop.getProperty("sink.file.format")); setSentryDsn(prop.getProperty("sentry.dsn")); // Connection params @@ -891,7 +891,7 @@ public String toString() { ",\n\tsourceConnectionParams=" + sourceConnectionParams + ",\n\tsinkConnectionParams=" + sinkConnectionParams + ",\n\tsourceFileFormat='" + sourceFileFormat + '\'' + - ",\n\tsinkFileformat='" + sinkFileformat + '\'' + + ",\n\tsinkFileformat='" + sinkFileFormat + '\'' + '}'; } @@ -938,17 +938,17 @@ private void setSourceFileFormatNotNull(String fileFormat) { this.sourceFileFormat = fileFormat; } - public String getSinkFileformat() { - return sinkFileformat; + public String getSinkFileFormat() { + return sinkFileFormat; } - public void setSinkFileformat(String sinkFileformat) { - this.sinkFileformat = sinkFileformat; + public void setSinkFileFormat(String sinkFileFormat) { + this.sinkFileFormat = sinkFileFormat; } private void setSinkFileFormatNotNull(String fileFormat) { if (fileFormat != null && !fileFormat.isEmpty()) - this.sinkFileformat = fileFormat; + this.sinkFileFormat = fileFormat; } public String getSentryDsn() { diff --git a/src/main/java/org/replicadb/config/Sentry.java b/src/main/java/org/replicadb/config/Sentry.java index 1e29cc7..42b2431 100644 --- a/src/main/java/org/replicadb/config/Sentry.java +++ b/src/main/java/org/replicadb/config/Sentry.java @@ -54,7 +54,7 @@ public static void SentryInit(ToolOptions options) { scope.setTag("source.connect", options.getSourceConnect()); scope.setTag("sink.connect", options.getSinkConnect()); if (options.getVersion() != null) scope.setTag("release.version", options.getVersion()); - if (options.getSinkFileformat() != null) scope.setTag("sink.file_format", options.getSinkFileformat()); + if (options.getSinkFileFormat() != null) scope.setTag("sink.file_format", options.getSinkFileFormat()); if (options.getSourceFileFormat() != null) scope.setTag("source.file_format", options.getSourceFileFormat()); }); diff --git a/src/main/java/org/replicadb/manager/file/FileManagerFactory.java b/src/main/java/org/replicadb/manager/file/FileManagerFactory.java index 321166b..dd8bd94 100644 --- a/src/main/java/org/replicadb/manager/file/FileManagerFactory.java +++ b/src/main/java/org/replicadb/manager/file/FileManagerFactory.java @@ -23,7 +23,7 @@ public FileManager accept(ToolOptions options, DataSourceType dsType) { if (dsType == DataSourceType.SOURCE) { fileFormat = options.getSourceFileFormat(); } else if (dsType == DataSourceType.SINK) { - fileFormat = options.getSinkFileformat(); + fileFormat = options.getSinkFileFormat(); } else { LOG.error("DataSourceType must be Source or Sink"); } diff --git a/src/test/java/org/replicadb/postgres/Postgres2CsvFileTest.java b/src/test/java/org/replicadb/postgres/Postgres2CsvFileTest.java index 51e7c79..c92003b 100644 --- a/src/test/java/org/replicadb/postgres/Postgres2CsvFileTest.java +++ b/src/test/java/org/replicadb/postgres/Postgres2CsvFileTest.java @@ -22,6 +22,7 @@ import java.nio.file.Paths; import java.sql.*; import java.util.HashMap; +import java.util.Properties; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -90,6 +91,10 @@ void testFileComplete () throws ParseException, IOException { }; ToolOptions options = new ToolOptions(args); + Properties sinkConnectionParams = new Properties(); + sinkConnectionParams.setProperty("format", "EXCEL"); + options.setSinkConnectionParams(sinkConnectionParams); + Assertions.assertEquals(0, ReplicaDB.processReplica(options)); assertEquals(TOTAL_SINK_ROWS, countSinkRows()); } From 9cfaff2d4833d7268972b828dcb48e890b6b61e6 Mon Sep 17 00:00:00 2001 From: Oscar Salvador Magallanes Date: Wed, 31 Jan 2024 17:55:18 +0100 Subject: [PATCH 6/7] chore: upgrade google guava --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 53d251a..63363d0 100644 --- a/pom.xml +++ b/pom.xml @@ -313,7 +313,7 @@ com.google.guava guava - [30.0-jre,) + 32.1.3-jre From 90eedfda45017f41325949f61665e9a8f82b125b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 00:21:34 +0000 Subject: [PATCH 7/7] build(deps): bump org.postgresql:postgresql from 42.3.7 to 42.7.2 Bumps [org.postgresql:postgresql](https://github.com/pgjdbc/pgjdbc) from 42.3.7 to 42.7.2. - [Release notes](https://github.com/pgjdbc/pgjdbc/releases) - [Changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md) - [Commits](https://github.com/pgjdbc/pgjdbc/commits) --- updated-dependencies: - dependency-name: org.postgresql:postgresql dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 63363d0..d4b2116 100644 --- a/pom.xml +++ b/pom.xml @@ -166,7 +166,7 @@ org.postgresql postgresql - 42.3.7 + 42.7.2