Path: blob/master/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java
40948 views
/*1* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.rowset;2627import java.sql.*;28import javax.sql.*;29import java.io.*;30import java.math.*;31import java.util.*;32import java.text.*;33import java.security.AccessController;34import java.security.PrivilegedActionException;35import java.security.PrivilegedExceptionAction;3637import javax.sql.rowset.*;38import javax.sql.rowset.spi.*;39import javax.sql.rowset.serial.*;40import com.sun.rowset.internal.*;41import com.sun.rowset.providers.*;42import sun.reflect.misc.ReflectUtil;4344import static java.nio.charset.StandardCharsets.US_ASCII;4546/**47* The standard implementation of the <code>CachedRowSet</code> interface.48*49* See interface definition for full behavior and implementation requirements.50* This reference implementation has made provision for a one-to-one write back51* facility and it is curremtly be possible to change the peristence provider52* during the life-time of any CachedRowSetImpl.53*54* @author Jonathan Bruce, Amit Handa55*/5657public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetInternal, Serializable, Cloneable, CachedRowSet {5859/**60* The <code>SyncProvider</code> used by the CachedRowSet61*/62private SyncProvider provider;6364/**65* The <code>RowSetReaderImpl</code> object that is the reader66* for this rowset. The method <code>execute</code> uses this67* reader as part of its implementation.68* @serial69*/70private RowSetReader rowSetReader;7172/**73* The <code>RowSetWriterImpl</code> object that is the writer74* for this rowset. The method <code>acceptChanges</code> uses75* this writer as part of its implementation.76* @serial77*/78private RowSetWriter rowSetWriter;7980/**81* The <code>Connection</code> object that connects with this82* <code>CachedRowSetImpl</code> object's current underlying data source.83*/84private transient Connection conn;8586/**87* The <code>ResultSetMetaData</code> object that contains information88* about the columns in the <code>ResultSet</code> object that is the89* current source of data for this <code>CachedRowSetImpl</code> object.90*/91private transient ResultSetMetaData RSMD;9293/**94* The <code>RowSetMetaData</code> object that contains information about95* the columns in this <code>CachedRowSetImpl</code> object.96* @serial97*/98private RowSetMetaDataImpl RowSetMD;99100// Properties of this RowSet101102/**103* An array containing the columns in this <code>CachedRowSetImpl</code>104* object that form a unique identifier for a row. This array105* is used by the writer.106* @serial107*/108private int keyCols[];109110/**111* The name of the table in the underlying database to which updates112* should be written. This name is needed because most drivers113* do not return this information in a <code>ResultSetMetaData</code>114* object.115* @serial116*/117private String tableName;118119/**120* A <code>Vector</code> object containing the <code>Row</code>121* objects that comprise this <code>CachedRowSetImpl</code> object.122* @serial123*/124private Vector<Object> rvh;125126/**127* The current position of the cursor in this <code>CachedRowSetImpl</code>128* object.129* @serial130*/131private int cursorPos;132133/**134* The current position of the cursor in this <code>CachedRowSetImpl</code>135* object not counting rows that have been deleted, if any.136* <P>137* For example, suppose that the cursor is on the last row of a rowset138* that started with five rows and subsequently had the second and third139* rows deleted. The <code>absolutePos</code> would be <code>3</code>,140* whereas the <code>cursorPos</code> would be <code>5</code>.141* @serial142*/143private int absolutePos;144145/**146* The number of deleted rows currently in this <code>CachedRowSetImpl</code>147* object.148* @serial149*/150private int numDeleted;151152/**153* The total number of rows currently in this <code>CachedRowSetImpl</code>154* object.155* @serial156*/157private int numRows;158159/**160* A special row used for constructing a new row. A new161* row is constructed by using <code>ResultSet.updateXXX</code>162* methods to insert column values into the insert row.163* @serial164*/165private InsertRow insertRow;166167/**168* A <code>boolean</code> indicating whether the cursor is169* currently on the insert row.170* @serial171*/172private boolean onInsertRow;173174/**175* The field that temporarily holds the last position of the176* cursor before it moved to the insert row, thus preserving177* the number of the current row to which the cursor may return.178* @serial179*/180private int currentRow;181182/**183* A <code>boolean</code> indicating whether the last value184* returned was an SQL <code>NULL</code>.185* @serial186*/187private boolean lastValueNull;188189/**190* A <code>SQLWarning</code> which logs on the warnings191*/192private SQLWarning sqlwarn;193194/**195* Used to track match column for JoinRowSet consumption196*/197private String strMatchColumn ="";198199/**200* Used to track match column for JoinRowSet consumption201*/202private int iMatchColumn = -1;203204/**205* A <code>RowSetWarning</code> which logs on the warnings206*/207private RowSetWarning rowsetWarning;208209/**210* The default SyncProvider for the RI CachedRowSetImpl211*/212private String DEFAULT_SYNC_PROVIDER = "com.sun.rowset.providers.RIOptimisticProvider";213214/**215* The boolean variable indicating locatorsUpdateValue216*/217private boolean dbmslocatorsUpdateCopy;218219/**220* The <code>ResultSet</code> object that is used to maintain the data when221* a ResultSet and start position are passed as parameters to the populate function222*/223private transient ResultSet resultSet;224225/**226* The integer value indicating the end position in the ResultSetwhere the picking227* up of rows for populating a CachedRowSet object was left off.228*/229private int endPos;230231/**232* The integer value indicating the end position in the ResultSetwhere the picking233* up of rows for populating a CachedRowSet object was left off.234*/235private int prevEndPos;236237/**238* The integer value indicating the position in the ResultSet, to populate the239* CachedRowSet object.240*/241private int startPos;242243/**244* The integer value indicating the position from where the page prior to this245* was populated.246*/247private int startPrev;248249/**250* The integer value indicating size of the page.251*/252private int pageSize;253254/**255* The integer value indicating number of rows that have been processed so far.256* Used for checking whether maxRows has been reached or not.257*/258private int maxRowsreached;259/**260* The boolean value when true signifies that pages are still to follow and a261* false value indicates that this is the last page.262*/263private boolean pagenotend = true;264265/**266* The boolean value indicating whether this is the first page or not.267*/268private boolean onFirstPage;269270/**271* The boolean value indicating whether this is the last page or not.272*/273private boolean onLastPage;274275/**276* The integer value indicating how many times the populate function has been called.277*/278private int populatecallcount;279280/**281* The integer value indicating the total number of rows to be processed in the282* ResultSet object passed to the populate function.283*/284private int totalRows;285286/**287* The boolean value indicating how the CahedRowSet object has been populated for288* paging purpose. True indicates that connection parameter is passed.289*/290private boolean callWithCon;291292/**293* CachedRowSet reader object to read the data from the ResultSet when a connection294* parameter is passed to populate the CachedRowSet object for paging.295*/296private CachedRowSetReader crsReader;297298/**299* The Vector holding the Match Columns300*/301private Vector<Integer> iMatchColumns;302303/**304* The Vector that will hold the Match Column names.305*/306private Vector<String> strMatchColumns;307308/**309* Trigger that indicates whether the active SyncProvider is exposes the310* additional TransactionalWriter method311*/312private boolean tXWriter = false;313314/**315* The field object for a transactional RowSet writer316*/317private TransactionalWriter tWriter = null;318319protected transient JdbcRowSetResourceBundle resBundle;320321private boolean updateOnInsert;322323324325/**326* Constructs a new default <code>CachedRowSetImpl</code> object with327* the capacity to hold 100 rows. This new object has no metadata328* and has the following default values:329* <pre>330* onInsertRow = false331* insertRow = null332* cursorPos = 0333* numRows = 0334* showDeleted = false335* queryTimeout = 0336* maxRows = 0337* maxFieldSize = 0338* rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE339* concurrency = ResultSet.CONCUR_UPDATABLE340* readOnly = false341* isolation = Connection.TRANSACTION_READ_COMMITTED342* escapeProcessing = true343* onInsertRow = false344* insertRow = null345* cursorPos = 0346* absolutePos = 0347* numRows = 0348* </pre>349* A <code>CachedRowSetImpl</code> object is configured to use the default350* <code>RIOptimisticProvider</code> implementation to provide connectivity351* and synchronization capabilities to the set data source.352* <P>353* @throws SQLException if an error occurs354*/355@SuppressWarnings("removal")356public CachedRowSetImpl() throws SQLException {357358try {359resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();360} catch(IOException ioe) {361throw new RuntimeException(ioe);362}363364// set the Reader, this maybe overridden latter365try {366provider = AccessController.doPrivileged(new PrivilegedExceptionAction<>() {367@Override368public SyncProvider run() throws SyncFactoryException {369return SyncFactory.getInstance(DEFAULT_SYNC_PROVIDER);370}371}, null, new RuntimePermission("accessClassInPackage.com.sun.rowset.providers"));372} catch (PrivilegedActionException pae) {373throw (SyncFactoryException) pae.getException();374}375376if (!(provider instanceof RIOptimisticProvider)) {377throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidp").toString());378}379380rowSetReader = (CachedRowSetReader)provider.getRowSetReader();381rowSetWriter = (CachedRowSetWriter)provider.getRowSetWriter();382383// allocate the parameters collection384initParams();385386initContainer();387388// set up some default values389initProperties();390391// insert row setup392onInsertRow = false;393insertRow = null;394395// set the warninings396sqlwarn = new SQLWarning();397rowsetWarning = new RowSetWarning();398399}400401/**402* Provides a <code>CachedRowSetImpl</code> instance with the same default properties as403* as the zero parameter constructor.404* <pre>405* onInsertRow = false406* insertRow = null407* cursorPos = 0408* numRows = 0409* showDeleted = false410* queryTimeout = 0411* maxRows = 0412* maxFieldSize = 0413* rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE414* concurrency = ResultSet.CONCUR_UPDATABLE415* readOnly = false416* isolation = Connection.TRANSACTION_READ_COMMITTED417* escapeProcessing = true418* onInsertRow = false419* insertRow = null420* cursorPos = 0421* absolutePos = 0422* numRows = 0423* </pre>424*425* However, applications will have the means to specify at runtime the426* desired <code>SyncProvider</code> object.427* <p>428* For example, creating a <code>CachedRowSetImpl</code> object as follows ensures429* that a it is established with the <code>com.foo.provider.Impl</code> synchronization430* implementation providing the synchronization mechanism for this disconnected431* <code>RowSet</code> object.432* <pre>433* Hashtable env = new Hashtable();434* env.put(javax.sql.rowset.spi.SyncFactory.ROWSET_PROVIDER_NAME,435* "com.foo.provider.Impl");436* CachedRowSetImpl crs = new CachedRowSet(env);437* </pre>438* <p>439* Calling this constructor with a <code>null</code> parameter will440* cause the <code>SyncFactory</code> to provide the reference441* optimistic provider <code>com.sun.rowset.providers.RIOptimisticProvider</code>.442* <p>443* In addition, the following properties can be associated with the444* provider to assist in determining the choice of the synchronizaton445* provider such as:446* <ul>447* <li><code>ROWSET_SYNC_PROVIDER</code> - the property specifying the448* <code>SyncProvider</code> class name to be instantiated by the449* <code>SyncFacttory</code>450* <li><code>ROWSET_SYNC_VENDOR</code> - the property specifying the software451* vendor associated with a <code>SyncProvider</code> implementation.452* <li><code>ROWSET_SYNC_PROVIDER_VER</code> - the property specifying the453* version of the <code>SyncProvider</code> implementation provided by the454* software vendor.455* </ul>456* More specific detailes are available in the <code>SyncFactory</code>457* and <code>SyncProvider</code> specificiations later in this document.458* <p>459* @param env a <code>Hashtable</code> object with a list of desired460* synchronization providers461* @throws SQLException if the requested provider cannot be found by the462* synchronization factory463* @see SyncProvider464*/465public CachedRowSetImpl(@SuppressWarnings("rawtypes") Hashtable env) throws SQLException {466467468try {469resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();470} catch(IOException ioe) {471throw new RuntimeException(ioe);472}473474if (env == null) {475throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nullhash").toString());476}477478String providerName = (String)env.get(479javax.sql.rowset.spi.SyncFactory.ROWSET_SYNC_PROVIDER);480481// set the Reader, this maybe overridden latter482provider =483SyncFactory.getInstance(providerName);484485rowSetReader = provider.getRowSetReader();486rowSetWriter = provider.getRowSetWriter();487488initParams(); // allocate the parameters collection489initContainer();490initProperties(); // set up some default values491}492493/**494* Sets the <code>rvh</code> field to a new <code>Vector</code>495* object with a capacity of 100 and sets the496* <code>cursorPos</code> and <code>numRows</code> fields to zero.497*/498private void initContainer() {499500rvh = new Vector<Object>(100);501cursorPos = 0;502absolutePos = 0;503numRows = 0;504numDeleted = 0;505}506507/**508* Sets the properties for this <code>CachedRowSetImpl</code> object to509* their default values. This method is called internally by the510* default constructor.511*/512513private void initProperties() throws SQLException {514515if(resBundle == null) {516try {517resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();518} catch(IOException ioe) {519throw new RuntimeException(ioe);520}521}522setShowDeleted(false);523setQueryTimeout(0);524setMaxRows(0);525setMaxFieldSize(0);526setType(ResultSet.TYPE_SCROLL_INSENSITIVE);527setConcurrency(ResultSet.CONCUR_UPDATABLE);528if((rvh.size() > 0) && (isReadOnly() == false))529setReadOnly(false);530else531setReadOnly(true);532setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);533setEscapeProcessing(true);534//setTypeMap(null);535checkTransactionalWriter();536537//Instantiating the vector for MatchColumns538539iMatchColumns = new Vector<Integer>(10);540for(int i = 0; i < 10 ; i++) {541iMatchColumns.add(i, -1);542}543544strMatchColumns = new Vector<String>(10);545for(int j = 0; j < 10; j++) {546strMatchColumns.add(j,null);547}548}549550/**551* Determine whether the SyncProvider's writer implements the552* <code>TransactionalWriter<code> interface553*/554private void checkTransactionalWriter() {555if (rowSetWriter != null) {556Class<?> c = rowSetWriter.getClass();557if (c != null) {558Class<?>[] theInterfaces = c.getInterfaces();559for (int i = 0; i < theInterfaces.length; i++) {560if ((theInterfaces[i].getName()).indexOf("TransactionalWriter") > 0) {561tXWriter = true;562establishTransactionalWriter();563}564}565}566}567}568569/**570* Sets an private field to all transaction bounddaries to be set571*/572private void establishTransactionalWriter() {573tWriter = (TransactionalWriter)provider.getRowSetWriter();574}575576//-----------------------------------------------------------------------577// Properties578//-----------------------------------------------------------------------579580/**581* Sets this <code>CachedRowSetImpl</code> object's command property582* to the given <code>String</code> object and clears the parameters,583* if any, that were set for the previous command.584* <P>585* The command property may not be needed586* if the rowset is produced by a data source, such as a spreadsheet,587* that does not support commands. Thus, this property is optional588* and may be <code>null</code>.589*590* @param cmd a <code>String</code> object containing an SQL query591* that will be set as the command; may be <code>null</code>592* @throws SQLException if an error occurs593*/594public void setCommand(String cmd) throws SQLException {595596super.setCommand(cmd);597598if(!buildTableName(cmd).isEmpty()) {599this.setTableName(buildTableName(cmd));600}601}602603604//---------------------------------------------------------------------605// Reading and writing data606//---------------------------------------------------------------------607608/**609* Populates this <code>CachedRowSetImpl</code> object with data from610* the given <code>ResultSet</code> object. This611* method is an alternative to the method <code>execute</code>612* for filling the rowset with data. The method <code>populate</code>613* does not require that the properties needed by the method614* <code>execute</code>, such as the <code>command</code> property,615* be set. This is true because the method <code>populate</code>616* is given the <code>ResultSet</code> object from617* which to get data and thus does not need to use the properties618* required for setting up a connection and executing this619* <code>CachedRowSetImpl</code> object's command.620* <P>621* After populating this rowset with data, the method622* <code>populate</code> sets the rowset's metadata and623* then sends a <code>RowSetChangedEvent</code> object624* to all registered listeners prior to returning.625*626* @param data the <code>ResultSet</code> object containing the data627* to be read into this <code>CachedRowSetImpl</code> object628* @throws SQLException if an error occurs; or the max row setting is629* violated while populating the RowSet630* @see #execute631*/632633public void populate(ResultSet data) throws SQLException {634int rowsFetched;635Row currentRow;636int numCols;637int i;638Map<String, Class<?>> map = getTypeMap();639Object obj;640int mRows;641642if (data == null) {643throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString());644}645this.resultSet = data;646647// get the meta data for this ResultSet648RSMD = data.getMetaData();649650// set up the metadata651RowSetMD = new RowSetMetaDataImpl();652initMetaData(RowSetMD, RSMD);653654// release the meta-data so that aren't tempted to use it.655RSMD = null;656numCols = RowSetMD.getColumnCount();657mRows = this.getMaxRows();658rowsFetched = 0;659currentRow = null;660661while ( data.next()) {662663currentRow = new Row(numCols);664665if ( rowsFetched > mRows && mRows > 0) {666rowsetWarning.setNextWarning(new RowSetWarning("Populating rows "667+ "setting has exceeded max row setting"));668}669for ( i = 1; i <= numCols; i++) {670/*671* check if the user has set a map. If no map672* is set then use plain getObject. This lets673* us work with drivers that do not support674* getObject with a map in fairly sensible way675*/676if (map == null || map.isEmpty()) {677obj = data.getObject(i);678} else {679obj = data.getObject(i, map);680}681/*682* the following block checks for the various683* types that we have to serialize in order to684* store - right now only structs have been tested685*/686if (obj instanceof Struct) {687obj = new SerialStruct((Struct)obj, map);688} else if (obj instanceof SQLData) {689obj = new SerialStruct((SQLData)obj, map);690} else if (obj instanceof Blob) {691obj = new SerialBlob((Blob)obj);692} else if (obj instanceof Clob) {693obj = new SerialClob((Clob)obj);694} else if (obj instanceof java.sql.Array) {695if(map != null)696obj = new SerialArray((java.sql.Array)obj, map);697else698obj = new SerialArray((java.sql.Array)obj);699}700701currentRow.initColumnObject(i, obj);702}703rowsFetched++;704rvh.add(currentRow);705}706707numRows = rowsFetched ;708// Also rowsFetched should be equal to rvh.size()709710// notify any listeners that the rowset has changed711notifyRowSetChanged();712713714}715716/**717* Initializes the given <code>RowSetMetaData</code> object with the values718* in the given <code>ResultSetMetaData</code> object.719*720* @param md the <code>RowSetMetaData</code> object for this721* <code>CachedRowSetImpl</code> object, which will be set with722* values from rsmd723* @param rsmd the <code>ResultSetMetaData</code> object from which new724* values for md will be read725* @throws SQLException if an error occurs726*/727private void initMetaData(RowSetMetaDataImpl md, ResultSetMetaData rsmd) throws SQLException {728int numCols = rsmd.getColumnCount();729730md.setColumnCount(numCols);731for (int col=1; col <= numCols; col++) {732md.setAutoIncrement(col, rsmd.isAutoIncrement(col));733if(rsmd.isAutoIncrement(col))734updateOnInsert = true;735md.setCaseSensitive(col, rsmd.isCaseSensitive(col));736md.setCurrency(col, rsmd.isCurrency(col));737md.setNullable(col, rsmd.isNullable(col));738md.setSigned(col, rsmd.isSigned(col));739md.setSearchable(col, rsmd.isSearchable(col));740/*741* The PostgreSQL drivers sometimes return negative columnDisplaySize,742* which causes an exception to be thrown. Check for it.743*/744int size = rsmd.getColumnDisplaySize(col);745if (size < 0) {746size = 0;747}748md.setColumnDisplaySize(col, size);749md.setColumnLabel(col, rsmd.getColumnLabel(col));750md.setColumnName(col, rsmd.getColumnName(col));751md.setSchemaName(col, rsmd.getSchemaName(col));752/*753* Drivers return some strange values for precision, for non-numeric data, including reports of754* non-integer values; maybe we should check type, & set to 0 for non-numeric types.755*/756int precision = rsmd.getPrecision(col);757if (precision < 0) {758precision = 0;759}760md.setPrecision(col, precision);761762/*763* It seems, from a bug report, that a driver can sometimes return a negative764* value for scale. javax.sql.rowset.RowSetMetaDataImpl will throw an exception765* if we attempt to set a negative value. As such, we'll check for this case.766*/767int scale = rsmd.getScale(col);768if (scale < 0) {769scale = 0;770}771md.setScale(col, scale);772md.setTableName(col, rsmd.getTableName(col));773md.setCatalogName(col, rsmd.getCatalogName(col));774md.setColumnType(col, rsmd.getColumnType(col));775md.setColumnTypeName(col, rsmd.getColumnTypeName(col));776}777778if( conn != null){779// JDBC 4.0 mandates as does the Java EE spec that all DataBaseMetaData methods780// must be implemented, therefore, the previous fix for 5055528 is being backed out781dbmslocatorsUpdateCopy = conn.getMetaData().locatorsUpdateCopy();782}783}784785/**786* Populates this <code>CachedRowSetImpl</code> object with data,787* using the given connection to produce the result set from788* which data will be read. A second form of this method,789* which takes no arguments, uses the values from this rowset's790* user, password, and either url or data source properties to791* create a new database connection. The form of <code>execute</code>792* that is given a connection ignores these properties.793*794* @param conn A standard JDBC <code>Connection</code> object that this795* <code>CachedRowSet</code> object can pass to a synchronization provider796* to establish a connection to the data source797* @throws SQLException if an invalid <code>Connection</code> is supplied798* or an error occurs in establishing the connection to the799* data source800* @see #populate801* @see java.sql.Connection802*/803public void execute(Connection conn) throws SQLException {804// store the connection so the reader can find it.805setConnection(conn);806807if(getPageSize() != 0){808crsReader = (CachedRowSetReader)provider.getRowSetReader();809crsReader.setStartPosition(1);810callWithCon = true;811crsReader.readData((RowSetInternal)this);812}813814// Now call the current reader's readData method815else {816rowSetReader.readData((RowSetInternal)this);817}818RowSetMD = (RowSetMetaDataImpl)this.getMetaData();819820if(conn != null){821// JDBC 4.0 mandates as does the Java EE spec that all DataBaseMetaData methods822// must be implemented, therefore, the previous fix for 5055528 is being backed out823dbmslocatorsUpdateCopy = conn.getMetaData().locatorsUpdateCopy();824}825826}827828/**829* Sets this <code>CachedRowSetImpl</code> object's connection property830* to the given <code>Connection</code> object. This method is called831* internally by the version of the method <code>execute</code> that takes a832* <code>Connection</code> object as an argument. The reader for this833* <code>CachedRowSetImpl</code> object can retrieve the connection stored834* in the rowset's connection property by calling its835* <code>getConnection</code> method.836*837* @param connection the <code>Connection</code> object that was passed in838* to the method <code>execute</code> and is to be stored839* in this <code>CachedRowSetImpl</code> object's connection840* property841*/842private void setConnection (Connection connection) {843conn = connection;844}845846847/**848* Propagates all row update, insert, and delete changes to the849* underlying data source backing this <code>CachedRowSetImpl</code>850* object.851* <P>852* <b>Note</b>In the reference implementation an optimistic concurrency implementation853* is provided as a sample implementation of a the <code>SyncProvider</code>854* abstract class.855* <P>856* This method fails if any of the updates cannot be propagated back857* to the data source. When it fails, the caller can assume that858* none of the updates are reflected in the data source.859* When an exception is thrown, the current row860* is set to the first "updated" row that resulted in an exception861* unless the row that caused the exception is a "deleted" row.862* In that case, when deleted rows are not shown, which is usually true,863* the current row is not affected.864* <P>865* If no <code>SyncProvider</code> is configured, the reference implementation866* leverages the <code>RIOptimisticProvider</code> available which provides the867* default and reference synchronization capabilities for disconnected868* <code>RowSets</code>.869*870* @throws SQLException if the cursor is on the insert row or the underlying871* reference synchronization provider fails to commit the updates872* to the datasource873* @throws SyncProviderException if an internal error occurs within the874* <code>SyncProvider</code> instance during either during the875* process or at any time when the <code>SyncProvider</code>876* instance touches the data source.877* @see #acceptChanges(java.sql.Connection)878* @see javax.sql.RowSetWriter879* @see javax.sql.rowset.spi.SyncProvider880*/881public void acceptChanges() throws SyncProviderException {882if (onInsertRow == true) {883throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());884}885886int saveCursorPos = cursorPos;887boolean success = false;888boolean conflict = false;889890try {891if (rowSetWriter != null) {892saveCursorPos = cursorPos;893conflict = rowSetWriter.writeData((RowSetInternal)this);894cursorPos = saveCursorPos;895}896897if (tXWriter) {898// do commit/rollback's here899if (!conflict) {900tWriter = (TransactionalWriter)rowSetWriter;901tWriter.rollback();902success = false;903} else {904tWriter = (TransactionalWriter)rowSetWriter;905if (tWriter instanceof CachedRowSetWriter) {906((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);907} else {908tWriter.commit();909}910911success = true;912}913}914915if (success == true) {916setOriginal();917} else if (!(success) ) {918throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.accfailed").toString());919}920921} catch (SyncProviderException spe) {922throw spe;923} catch (SQLException e) {924e.printStackTrace();925throw new SyncProviderException(e.getMessage());926} catch (SecurityException e) {927throw new SyncProviderException(e.getMessage());928}929}930931/**932* Propagates all row update, insert, and delete changes to the933* data source backing this <code>CachedRowSetImpl</code> object934* using the given <code>Connection</code> object.935* <P>936* The reference implementation <code>RIOptimisticProvider</code>937* modifies its synchronization to a write back function given938* the updated connection939* The reference implementation modifies its synchronization behaviour940* via the <code>SyncProvider</code> to ensure the synchronization941* occurs according to the updated JDBC <code>Connection</code>942* properties.943*944* @param con a standard JDBC <code>Connection</code> object945* @throws SQLException if the cursor is on the insert row or the underlying946* synchronization provider fails to commit the updates947* back to the data source948* @see #acceptChanges949* @see javax.sql.RowSetWriter950* @see javax.sql.rowset.spi.SyncFactory951* @see javax.sql.rowset.spi.SyncProvider952*/953public void acceptChanges(Connection con) throws SyncProviderException{954setConnection(con);955acceptChanges();956}957958/**959* Restores this <code>CachedRowSetImpl</code> object to its original state,960* that is, its state before the last set of changes.961* <P>962* Before returning, this method moves the cursor before the first row963* and sends a <code>rowSetChanged</code> event to all registered964* listeners.965* @throws SQLException if an error is occurs rolling back the RowSet966* state to the definied original value.967* @see javax.sql.RowSetListener#rowSetChanged968*/969public void restoreOriginal() throws SQLException {970Row currentRow;971for (Iterator<?> i = rvh.iterator(); i.hasNext();) {972currentRow = (Row)i.next();973if (currentRow.getInserted() == true) {974i.remove();975--numRows;976} else {977if (currentRow.getDeleted() == true) {978currentRow.clearDeleted();979}980if (currentRow.getUpdated() == true) {981currentRow.clearUpdated();982}983}984}985// move to before the first986cursorPos = 0;987988// notify any listeners989notifyRowSetChanged();990}991992/**993* Releases the current contents of this <code>CachedRowSetImpl</code>994* object and sends a <code>rowSetChanged</code> event object to all995* registered listeners.996*997* @throws SQLException if an error occurs flushing the contents of998* RowSet.999* @see javax.sql.RowSetListener#rowSetChanged1000*/1001public void release() throws SQLException {1002initContainer();1003notifyRowSetChanged();1004}10051006/**1007* Cancels deletion of the current row and notifies listeners that1008* a row has changed.1009* <P>1010* Note: This method can be ignored if deleted rows are not being shown,1011* which is the normal case.1012*1013* @throws SQLException if the cursor is not on a valid row1014*/1015public void undoDelete() throws SQLException {1016if (getShowDeleted() == false) {1017return;1018}1019// make sure we are on a row1020checkCursor();10211022// don't want this to happen...1023if (onInsertRow == true) {1024throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());1025}10261027Row currentRow = (Row)getCurrentRow();1028if (currentRow.getDeleted() == true) {1029currentRow.clearDeleted();1030--numDeleted;1031notifyRowChanged();1032}1033}10341035/**1036* Immediately removes the current row from this1037* <code>CachedRowSetImpl</code> object if the row has been inserted, and1038* also notifies listeners the a row has changed. An exception is thrown1039* if the row is not a row that has been inserted or the cursor is before1040* the first row, after the last row, or on the insert row.1041* <P>1042* This operation cannot be undone.1043*1044* @throws SQLException if an error occurs,1045* the cursor is not on a valid row,1046* or the row has not been inserted1047*/1048public void undoInsert() throws SQLException {1049// make sure we are on a row1050checkCursor();10511052// don't want this to happen...1053if (onInsertRow == true) {1054throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());1055}10561057Row currentRow = (Row)getCurrentRow();1058if (currentRow.getInserted() == true) {1059rvh.remove(cursorPos-1);1060--numRows;1061notifyRowChanged();1062} else {1063throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.illegalop").toString());1064}1065}10661067/**1068* Immediately reverses the last update operation if the1069* row has been modified. This method can be1070* called to reverse updates on a all columns until all updates in a row have1071* been rolled back to their originating state since the last synchronization1072* (<code>acceptChanges</code>) or population. This method may also be called1073* while performing updates to the insert row.1074* <P>1075* {@code undoUpdate} may be called at any time during the life-time of a1076* rowset, however after a synchronization has occurs this method has no1077* affect until further modification to the RowSet data occurs.1078*1079* @throws SQLException if cursor is before the first row, after the last1080* row in rowset.1081* @see #undoDelete1082* @see #undoInsert1083* @see java.sql.ResultSet#cancelRowUpdates1084*/1085public void undoUpdate() throws SQLException {1086// if on insert row, cancel the insert row1087// make the insert row flag,1088// cursorPos back to the current row1089moveToCurrentRow();10901091// else if not on insert row1092// call undoUpdate or undoInsert1093undoDelete();10941095undoInsert();10961097}10981099//--------------------------------------------------------------------1100// Views1101//--------------------------------------------------------------------11021103/**1104* Returns a new <code>RowSet</code> object backed by the same data as1105* that of this <code>CachedRowSetImpl</code> object and sharing a set of cursors1106* with it. This allows cursors to interate over a shared set of rows, providing1107* multiple views of the underlying data.1108*1109* @return a <code>RowSet</code> object that is a copy of this <code>CachedRowSetImpl</code>1110* object and shares a set of cursors with it1111* @throws SQLException if an error occurs or cloning is1112* not supported1113* @see javax.sql.RowSetEvent1114* @see javax.sql.RowSetListener1115*/1116public RowSet createShared() throws SQLException {1117RowSet clone;1118try {1119clone = (RowSet)clone();1120} catch (CloneNotSupportedException ex) {1121throw new SQLException(ex.getMessage());1122}1123return clone;1124}11251126/**1127* Returns a new <code>RowSet</code> object containing by the same data1128* as this <code>CachedRowSetImpl</code> object. This method1129* differs from the method <code>createCopy</code> in that it throws a1130* <code>CloneNotSupportedException</code> object instead of an1131* <code>SQLException</code> object, as the method <code>createShared</code>1132* does. This <code>clone</code>1133* method is called internally by the method <code>createShared</code>,1134* which catches the <code>CloneNotSupportedException</code> object1135* and in turn throws a new <code>SQLException</code> object.1136*1137* @return a copy of this <code>CachedRowSetImpl</code> object1138* @throws CloneNotSupportedException if an error occurs when1139* attempting to clone this <code>CachedRowSetImpl</code> object1140* @see #createShared1141*/1142protected Object clone() throws CloneNotSupportedException {1143return (super.clone());1144}11451146/**1147* Creates a <code>RowSet</code> object that is a deep copy of1148* this <code>CachedRowSetImpl</code> object's data, including1149* constraints. Updates made1150* on a copy are not visible to the original rowset;1151* a copy of a rowset is completely independent from the original.1152* <P>1153* Making a copy saves the cost of creating an identical rowset1154* from first principles, which can be quite expensive.1155* For example, it can eliminate the need to query a1156* remote database server.1157* @return a new <code>CachedRowSet</code> object that is a deep copy1158* of this <code>CachedRowSet</code> object and is1159* completely independent from this <code>CachedRowSetImpl</code>1160* object.1161* @throws SQLException if an error occurs in generating the copy of this1162* of the <code>CachedRowSetImpl</code>1163* @see #createShared1164* @see javax.sql.RowSetEvent1165* @see javax.sql.RowSetListener1166*/1167public CachedRowSet createCopy() throws SQLException {1168ObjectOutputStream out;1169ByteArrayOutputStream bOut = new ByteArrayOutputStream();1170try {1171out = new ObjectOutputStream(bOut);1172out.writeObject(this);1173} catch (IOException ex) {1174throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1175}11761177ObjectInputStream in;11781179try {1180ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());1181in = new ObjectInputStream(bIn);1182} catch (StreamCorruptedException ex) {1183throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1184} catch (IOException ex) {1185throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1186}11871188try {1189//return ((CachedRowSet)(in.readObject()));1190CachedRowSetImpl crsTemp = (CachedRowSetImpl)in.readObject();1191crsTemp.resBundle = this.resBundle;1192return ((CachedRowSet)crsTemp);11931194} catch (ClassNotFoundException ex) {1195throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1196} catch (OptionalDataException ex) {1197throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1198} catch (IOException ex) {1199throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1200}1201}12021203/**1204* Creates a <code>RowSet</code> object that is a copy of1205* this <code>CachedRowSetImpl</code> object's table structure1206* and the constraints only.1207* There will be no data in the object being returned.1208* Updates made on a copy are not visible to the original rowset.1209* <P>1210* This helps in getting the underlying XML schema which can1211* be used as the basis for populating a <code>WebRowSet</code>.1212*1213* @return a new <code>CachedRowSet</code> object that is a copy1214* of this <code>CachedRowSetImpl</code> object's schema and1215* retains all the constraints on the original rowset but contains1216* no data1217* @throws SQLException if an error occurs in generating the copy1218* of the <code>CachedRowSet</code> object1219* @see #createShared1220* @see #createCopy1221* @see #createCopyNoConstraints1222* @see javax.sql.RowSetEvent1223* @see javax.sql.RowSetListener1224*/1225public CachedRowSet createCopySchema() throws SQLException {1226// Copy everything except data i.e all constraints12271228// Store the number of rows of "this"1229// and make numRows equals zero.1230// and make data also zero.1231int nRows = numRows;1232numRows = 0;12331234CachedRowSet crs = this.createCopy();12351236// reset this object back to number of rows.1237numRows = nRows;12381239return crs;1240}12411242/**1243* Creates a <code>CachedRowSet</code> object that is a copy of1244* this <code>CachedRowSetImpl</code> object's data only.1245* All constraints set in this object will not be there1246* in the returning object. Updates made1247* on a copy are not visible to the original rowset.1248*1249* @return a new <code>CachedRowSet</code> object that is a deep copy1250* of this <code>CachedRowSetImpl</code> object and is1251* completely independent from this <code>CachedRowSetImpl</code> object1252* @throws SQLException if an error occurs in generating the copy of the1253* of the <code>CachedRowSet</code>1254* @see #createShared1255* @see #createCopy1256* @see #createCopySchema1257* @see javax.sql.RowSetEvent1258* @see javax.sql.RowSetListener1259*/1260public CachedRowSet createCopyNoConstraints() throws SQLException {1261// Copy the whole data ONLY without any constraints.1262CachedRowSetImpl crs;1263crs = (CachedRowSetImpl)this.createCopy();12641265crs.initProperties();1266try {1267crs.unsetMatchColumn(crs.getMatchColumnIndexes());1268} catch(SQLException sqle) {1269//do nothing, if the setMatchColumn is not set.1270}12711272try {1273crs.unsetMatchColumn(crs.getMatchColumnNames());1274} catch(SQLException sqle) {1275//do nothing, if the setMatchColumn is not set.1276}12771278return crs;1279}12801281/**1282* Converts this <code>CachedRowSetImpl</code> object to a collection1283* of tables. The sample implementation utilitizes the <code>TreeMap</code>1284* collection type.1285* This class guarantees that the map will be in ascending key order,1286* sorted according to the natural order for the key's class.1287*1288* @return a <code>Collection</code> object consisting of tables,1289* each of which is a copy of a row in this1290* <code>CachedRowSetImpl</code> object1291* @throws SQLException if an error occurs in generating the collection1292* @see #toCollection(int)1293* @see #toCollection(String)1294* @see java.util.TreeMap1295*/1296public Collection<?> toCollection() throws SQLException {12971298TreeMap<Integer, Object> tMap = new TreeMap<>();12991300for (int i = 0; i<numRows; i++) {1301tMap.put(i, rvh.get(i));1302}13031304return (tMap.values());1305}13061307/**1308* Returns the specified column of this <code>CachedRowSetImpl</code> object1309* as a <code>Collection</code> object. This method makes a copy of the1310* column's data and utilitizes the <code>Vector</code> to establish the1311* collection. The <code>Vector</code> class implements a growable array1312* objects allowing the individual components to be accessed using an1313* an integer index similar to that of an array.1314*1315* @return a <code>Collection</code> object that contains the value(s)1316* stored in the specified column of this1317* <code>CachedRowSetImpl</code>1318* object1319* @throws SQLException if an error occurs generated the collection; or1320* an invalid column is provided.1321* @see #toCollection()1322* @see #toCollection(String)1323* @see java.util.Vector1324*/1325public Collection<?> toCollection(int column) throws SQLException {13261327int nRows = numRows;1328Vector<Object> vec = new Vector<>(nRows);13291330// create a copy1331CachedRowSetImpl crsTemp;1332crsTemp = (CachedRowSetImpl) this.createCopy();13331334while(nRows!=0) {1335crsTemp.next();1336vec.add(crsTemp.getObject(column));1337nRows--;1338}13391340return (Collection)vec;1341}13421343/**1344* Returns the specified column of this <code>CachedRowSetImpl</code> object1345* as a <code>Collection</code> object. This method makes a copy of the1346* column's data and utilitizes the <code>Vector</code> to establish the1347* collection. The <code>Vector</code> class implements a growable array1348* objects allowing the individual components to be accessed using an1349* an integer index similar to that of an array.1350*1351* @return a <code>Collection</code> object that contains the value(s)1352* stored in the specified column of this1353* <code>CachedRowSetImpl</code>1354* object1355* @throws SQLException if an error occurs generated the collection; or1356* an invalid column is provided.1357* @see #toCollection()1358* @see #toCollection(int)1359* @see java.util.Vector1360*/1361public Collection<?> toCollection(String column) throws SQLException {1362return toCollection(getColIdxByName(column));1363}13641365//--------------------------------------------------------------------1366// Advanced features1367//--------------------------------------------------------------------136813691370/**1371* Returns the <code>SyncProvider</code> implementation being used1372* with this <code>CachedRowSetImpl</code> implementation rowset.1373*1374* @return the SyncProvider used by the rowset. If not provider was1375* set when the rowset was instantiated, the reference1376* implementation (default) provider is returned.1377* @throws SQLException if error occurs while return the1378* <code>SyncProvider</code> instance.1379*/1380public SyncProvider getSyncProvider() throws SQLException {1381return provider;1382}13831384/**1385* Sets the active <code>SyncProvider</code> and attempts to load1386* load the new provider using the <code>SyncFactory</code> SPI.1387*1388* @throws SQLException if an error occurs while resetting the1389* <code>SyncProvider</code>.1390*/1391public void setSyncProvider(String providerStr) throws SQLException {1392provider =1393SyncFactory.getInstance(providerStr);13941395rowSetReader = provider.getRowSetReader();1396rowSetWriter = provider.getRowSetWriter();1397}139813991400//-----------------1401// methods inherited from RowSet1402//-----------------1403140414051406140714081409//---------------------------------------------------------------------1410// Reading and writing data1411//---------------------------------------------------------------------14121413/**1414* Populates this <code>CachedRowSetImpl</code> object with data.1415* This form of the method uses the rowset's user, password, and url or1416* data source name properties to create a database1417* connection. If properties that are needed1418* have not been set, this method will throw an exception.1419* <P>1420* Another form of this method uses an existing JDBC <code>Connection</code>1421* object instead of creating a new one; therefore, it ignores the1422* properties used for establishing a new connection.1423* <P>1424* The query specified by the command property is executed to create a1425* <code>ResultSet</code> object from which to retrieve data.1426* The current contents of the rowset are discarded, and the1427* rowset's metadata is also (re)set. If there are outstanding updates,1428* they are also ignored.1429* <P>1430* The method <code>execute</code> closes any database connections that it1431* creates.1432*1433* @throws SQLException if an error occurs or the1434* necessary properties have not been set1435*/1436public void execute() throws SQLException {1437execute(null);1438}1439144014411442//-----------------------------------1443// Methods inherited from ResultSet1444//-----------------------------------14451446/**1447* Moves the cursor down one row from its current position and1448* returns <code>true</code> if the new cursor position is a1449* valid row.1450* The cursor for a new <code>ResultSet</code> object is initially1451* positioned before the first row. The first call to the method1452* <code>next</code> moves the cursor to the first row, making it1453* the current row; the second call makes the second row the1454* current row, and so on.1455*1456* <P>If an input stream from the previous row is open, it is1457* implicitly closed. The <code>ResultSet</code> object's warning1458* chain is cleared when a new row is read.1459*1460* @return <code>true</code> if the new current row is valid;1461* <code>false</code> if there are no more rows1462* @throws SQLException if an error occurs or1463* the cursor is not positioned in the rowset, before1464* the first row, or after the last row1465*/1466public boolean next() throws SQLException {1467/*1468* make sure things look sane. The cursor must be1469* positioned in the rowset or before first (0) or1470* after last (numRows + 1)1471*/1472if (cursorPos < 0 || cursorPos >= numRows + 1) {1473throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());1474}1475// now move and notify1476boolean ret = this.internalNext();1477notifyCursorMoved();14781479return ret;1480}14811482/**1483* Moves this <code>CachedRowSetImpl</code> object's cursor to the next1484* row and returns <code>true</code> if the cursor is still in the rowset;1485* returns <code>false</code> if the cursor has moved to the position after1486* the last row.1487* <P>1488* This method handles the cases where the cursor moves to a row that1489* has been deleted.1490* If this rowset shows deleted rows and the cursor moves to a row1491* that has been deleted, this method moves the cursor to the next1492* row until the cursor is on a row that has not been deleted.1493* <P>1494* The method <code>internalNext</code> is called by methods such as1495* <code>next</code>, <code>absolute</code>, and <code>relative</code>,1496* and, as its name implies, is only called internally.1497* <p>1498* This is a implementation only method and is not required as a standard1499* implementation of the <code>CachedRowSet</code> interface.1500*1501* @return <code>true</code> if the cursor is on a valid row in this1502* rowset; <code>false</code> if it is after the last row1503* @throws SQLException if an error occurs1504*/1505protected boolean internalNext() throws SQLException {1506boolean ret = false;15071508do {1509if (cursorPos < numRows) {1510++cursorPos;1511ret = true;1512} else if (cursorPos == numRows) {1513// increment to after last1514++cursorPos;1515ret = false;1516break;1517}1518} while ((getShowDeleted() == false) && (rowDeleted() == true));15191520/* each call to internalNext may increment cursorPos multiple1521* times however, the absolutePos only increments once per call.1522*/1523if (ret == true)1524absolutePos++;1525else1526absolutePos = 0;15271528return ret;1529}15301531/**1532* Closes this <code>CachedRowSetImpl</code> objecy and releases any resources1533* it was using.1534*1535* @throws SQLException if an error occurs when releasing any resources in use1536* by this <code>CachedRowSetImpl</code> object1537*/1538public void close() throws SQLException {15391540// close all data structures holding1541// the disconnected rowset15421543cursorPos = 0;1544absolutePos = 0;1545numRows = 0;1546numDeleted = 0;15471548// set all insert(s), update(s) & delete(s),1549// if at all, to their initial values.1550initProperties();15511552// clear the vector of it's present contents1553rvh.clear();15541555// this will make it eligible for gc1556// rvh = null;1557}15581559/**1560* Reports whether the last column read was SQL <code>NULL</code>.1561* Note that you must first call the method <code>getXXX</code>1562* on a column to try to read its value and then call the method1563* <code>wasNull</code> to determine whether the value was1564* SQL <code>NULL</code>.1565*1566* @return <code>true</code> if the value in the last column read1567* was SQL <code>NULL</code>; <code>false</code> otherwise1568* @throws SQLException if an error occurs1569*/1570public boolean wasNull() throws SQLException {1571return lastValueNull;1572}15731574/**1575* Sets the field <code>lastValueNull</code> to the given1576* <code>boolean</code> value.1577*1578* @param value <code>true</code> to indicate that the value of1579* the last column read was SQL <code>NULL</code>;1580* <code>false</code> to indicate that it was not1581*/1582private void setLastValueNull(boolean value) {1583lastValueNull = value;1584}15851586// Methods for accessing results by column index15871588/**1589* Checks to see whether the given index is a valid column number1590* in this <code>CachedRowSetImpl</code> object and throws1591* an <code>SQLException</code> if it is not. The index is out of bounds1592* if it is less than <code>1</code> or greater than the number of1593* columns in this rowset.1594* <P>1595* This method is called internally by the <code>getXXX</code> and1596* <code>updateXXX</code> methods.1597*1598* @param idx the number of a column in this <code>CachedRowSetImpl</code>1599* object; must be between <code>1</code> and the number of1600* rows in this rowset1601* @throws SQLException if the given index is out of bounds1602*/1603private void checkIndex(int idx) throws SQLException {1604if (idx < 1 || RowSetMD == null || idx > RowSetMD.getColumnCount()) {1605throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString());1606}1607}16081609/**1610* Checks to see whether the cursor for this <code>CachedRowSetImpl</code>1611* object is on a row in the rowset and throws an1612* <code>SQLException</code> if it is not.1613* <P>1614* This method is called internally by <code>getXXX</code> methods, by1615* <code>updateXXX</code> methods, and by methods that update, insert,1616* or delete a row or that cancel a row update, insert, or delete.1617*1618* @throws SQLException if the cursor for this <code>CachedRowSetImpl</code>1619* object is not on a valid row1620*/1621private void checkCursor() throws SQLException {1622if (isAfterLast() == true || isBeforeFirst() == true) {1623throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());1624}1625}16261627/**1628* Returns the column number of the column with the given name in this1629* <code>CachedRowSetImpl</code> object. This method throws an1630* <code>SQLException</code> if the given name is not the name of1631* one of the columns in this rowset.1632*1633* @param name a <code>String</code> object that is the name of a column in1634* this <code>CachedRowSetImpl</code> object1635* @throws SQLException if the given name does not match the name of one of1636* the columns in this rowset1637*/1638private int getColIdxByName(String name) throws SQLException {1639RowSetMD = (RowSetMetaDataImpl)this.getMetaData();1640int cols = RowSetMD.getColumnCount();1641if (RowSetMD != null) {1642for (int i = 1; i <= cols; ++i) {1643String colName = RowSetMD.getColumnName(i);1644if (colName != null)1645if (name.equalsIgnoreCase(colName))1646return (i);1647else1648continue;1649}1650}1651throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalcolnm").toString());16521653}16541655/**1656* Returns the insert row or the current row of this1657* <code>CachedRowSetImpl</code>object.1658*1659* @return the <code>Row</code> object on which this <code>CachedRowSetImpl</code>1660* objects's cursor is positioned1661*/1662protected BaseRow getCurrentRow() {1663if (onInsertRow == true) {1664return (BaseRow)insertRow;1665} else {1666return (BaseRow)(rvh.get(cursorPos - 1));1667}1668}16691670/**1671* Removes the row on which the cursor is positioned.1672* <p>1673* This is a implementation only method and is not required as a standard1674* implementation of the <code>CachedRowSet</code> interface.1675*1676* @throws SQLException if the cursor is positioned on the insert1677* row1678*/1679protected void removeCurrentRow() {1680((Row)getCurrentRow()).setDeleted();1681rvh.remove(cursorPos - 1);1682--numRows;1683}168416851686/**1687* Retrieves the value of the designated column in the current row1688* of this <code>CachedRowSetImpl</code> object as a1689* <code>String</code> object.1690*1691* @param columnIndex the first column is <code>1</code>, the second1692* is <code>2</code>, and so on; must be <code>1</code> or larger1693* and equal to or less than the number of columns in the rowset1694* @return the column value; if the value is SQL <code>NULL</code>, the1695* result is <code>null</code>1696* @throws SQLException if (1) the given column index is out of bounds,1697* (2) the cursor is not on one of this rowset's rows or its1698* insert row, or (3) the designated column does not store an1699* SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL,1700* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, <b>CHAR</b>, <b>VARCHAR</b></code>1701* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1702* recommended return type.1703*/1704public String getString(int columnIndex) throws SQLException {1705Object value;17061707// sanity check.1708checkIndex(columnIndex);1709// make sure the cursor is on a valid row1710checkCursor();17111712setLastValueNull(false);1713value = getCurrentRow().getColumnObject(columnIndex);17141715// check for SQL NULL1716if (value == null) {1717setLastValueNull(true);1718return null;1719}17201721return value.toString();1722}17231724/**1725* Retrieves the value of the designated column in the current row1726* of this <code>CachedRowSetImpl</code> object as a1727* <code>boolean</code> value.1728*1729* @param columnIndex the first column is <code>1</code>, the second1730* is <code>2</code>, and so on; must be <code>1</code> or larger1731* and equal to or less than the number of columns in the rowset1732* @return the column value as a <code>boolean</code> in the Java progamming language;1733* if the value is SQL <code>NULL</code>, the result is <code>false</code>1734* @throws SQLException if (1) the given column index is out of bounds,1735* (2) the cursor is not on one of this rowset's rows or its1736* insert row, or (3) the designated column does not store an1737* SQL <code>BOOLEAN</code> value1738* @see #getBoolean(String)1739*/1740public boolean getBoolean(int columnIndex) throws SQLException {1741Object value;17421743// sanity check.1744checkIndex(columnIndex);1745// make sure the cursor is on a valid row1746checkCursor();17471748setLastValueNull(false);1749value = getCurrentRow().getColumnObject(columnIndex);17501751// check for SQL NULL1752if (value == null) {1753setLastValueNull(true);1754return false;1755}17561757// check for Boolean...1758if (value instanceof Boolean) {1759return ((Boolean)value).booleanValue();1760}17611762// convert to a Double and compare to zero1763try {1764return Double.compare(Double.parseDouble(value.toString()), 0) != 0;1765} catch (NumberFormatException ex) {1766throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.boolfail").toString(),1767new Object[] {value.toString().trim(), columnIndex}));1768}1769}17701771/**1772* Retrieves the value of the designated column in the current row1773* of this <code>CachedRowSetImpl</code> object as a1774* <code>byte</code> value.1775*1776* @param columnIndex the first column is <code>1</code>, the second1777* is <code>2</code>, and so on; must be <code>1</code> or larger1778* and equal to or less than the number of columns in the rowset1779* @return the column value as a <code>byte</code> in the Java programming1780* language; if the value is SQL <code>NULL</code>, the result is <code>0</code>1781* @throws SQLException if (1) the given column index is out of bounds,1782* (2) the cursor is not on one of this rowset's rows or its1783* insert row, or (3) the designated column does not store an1784* SQL <code><b>TINYINT</b>, SMALLINT, INTEGER, BIGINT, REAL,1785* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1786* or <code>LONGVARCHAR</code> value. The bold SQL type1787* designates the recommended return type.1788* @see #getByte(String)1789*/1790public byte getByte(int columnIndex) throws SQLException {1791Object value;17921793// sanity check.1794checkIndex(columnIndex);1795// make sure the cursor is on a valid row1796checkCursor();17971798setLastValueNull(false);1799value = getCurrentRow().getColumnObject(columnIndex);18001801// check for SQL NULL1802if (value == null) {1803setLastValueNull(true);1804return (byte)0;1805}1806try {1807return ((Byte.valueOf(value.toString())).byteValue());1808} catch (NumberFormatException ex) {1809throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(),1810new Object[] {value.toString().trim(), columnIndex}));1811}1812}18131814/**1815* Retrieves the value of the designated column in the current row1816* of this <code>CachedRowSetImpl</code> object as a1817* <code>short</code> value.1818*1819* @param columnIndex the first column is <code>1</code>, the second1820* is <code>2</code>, and so on; must be <code>1</code> or larger1821* and equal to or less than the number of columns in the rowset1822* @return the column value; if the value is SQL <code>NULL</code>, the1823* result is <code>0</code>1824* @throws SQLException if (1) the given column index is out of bounds,1825* (2) the cursor is not on one of this rowset's rows or its1826* insert row, or (3) the designated column does not store an1827* SQL <code>TINYINT, <b>SMALLINT</b>, INTEGER, BIGINT, REAL1828* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1829* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1830* recommended return type.1831* @see #getShort(String)1832*/1833public short getShort(int columnIndex) throws SQLException {1834Object value;18351836// sanity check.1837checkIndex(columnIndex);1838// make sure the cursor is on a valid row1839checkCursor();18401841setLastValueNull(false);1842value = getCurrentRow().getColumnObject(columnIndex);18431844// check for SQL NULL1845if (value == null) {1846setLastValueNull(true);1847return (short)0;1848}18491850try {1851return ((Short.valueOf(value.toString().trim())).shortValue());1852} catch (NumberFormatException ex) {1853throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(),1854new Object[] {value.toString().trim(), columnIndex}));1855}1856}18571858/**1859* Retrieves the value of the designated column in the current row1860* of this <code>CachedRowSetImpl</code> object as an1861* <code>int</code> value.1862*1863* @param columnIndex the first column is <code>1</code>, the second1864* is <code>2</code>, and so on; must be <code>1</code> or larger1865* and equal to or less than the number of columns in the rowset1866* @return the column value; if the value is SQL <code>NULL</code>, the1867* result is <code>0</code>1868* @throws SQLException if (1) the given column index is out of bounds,1869* (2) the cursor is not on one of this rowset's rows or its1870* insert row, or (3) the designated column does not store an1871* SQL <code>TINYINT, SMALLINT, <b>INTEGER</b>, BIGINT, REAL1872* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1873* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1874* recommended return type.1875*/1876public int getInt(int columnIndex) throws SQLException {1877Object value;18781879// sanity check.1880checkIndex(columnIndex);1881// make sure the cursor is on a valid row1882checkCursor();18831884setLastValueNull(false);1885value = getCurrentRow().getColumnObject(columnIndex);18861887// check for SQL NULL1888if (value == null) {1889setLastValueNull(true);1890return 0;1891}18921893try {1894return ((Integer.valueOf(value.toString().trim())).intValue());1895} catch (NumberFormatException ex) {1896throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(),1897new Object[] {value.toString().trim(), columnIndex}));1898}1899}19001901/**1902* Retrieves the value of the designated column in the current row1903* of this <code>CachedRowSetImpl</code> object as a1904* <code>long</code> value.1905*1906* @param columnIndex the first column is <code>1</code>, the second1907* is <code>2</code>, and so on; must be <code>1</code> or larger1908* and equal to or less than the number of columns in the rowset1909* @return the column value; if the value is SQL <code>NULL</code>, the1910* result is <code>0</code>1911* @throws SQLException if (1) the given column index is out of bounds,1912* (2) the cursor is not on one of this rowset's rows or its1913* insert row, or (3) the designated column does not store an1914* SQL <code>TINYINT, SMALLINT, INTEGER, <b>BIGINT</b>, REAL1915* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1916* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1917* recommended return type.1918* @see #getLong(String)1919*/1920public long getLong(int columnIndex) throws SQLException {1921Object value;19221923// sanity check.1924checkIndex(columnIndex);1925// make sure the cursor is on a valid row1926checkCursor();19271928setLastValueNull(false);1929value = getCurrentRow().getColumnObject(columnIndex);19301931// check for SQL NULL1932if (value == null) {1933setLastValueNull(true);1934return (long)0;1935}1936try {1937return ((Long.valueOf(value.toString().trim())).longValue());1938} catch (NumberFormatException ex) {1939throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(),1940new Object[] {value.toString().trim(), columnIndex}));1941}1942}19431944/**1945* Retrieves the value of the designated column in the current row1946* of this <code>CachedRowSetImpl</code> object as a1947* <code>float</code> value.1948*1949* @param columnIndex the first column is <code>1</code>, the second1950* is <code>2</code>, and so on; must be <code>1</code> or larger1951* and equal to or less than the number of columns in the rowset1952* @return the column value; if the value is SQL <code>NULL</code>, the1953* result is <code>0</code>1954* @throws SQLException if (1) the given column index is out of bounds,1955* (2) the cursor is not on one of this rowset's rows or its1956* insert row, or (3) the designated column does not store an1957* SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, <b>REAL</b>,1958* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1959* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1960* recommended return type.1961* @see #getFloat(String)1962*/1963public float getFloat(int columnIndex) throws SQLException {1964Object value;19651966// sanity check.1967checkIndex(columnIndex);1968// make sure the cursor is on a valid row1969checkCursor();19701971setLastValueNull(false);1972value = getCurrentRow().getColumnObject(columnIndex);19731974// check for SQL NULL1975if (value == null) {1976setLastValueNull(true);1977return (float)0;1978}1979try {1980return Float.parseFloat(value.toString());1981} catch (NumberFormatException ex) {1982throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.floatfail").toString(),1983new Object[] {value.toString().trim(), columnIndex}));1984}1985}19861987/**1988* Retrieves the value of the designated column in the current row1989* of this <code>CachedRowSetImpl</code> object as a1990* <code>double</code> value.1991*1992* @param columnIndex the first column is <code>1</code>, the second1993* is <code>2</code>, and so on; must be <code>1</code> or larger1994* and equal to or less than the number of columns in the rowset1995* @return the column value; if the value is SQL <code>NULL</code>, the1996* result is <code>0</code>1997* @throws SQLException if (1) the given column index is out of bounds,1998* (2) the cursor is not on one of this rowset's rows or its1999* insert row, or (3) the designated column does not store an2000* SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL,2001* <b>FLOAT</b>, <b>DOUBLE</b>, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>2002* or <code>LONGVARCHAR</code> value. The bold SQL type designates the2003* recommended return type.2004* @see #getDouble(String)2005*2006*/2007public double getDouble(int columnIndex) throws SQLException {2008Object value;20092010// sanity check.2011checkIndex(columnIndex);2012// make sure the cursor is on a valid row2013checkCursor();20142015setLastValueNull(false);2016value = getCurrentRow().getColumnObject(columnIndex);20172018// check for SQL NULL2019if (value == null) {2020setLastValueNull(true);2021return (double)0;2022}2023try {2024return Double.parseDouble(value.toString().trim());2025} catch (NumberFormatException ex) {2026throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(),2027new Object[] {value.toString().trim(), columnIndex}));2028}2029}20302031/**2032* Retrieves the value of the designated column in the current row2033* of this <code>CachedRowSetImpl</code> object as a2034* <code>java.math.BigDecimal</code> object.2035* <P>2036* This method is deprecated; use the version of <code>getBigDecimal</code>2037* that does not take a scale parameter and returns a value with full2038* precision.2039*2040* @param columnIndex the first column is <code>1</code>, the second2041* is <code>2</code>, and so on; must be <code>1</code> or larger2042* and equal to or less than the number of columns in the rowset2043* @param scale the number of digits to the right of the decimal point in the2044* value returned2045* @return the column value with the specified number of digits to the right2046* of the decimal point; if the value is SQL <code>NULL</code>, the2047* result is <code>null</code>2048* @throws SQLException if the given column index is out of bounds,2049* the cursor is not on a valid row, or this method fails2050* @deprecated2051*/2052@Deprecated2053public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {2054Object value;2055BigDecimal bDecimal, retVal;20562057// sanity check.2058checkIndex(columnIndex);2059// make sure the cursor is on a valid row2060checkCursor();20612062setLastValueNull(false);2063value = getCurrentRow().getColumnObject(columnIndex);20642065// check for SQL NULL2066if (value == null) {2067setLastValueNull(true);2068return (new BigDecimal(0));2069}20702071bDecimal = this.getBigDecimal(columnIndex);20722073retVal = bDecimal.setScale(scale);20742075return retVal;2076}20772078/**2079* Retrieves the value of the designated column in the current row2080* of this <code>CachedRowSetImpl</code> object as a2081* <code>byte</code> array value.2082*2083* @param columnIndex the first column is <code>1</code>, the second2084* is <code>2</code>, and so on; must be <code>1</code> or larger2085* and equal to or less than the number of columns in the rowset2086* @return the column value as a <code>byte</code> array in the Java programming2087* language; if the value is SQL <code>NULL</code>, the2088* result is <code>null</code>2089*2090* @throws SQLException if (1) the given column index is out of bounds,2091* (2) the cursor is not on one of this rowset's rows or its2092* insert row, or (3) the designated column does not store an2093* SQL <code><b>BINARY</b>, <b>VARBINARY</b> or2094* LONGVARBINARY</code> value.2095* The bold SQL type designates the recommended return type.2096* @see #getBytes(String)2097*/2098public byte[] getBytes(int columnIndex) throws SQLException {2099// sanity check.2100checkIndex(columnIndex);2101// make sure the cursor is on a valid row2102checkCursor();21032104if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) {2105throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());2106}21072108return (byte[])(getCurrentRow().getColumnObject(columnIndex));2109}21102111/**2112* Retrieves the value of the designated column in the current row2113* of this <code>CachedRowSetImpl</code> object as a2114* <code>java.sql.Date</code> object.2115*2116* @param columnIndex the first column is <code>1</code>, the second2117* is <code>2</code>, and so on; must be <code>1</code> or larger2118* and equal to or less than the number of columns in the rowset2119* @return the column value as a <code>java.sql.Data</code> object; if2120* the value is SQL <code>NULL</code>, the2121* result is <code>null</code>2122* @throws SQLException if the given column index is out of bounds,2123* the cursor is not on a valid row, or this method fails2124*/2125public java.sql.Date getDate(int columnIndex) throws SQLException {2126Object value;21272128// sanity check.2129checkIndex(columnIndex);2130// make sure the cursor is on a valid row2131checkCursor();21322133setLastValueNull(false);2134value = getCurrentRow().getColumnObject(columnIndex);21352136// check for SQL NULL2137if (value == null) {2138setLastValueNull(true);2139return null;2140}21412142/*2143* The object coming back from the db could be2144* a date, a timestamp, or a char field variety.2145* If it's a date type return it, a timestamp2146* we turn into a long and then into a date,2147* char strings we try to parse. Yuck.2148*/2149switch (RowSetMD.getColumnType(columnIndex)) {2150case java.sql.Types.DATE: {2151long sec = ((java.sql.Date)value).getTime();2152return new java.sql.Date(sec);2153}2154case java.sql.Types.TIMESTAMP: {2155long sec = ((java.sql.Timestamp)value).getTime();2156return new java.sql.Date(sec);2157}2158case java.sql.Types.CHAR:2159case java.sql.Types.VARCHAR:2160case java.sql.Types.LONGVARCHAR: {2161try {2162DateFormat df = DateFormat.getDateInstance();2163return ((java.sql.Date)(df.parse(value.toString())));2164} catch (ParseException ex) {2165throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(),2166new Object[] {value.toString().trim(), columnIndex}));2167}2168}2169default: {2170throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(),2171new Object[] {value.toString().trim(), columnIndex}));2172}2173}2174}21752176/**2177* Retrieves the value of the designated column in the current row2178* of this <code>CachedRowSetImpl</code> object as a2179* <code>java.sql.Time</code> object.2180*2181* @param columnIndex the first column is <code>1</code>, the second2182* is <code>2</code>, and so on; must be <code>1</code> or larger2183* and equal to or less than the number of columns in the rowset2184* @return the column value; if the value is SQL <code>NULL</code>, the2185* result is <code>null</code>2186* @throws SQLException if the given column index is out of bounds,2187* the cursor is not on a valid row, or this method fails2188*/2189public java.sql.Time getTime(int columnIndex) throws SQLException {2190Object value;21912192// sanity check.2193checkIndex(columnIndex);2194// make sure the cursor is on a valid row2195checkCursor();21962197setLastValueNull(false);2198value = getCurrentRow().getColumnObject(columnIndex);21992200// check for SQL NULL2201if (value == null) {2202setLastValueNull(true);2203return null;2204}22052206/*2207* The object coming back from the db could be2208* a date, a timestamp, or a char field variety.2209* If it's a date type return it, a timestamp2210* we turn into a long and then into a date,2211* char strings we try to parse. Yuck.2212*/2213switch (RowSetMD.getColumnType(columnIndex)) {2214case java.sql.Types.TIME: {2215return (java.sql.Time)value;2216}2217case java.sql.Types.TIMESTAMP: {2218long sec = ((java.sql.Timestamp)value).getTime();2219return new java.sql.Time(sec);2220}2221case java.sql.Types.CHAR:2222case java.sql.Types.VARCHAR:2223case java.sql.Types.LONGVARCHAR: {2224try {2225DateFormat tf = DateFormat.getTimeInstance();2226return ((java.sql.Time)(tf.parse(value.toString())));2227} catch (ParseException ex) {2228throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(),2229new Object[] {value.toString().trim(), columnIndex}));2230}2231}2232default: {2233throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(),2234new Object[] {value.toString().trim(), columnIndex}));2235}2236}2237}22382239/**2240* Retrieves the value of the designated column in the current row2241* of this <code>CachedRowSetImpl</code> object as a2242* <code>java.sql.Timestamp</code> object.2243*2244* @param columnIndex the first column is <code>1</code>, the second2245* is <code>2</code>, and so on; must be <code>1</code> or larger2246* and equal to or less than the number of columns in the rowset2247* @return the column value; if the value is SQL <code>NULL</code>, the2248* result is <code>null</code>2249* @throws SQLException if the given column index is out of bounds,2250* the cursor is not on a valid row, or this method fails2251*/2252public java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException {2253Object value;22542255// sanity check.2256checkIndex(columnIndex);2257// make sure the cursor is on a valid row2258checkCursor();22592260setLastValueNull(false);2261value = getCurrentRow().getColumnObject(columnIndex);22622263// check for SQL NULL2264if (value == null) {2265setLastValueNull(true);2266return null;2267}22682269/*2270* The object coming back from the db could be2271* a date, a timestamp, or a char field variety.2272* If it's a date type return it; a timestamp2273* we turn into a long and then into a date;2274* char strings we try to parse. Yuck.2275*/2276switch (RowSetMD.getColumnType(columnIndex)) {2277case java.sql.Types.TIMESTAMP: {2278return (java.sql.Timestamp)value;2279}2280case java.sql.Types.TIME: {2281long sec = ((java.sql.Time)value).getTime();2282return new java.sql.Timestamp(sec);2283}2284case java.sql.Types.DATE: {2285long sec = ((java.sql.Date)value).getTime();2286return new java.sql.Timestamp(sec);2287}2288case java.sql.Types.CHAR:2289case java.sql.Types.VARCHAR:2290case java.sql.Types.LONGVARCHAR: {2291try {2292DateFormat tf = DateFormat.getTimeInstance();2293return ((java.sql.Timestamp)(tf.parse(value.toString())));2294} catch (ParseException ex) {2295throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(),2296new Object[] {value.toString().trim(), columnIndex}));2297}2298}2299default: {2300throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(),2301new Object[] {value.toString().trim(), columnIndex}));2302}2303}2304}23052306/**2307* Retrieves the value of the designated column in the current row of this2308* <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code>2309* object.2310*2311* A column value can be retrieved as a stream of ASCII characters2312* and then read in chunks from the stream. This method is particularly2313* suitable for retrieving large <code>LONGVARCHAR</code> values. The JDBC2314* driver will do any necessary conversion from the database format into ASCII.2315*2316* <P><B>Note:</B> All the data in the returned stream must be2317* read prior to getting the value of any other column. The next2318* call to a get method implicitly closes the stream. . Also, a2319* stream may return <code>0</code> for <code>CachedRowSetImpl.available()</code>2320* whether there is data available or not.2321*2322* @param columnIndex the first column is <code>1</code>, the second2323* is <code>2</code>, and so on; must be <code>1</code> or larger2324* and equal to or less than the number of columns in this rowset2325* @return a Java input stream that delivers the database column value2326* as a stream of one-byte ASCII characters. If the value is SQL2327* <code>NULL</code>, the result is <code>null</code>.2328* @throws SQLException if (1) the given column index is out of bounds,2329* (2) the cursor is not on one of this rowset's rows or its2330* insert row, or (3) the designated column does not store an2331* SQL <code>CHAR, VARCHAR</code>, <code><b>LONGVARCHAR</b></code>2332* <code>BINARY, VARBINARY</code> or <code>LONGVARBINARY</code> value. The2333* bold SQL type designates the recommended return types that this method is2334* used to retrieve.2335* @see #getAsciiStream(String)2336*/2337public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException {2338Object value;23392340// always free an old stream2341asciiStream = null;23422343// sanity check2344checkIndex(columnIndex);2345//make sure the cursor is on a vlid row2346checkCursor();23472348value = getCurrentRow().getColumnObject(columnIndex);2349if (value == null) {2350lastValueNull = true;2351return null;2352}23532354if (isString(RowSetMD.getColumnType(columnIndex))) {2355asciiStream = new ByteArrayInputStream(((String)value).getBytes(US_ASCII));2356} else {2357throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());2358}23592360return asciiStream;2361}23622363/**2364* A column value can be retrieved as a stream of Unicode characters2365* and then read in chunks from the stream. This method is particularly2366* suitable for retrieving large LONGVARCHAR values. The JDBC driver will2367* do any necessary conversion from the database format into Unicode.2368*2369* <P><B>Note:</B> All the data in the returned stream must be2370* read prior to getting the value of any other column. The next2371* call to a get method implicitly closes the stream. . Also, a2372* stream may return 0 for available() whether there is data2373* available or not.2374*2375* @param columnIndex the first column is <code>1</code>, the second2376* is <code>2</code>, and so on; must be <code>1</code> or larger2377* and equal to or less than the number of columns in this rowset2378* @return a Java input stream that delivers the database column value2379* as a stream of two byte Unicode characters. If the value is SQL NULL2380* then the result is null.2381* @throws SQLException if an error occurs2382* @deprecated2383*/2384@Deprecated2385public java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException {2386// always free an old stream2387unicodeStream = null;23882389// sanity check.2390checkIndex(columnIndex);2391// make sure the cursor is on a valid row2392checkCursor();23932394if (isBinary(RowSetMD.getColumnType(columnIndex)) == false &&2395isString(RowSetMD.getColumnType(columnIndex)) == false) {2396throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());2397}23982399Object value = getCurrentRow().getColumnObject(columnIndex);2400if (value == null) {2401lastValueNull = true;2402return null;2403}24042405unicodeStream = new StringBufferInputStream(value.toString());24062407return unicodeStream;2408}24092410/**2411* Retrieves the value of the designated column in the current row of this2412* <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code>2413* object.2414* <P>2415* A column value can be retrieved as a stream of uninterpreted bytes2416* and then read in chunks from the stream. This method is particularly2417* suitable for retrieving large <code>LONGVARBINARY</code> values.2418*2419* <P><B>Note:</B> All the data in the returned stream must be2420* read prior to getting the value of any other column. The next2421* call to a get method implicitly closes the stream. Also, a2422* stream may return <code>0</code> for2423* <code>CachedRowSetImpl.available()</code> whether there is data2424* available or not.2425*2426* @param columnIndex the first column is <code>1</code>, the second2427* is <code>2</code>, and so on; must be <code>1</code> or larger2428* and equal to or less than the number of columns in the rowset2429* @return a Java input stream that delivers the database column value2430* as a stream of uninterpreted bytes. If the value is SQL <code>NULL</code>2431* then the result is <code>null</code>.2432* @throws SQLException if (1) the given column index is out of bounds,2433* (2) the cursor is not on one of this rowset's rows or its2434* insert row, or (3) the designated column does not store an2435* SQL <code>BINARY, VARBINARY</code> or <code><b>LONGVARBINARY</b></code>2436* The bold type indicates the SQL type that this method is recommened2437* to retrieve.2438* @see #getBinaryStream(String)2439*/2440public java.io.InputStream getBinaryStream(int columnIndex) throws SQLException {24412442// always free an old stream2443binaryStream = null;24442445// sanity check.2446checkIndex(columnIndex);2447// make sure the cursor is on a valid row2448checkCursor();24492450if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) {2451throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());2452}24532454Object value = getCurrentRow().getColumnObject(columnIndex);2455if (value == null) {2456lastValueNull = true;2457return null;2458}24592460binaryStream = new ByteArrayInputStream((byte[])value);24612462return binaryStream;24632464}246524662467// Methods for accessing results by column name24682469/**2470* Retrieves the value stored in the designated column2471* of the current row as a <code>String</code> object.2472*2473* @param columnName a <code>String</code> object giving the SQL name of2474* a column in this <code>CachedRowSetImpl</code> object2475* @return the column value; if the value is SQL <code>NULL</code>,2476* the result is <code>null</code>2477* @throws SQLException if (1) the given column name is not the name of2478* a column in this rowset, (2) the cursor is not on one of2479* this rowset's rows or its insert row, or (3) the designated2480* column does not store an SQL {@code TINYINT, SMALLINT, INTEGER2481* BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, }2482* <b>{@code CHAR, VARCHAR}</b> or2483* <b>{@code LONGVARCHAR}</b> value.2484* The bold SQL type designates the recommended return type.2485*/2486public String getString(String columnName) throws SQLException {2487return getString(getColIdxByName(columnName));2488}24892490/**2491* Retrieves the value stored in the designated column2492* of the current row as a <code>boolean</code> value.2493*2494* @param columnName a <code>String</code> object giving the SQL name of2495* a column in this <code>CachedRowSetImpl</code> object2496* @return the column value as a <code>boolean</code> in the Java programming2497* language; if the value is SQL <code>NULL</code>,2498* the result is <code>false</code>2499* @throws SQLException if (1) the given column name is not the name of2500* a column in this rowset, (2) the cursor is not on one of2501* this rowset's rows or its insert row, or (3) the designated2502* column does not store an SQL <code>BOOLEAN</code> value2503* @see #getBoolean(int)2504*/2505public boolean getBoolean(String columnName) throws SQLException {2506return getBoolean(getColIdxByName(columnName));2507}25082509/**2510* Retrieves the value stored in the designated column2511* of the current row as a <code>byte</code> value.2512*2513* @param columnName a <code>String</code> object giving the SQL name of2514* a column in this <code>CachedRowSetImpl</code> object2515* @return the column value as a <code>byte</code> in the Java programming2516* language; if the value is SQL <code>NULL</code>, the result is <code>0</code>2517* @throws SQLException if (1) the given column name is not the name of2518* a column in this rowset, (2) the cursor is not on one of2519* this rowset's rows or its insert row, or (3) the designated2520* column does not store an SQL <code><B>TINYINT</B>, SMALLINT, INTEGER,2521* BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR,2522* VARCHAR</code> or <code>LONGVARCHAR</code> value. The2523* bold type designates the recommended return type2524*/2525public byte getByte(String columnName) throws SQLException {2526return getByte(getColIdxByName(columnName));2527}25282529/**2530* Retrieves the value stored in the designated column2531* of the current row as a <code>short</code> value.2532*2533* @param columnName a <code>String</code> object giving the SQL name of2534* a column in this <code>CachedRowSetImpl</code> object2535* @return the column value; if the value is SQL <code>NULL</code>,2536* the result is <code>0</code>2537* @throws SQLException if (1) the given column name is not the name of2538* a column in this rowset, (2) the cursor is not on one of2539* this rowset's rows or its insert row, or (3) the designated2540* column does not store an SQL <code>TINYINT, <b>SMALLINT</b>, INTEGER2541* BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR,2542* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2543* designates the recommended return type.2544* @see #getShort(int)2545*/2546public short getShort(String columnName) throws SQLException {2547return getShort(getColIdxByName(columnName));2548}25492550/**2551* Retrieves the value stored in the designated column2552* of the current row as an <code>int</code> value.2553*2554* @param columnName a <code>String</code> object giving the SQL name of2555* a column in this <code>CachedRowSetImpl</code> object2556* @return the column value; if the value is SQL <code>NULL</code>,2557* the result is <code>0</code>2558* @throws SQLException if (1) the given column name is not the name2559* of a column in this rowset,2560* (2) the cursor is not on one of this rowset's rows or its2561* insert row, or (3) the designated column does not store an2562* SQL <code>TINYINT, SMALLINT, <b>INTEGER</b>, BIGINT, REAL2563* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>2564* or <code>LONGVARCHAR</code> value. The bold SQL type designates the2565* recommended return type.2566*/2567public int getInt(String columnName) throws SQLException {2568return getInt(getColIdxByName(columnName));2569}25702571/**2572* Retrieves the value stored in the designated column2573* of the current row as a <code>long</code> value.2574*2575* @param columnName a <code>String</code> object giving the SQL name of2576* a column in this <code>CachedRowSetImpl</code> object2577* @return the column value; if the value is SQL <code>NULL</code>,2578* the result is <code>0</code>2579* @throws SQLException if (1) the given column name is not the name of2580* a column in this rowset, (2) the cursor is not on one of2581* this rowset's rows or its insert row, or (3) the designated2582* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER2583* <b>BIGINT</b>, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR,2584* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2585* designates the recommended return type.2586* @see #getLong(int)2587*/2588public long getLong(String columnName) throws SQLException {2589return getLong(getColIdxByName(columnName));2590}25912592/**2593* Retrieves the value stored in the designated column2594* of the current row as a <code>float</code> value.2595*2596* @param columnName a <code>String</code> object giving the SQL name of2597* a column in this <code>CachedRowSetImpl</code> object2598* @return the column value; if the value is SQL <code>NULL</code>,2599* the result is <code>0</code>2600* @throws SQLException if (1) the given column name is not the name of2601* a column in this rowset, (2) the cursor is not on one of2602* this rowset's rows or its insert row, or (3) the designated2603* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER2604* BIGINT, <b>REAL</b>, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR,2605* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2606* designates the recommended return type.2607* @see #getFloat(String)2608*/2609public float getFloat(String columnName) throws SQLException {2610return getFloat(getColIdxByName(columnName));2611}26122613/**2614* Retrieves the value stored in the designated column2615* of the current row of this <code>CachedRowSetImpl</code> object2616* as a <code>double</code> value.2617*2618* @param columnName a <code>String</code> object giving the SQL name of2619* a column in this <code>CachedRowSetImpl</code> object2620* @return the column value; if the value is SQL <code>NULL</code>,2621* the result is <code>0</code>2622* @throws SQLException if (1) the given column name is not the name of2623* a column in this rowset, (2) the cursor is not on one of2624* this rowset's rows or its insert row, or (3) the designated2625* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER2626* BIGINT, REAL, <b>FLOAT</b>, <b>DOUBLE</b>, DECIMAL, NUMERIC, BIT, CHAR,2627* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2628* designates the recommended return types.2629* @see #getDouble(int)2630*/2631public double getDouble(String columnName) throws SQLException {2632return getDouble(getColIdxByName(columnName));2633}26342635/**2636* Retrieves the value stored in the designated column2637* of the current row as a <code>java.math.BigDecimal</code> object.2638*2639* @param columnName a <code>String</code> object giving the SQL name of2640* a column in this <code>CachedRowSetImpl</code> object2641* @param scale the number of digits to the right of the decimal point2642* @return a java.math.BugDecimal object with <code><i>scale</i></code>2643* number of digits to the right of the decimal point.2644* @throws SQLException if (1) the given column name is not the name of2645* a column in this rowset, (2) the cursor is not on one of2646* this rowset's rows or its insert row, or (3) the designated2647* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER2648* BIGINT, REAL, FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT CHAR,2649* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2650* designates the recommended return type that this method is used to2651* retrieve.2652* @deprecated Use the <code>getBigDecimal(String columnName)</code>2653* method instead2654*/2655@Deprecated2656public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {2657return getBigDecimal(getColIdxByName(columnName), scale);2658}26592660/**2661* Retrieves the value stored in the designated column2662* of the current row as a <code>byte</code> array.2663* The bytes represent the raw values returned by the driver.2664*2665* @param columnName a <code>String</code> object giving the SQL name of2666* a column in this <code>CachedRowSetImpl</code> object2667* @return the column value as a <code>byte</code> array in the Java programming2668* language; if the value is SQL <code>NULL</code>, the result is <code>null</code>2669* @throws SQLException if (1) the given column name is not the name of2670* a column in this rowset, (2) the cursor is not on one of2671* this rowset's rows or its insert row, or (3) the designated2672* column does not store an SQL <code><b>BINARY</b>, <b>VARBINARY</b>2673* </code> or <code>LONGVARBINARY</code> values2674* The bold SQL type designates the recommended return type.2675* @see #getBytes(int)2676*/2677public byte[] getBytes(String columnName) throws SQLException {2678return getBytes(getColIdxByName(columnName));2679}26802681/**2682* Retrieves the value stored in the designated column2683* of the current row as a <code>java.sql.Date</code> object.2684*2685* @param columnName a <code>String</code> object giving the SQL name of2686* a column in this <code>CachedRowSetImpl</code> object2687* @return the column value; if the value is SQL <code>NULL</code>,2688* the result is <code>null</code>2689* @throws SQLException if (1) the given column name is not the name of2690* a column in this rowset, (2) the cursor is not on one of2691* this rowset's rows or its insert row, or (3) the designated2692* column does not store an SQL <code>DATE</code> or2693* <code>TIMESTAMP</code> value2694*/2695public java.sql.Date getDate(String columnName) throws SQLException {2696return getDate(getColIdxByName(columnName));2697}26982699/**2700* Retrieves the value stored in the designated column2701* of the current row as a <code>java.sql.Time</code> object.2702*2703* @param columnName a <code>String</code> object giving the SQL name of2704* a column in this <code>CachedRowSetImpl</code> object2705* @return the column value; if the value is SQL <code>NULL</code>,2706* the result is <code>null</code>2707* @throws SQLException if the given column name does not match one of2708* this rowset's column names or the cursor is not on one of2709* this rowset's rows or its insert row2710*/2711public java.sql.Time getTime(String columnName) throws SQLException {2712return getTime(getColIdxByName(columnName));2713}27142715/**2716* Retrieves the value stored in the designated column2717* of the current row as a <code>java.sql.Timestamp</code> object.2718*2719* @param columnName a <code>String</code> object giving the SQL name of2720* a column in this <code>CachedRowSetImpl</code> object2721* @return the column value; if the value is SQL <code>NULL</code>,2722* the result is <code>null</code>2723* @throws SQLException if the given column name does not match one of2724* this rowset's column names or the cursor is not on one of2725* this rowset's rows or its insert row2726*/2727public java.sql.Timestamp getTimestamp(String columnName) throws SQLException {2728return getTimestamp(getColIdxByName(columnName));2729}27302731/**2732* Retrieves the value of the designated column in the current row of this2733* <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code>2734* object.2735*2736* A column value can be retrieved as a stream of ASCII characters2737* and then read in chunks from the stream. This method is particularly2738* suitable for retrieving large <code>LONGVARCHAR</code> values. The2739* <code>SyncProvider</code> will rely on the JDBC driver to do any necessary2740* conversion from the database format into ASCII format.2741*2742* <P><B>Note:</B> All the data in the returned stream must2743* be read prior to getting the value of any other column. The2744* next call to a <code>getXXX</code> method implicitly closes the stream.2745*2746* @param columnName a <code>String</code> object giving the SQL name of2747* a column in this <code>CachedRowSetImpl</code> object2748* @return a Java input stream that delivers the database column value2749* as a stream of one-byte ASCII characters. If the value is SQL2750* <code>NULL</code>, the result is <code>null</code>.2751* @throws SQLException if (1) the given column name is not the name of2752* a column in this rowset2753* (2) the cursor is not on one of this rowset's rows or its2754* insert row, or (3) the designated column does not store an2755* SQL <code>CHAR, VARCHAR</code>, <code><b>LONGVARCHAR</b></code>2756* <code>BINARY, VARBINARY</code> or <code>LONGVARBINARY</code> value. The2757* bold SQL type designates the recommended return types that this method is2758* used to retrieve.2759* @see #getAsciiStream(int)2760*/2761public java.io.InputStream getAsciiStream(String columnName) throws SQLException {2762return getAsciiStream(getColIdxByName(columnName));27632764}27652766/**2767* A column value can be retrieved as a stream of Unicode characters2768* and then read in chunks from the stream. This method is particularly2769* suitable for retrieving large <code>LONGVARCHAR</code> values.2770* The JDBC driver will do any necessary conversion from the database2771* format into Unicode.2772*2773* <P><B>Note:</B> All the data in the returned stream must2774* be read prior to getting the value of any other column. The2775* next call to a <code>getXXX</code> method implicitly closes the stream.2776*2777* @param columnName a <code>String</code> object giving the SQL name of2778* a column in this <code>CachedRowSetImpl</code> object2779* @return a Java input stream that delivers the database column value2780* as a stream of two-byte Unicode characters. If the value is2781* SQL <code>NULL</code>, the result is <code>null</code>.2782* @throws SQLException if the given column name does not match one of2783* this rowset's column names or the cursor is not on one of2784* this rowset's rows or its insert row2785* @deprecated use the method <code>getCharacterStream</code> instead2786*/2787@Deprecated2788public java.io.InputStream getUnicodeStream(String columnName) throws SQLException {2789return getUnicodeStream(getColIdxByName(columnName));2790}27912792/**2793* Retrieves the value of the designated column in the current row of this2794* <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code>2795* object.2796* <P>2797* A column value can be retrieved as a stream of uninterpreted bytes2798* and then read in chunks from the stream. This method is particularly2799* suitable for retrieving large <code>LONGVARBINARY</code> values.2800*2801* <P><B>Note:</B> All the data in the returned stream must be2802* read prior to getting the value of any other column. The next2803* call to a get method implicitly closes the stream. Also, a2804* stream may return <code>0</code> for <code>CachedRowSetImpl.available()</code>2805* whether there is data available or not.2806*2807* @param columnName a <code>String</code> object giving the SQL name of2808* a column in this <code>CachedRowSetImpl</code> object2809* @return a Java input stream that delivers the database column value2810* as a stream of uninterpreted bytes. If the value is SQL2811* <code>NULL</code>, the result is <code>null</code>.2812* @throws SQLException if (1) the given column name is unknown,2813* (2) the cursor is not on one of this rowset's rows or its2814* insert row, or (3) the designated column does not store an2815* SQL <code>BINARY, VARBINARY</code> or <code><b>LONGVARBINARY</b></code>2816* The bold type indicates the SQL type that this method is recommened2817* to retrieve.2818* @see #getBinaryStream(int)2819*2820*/2821public java.io.InputStream getBinaryStream(String columnName) throws SQLException {2822return getBinaryStream(getColIdxByName(columnName));2823}282428252826// Advanced features:28272828/**2829* The first warning reported by calls on this <code>CachedRowSetImpl</code>2830* object is returned. Subsequent <code>CachedRowSetImpl</code> warnings will2831* be chained to this <code>SQLWarning</code>.2832*2833* <P>The warning chain is automatically cleared each time a new2834* row is read.2835*2836* <P><B>Note:</B> This warning chain only covers warnings caused2837* by <code>ResultSet</code> methods. Any warning caused by statement2838* methods (such as reading OUT parameters) will be chained on the2839* <code>Statement</code> object.2840*2841* @return the first SQLWarning or null2842*/2843public SQLWarning getWarnings() {2844return sqlwarn;2845}28462847/**2848* Clears all the warnings reporeted for the <code>CachedRowSetImpl</code>2849* object. After a call to this method, the <code>getWarnings</code> method2850* returns <code>null</code> until a new warning is reported for this2851* <code>CachedRowSetImpl</code> object.2852*/2853public void clearWarnings() {2854sqlwarn = null;2855}28562857/**2858* Retrieves the name of the SQL cursor used by this2859* <code>CachedRowSetImpl</code> object.2860*2861* <P>In SQL, a result table is retrieved through a cursor that is2862* named. The current row of a <code>ResultSet</code> can be updated or deleted2863* using a positioned update/delete statement that references the2864* cursor name. To ensure that the cursor has the proper isolation2865* level to support an update operation, the cursor's <code>SELECT</code>2866* statement should be of the form <code>select for update</code>.2867* If the <code>for update</code> clause2868* is omitted, positioned updates may fail.2869*2870* <P>JDBC supports this SQL feature by providing the name of the2871* SQL cursor used by a <code>ResultSet</code> object. The current row2872* of a result set is also the current row of this SQL cursor.2873*2874* <P><B>Note:</B> If positioned updates are not supported, an2875* <code>SQLException</code> is thrown.2876*2877* @return the SQL cursor name for this <code>CachedRowSetImpl</code> object's2878* cursor2879* @throws SQLException if an error occurs2880*/2881public String getCursorName() throws SQLException {2882throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.posupdate").toString());2883}28842885/**2886* Retrieves a <code>ResultSetMetaData</code> object instance that2887* contains information about the <code>CachedRowSet</code> object.2888* However, applications should cast the returned object to a2889* <code>RowSetMetaData</code> interface implementation. In the2890* reference implementation, this cast can be done on the2891* <code>RowSetMetaDataImpl</code> class.2892* <P>2893* For example:2894* <pre>2895* CachedRowSet crs = new CachedRowSetImpl();2896* RowSetMetaDataImpl metaData =2897* (RowSetMetaDataImpl)crs.getMetaData();2898* // Set the number of columns in the RowSet object for2899* // which this RowSetMetaDataImpl object was created to the2900* // given number.2901* metaData.setColumnCount(3);2902* crs.setMetaData(metaData);2903* </pre>2904*2905* @return the <code>ResultSetMetaData</code> object that describes this2906* <code>CachedRowSetImpl</code> object's columns2907* @throws SQLException if an error occurs in generating the RowSet2908* meta data; or if the <code>CachedRowSetImpl</code> is empty.2909* @see javax.sql.RowSetMetaData2910*/2911public ResultSetMetaData getMetaData() throws SQLException {2912return (ResultSetMetaData)RowSetMD;2913}291429152916/**2917* Retrieves the value of the designated column in the current row2918* of this <code>CachedRowSetImpl</code> object as an2919* <code>Object</code> value.2920* <P>2921* The type of the <code>Object</code> will be the default2922* Java object type corresponding to the column's SQL type,2923* following the mapping for built-in types specified in the JDBC 3.02924* specification.2925* <P>2926* This method may also be used to read datatabase-specific2927* abstract data types.2928* <P>2929* This implementation of the method <code>getObject</code> extends its2930* behavior so that it gets the attributes of an SQL structured type2931* as an array of <code>Object</code> values. This method also custom2932* maps SQL user-defined types to classes in the Java programming language.2933* When the specified column contains2934* a structured or distinct value, the behavior of this method is as2935* if it were a call to the method <code>getObject(columnIndex,2936* this.getStatement().getConnection().getTypeMap())</code>.2937*2938* @param columnIndex the first column is <code>1</code>, the second2939* is <code>2</code>, and so on; must be <code>1</code> or larger2940* and equal to or less than the number of columns in the rowset2941* @return a <code>java.lang.Object</code> holding the column value;2942* if the value is SQL <code>NULL</code>, the result is <code>null</code>2943* @throws SQLException if the given column index is out of bounds,2944* the cursor is not on a valid row, or there is a problem getting2945* the <code>Class</code> object for a custom mapping2946* @see #getObject(String)2947*/2948public Object getObject(int columnIndex) throws SQLException {2949Object value;2950Map<String, Class<?>> map;29512952// sanity check.2953checkIndex(columnIndex);2954// make sure the cursor is on a valid row2955checkCursor();29562957setLastValueNull(false);2958value = getCurrentRow().getColumnObject(columnIndex);29592960// check for SQL NULL2961if (value == null) {2962setLastValueNull(true);2963return null;2964}2965if (value instanceof Struct) {2966Struct s = (Struct)value;2967map = getTypeMap();2968// look up the class in the map2969Class<?> c = map.get(s.getSQLTypeName());2970if (c != null) {2971// create new instance of the class2972SQLData obj = null;2973try {2974ReflectUtil.checkPackageAccess(c);2975@SuppressWarnings("deprecation")2976Object tmp = c.newInstance();2977obj = (SQLData) tmp;2978} catch(Exception ex) {2979throw new SQLException("Unable to Instantiate: ", ex);2980}2981// get the attributes from the struct2982Object attribs[] = s.getAttributes(map);2983// create the SQLInput "stream"2984SQLInputImpl sqlInput = new SQLInputImpl(attribs, map);2985// read the values...2986obj.readSQL(sqlInput, s.getSQLTypeName());2987return (Object)obj;2988}2989}2990return value;2991}29922993/**2994* Retrieves the value of the designated column in the current row2995* of this <code>CachedRowSetImpl</code> object as an2996* <code>Object</code> value.2997* <P>2998* The type of the <code>Object</code> will be the default2999* Java object type corresponding to the column's SQL type,3000* following the mapping for built-in types specified in the JDBC 3.03001* specification.3002* <P>3003* This method may also be used to read datatabase-specific3004* abstract data types.3005* <P>3006* This implementation of the method <code>getObject</code> extends its3007* behavior so that it gets the attributes of an SQL structured type3008* as an array of <code>Object</code> values. This method also custom3009* maps SQL user-defined types to classes3010* in the Java programming language. When the specified column contains3011* a structured or distinct value, the behavior of this method is as3012* if it were a call to the method <code>getObject(columnIndex,3013* this.getStatement().getConnection().getTypeMap())</code>.3014*3015* @param columnName a <code>String</code> object that must match the3016* SQL name of a column in this rowset, ignoring case3017* @return a <code>java.lang.Object</code> holding the column value;3018* if the value is SQL <code>NULL</code>, the result is <code>null</code>3019* @throws SQLException if (1) the given column name does not match one of3020* this rowset's column names, (2) the cursor is not3021* on a valid row, or (3) there is a problem getting3022* the <code>Class</code> object for a custom mapping3023* @see #getObject(int)3024*/3025public Object getObject(String columnName) throws SQLException {3026return getObject(getColIdxByName(columnName));3027}30283029//----------------------------------------------------------------30303031/**3032* Maps the given column name for one of this <code>CachedRowSetImpl</code>3033* object's columns to its column number.3034*3035* @param columnName a <code>String</code> object that must match the3036* SQL name of a column in this rowset, ignoring case3037* @return the column index of the given column name3038* @throws SQLException if the given column name does not match one3039* of this rowset's column names3040*/3041public int findColumn(String columnName) throws SQLException {3042return getColIdxByName(columnName);3043}304430453046//--------------------------JDBC 2.0-----------------------------------30473048//---------------------------------------------------------------------3049// Getter's and Setter's3050//---------------------------------------------------------------------30513052/**3053* Retrieves the value stored in the designated column3054* of the current row as a <code>java.io.Reader</code> object.3055*3056* <P><B>Note:</B> All the data in the returned stream must3057* be read prior to getting the value of any other column. The3058* next call to a <code>getXXX</code> method implicitly closes the stream.3059*3060* @param columnIndex the first column is <code>1</code>, the second3061* is <code>2</code>, and so on; must be <code>1</code> or larger3062* and equal to or less than the number of columns in the rowset3063* @return a Java character stream that delivers the database column value3064* as a stream of two-byte unicode characters in a3065* <code>java.io.Reader</code> object. If the value is3066* SQL <code>NULL</code>, the result is <code>null</code>.3067* @throws SQLException if (1) the given column index is out of bounds,3068* (2) the cursor is not on one of this rowset's rows or its3069* insert row, or (3) the designated column does not store an3070* SQL <code>CHAR, VARCHAR, <b>LONGVARCHAR</b>, BINARY, VARBINARY</code> or3071* <code>LONGVARBINARY</code> value.3072* The bold SQL type designates the recommended return type.3073* @see #getCharacterStream(String)3074*/3075public java.io.Reader getCharacterStream(int columnIndex) throws SQLException{30763077// sanity check.3078checkIndex(columnIndex);3079// make sure the cursor is on a valid row3080checkCursor();30813082if (isBinary(RowSetMD.getColumnType(columnIndex))) {3083Object value = getCurrentRow().getColumnObject(columnIndex);3084if (value == null) {3085lastValueNull = true;3086return null;3087}3088charStream = new InputStreamReader3089(new ByteArrayInputStream((byte[])value));3090} else if (isString(RowSetMD.getColumnType(columnIndex))) {3091Object value = getCurrentRow().getColumnObject(columnIndex);3092if (value == null) {3093lastValueNull = true;3094return null;3095}3096charStream = new StringReader(value.toString());3097} else {3098throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());3099}31003101return charStream;3102}31033104/**3105* Retrieves the value stored in the designated column3106* of the current row as a <code>java.io.Reader</code> object.3107*3108* <P><B>Note:</B> All the data in the returned stream must3109* be read prior to getting the value of any other column. The3110* next call to a <code>getXXX</code> method implicitly closes the stream.3111*3112* @param columnName a <code>String</code> object giving the SQL name of3113* a column in this <code>CachedRowSetImpl</code> object3114* @return a Java input stream that delivers the database column value3115* as a stream of two-byte Unicode characters. If the value is3116* SQL <code>NULL</code>, the result is <code>null</code>.3117* @throws SQLException if (1) the given column name is not the name of3118* a column in this rowset, (2) the cursor is not on one of3119* this rowset's rows or its insert row, or (3) the designated3120* column does not store an SQL <code>CHAR, VARCHAR, <b>LONGVARCHAR</b>,3121* BINARY, VARYBINARY</code> or <code>LONGVARBINARY</code> value.3122* The bold SQL type designates the recommended return type.3123*/3124public java.io.Reader getCharacterStream(String columnName) throws SQLException {3125return getCharacterStream(getColIdxByName(columnName));3126}31273128/**3129* Retrieves the value of the designated column in the current row3130* of this <code>CachedRowSetImpl</code> object as a3131* <code>java.math.BigDecimal</code> object.3132*3133* @param columnIndex the first column is <code>1</code>, the second3134* is <code>2</code>, and so on; must be <code>1</code> or larger3135* and equal to or less than the number of columns in the rowset3136* @return a <code>java.math.BigDecimal</code> value with full precision;3137* if the value is SQL <code>NULL</code>, the result is <code>null</code>3138* @throws SQLException if (1) the given column index is out of bounds,3139* (2) the cursor is not on one of this rowset's rows or its3140* insert row, or (3) the designated column does not store an3141* SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL,3142* FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT, CHAR, VARCHAR</code>3143* or <code>LONGVARCHAR</code> value. The bold SQL type designates the3144* recommended return types that this method is used to retrieve.3145* @see #getBigDecimal(String)3146*/3147public BigDecimal getBigDecimal(int columnIndex) throws SQLException {3148Object value;31493150// sanity check.3151checkIndex(columnIndex);3152// make sure the cursor is on a valid row3153checkCursor();31543155setLastValueNull(false);3156value = getCurrentRow().getColumnObject(columnIndex);31573158// check for SQL NULL3159if (value == null) {3160setLastValueNull(true);3161return null;3162}3163try {3164return (new BigDecimal(value.toString().trim()));3165} catch (NumberFormatException ex) {3166throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(),3167new Object[] {value.toString().trim(), columnIndex}));3168}3169}31703171/**3172* Retrieves the value of the designated column in the current row3173* of this <code>CachedRowSetImpl</code> object as a3174* <code>java.math.BigDecimal</code> object.3175*3176* @param columnName a <code>String</code> object that must match the3177* SQL name of a column in this rowset, ignoring case3178* @return a <code>java.math.BigDecimal</code> value with full precision;3179* if the value is SQL <code>NULL</code>, the result is <code>null</code>3180* @throws SQLException if (1) the given column name is not the name of3181* a column in this rowset, (2) the cursor is not on one of3182* this rowset's rows or its insert row, or (3) the designated3183* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER3184* BIGINT, REAL, FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT CHAR,3185* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type3186* designates the recommended return type that this method is used to3187* retrieve3188* @see #getBigDecimal(int)3189*/3190public BigDecimal getBigDecimal(String columnName) throws SQLException {3191return getBigDecimal(getColIdxByName(columnName));3192}31933194//---------------------------------------------------------------------3195// Traversal/Positioning3196//---------------------------------------------------------------------31973198/**3199* Returns the number of rows in this <code>CachedRowSetImpl</code> object.3200*3201* @return number of rows in the rowset3202*/3203public int size() {3204return numRows;3205}32063207/**3208* Indicates whether the cursor is before the first row in this3209* <code>CachedRowSetImpl</code> object.3210*3211* @return <code>true</code> if the cursor is before the first row;3212* <code>false</code> otherwise or if the rowset contains no rows3213* @throws SQLException if an error occurs3214*/3215public boolean isBeforeFirst() throws SQLException {3216if (cursorPos == 0 && numRows > 0) {3217return true;3218} else {3219return false;3220}3221}32223223/**3224* Indicates whether the cursor is after the last row in this3225* <code>CachedRowSetImpl</code> object.3226*3227* @return <code>true</code> if the cursor is after the last row;3228* <code>false</code> otherwise or if the rowset contains no rows3229* @throws SQLException if an error occurs3230*/3231public boolean isAfterLast() throws SQLException {3232if (cursorPos == numRows+1 && numRows > 0) {3233return true;3234} else {3235return false;3236}3237}32383239/**3240* Indicates whether the cursor is on the first row in this3241* <code>CachedRowSetImpl</code> object.3242*3243* @return <code>true</code> if the cursor is on the first row;3244* <code>false</code> otherwise or if the rowset contains no rows3245* @throws SQLException if an error occurs3246*/3247public boolean isFirst() throws SQLException {3248// this becomes nasty because of deletes.3249int saveCursorPos = cursorPos;3250int saveAbsoluteCursorPos = absolutePos;3251internalFirst();3252if (cursorPos == saveCursorPos) {3253return true;3254} else {3255cursorPos = saveCursorPos;3256absolutePos = saveAbsoluteCursorPos;3257return false;3258}3259}32603261/**3262* Indicates whether the cursor is on the last row in this3263* <code>CachedRowSetImpl</code> object.3264* <P>3265* Note: Calling the method <code>isLast</code> may be expensive3266* because the JDBC driver might need to fetch ahead one row in order3267* to determine whether the current row is the last row in this rowset.3268*3269* @return <code>true</code> if the cursor is on the last row;3270* <code>false</code> otherwise or if this rowset contains no rows3271* @throws SQLException if an error occurs3272*/3273public boolean isLast() throws SQLException {3274int saveCursorPos = cursorPos;3275int saveAbsoluteCursorPos = absolutePos;3276boolean saveShowDeleted = getShowDeleted();3277setShowDeleted(true);3278internalLast();3279if (cursorPos == saveCursorPos) {3280setShowDeleted(saveShowDeleted);3281return true;3282} else {3283setShowDeleted(saveShowDeleted);3284cursorPos = saveCursorPos;3285absolutePos = saveAbsoluteCursorPos;3286return false;3287}3288}32893290/**3291* Moves this <code>CachedRowSetImpl</code> object's cursor to the front of3292* the rowset, just before the first row. This method has no effect if3293* this rowset contains no rows.3294*3295* @throws SQLException if an error occurs or the type of this rowset3296* is <code>ResultSet.TYPE_FORWARD_ONLY</code>3297*/3298public void beforeFirst() throws SQLException {3299if (getType() == ResultSet.TYPE_FORWARD_ONLY) {3300throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.beforefirst").toString());3301}3302cursorPos = 0;3303absolutePos = 0;3304notifyCursorMoved();3305}33063307/**3308* Moves this <code>CachedRowSetImpl</code> object's cursor to the end of3309* the rowset, just after the last row. This method has no effect if3310* this rowset contains no rows.3311*3312* @throws SQLException if an error occurs3313*/3314public void afterLast() throws SQLException {3315if (numRows > 0) {3316cursorPos = numRows + 1;3317absolutePos = 0;3318notifyCursorMoved();3319}3320}33213322/**3323* Moves this <code>CachedRowSetImpl</code> object's cursor to the first row3324* and returns <code>true</code> if the operation was successful. This3325* method also notifies registered listeners that the cursor has moved.3326*3327* @return <code>true</code> if the cursor is on a valid row;3328* <code>false</code> otherwise or if there are no rows in this3329* <code>CachedRowSetImpl</code> object3330* @throws SQLException if the type of this rowset3331* is <code>ResultSet.TYPE_FORWARD_ONLY</code>3332*/3333public boolean first() throws SQLException {3334if(getType() == ResultSet.TYPE_FORWARD_ONLY) {3335throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.first").toString());3336}33373338// move and notify3339boolean ret = this.internalFirst();3340notifyCursorMoved();33413342return ret;3343}33443345/**3346* Moves this <code>CachedRowSetImpl</code> object's cursor to the first3347* row and returns <code>true</code> if the operation is successful.3348* <P>3349* This method is called internally by the methods <code>first</code>,3350* <code>isFirst</code>, and <code>absolute</code>.3351* It in turn calls the method <code>internalNext</code> in order to3352* handle the case where the first row is a deleted row that is not visible.3353* <p>3354* This is a implementation only method and is not required as a standard3355* implementation of the <code>CachedRowSet</code> interface.3356*3357* @return <code>true</code> if the cursor moved to the first row;3358* <code>false</code> otherwise3359* @throws SQLException if an error occurs3360*/3361protected boolean internalFirst() throws SQLException {3362boolean ret = false;33633364if (numRows > 0) {3365cursorPos = 1;3366if ((getShowDeleted() == false) && (rowDeleted() == true)) {3367ret = internalNext();3368} else {3369ret = true;3370}3371}33723373if (ret == true)3374absolutePos = 1;3375else3376absolutePos = 0;33773378return ret;3379}33803381/**3382* Moves this <code>CachedRowSetImpl</code> object's cursor to the last row3383* and returns <code>true</code> if the operation was successful. This3384* method also notifies registered listeners that the cursor has moved.3385*3386* @return <code>true</code> if the cursor is on a valid row;3387* <code>false</code> otherwise or if there are no rows in this3388* <code>CachedRowSetImpl</code> object3389* @throws SQLException if the type of this rowset3390* is <code>ResultSet.TYPE_FORWARD_ONLY</code>3391*/3392public boolean last() throws SQLException {3393if (getType() == ResultSet.TYPE_FORWARD_ONLY) {3394throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString());3395}33963397// move and notify3398boolean ret = this.internalLast();3399notifyCursorMoved();34003401return ret;3402}34033404/**3405* Moves this <code>CachedRowSetImpl</code> object's cursor to the last3406* row and returns <code>true</code> if the operation is successful.3407* <P>3408* This method is called internally by the method <code>last</code>3409* when rows have been deleted and the deletions are not visible.3410* The method <code>internalLast</code> handles the case where the3411* last row is a deleted row that is not visible by in turn calling3412* the method <code>internalPrevious</code>.3413* <p>3414* This is a implementation only method and is not required as a standard3415* implementation of the <code>CachedRowSet</code> interface.3416*3417* @return <code>true</code> if the cursor moved to the last row;3418* <code>false</code> otherwise3419* @throws SQLException if an error occurs3420*/3421protected boolean internalLast() throws SQLException {3422boolean ret = false;34233424if (numRows > 0) {3425cursorPos = numRows;3426if ((getShowDeleted() == false) && (rowDeleted() == true)) {3427ret = internalPrevious();3428} else {3429ret = true;3430}3431}3432if (ret == true)3433absolutePos = numRows - numDeleted;3434else3435absolutePos = 0;3436return ret;3437}34383439/**3440* Returns the number of the current row in this <code>CachedRowSetImpl</code>3441* object. The first row is number 1, the second number 2, and so on.3442*3443* @return the number of the current row; <code>0</code> if there is no3444* current row3445* @throws SQLException if an error occurs; or if the <code>CacheRowSetImpl</code>3446* is empty3447*/3448public int getRow() throws SQLException {3449// are we on a valid row? Valid rows are between first and last3450if (numRows > 0 &&3451cursorPos > 0 &&3452cursorPos < (numRows + 1) &&3453(getShowDeleted() == false && rowDeleted() == false)) {3454return absolutePos;3455} else if (getShowDeleted() == true) {3456return cursorPos;3457} else {3458return 0;3459}3460}34613462/**3463* Moves this <code>CachedRowSetImpl</code> object's cursor to the row number3464* specified.3465*3466* <p>If the number is positive, the cursor moves to an absolute row with3467* respect to the beginning of the rowset. The first row is row 1, the second3468* is row 2, and so on. For example, the following command, in which3469* <code>crs</code> is a <code>CachedRowSetImpl</code> object, moves the cursor3470* to the fourth row, starting from the beginning of the rowset.3471* <PRE><code>3472*3473* crs.absolute(4);3474*3475* </code> </PRE>3476* <P>3477* If the number is negative, the cursor moves to an absolute row position3478* with respect to the end of the rowset. For example, calling3479* <code>absolute(-1)</code> positions the cursor on the last row,3480* <code>absolute(-2)</code> moves it on the next-to-last row, and so on.3481* If the <code>CachedRowSetImpl</code> object <code>crs</code> has five rows,3482* the following command moves the cursor to the fourth-to-last row, which3483* in the case of a rowset with five rows, is also the second row, counting3484* from the beginning.3485* <PRE><code>3486*3487* crs.absolute(-4);3488*3489* </code> </PRE>3490*3491* If the number specified is larger than the number of rows, the cursor3492* will move to the position after the last row. If the number specified3493* would move the cursor one or more rows before the first row, the cursor3494* moves to the position before the first row.3495* <P>3496* Note: Calling <code>absolute(1)</code> is the same as calling the3497* method <code>first()</code>. Calling <code>absolute(-1)</code> is the3498* same as calling <code>last()</code>.3499*3500* @param row a positive number to indicate the row, starting row numbering from3501* the first row, which is <code>1</code>; a negative number to indicate3502* the row, starting row numbering from the last row, which is3503* <code>-1</code>; it must not be <code>0</code>3504* @return <code>true</code> if the cursor is on the rowset; <code>false</code>3505* otherwise3506* @throws SQLException if the given cursor position is <code>0</code> or the3507* type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code>3508*/3509public boolean absolute( int row ) throws SQLException {3510if (row == 0 || getType() == ResultSet.TYPE_FORWARD_ONLY) {3511throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.absolute").toString());3512}35133514if (row > 0) { // we are moving foward3515if (row > numRows) {3516// fell off the end3517afterLast();3518return false;3519} else {3520if (absolutePos <= 0)3521internalFirst();3522}3523} else { // we are moving backward3524if (cursorPos + row < 0) {3525// fell off the front3526beforeFirst();3527return false;3528} else {3529if (absolutePos >= 0)3530internalLast();3531}3532}35333534// Now move towards the absolute row that we're looking for3535while (absolutePos != row) {3536if (absolutePos < row) {3537if (!internalNext())3538break;3539}3540else {3541if (!internalPrevious())3542break;3543}3544}35453546notifyCursorMoved();35473548if (isAfterLast() || isBeforeFirst()) {3549return false;3550} else {3551return true;3552}3553}35543555/**3556* Moves the cursor the specified number of rows from the current3557* position, with a positive number moving it forward and a3558* negative number moving it backward.3559* <P>3560* If the number is positive, the cursor moves the specified number of3561* rows toward the end of the rowset, starting at the current row.3562* For example, the following command, in which3563* <code>crs</code> is a <code>CachedRowSetImpl</code> object with 100 rows,3564* moves the cursor forward four rows from the current row. If the3565* current row is 50, the cursor would move to row 54.3566* <PRE><code>3567*3568* crs.relative(4);3569*3570* </code> </PRE>3571* <P>3572* If the number is negative, the cursor moves back toward the beginning3573* the specified number of rows, starting at the current row.3574* For example, calling the method3575* <code>absolute(-1)</code> positions the cursor on the last row,3576* <code>absolute(-2)</code> moves it on the next-to-last row, and so on.3577* If the <code>CachedRowSetImpl</code> object <code>crs</code> has five rows,3578* the following command moves the cursor to the fourth-to-last row, which3579* in the case of a rowset with five rows, is also the second row3580* from the beginning.3581* <PRE><code>3582*3583* crs.absolute(-4);3584*3585* </code> </PRE>3586*3587* If the number specified is larger than the number of rows, the cursor3588* will move to the position after the last row. If the number specified3589* would move the cursor one or more rows before the first row, the cursor3590* moves to the position before the first row. In both cases, this method3591* throws an <code>SQLException</code>.3592* <P>3593* Note: Calling <code>absolute(1)</code> is the same as calling the3594* method <code>first()</code>. Calling <code>absolute(-1)</code> is the3595* same as calling <code>last()</code>. Calling <code>relative(0)</code>3596* is valid, but it does not change the cursor position.3597*3598* @param rows an <code>int</code> indicating the number of rows to move3599* the cursor, starting at the current row; a positive number3600* moves the cursor forward; a negative number moves the cursor3601* backward; must not move the cursor past the valid3602* rows3603* @return <code>true</code> if the cursor is on a row in this3604* <code>CachedRowSetImpl</code> object; <code>false</code>3605* otherwise3606* @throws SQLException if there are no rows in this rowset, the cursor is3607* positioned either before the first row or after the last row, or3608* the rowset is type <code>ResultSet.TYPE_FORWARD_ONLY</code>3609*/3610public boolean relative(int rows) throws SQLException {3611if (numRows == 0 || isBeforeFirst() ||3612isAfterLast() || getType() == ResultSet.TYPE_FORWARD_ONLY) {3613throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.relative").toString());3614}36153616if (rows == 0) {3617return true;3618}36193620if (rows > 0) { // we are moving forward3621if (cursorPos + rows > numRows) {3622// fell off the end3623afterLast();3624} else {3625for (int i=0; i < rows; i++) {3626if (!internalNext())3627break;3628}3629}3630} else { // we are moving backward3631if (cursorPos + rows < 0) {3632// fell off the front3633beforeFirst();3634} else {3635for (int i=rows; i < 0; i++) {3636if (!internalPrevious())3637break;3638}3639}3640}3641notifyCursorMoved();36423643if (isAfterLast() || isBeforeFirst()) {3644return false;3645} else {3646return true;3647}3648}36493650/**3651* Moves this <code>CachedRowSetImpl</code> object's cursor to the3652* previous row and returns <code>true</code> if the cursor is on3653* a valid row or <code>false</code> if it is not.3654* This method also notifies all listeners registered with this3655* <code>CachedRowSetImpl</code> object that its cursor has moved.3656* <P>3657* Note: calling the method <code>previous()</code> is not the same3658* as calling the method <code>relative(-1)</code>. This is true3659* because it is possible to call <code>previous()</code> from the insert3660* row, from after the last row, or from the current row, whereas3661* <code>relative</code> may only be called from the current row.3662* <P>3663* The method <code>previous</code> may used in a <code>while</code>3664* loop to iterate through a rowset starting after the last row3665* and moving toward the beginning. The loop ends when <code>previous</code>3666* returns <code>false</code>, meaning that there are no more rows.3667* For example, the following code fragment retrieves all the data in3668* the <code>CachedRowSetImpl</code> object <code>crs</code>, which has3669* three columns. Note that the cursor must initially be positioned3670* after the last row so that the first call to the method3671* <code>previous</code> places the cursor on the last line.3672* <PRE> <code>3673*3674* crs.afterLast();3675* while (previous()) {3676* String name = crs.getString(1);3677* int age = crs.getInt(2);3678* short ssn = crs.getShort(3);3679* System.out.println(name + " " + age + " " + ssn);3680* }3681*3682* </code> </PRE>3683* This method throws an <code>SQLException</code> if the cursor is not3684* on a row in the rowset, before the first row, or after the last row.3685*3686* @return <code>true</code> if the cursor is on a valid row;3687* <code>false</code> if it is before the first row or after the3688* last row3689* @throws SQLException if the cursor is not on a valid position or the3690* type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code>3691*/3692public boolean previous() throws SQLException {3693if (getType() == ResultSet.TYPE_FORWARD_ONLY) {3694throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString());3695}3696/*3697* make sure things look sane. The cursor must be3698* positioned in the rowset or before first (0) or3699* after last (numRows + 1)3700*/3701if (cursorPos < 0 || cursorPos > numRows + 1) {3702throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());3703}3704// move and notify3705boolean ret = this.internalPrevious();3706notifyCursorMoved();37073708return ret;3709}37103711/**3712* Moves the cursor to the previous row in this <code>CachedRowSetImpl</code>3713* object, skipping past deleted rows that are not visible; returns3714* <code>true</code> if the cursor is on a row in this rowset and3715* <code>false</code> when the cursor goes before the first row.3716* <P>3717* This method is called internally by the method <code>previous</code>.3718* <P>3719* This is a implementation only method and is not required as a standard3720* implementation of the <code>CachedRowSet</code> interface.3721*3722* @return <code>true</code> if the cursor is on a row in this rowset;3723* <code>false</code> when the cursor reaches the position before3724* the first row3725* @throws SQLException if an error occurs3726*/3727protected boolean internalPrevious() throws SQLException {3728boolean ret = false;37293730do {3731if (cursorPos > 1) {3732--cursorPos;3733ret = true;3734} else if (cursorPos == 1) {3735// decrement to before first3736--cursorPos;3737ret = false;3738break;3739}3740} while ((getShowDeleted() == false) && (rowDeleted() == true));37413742/*3743* Each call to internalPrevious may move the cursor3744* over multiple rows, the absolute position moves one row3745*/3746if (ret == true)3747--absolutePos;3748else3749absolutePos = 0;37503751return ret;3752}375337543755//---------------------------------------------------------------------3756// Updates3757//---------------------------------------------------------------------37583759/**3760* Indicates whether the current row of this <code>CachedRowSetImpl</code>3761* object has been updated. The value returned3762* depends on whether this rowset can detect updates: <code>false</code>3763* will always be returned if it does not detect updates.3764*3765* @return <code>true</code> if the row has been visibly updated3766* by the owner or another and updates are detected;3767* <code>false</code> otherwise3768* @throws SQLException if the cursor is on the insert row or not3769* not on a valid row3770*3771* @see DatabaseMetaData#updatesAreDetected3772*/3773public boolean rowUpdated() throws SQLException {3774// make sure the cursor is on a valid row3775checkCursor();3776if (onInsertRow == true) {3777throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());3778}3779return(((Row)getCurrentRow()).getUpdated());3780}37813782/**3783* Indicates whether the designated column of the current row of3784* this <code>CachedRowSetImpl</code> object has been updated. The3785* value returned depends on whether this rowset can detcted updates:3786* <code>false</code> will always be returned if it does not detect updates.3787*3788* @param idx the index identifier of the column that may be have been updated.3789* @return <code>true</code> is the designated column has been updated3790* and the rowset detects updates; <code>false</code> if the rowset has not3791* been updated or the rowset does not detect updates3792* @throws SQLException if the cursor is on the insert row or not3793* on a valid row3794* @see DatabaseMetaData#updatesAreDetected3795*/3796public boolean columnUpdated(int idx) throws SQLException {3797// make sure the cursor is on a valid row3798checkCursor();3799if (onInsertRow == true) {3800throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());3801}3802return (((Row)getCurrentRow()).getColUpdated(idx - 1));3803}38043805/**3806* Indicates whether the designated column of the current row of3807* this <code>CachedRowSetImpl</code> object has been updated. The3808* value returned depends on whether this rowset can detcted updates:3809* <code>false</code> will always be returned if it does not detect updates.3810*3811* @param columnName the <code>String</code> column name column that may be have3812* been updated.3813* @return <code>true</code> is the designated column has been updated3814* and the rowset detects updates; <code>false</code> if the rowset has not3815* been updated or the rowset does not detect updates3816* @throws SQLException if the cursor is on the insert row or not3817* on a valid row3818* @see DatabaseMetaData#updatesAreDetected3819*/3820public boolean columnUpdated(String columnName) throws SQLException {3821return columnUpdated(getColIdxByName(columnName));3822}38233824/**3825* Indicates whether the current row has been inserted. The value returned3826* depends on whether or not the rowset can detect visible inserts.3827*3828* @return <code>true</code> if a row has been inserted and inserts are detected;3829* <code>false</code> otherwise3830* @throws SQLException if the cursor is on the insert row or not3831* not on a valid row3832*3833* @see DatabaseMetaData#insertsAreDetected3834*/3835public boolean rowInserted() throws SQLException {3836// make sure the cursor is on a valid row3837checkCursor();3838if (onInsertRow == true) {3839throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());3840}3841return(((Row)getCurrentRow()).getInserted());3842}38433844/**3845* Indicates whether the current row has been deleted. A deleted row3846* may leave a visible "hole" in a rowset. This method can be used to3847* detect such holes if the rowset can detect deletions. This method3848* will always return <code>false</code> if this rowset cannot detect3849* deletions.3850*3851* @return <code>true</code> if (1)the current row is blank, indicating that3852* the row has been deleted, and (2)deletions are detected;3853* <code>false</code> otherwise3854* @throws SQLException if the cursor is on a valid row in this rowset3855* @see DatabaseMetaData#deletesAreDetected3856*/3857public boolean rowDeleted() throws SQLException {3858// make sure the cursor is on a valid row38593860if (isAfterLast() == true ||3861isBeforeFirst() == true ||3862onInsertRow == true) {38633864throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());3865}3866return(((Row)getCurrentRow()).getDeleted());3867}38683869/**3870* Indicates whether the given SQL data type is a numberic type.3871*3872* @param type one of the constants from <code>java.sql.Types</code>3873* @return <code>true</code> if the given type is <code>NUMERIC</code>,'3874* <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>,3875* <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>,3876* <code>REAL</code>, <code>DOUBLE</code>, or <code>FLOAT</code>;3877* <code>false</code> otherwise3878*/3879private boolean isNumeric(int type) {3880switch (type) {3881case java.sql.Types.NUMERIC:3882case java.sql.Types.DECIMAL:3883case java.sql.Types.BIT:3884case java.sql.Types.TINYINT:3885case java.sql.Types.SMALLINT:3886case java.sql.Types.INTEGER:3887case java.sql.Types.BIGINT:3888case java.sql.Types.REAL:3889case java.sql.Types.DOUBLE:3890case java.sql.Types.FLOAT:3891return true;3892default:3893return false;3894}3895}38963897/**3898* Indicates whether the given SQL data type is a string type.3899*3900* @param type one of the constants from <code>java.sql.Types</code>3901* @return <code>true</code> if the given type is <code>CHAR</code>,'3902* <code>VARCHAR</code>, or <code>LONGVARCHAR</code>;3903* <code>false</code> otherwise3904*/3905private boolean isString(int type) {3906switch (type) {3907case java.sql.Types.CHAR:3908case java.sql.Types.VARCHAR:3909case java.sql.Types.LONGVARCHAR:3910return true;3911default:3912return false;3913}3914}39153916/**3917* Indicates whether the given SQL data type is a binary type.3918*3919* @param type one of the constants from <code>java.sql.Types</code>3920* @return <code>true</code> if the given type is <code>BINARY</code>,'3921* <code>VARBINARY</code>, or <code>LONGVARBINARY</code>;3922* <code>false</code> otherwise3923*/3924private boolean isBinary(int type) {3925switch (type) {3926case java.sql.Types.BINARY:3927case java.sql.Types.VARBINARY:3928case java.sql.Types.LONGVARBINARY:3929return true;3930default:3931return false;3932}3933}39343935/**3936* Indicates whether the given SQL data type is a temporal type.3937* This method is called internally by the conversion methods3938* <code>convertNumeric</code> and <code>convertTemporal</code>.3939*3940* @param type one of the constants from <code>java.sql.Types</code>3941* @return <code>true</code> if the given type is <code>DATE</code>,3942* <code>TIME</code>, or <code>TIMESTAMP</code>;3943* <code>false</code> otherwise3944*/3945private boolean isTemporal(int type) {3946switch (type) {3947case java.sql.Types.DATE:3948case java.sql.Types.TIME:3949case java.sql.Types.TIMESTAMP:3950return true;3951default:3952return false;3953}3954}39553956/**3957* Indicates whether the given SQL data type is a boolean type.3958* This method is called internally by the conversion methods3959* <code>convertNumeric</code> and <code>convertBoolean</code>.3960*3961* @param type one of the constants from <code>java.sql.Types</code>3962* @return <code>true</code> if the given type is <code>BIT</code>,3963* , or <code>BOOLEAN</code>;3964* <code>false</code> otherwise3965*/3966private boolean isBoolean(int type) {3967switch (type) {3968case java.sql.Types.BIT:3969case java.sql.Types.BOOLEAN:3970return true;3971default:3972return false;3973}3974}397539763977/**3978* Converts the given <code>Object</code> in the Java programming language3979* to the standard mapping for the specified SQL target data type.3980* The conversion must be to a string or numeric type, but there are no3981* restrictions on the type to be converted. If the source type and target3982* type are the same, the given object is simply returned.3983*3984* @param srcObj the <code>Object</code> in the Java programming language3985* that is to be converted to the target type3986* @param srcType the data type that is the standard mapping in SQL of the3987* object to be converted; must be one of the constants in3988* <code>java.sql.Types</code>3989* @param trgType the SQL data type to which to convert the given object;3990* must be one of the following constants in3991* <code>java.sql.Types</code>: <code>NUMERIC</code>,3992* <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>,3993* <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>,3994* <code>REAL</code>, <code>DOUBLE</code>, <code>FLOAT</code>,3995* <code>VARCHAR</code>, <code>LONGVARCHAR</code>, or <code>CHAR</code>3996* @return an <code>Object</code> value.that is3997* the standard object mapping for the target SQL type3998* @throws SQLException if the given target type is not one of the string or3999* numeric types in <code>java.sql.Types</code>4000*/4001private Object convertNumeric(Object srcObj, int srcType,4002int trgType) throws SQLException {40034004if (srcType == trgType) {4005return srcObj;4006}40074008if (isNumeric(trgType) == false && isString(trgType) == false) {4009throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType);4010}40114012try {4013switch (trgType) {4014case java.sql.Types.BIT:4015Integer i = Integer.valueOf(srcObj.toString().trim());4016return i.equals(0) ?4017Boolean.valueOf(false) :4018Boolean.valueOf(true);4019case java.sql.Types.TINYINT:4020return Byte.valueOf(srcObj.toString().trim());4021case java.sql.Types.SMALLINT:4022return Short.valueOf(srcObj.toString().trim());4023case java.sql.Types.INTEGER:4024return Integer.valueOf(srcObj.toString().trim());4025case java.sql.Types.BIGINT:4026return Long.valueOf(srcObj.toString().trim());4027case java.sql.Types.NUMERIC:4028case java.sql.Types.DECIMAL:4029return new BigDecimal(srcObj.toString().trim());4030case java.sql.Types.REAL:4031case java.sql.Types.FLOAT:4032return Float.valueOf(srcObj.toString().trim());4033case java.sql.Types.DOUBLE:4034return Double.valueOf(srcObj.toString().trim());4035case java.sql.Types.CHAR:4036case java.sql.Types.VARCHAR:4037case java.sql.Types.LONGVARCHAR:4038return srcObj.toString();4039default:4040throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);4041}4042} catch (NumberFormatException ex) {4043throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType);4044}4045}40464047/**4048* Converts the given <code>Object</code> in the Java programming language4049* to the standard object mapping for the specified SQL target data type.4050* The conversion must be to a string or temporal type, and there are also4051* restrictions on the type to be converted.4052* <P>4053* <TABLE ALIGN="CENTER" BORDER CELLPADDING=10 BORDERCOLOR="#0000FF"4054* <CAPTION ALIGN="CENTER"><B>Parameters and Return Values</B></CAPTION>4055* <TR>4056* <TD><B>Source SQL Type</B>4057* <TD><B>Target SQL Type</B>4058* <TD><B>Object Returned</B>4059* </TR>4060* <TR>4061* <TD><code>TIMESTAMP</code>4062* <TD><code>DATE</code>4063* <TD><code>java.sql.Date</code>4064* </TR>4065* <TR>4066* <TD><code>TIMESTAMP</code>4067* <TD><code>TIME</code>4068* <TD><code>java.sql.Time</code>4069* </TR>4070* <TR>4071* <TD><code>TIME</code>4072* <TD><code>TIMESTAMP</code>4073* <TD><code>java.sql.Timestamp</code>4074* </TR>4075* <TR>4076* <TD><code>DATE</code>, <code>TIME</code>, or <code>TIMESTAMP</code>4077* <TD><code>CHAR</code>, <code>VARCHAR</code>, or <code>LONGVARCHAR</code>4078* <TD><code>java.lang.String</code>4079* </TR>4080* </TABLE>4081* <P>4082* If the source type and target type are the same,4083* the given object is simply returned.4084*4085* @param srcObj the <code>Object</code> in the Java programming language4086* that is to be converted to the target type4087* @param srcType the data type that is the standard mapping in SQL of the4088* object to be converted; must be one of the constants in4089* <code>java.sql.Types</code>4090* @param trgType the SQL data type to which to convert the given object;4091* must be one of the following constants in4092* <code>java.sql.Types</code>: <code>DATE</code>,4093* <code>TIME</code>, <code>TIMESTAMP</code>, <code>CHAR</code>,4094* <code>VARCHAR</code>, or <code>LONGVARCHAR</code>4095* @return an <code>Object</code> value.that is4096* the standard object mapping for the target SQL type4097* @throws SQLException if the given target type is not one of the string or4098* temporal types in <code>java.sql.Types</code>4099*/4100private Object convertTemporal(Object srcObj,4101int srcType, int trgType) throws SQLException {41024103if (srcType == trgType) {4104return srcObj;4105}41064107if (isNumeric(trgType) == true ||4108(isString(trgType) == false && isTemporal(trgType) == false)) {4109throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4110}41114112try {4113switch (trgType) {4114case java.sql.Types.DATE:4115if (srcType == java.sql.Types.TIMESTAMP) {4116return new java.sql.Date(((java.sql.Timestamp)srcObj).getTime());4117} else {4118throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4119}4120case java.sql.Types.TIMESTAMP:4121if (srcType == java.sql.Types.TIME) {4122return new Timestamp(((java.sql.Time)srcObj).getTime());4123} else {4124return new Timestamp(((java.sql.Date)srcObj).getTime());4125}4126case java.sql.Types.TIME:4127if (srcType == java.sql.Types.TIMESTAMP) {4128return new Time(((java.sql.Timestamp)srcObj).getTime());4129} else {4130throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4131}4132case java.sql.Types.CHAR:4133case java.sql.Types.VARCHAR:4134case java.sql.Types.LONGVARCHAR:4135return srcObj.toString();4136default:4137throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4138}4139} catch (NumberFormatException ex) {4140throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4141}41424143}41444145/**4146* Converts the given <code>Object</code> in the Java programming language4147* to the standard mapping for the specified SQL target data type.4148* The conversion must be to a string or numeric type, but there are no4149* restrictions on the type to be converted. If the source type and target4150* type are the same, the given object is simply returned.4151*4152* @param srcObj the <code>Object</code> in the Java programming language4153* that is to be converted to the target type4154* @param srcType the data type that is the standard mapping in SQL of the4155* object to be converted; must be one of the constants in4156* <code>java.sql.Types</code>4157* @param trgType the SQL data type to which to convert the given object;4158* must be one of the following constants in4159* <code>java.sql.Types</code>: <code>BIT</code>,4160* or <code>BOOLEAN</code>4161* @return an <code>Object</code> value.that is4162* the standard object mapping for the target SQL type4163* @throws SQLException if the given target type is not one of the Boolean4164* types in <code>java.sql.Types</code>4165*/4166private Object convertBoolean(Object srcObj, int srcType,4167int trgType) throws SQLException {41684169if (srcType == trgType) {4170return srcObj;4171}41724173if (isNumeric(trgType) == true ||4174(isString(trgType) == false && isBoolean(trgType) == false)) {4175throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4176}417741784179try {4180switch (trgType) {4181case java.sql.Types.BIT:4182Integer i = Integer.valueOf(srcObj.toString().trim());4183return i.equals(0) ?4184Boolean.valueOf(false) :4185Boolean.valueOf(true);4186case java.sql.Types.BOOLEAN:4187return Boolean.valueOf(srcObj.toString().trim());4188default:4189throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);4190}4191} catch (NumberFormatException ex) {4192throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType);4193}4194}41954196/**4197* Sets the designated nullable column in the current row or the4198* insert row of this <code>CachedRowSetImpl</code> object with4199* <code>null</code> value.4200* <P>4201* This method updates a column value in the current row or the insert4202* row of this rowset; however, another method must be called to complete4203* the update process. If the cursor is on a row in the rowset, the4204* method {@link #updateRow} must be called to mark the row as updated4205* and to notify listeners that the row has changed.4206* If the cursor is on the insert row, the method {@link #insertRow}4207* must be called to insert the new row into this rowset and to notify4208* listeners that a row has changed.4209* <P>4210* In order to propagate updates in this rowset to the underlying4211* data source, an application must call the method {@link #acceptChanges}4212* after it calls either <code>updateRow</code> or <code>insertRow</code>.4213*4214* @param columnIndex the first column is <code>1</code>, the second4215* is <code>2</code>, and so on; must be <code>1</code> or larger4216* and equal to or less than the number of columns in this rowset4217* @throws SQLException if (1) the given column index is out of bounds,4218* (2) the cursor is not on one of this rowset's rows or its4219* insert row, or (3) this rowset is4220* <code>ResultSet.CONCUR_READ_ONLY</code>4221*/4222public void updateNull(int columnIndex) throws SQLException {4223// sanity check.4224checkIndex(columnIndex);4225// make sure the cursor is on a valid row4226checkCursor();42274228BaseRow row = getCurrentRow();4229row.setColumnObject(columnIndex, null);42304231}42324233/**4234* Sets the designated column in either the current row or the insert4235* row of this <code>CachedRowSetImpl</code> object with the given4236* <code>boolean</code> value.4237* <P>4238* This method updates a column value in the current row or the insert4239* row of this rowset, but it does not update the database.4240* If the cursor is on a row in the rowset, the4241* method {@link #updateRow} must be called to update the database.4242* If the cursor is on the insert row, the method {@link #insertRow}4243* must be called, which will insert the new row into both this rowset4244* and the database. Both of these methods must be called before the4245* cursor moves to another row.4246*4247* @param columnIndex the first column is <code>1</code>, the second4248* is <code>2</code>, and so on; must be <code>1</code> or larger4249* and equal to or less than the number of columns in this rowset4250* @param x the new column value4251* @throws SQLException if (1) the given column index is out of bounds,4252* (2) the cursor is not on one of this rowset's rows or its4253* insert row, or (3) this rowset is4254* <code>ResultSet.CONCUR_READ_ONLY</code>4255*/4256public void updateBoolean(int columnIndex, boolean x) throws SQLException {4257// sanity check.4258checkIndex(columnIndex);4259// make sure the cursor is on a valid row4260checkCursor();4261Object obj = convertBoolean(Boolean.valueOf(x),4262java.sql.Types.BIT,4263RowSetMD.getColumnType(columnIndex));42644265getCurrentRow().setColumnObject(columnIndex, obj);4266}42674268/**4269* Sets the designated column in either the current row or the insert4270* row of this <code>CachedRowSetImpl</code> object with the given4271* <code>byte</code> value.4272* <P>4273* This method updates a column value in the current row or the insert4274* row of this rowset, but it does not update the database.4275* If the cursor is on a row in the rowset, the4276* method {@link #updateRow} must be called to update the database.4277* If the cursor is on the insert row, the method {@link #insertRow}4278* must be called, which will insert the new row into both this rowset4279* and the database. Both of these methods must be called before the4280* cursor moves to another row.4281*4282* @param columnIndex the first column is <code>1</code>, the second4283* is <code>2</code>, and so on; must be <code>1</code> or larger4284* and equal to or less than the number of columns in this rowset4285* @param x the new column value4286* @throws SQLException if (1) the given column index is out of bounds,4287* (2) the cursor is not on one of this rowset's rows or its4288* insert row, or (3) this rowset is4289* <code>ResultSet.CONCUR_READ_ONLY</code>4290*/4291public void updateByte(int columnIndex, byte x) throws SQLException {4292// sanity check.4293checkIndex(columnIndex);4294// make sure the cursor is on a valid row4295checkCursor();42964297Object obj = convertNumeric(Byte.valueOf(x),4298java.sql.Types.TINYINT,4299RowSetMD.getColumnType(columnIndex));43004301getCurrentRow().setColumnObject(columnIndex, obj);4302}43034304/**4305* Sets the designated column in either the current row or the insert4306* row of this <code>CachedRowSetImpl</code> object with the given4307* <code>short</code> value.4308* <P>4309* This method updates a column value in the current row or the insert4310* row of this rowset, but it does not update the database.4311* If the cursor is on a row in the rowset, the4312* method {@link #updateRow} must be called to update the database.4313* If the cursor is on the insert row, the method {@link #insertRow}4314* must be called, which will insert the new row into both this rowset4315* and the database. Both of these methods must be called before the4316* cursor moves to another row.4317*4318* @param columnIndex the first column is <code>1</code>, the second4319* is <code>2</code>, and so on; must be <code>1</code> or larger4320* and equal to or less than the number of columns in this rowset4321* @param x the new column value4322* @throws SQLException if (1) the given column index is out of bounds,4323* (2) the cursor is not on one of this rowset's rows or its4324* insert row, or (3) this rowset is4325* <code>ResultSet.CONCUR_READ_ONLY</code>4326*/4327public void updateShort(int columnIndex, short x) throws SQLException {4328// sanity check.4329checkIndex(columnIndex);4330// make sure the cursor is on a valid row4331checkCursor();43324333Object obj = convertNumeric(Short.valueOf(x),4334java.sql.Types.SMALLINT,4335RowSetMD.getColumnType(columnIndex));43364337getCurrentRow().setColumnObject(columnIndex, obj);4338}43394340/**4341* Sets the designated column in either the current row or the insert4342* row of this <code>CachedRowSetImpl</code> object with the given4343* <code>int</code> value.4344* <P>4345* This method updates a column value in the current row or the insert4346* row of this rowset, but it does not update the database.4347* If the cursor is on a row in the rowset, the4348* method {@link #updateRow} must be called to update the database.4349* If the cursor is on the insert row, the method {@link #insertRow}4350* must be called, which will insert the new row into both this rowset4351* and the database. Both of these methods must be called before the4352* cursor moves to another row.4353*4354* @param columnIndex the first column is <code>1</code>, the second4355* is <code>2</code>, and so on; must be <code>1</code> or larger4356* and equal to or less than the number of columns in this rowset4357* @param x the new column value4358* @throws SQLException if (1) the given column index is out of bounds,4359* (2) the cursor is not on one of this rowset's rows or its4360* insert row, or (3) this rowset is4361* <code>ResultSet.CONCUR_READ_ONLY</code>4362*/4363public void updateInt(int columnIndex, int x) throws SQLException {4364// sanity check.4365checkIndex(columnIndex);4366// make sure the cursor is on a valid row4367checkCursor();4368Object obj = convertNumeric(x,4369java.sql.Types.INTEGER,4370RowSetMD.getColumnType(columnIndex));43714372getCurrentRow().setColumnObject(columnIndex, obj);4373}43744375/**4376* Sets the designated column in either the current row or the insert4377* row of this <code>CachedRowSetImpl</code> object with the given4378* <code>long</code> value.4379* <P>4380* This method updates a column value in the current row or the insert4381* row of this rowset, but it does not update the database.4382* If the cursor is on a row in the rowset, the4383* method {@link #updateRow} must be called to update the database.4384* If the cursor is on the insert row, the method {@link #insertRow}4385* must be called, which will insert the new row into both this rowset4386* and the database. Both of these methods must be called before the4387* cursor moves to another row.4388*4389* @param columnIndex the first column is <code>1</code>, the second4390* is <code>2</code>, and so on; must be <code>1</code> or larger4391* and equal to or less than the number of columns in this rowset4392* @param x the new column value4393* @throws SQLException if (1) the given column index is out of bounds,4394* (2) the cursor is not on one of this rowset's rows or its4395* insert row, or (3) this rowset is4396* <code>ResultSet.CONCUR_READ_ONLY</code>4397*/4398public void updateLong(int columnIndex, long x) throws SQLException {4399// sanity check.4400checkIndex(columnIndex);4401// make sure the cursor is on a valid row4402checkCursor();44034404Object obj = convertNumeric(Long.valueOf(x),4405java.sql.Types.BIGINT,4406RowSetMD.getColumnType(columnIndex));44074408getCurrentRow().setColumnObject(columnIndex, obj);44094410}44114412/**4413* Sets the designated column in either the current row or the insert4414* row of this <code>CachedRowSetImpl</code> object with the given4415* <code>float</code> value.4416* <P>4417* This method updates a column value in the current row or the insert4418* row of this rowset, but it does not update the database.4419* If the cursor is on a row in the rowset, the4420* method {@link #updateRow} must be called to update the database.4421* If the cursor is on the insert row, the method {@link #insertRow}4422* must be called, which will insert the new row into both this rowset4423* and the database. Both of these methods must be called before the4424* cursor moves to another row.4425*4426* @param columnIndex the first column is <code>1</code>, the second4427* is <code>2</code>, and so on; must be <code>1</code> or larger4428* and equal to or less than the number of columns in this rowset4429* @param x the new column value4430* @throws SQLException if (1) the given column index is out of bounds,4431* (2) the cursor is not on one of this rowset's rows or its4432* insert row, or (3) this rowset is4433* <code>ResultSet.CONCUR_READ_ONLY</code>4434*/4435public void updateFloat(int columnIndex, float x) throws SQLException {4436// sanity check.4437checkIndex(columnIndex);4438// make sure the cursor is on a valid row4439checkCursor();44404441Object obj = convertNumeric(Float.valueOf(x),4442java.sql.Types.REAL,4443RowSetMD.getColumnType(columnIndex));44444445getCurrentRow().setColumnObject(columnIndex, obj);4446}44474448/**4449* Sets the designated column in either the current row or the insert4450* row of this <code>CachedRowSetImpl</code> object with the given4451* <code>double</code> value.4452*4453* This method updates a column value in either the current row or4454* the insert row of this rowset, but it does not update the4455* database. If the cursor is on a row in the rowset, the4456* method {@link #updateRow} must be called to update the database.4457* If the cursor is on the insert row, the method {@link #insertRow}4458* must be called, which will insert the new row into both this rowset4459* and the database. Both of these methods must be called before the4460* cursor moves to another row.4461*4462* @param columnIndex the first column is <code>1</code>, the second4463* is <code>2</code>, and so on; must be <code>1</code> or larger4464* and equal to or less than the number of columns in this rowset4465* @param x the new column value4466* @throws SQLException if (1) the given column index is out of bounds,4467* (2) the cursor is not on one of this rowset's rows or its4468* insert row, or (3) this rowset is4469* <code>ResultSet.CONCUR_READ_ONLY</code>4470*/4471public void updateDouble(int columnIndex, double x) throws SQLException {4472// sanity check.4473checkIndex(columnIndex);4474// make sure the cursor is on a valid row4475checkCursor();4476Object obj = convertNumeric(Double.valueOf(x),4477java.sql.Types.DOUBLE,4478RowSetMD.getColumnType(columnIndex));44794480getCurrentRow().setColumnObject(columnIndex, obj);4481}44824483/**4484* Sets the designated column in either the current row or the insert4485* row of this <code>CachedRowSetImpl</code> object with the given4486* <code>java.math.BigDecimal</code> object.4487* <P>4488* This method updates a column value in the current row or the insert4489* row of this rowset, but it does not update the database.4490* If the cursor is on a row in the rowset, the4491* method {@link #updateRow} must be called to update the database.4492* If the cursor is on the insert row, the method {@link #insertRow}4493* must be called, which will insert the new row into both this rowset4494* and the database. Both of these methods must be called before the4495* cursor moves to another row.4496*4497* @param columnIndex the first column is <code>1</code>, the second4498* is <code>2</code>, and so on; must be <code>1</code> or larger4499* and equal to or less than the number of columns in this rowset4500* @param x the new column value4501* @throws SQLException if (1) the given column index is out of bounds,4502* (2) the cursor is not on one of this rowset's rows or its4503* insert row, or (3) this rowset is4504* <code>ResultSet.CONCUR_READ_ONLY</code>4505*/4506public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {4507// sanity check.4508checkIndex(columnIndex);4509// make sure the cursor is on a valid row4510checkCursor();45114512Object obj = convertNumeric(x,4513java.sql.Types.NUMERIC,4514RowSetMD.getColumnType(columnIndex));45154516getCurrentRow().setColumnObject(columnIndex, obj);4517}45184519/**4520* Sets the designated column in either the current row or the insert4521* row of this <code>CachedRowSetImpl</code> object with the given4522* <code>String</code> object.4523* <P>4524* This method updates a column value in either the current row or4525* the insert row of this rowset, but it does not update the4526* database. If the cursor is on a row in the rowset, the4527* method {@link #updateRow} must be called to mark the row as updated.4528* If the cursor is on the insert row, the method {@link #insertRow}4529* must be called to insert the new row into this rowset and mark it4530* as inserted. Both of these methods must be called before the4531* cursor moves to another row.4532* <P>4533* The method <code>acceptChanges</code> must be called if the4534* updated values are to be written back to the underlying database.4535*4536* @param columnIndex the first column is <code>1</code>, the second4537* is <code>2</code>, and so on; must be <code>1</code> or larger4538* and equal to or less than the number of columns in this rowset4539* @param x the new column value4540* @throws SQLException if (1) the given column index is out of bounds,4541* (2) the cursor is not on one of this rowset's rows or its4542* insert row, or (3) this rowset is4543* <code>ResultSet.CONCUR_READ_ONLY</code>4544*/4545public void updateString(int columnIndex, String x) throws SQLException {4546// sanity check.4547checkIndex(columnIndex);4548// make sure the cursor is on a valid row4549checkCursor();45504551getCurrentRow().setColumnObject(columnIndex, x);4552}45534554/**4555* Sets the designated column in either the current row or the insert4556* row of this <code>CachedRowSetImpl</code> object with the given4557* <code>byte</code> array.4558*4559* This method updates a column value in either the current row or4560* the insert row of this rowset, but it does not update the4561* database. If the cursor is on a row in the rowset, the4562* method {@link #updateRow} must be called to update the database.4563* If the cursor is on the insert row, the method {@link #insertRow}4564* must be called, which will insert the new row into both this rowset4565* and the database. Both of these methods must be called before the4566* cursor moves to another row.4567*4568* @param columnIndex the first column is <code>1</code>, the second4569* is <code>2</code>, and so on; must be <code>1</code> or larger4570* and equal to or less than the number of columns in this rowset4571* @param x the new column value4572* @throws SQLException if (1) the given column index is out of bounds,4573* (2) the cursor is not on one of this rowset's rows or its4574* insert row, or (3) this rowset is4575* <code>ResultSet.CONCUR_READ_ONLY</code>4576*/4577public void updateBytes(int columnIndex, byte x[]) throws SQLException {4578// sanity check.4579checkIndex(columnIndex);4580// make sure the cursor is on a valid row4581checkCursor();45824583if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) {4584throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4585}45864587getCurrentRow().setColumnObject(columnIndex, x);4588}45894590/**4591* Sets the designated column in either the current row or the insert4592* row of this <code>CachedRowSetImpl</code> object with the given4593* <code>Date</code> object.4594*4595* This method updates a column value in either the current row or4596* the insert row of this rowset, but it does not update the4597* database. If the cursor is on a row in the rowset, the4598* method {@link #updateRow} must be called to update the database.4599* If the cursor is on the insert row, the method {@link #insertRow}4600* must be called, which will insert the new row into both this rowset4601* and the database. Both of these methods must be called before the4602* cursor moves to another row.4603*4604* @param columnIndex the first column is <code>1</code>, the second4605* is <code>2</code>, and so on; must be <code>1</code> or larger4606* and equal to or less than the number of columns in this rowset4607* @param x the new column value4608* @throws SQLException if (1) the given column index is out of bounds,4609* (2) the cursor is not on one of this rowset's rows or its4610* insert row, (3) the type of the designated column is not4611* an SQL <code>DATE</code> or <code>TIMESTAMP</code>, or4612* (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4613*/4614public void updateDate(int columnIndex, java.sql.Date x) throws SQLException {4615// sanity check.4616checkIndex(columnIndex);4617// make sure the cursor is on a valid row4618checkCursor();46194620Object obj = convertTemporal(x,4621java.sql.Types.DATE,4622RowSetMD.getColumnType(columnIndex));46234624getCurrentRow().setColumnObject(columnIndex, obj);4625}46264627/**4628* Sets the designated column in either the current row or the insert4629* row of this <code>CachedRowSetImpl</code> object with the given4630* <code>Time</code> object.4631*4632* This method updates a column value in either the current row or4633* the insert row of this rowset, but it does not update the4634* database. If the cursor is on a row in the rowset, the4635* method {@link #updateRow} must be called to update the database.4636* If the cursor is on the insert row, the method {@link #insertRow}4637* must be called, which will insert the new row into both this rowset4638* and the database. Both of these methods must be called before the4639* cursor moves to another row.4640*4641* @param columnIndex the first column is <code>1</code>, the second4642* is <code>2</code>, and so on; must be <code>1</code> or larger4643* and equal to or less than the number of columns in this rowset4644* @param x the new column value4645* @throws SQLException if (1) the given column index is out of bounds,4646* (2) the cursor is not on one of this rowset's rows or its4647* insert row, (3) the type of the designated column is not4648* an SQL <code>TIME</code> or <code>TIMESTAMP</code>, or4649* (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4650*/4651public void updateTime(int columnIndex, java.sql.Time x) throws SQLException {4652// sanity check.4653checkIndex(columnIndex);4654// make sure the cursor is on a valid row4655checkCursor();46564657Object obj = convertTemporal(x,4658java.sql.Types.TIME,4659RowSetMD.getColumnType(columnIndex));46604661getCurrentRow().setColumnObject(columnIndex, obj);4662}46634664/**4665* Sets the designated column in either the current row or the insert4666* row of this <code>CachedRowSetImpl</code> object with the given4667* <code>Timestamp</code> object.4668*4669* This method updates a column value in either the current row or4670* the insert row of this rowset, but it does not update the4671* database. If the cursor is on a row in the rowset, the4672* method {@link #updateRow} must be called to update the database.4673* If the cursor is on the insert row, the method {@link #insertRow}4674* must be called, which will insert the new row into both this rowset4675* and the database. Both of these methods must be called before the4676* cursor moves to another row.4677*4678* @param columnIndex the first column is <code>1</code>, the second4679* is <code>2</code>, and so on; must be <code>1</code> or larger4680* and equal to or less than the number of columns in this rowset4681* @param x the new column value4682* @throws SQLException if (1) the given column index is out of bounds,4683* (2) the cursor is not on one of this rowset's rows or its4684* insert row, (3) the type of the designated column is not4685* an SQL <code>DATE</code>, <code>TIME</code>, or4686* <code>TIMESTAMP</code>, or (4) this rowset is4687* <code>ResultSet.CONCUR_READ_ONLY</code>4688*/4689public void updateTimestamp(int columnIndex, java.sql.Timestamp x) throws SQLException {4690// sanity check.4691checkIndex(columnIndex);4692// make sure the cursor is on a valid row4693checkCursor();46944695Object obj = convertTemporal(x,4696java.sql.Types.TIMESTAMP,4697RowSetMD.getColumnType(columnIndex));46984699getCurrentRow().setColumnObject(columnIndex, obj);4700}47014702/**4703* Sets the designated column in either the current row or the insert4704* row of this <code>CachedRowSetImpl</code> object with the given4705* ASCII stream value.4706* <P>4707* This method updates a column value in either the current row or4708* the insert row of this rowset, but it does not update the4709* database. If the cursor is on a row in the rowset, the4710* method {@link #updateRow} must be called to update the database.4711* If the cursor is on the insert row, the method {@link #insertRow}4712* must be called, which will insert the new row into both this rowset4713* and the database. Both of these methods must be called before the4714* cursor moves to another row.4715*4716* @param columnIndex the first column is <code>1</code>, the second4717* is <code>2</code>, and so on; must be <code>1</code> or larger4718* and equal to or less than the number of columns in this rowset4719* @param x the new column value4720* @param length the number of one-byte ASCII characters in the stream4721* @throws SQLException if this method is invoked4722*/4723public void updateAsciiStream(int columnIndex, java.io.InputStream x, int length) throws SQLException {4724// sanity Check4725checkIndex(columnIndex);4726// make sure the cursor is on a valid row4727checkCursor();472847294730if (isString(RowSetMD.getColumnType(columnIndex)) == false &&4731isBinary(RowSetMD.getColumnType(columnIndex)) == false) {4732throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4733}47344735byte buf[] = new byte[length];4736try {4737int charsRead = 0;4738do {4739charsRead += x.read(buf, charsRead, length - charsRead);4740} while (charsRead != length);4741//Changed the condition check to check for length instead of -14742} catch (java.io.IOException ex) {4743throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.asciistream").toString());4744}4745String str = new String(buf);47464747getCurrentRow().setColumnObject(columnIndex, str);47484749}47504751/**4752* Sets the designated column in either the current row or the insert4753* row of this <code>CachedRowSetImpl</code> object with the given4754* <code>java.io.InputStream</code> object.4755* <P>4756* This method updates a column value in either the current row or4757* the insert row of this rowset, but it does not update the4758* database. If the cursor is on a row in the rowset, the4759* method {@link #updateRow} must be called to update the database.4760* If the cursor is on the insert row, the method {@link #insertRow}4761* must be called, which will insert the new row into both this rowset4762* and the database. Both of these methods must be called before the4763* cursor moves to another row.4764*4765* @param columnIndex the first column is <code>1</code>, the second4766* is <code>2</code>, and so on; must be <code>1</code> or larger4767* and equal to or less than the number of columns in this rowset4768* @param x the new column value; must be a <code>java.io.InputStream</code>4769* containing <code>BINARY</code>, <code>VARBINARY</code>, or4770* <code>LONGVARBINARY</code> data4771* @param length the length of the stream in bytes4772* @throws SQLException if (1) the given column index is out of bounds,4773* (2) the cursor is not on one of this rowset's rows or its4774* insert row, (3) the data in the stream is not binary, or4775* (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4776*/4777public void updateBinaryStream(int columnIndex, java.io.InputStream x,int length) throws SQLException {4778// sanity Check4779checkIndex(columnIndex);4780// make sure the cursor is on a valid row4781checkCursor();47824783if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) {4784throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4785}47864787byte buf[] = new byte[length];4788try {4789int bytesRead = 0;4790do {4791bytesRead += x.read(buf, bytesRead, length - bytesRead);4792} while (bytesRead != -1);4793} catch (java.io.IOException ex) {4794throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString());4795}47964797getCurrentRow().setColumnObject(columnIndex, buf);4798}47994800/**4801* Sets the designated column in either the current row or the insert4802* row of this <code>CachedRowSetImpl</code> object with the given4803* <code>java.io.Reader</code> object.4804* <P>4805* This method updates a column value in either the current row or4806* the insert row of this rowset, but it does not update the4807* database. If the cursor is on a row in the rowset, the4808* method {@link #updateRow} must be called to update the database.4809* If the cursor is on the insert row, the method {@link #insertRow}4810* must be called, which will insert the new row into both this rowset4811* and the database. Both of these methods must be called before the4812* cursor moves to another row.4813*4814* @param columnIndex the first column is <code>1</code>, the second4815* is <code>2</code>, and so on; must be <code>1</code> or larger4816* and equal to or less than the number of columns in this rowset4817* @param x the new column value; must be a <code>java.io.Reader</code>4818* containing <code>BINARY</code>, <code>VARBINARY</code>,4819* <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,4820* or <code>LONGVARCHAR</code> data4821* @param length the length of the stream in characters4822* @throws SQLException if (1) the given column index is out of bounds,4823* (2) the cursor is not on one of this rowset's rows or its4824* insert row, (3) the data in the stream is not a binary or4825* character type, or (4) this rowset is4826* <code>ResultSet.CONCUR_READ_ONLY</code>4827*/4828public void updateCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException {4829// sanity Check4830checkIndex(columnIndex);4831// make sure the cursor is on a valid row4832checkCursor();48334834if (isString(RowSetMD.getColumnType(columnIndex)) == false &&4835isBinary(RowSetMD.getColumnType(columnIndex)) == false) {4836throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4837}48384839char buf[] = new char[length];4840try {4841int charsRead = 0;4842do {4843charsRead += x.read(buf, charsRead, length - charsRead);4844} while (charsRead != length);4845//Changed the condition checking to check for length instead of -14846} catch (java.io.IOException ex) {4847throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString());4848}4849String str = new String(buf);48504851getCurrentRow().setColumnObject(columnIndex, str);4852}48534854/**4855* Sets the designated column in either the current row or the insert4856* row of this <code>CachedRowSetImpl</code> object with the given4857* <code>Object</code> value. The <code>scale</code> parameter indicates4858* the number of digits to the right of the decimal point and is ignored4859* if the new column value is not a type that will be mapped to an SQL4860* <code>DECIMAL</code> or <code>NUMERIC</code> value.4861* <P>4862* This method updates a column value in either the current row or4863* the insert row of this rowset, but it does not update the4864* database. If the cursor is on a row in the rowset, the4865* method {@link #updateRow} must be called to update the database.4866* If the cursor is on the insert row, the method {@link #insertRow}4867* must be called, which will insert the new row into both this rowset4868* and the database. Both of these methods must be called before the4869* cursor moves to another row.4870*4871* @param columnIndex the first column is <code>1</code>, the second4872* is <code>2</code>, and so on; must be <code>1</code> or larger4873* and equal to or less than the number of columns in this rowset4874* @param x the new column value4875* @param scale the number of digits to the right of the decimal point (for4876* <code>DECIMAL</code> and <code>NUMERIC</code> types only)4877* @throws SQLException if (1) the given column index is out of bounds,4878* (2) the cursor is not on one of this rowset's rows or its4879* insert row, or (3) this rowset is4880* <code>ResultSet.CONCUR_READ_ONLY</code>4881*/4882public void updateObject(int columnIndex, Object x, int scale) throws SQLException {4883// sanity check.4884checkIndex(columnIndex);4885// make sure the cursor is on a valid row4886checkCursor();48874888int type = RowSetMD.getColumnType(columnIndex);4889if (type == Types.DECIMAL || type == Types.NUMERIC) {4890((java.math.BigDecimal)x).setScale(scale);4891}4892getCurrentRow().setColumnObject(columnIndex, x);4893}48944895/**4896* Sets the designated column in either the current row or the insert4897* row of this <code>CachedRowSetImpl</code> object with the given4898* <code>Object</code> value.4899* <P>4900* This method updates a column value in either the current row or4901* the insert row of this rowset, but it does not update the4902* database. If the cursor is on a row in the rowset, the4903* method {@link #updateRow} must be called to update the database.4904* If the cursor is on the insert row, the method {@link #insertRow}4905* must be called, which will insert the new row into both this rowset4906* and the database. Both of these methods must be called before the4907* cursor moves to another row.4908*4909* @param columnIndex the first column is <code>1</code>, the second4910* is <code>2</code>, and so on; must be <code>1</code> or larger4911* and equal to or less than the number of columns in this rowset4912* @param x the new column value4913* @throws SQLException if (1) the given column index is out of bounds,4914* (2) the cursor is not on one of this rowset's rows or its4915* insert row, or (3) this rowset is4916* <code>ResultSet.CONCUR_READ_ONLY</code>4917*/4918public void updateObject(int columnIndex, Object x) throws SQLException {4919// sanity check.4920checkIndex(columnIndex);4921// make sure the cursor is on a valid row4922checkCursor();49234924getCurrentRow().setColumnObject(columnIndex, x);4925}49264927/**4928* Sets the designated nullable column in the current row or the4929* insert row of this <code>CachedRowSetImpl</code> object with4930* <code>null</code> value.4931* <P>4932* This method updates a column value in the current row or the insert4933* row of this rowset, but it does not update the database.4934* If the cursor is on a row in the rowset, the4935* method {@link #updateRow} must be called to update the database.4936* If the cursor is on the insert row, the method {@link #insertRow}4937* must be called, which will insert the new row into both this rowset4938* and the database.4939*4940* @param columnName a <code>String</code> object that must match the4941* SQL name of a column in this rowset, ignoring case4942* @throws SQLException if (1) the given column name does not match the4943* name of a column in this rowset, (2) the cursor is not on4944* one of this rowset's rows or its insert row, or (3) this4945* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4946*/4947public void updateNull(String columnName) throws SQLException {4948updateNull(getColIdxByName(columnName));4949}49504951/**4952* Sets the designated column in either the current row or the insert4953* row of this <code>CachedRowSetImpl</code> object with the given4954* <code>boolean</code> value.4955* <P>4956* This method updates a column value in the current row or the insert4957* row of this rowset, but it does not update the database.4958* If the cursor is on a row in the rowset, the4959* method {@link #updateRow} must be called to update the database.4960* If the cursor is on the insert row, the method {@link #insertRow}4961* must be called, which will insert the new row into both this rowset4962* and the database. Both of these methods must be called before the4963* cursor moves to another row.4964*4965* @param columnName a <code>String</code> object that must match the4966* SQL name of a column in this rowset, ignoring case4967* @param x the new column value4968* @throws SQLException if (1) the given column name does not match the4969* name of a column in this rowset, (2) the cursor is not on4970* one of this rowset's rows or its insert row, or (3) this4971* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4972*/4973public void updateBoolean(String columnName, boolean x) throws SQLException {4974updateBoolean(getColIdxByName(columnName), x);4975}49764977/**4978* Sets the designated column in either the current row or the insert4979* row of this <code>CachedRowSetImpl</code> object with the given4980* <code>byte</code> value.4981* <P>4982* This method updates a column value in the current row or the insert4983* row of this rowset, but it does not update the database.4984* If the cursor is on a row in the rowset, the4985* method {@link #updateRow} must be called to update the database.4986* If the cursor is on the insert row, the method {@link #insertRow}4987* must be called, which will insert the new row into both this rowset4988* and the database. Both of these methods must be called before the4989* cursor moves to another row.4990*4991* @param columnName a <code>String</code> object that must match the4992* SQL name of a column in this rowset, ignoring case4993* @param x the new column value4994* @throws SQLException if (1) the given column name does not match the4995* name of a column in this rowset, (2) the cursor is not on4996* one of this rowset's rows or its insert row, or (3) this4997* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4998*/4999public void updateByte(String columnName, byte x) throws SQLException {5000updateByte(getColIdxByName(columnName), x);5001}50025003/**5004* Sets the designated column in either the current row or the insert5005* row of this <code>CachedRowSetImpl</code> object with the given5006* <code>short</code> value.5007* <P>5008* This method updates a column value in the current row or the insert5009* row of this rowset, but it does not update the database.5010* If the cursor is on a row in the rowset, the5011* method {@link #updateRow} must be called to update the database.5012* If the cursor is on the insert row, the method {@link #insertRow}5013* must be called, which will insert the new row into both this rowset5014* and the database. Both of these methods must be called before the5015* cursor moves to another row.5016*5017* @param columnName a <code>String</code> object that must match the5018* SQL name of a column in this rowset, ignoring case5019* @param x the new column value5020* @throws SQLException if (1) the given column name does not match the5021* name of a column in this rowset, (2) the cursor is not on5022* one of this rowset's rows or its insert row, or (3) this5023* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5024*/5025public void updateShort(String columnName, short x) throws SQLException {5026updateShort(getColIdxByName(columnName), x);5027}50285029/**5030* Sets the designated column in either the current row or the insert5031* row of this <code>CachedRowSetImpl</code> object with the given5032* <code>int</code> value.5033* <P>5034* This method updates a column value in the current row or the insert5035* row of this rowset, but it does not update the database.5036* If the cursor is on a row in the rowset, the5037* method {@link #updateRow} must be called to update the database.5038* If the cursor is on the insert row, the method {@link #insertRow}5039* must be called, which will insert the new row into both this rowset5040* and the database. Both of these methods must be called before the5041* cursor moves to another row.5042*5043* @param columnName a <code>String</code> object that must match the5044* SQL name of a column in this rowset, ignoring case5045* @param x the new column value5046* @throws SQLException if (1) the given column name does not match the5047* name of a column in this rowset, (2) the cursor is not on5048* one of this rowset's rows or its insert row, or (3) this5049* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5050*/5051public void updateInt(String columnName, int x) throws SQLException {5052updateInt(getColIdxByName(columnName), x);5053}50545055/**5056* Sets the designated column in either the current row or the insert5057* row of this <code>CachedRowSetImpl</code> object with the given5058* <code>long</code> value.5059* <P>5060* This method updates a column value in the current row or the insert5061* row of this rowset, but it does not update the database.5062* If the cursor is on a row in the rowset, the5063* method {@link #updateRow} must be called to update the database.5064* If the cursor is on the insert row, the method {@link #insertRow}5065* must be called, which will insert the new row into both this rowset5066* and the database. Both of these methods must be called before the5067* cursor moves to another row.5068*5069* @param columnName a <code>String</code> object that must match the5070* SQL name of a column in this rowset, ignoring case5071* @param x the new column value5072* @throws SQLException if (1) the given column name does not match the5073* name of a column in this rowset, (2) the cursor is not on5074* one of this rowset's rows or its insert row, or (3) this5075* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5076*/5077public void updateLong(String columnName, long x) throws SQLException {5078updateLong(getColIdxByName(columnName), x);5079}50805081/**5082* Sets the designated column in either the current row or the insert5083* row of this <code>CachedRowSetImpl</code> object with the given5084* <code>float</code> value.5085* <P>5086* This method updates a column value in the current row or the insert5087* row of this rowset, but it does not update the database.5088* If the cursor is on a row in the rowset, the5089* method {@link #updateRow} must be called to update the database.5090* If the cursor is on the insert row, the method {@link #insertRow}5091* must be called, which will insert the new row into both this rowset5092* and the database. Both of these methods must be called before the5093* cursor moves to another row.5094*5095* @param columnName a <code>String</code> object that must match the5096* SQL name of a column in this rowset, ignoring case5097* @param x the new column value5098* @throws SQLException if (1) the given column name does not match the5099* name of a column in this rowset, (2) the cursor is not on5100* one of this rowset's rows or its insert row, or (3) this5101* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5102*/5103public void updateFloat(String columnName, float x) throws SQLException {5104updateFloat(getColIdxByName(columnName), x);5105}51065107/**5108* Sets the designated column in either the current row or the insert5109* row of this <code>CachedRowSetImpl</code> object with the given5110* <code>double</code> value.5111*5112* This method updates a column value in either the current row or5113* the insert row of this rowset, but it does not update the5114* database. If the cursor is on a row in the rowset, the5115* method {@link #updateRow} must be called to update the database.5116* If the cursor is on the insert row, the method {@link #insertRow}5117* must be called, which will insert the new row into both this rowset5118* and the database. Both of these methods must be called before the5119* cursor moves to another row.5120*5121* @param columnName a <code>String</code> object that must match the5122* SQL name of a column in this rowset, ignoring case5123* @param x the new column value5124* @throws SQLException if (1) the given column name does not match the5125* name of a column in this rowset, (2) the cursor is not on5126* one of this rowset's rows or its insert row, or (3) this5127* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5128*/5129public void updateDouble(String columnName, double x) throws SQLException {5130updateDouble(getColIdxByName(columnName), x);5131}51325133/**5134* Sets the designated column in either the current row or the insert5135* row of this <code>CachedRowSetImpl</code> object with the given5136* <code>java.math.BigDecimal</code> object.5137* <P>5138* This method updates a column value in the current row or the insert5139* row of this rowset, but it does not update the database.5140* If the cursor is on a row in the rowset, the5141* method {@link #updateRow} must be called to update the database.5142* If the cursor is on the insert row, the method {@link #insertRow}5143* must be called, which will insert the new row into both this rowset5144* and the database. Both of these methods must be called before the5145* cursor moves to another row.5146*5147* @param columnName a <code>String</code> object that must match the5148* SQL name of a column in this rowset, ignoring case5149* @param x the new column value5150* @throws SQLException if (1) the given column name does not match the5151* name of a column in this rowset, (2) the cursor is not on5152* one of this rowset's rows or its insert row, or (3) this5153* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5154*/5155public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {5156updateBigDecimal(getColIdxByName(columnName), x);5157}51585159/**5160* Sets the designated column in either the current row or the insert5161* row of this <code>CachedRowSetImpl</code> object with the given5162* <code>String</code> object.5163*5164* This method updates a column value in either the current row or5165* the insert row of this rowset, but it does not update the5166* database. If the cursor is on a row in the rowset, the5167* method {@link #updateRow} must be called to update the database.5168* If the cursor is on the insert row, the method {@link #insertRow}5169* must be called, which will insert the new row into both this rowset5170* and the database. Both of these methods must be called before the5171* cursor moves to another row.5172*5173* @param columnName a <code>String</code> object that must match the5174* SQL name of a column in this rowset, ignoring case5175* @param x the new column value5176* @throws SQLException if (1) the given column name does not match the5177* name of a column in this rowset, (2) the cursor is not on5178* one of this rowset's rows or its insert row, or (3) this5179* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5180*/5181public void updateString(String columnName, String x) throws SQLException {5182updateString(getColIdxByName(columnName), x);5183}51845185/**5186* Sets the designated column in either the current row or the insert5187* row of this <code>CachedRowSetImpl</code> object with the given5188* <code>byte</code> array.5189*5190* This method updates a column value in either the current row or5191* the insert row of this rowset, but it does not update the5192* database. If the cursor is on a row in the rowset, the5193* method {@link #updateRow} must be called to update the database.5194* If the cursor is on the insert row, the method {@link #insertRow}5195* must be called, which will insert the new row into both this rowset5196* and the database. Both of these methods must be called before the5197* cursor moves to another row.5198*5199* @param columnName a <code>String</code> object that must match the5200* SQL name of a column in this rowset, ignoring case5201* @param x the new column value5202* @throws SQLException if (1) the given column name does not match the5203* name of a column in this rowset, (2) the cursor is not on5204* one of this rowset's rows or its insert row, or (3) this5205* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5206*/5207public void updateBytes(String columnName, byte x[]) throws SQLException {5208updateBytes(getColIdxByName(columnName), x);5209}52105211/**5212* Sets the designated column in either the current row or the insert5213* row of this <code>CachedRowSetImpl</code> object with the given5214* <code>Date</code> object.5215*5216* This method updates a column value in either the current row or5217* the insert row of this rowset, but it does not update the5218* database. If the cursor is on a row in the rowset, the5219* method {@link #updateRow} must be called to update the database.5220* If the cursor is on the insert row, the method {@link #insertRow}5221* must be called, which will insert the new row into both this rowset5222* and the database. Both of these methods must be called before the5223* cursor moves to another row.5224*5225* @param columnName a <code>String</code> object that must match the5226* SQL name of a column in this rowset, ignoring case5227* @param x the new column value5228* @throws SQLException if (1) the given column name does not match the5229* name of a column in this rowset, (2) the cursor is not on5230* one of this rowset's rows or its insert row, (3) the type5231* of the designated column is not an SQL <code>DATE</code> or5232* <code>TIMESTAMP</code>, or (4) this rowset is5233* <code>ResultSet.CONCUR_READ_ONLY</code>5234*/5235public void updateDate(String columnName, java.sql.Date x) throws SQLException {5236updateDate(getColIdxByName(columnName), x);5237}52385239/**5240* Sets the designated column in either the current row or the insert5241* row of this <code>CachedRowSetImpl</code> object with the given5242* <code>Time</code> object.5243*5244* This method updates a column value in either the current row or5245* the insert row of this rowset, but it does not update the5246* database. If the cursor is on a row in the rowset, the5247* method {@link #updateRow} must be called to update the database.5248* If the cursor is on the insert row, the method {@link #insertRow}5249* must be called, which will insert the new row into both this rowset5250* and the database. Both of these methods must be called before the5251* cursor moves to another row.5252*5253* @param columnName a <code>String</code> object that must match the5254* SQL name of a column in this rowset, ignoring case5255* @param x the new column value5256* @throws SQLException if (1) the given column name does not match the5257* name of a column in this rowset, (2) the cursor is not on5258* one of this rowset's rows or its insert row, (3) the type5259* of the designated column is not an SQL <code>TIME</code> or5260* <code>TIMESTAMP</code>, or (4) this rowset is5261* <code>ResultSet.CONCUR_READ_ONLY</code>5262*/5263public void updateTime(String columnName, java.sql.Time x) throws SQLException {5264updateTime(getColIdxByName(columnName), x);5265}52665267/**5268* Sets the designated column in either the current row or the insert5269* row of this <code>CachedRowSetImpl</code> object with the given5270* <code>Timestamp</code> object.5271*5272* This method updates a column value in either the current row or5273* the insert row of this rowset, but it does not update the5274* database. If the cursor is on a row in the rowset, the5275* method {@link #updateRow} must be called to update the database.5276* If the cursor is on the insert row, the method {@link #insertRow}5277* must be called, which will insert the new row into both this rowset5278* and the database. Both of these methods must be called before the5279* cursor moves to another row.5280*5281* @param columnName a <code>String</code> object that must match the5282* SQL name of a column in this rowset, ignoring case5283* @param x the new column value5284* @throws SQLException if the given column index is out of bounds or5285* the cursor is not on one of this rowset's rows or its5286* insert row5287* @throws SQLException if (1) the given column name does not match the5288* name of a column in this rowset, (2) the cursor is not on5289* one of this rowset's rows or its insert row, (3) the type5290* of the designated column is not an SQL <code>DATE</code>,5291* <code>TIME</code>, or <code>TIMESTAMP</code>, or (4) this5292* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5293*/5294public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException {5295updateTimestamp(getColIdxByName(columnName), x);5296}52975298/**5299* Sets the designated column in either the current row or the insert5300* row of this <code>CachedRowSetImpl</code> object with the given5301* ASCII stream value.5302* <P>5303* This method updates a column value in either the current row or5304* the insert row of this rowset, but it does not update the5305* database. If the cursor is on a row in the rowset, the5306* method {@link #updateRow} must be called to update the database.5307* If the cursor is on the insert row, the method {@link #insertRow}5308* must be called, which will insert the new row into both this rowset5309* and the database. Both of these methods must be called before the5310* cursor moves to another row.5311*5312* @param columnName a <code>String</code> object that must match the5313* SQL name of a column in this rowset, ignoring case5314* @param x the new column value5315* @param length the number of one-byte ASCII characters in the stream5316*/5317public void updateAsciiStream(String columnName,5318java.io.InputStream x,5319int length) throws SQLException {5320updateAsciiStream(getColIdxByName(columnName), x, length);5321}53225323/**5324* Sets the designated column in either the current row or the insert5325* row of this <code>CachedRowSetImpl</code> object with the given5326* <code>java.io.InputStream</code> object.5327* <P>5328* This method updates a column value in either the current row or5329* the insert row of this rowset, but it does not update the5330* database. If the cursor is on a row in the rowset, the5331* method {@link #updateRow} must be called to update the database.5332* If the cursor is on the insert row, the method {@link #insertRow}5333* must be called, which will insert the new row into both this rowset5334* and the database. Both of these methods must be called before the5335* cursor moves to another row.5336*5337* @param columnName a <code>String</code> object that must match the5338* SQL name of a column in this rowset, ignoring case5339* @param x the new column value; must be a <code>java.io.InputStream</code>5340* containing <code>BINARY</code>, <code>VARBINARY</code>, or5341* <code>LONGVARBINARY</code> data5342* @param length the length of the stream in bytes5343* @throws SQLException if (1) the given column name does not match the5344* name of a column in this rowset, (2) the cursor is not on5345* one of this rowset's rows or its insert row, (3) the data5346* in the stream is not binary, or (4) this rowset is5347* <code>ResultSet.CONCUR_READ_ONLY</code>5348*/5349public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException {5350updateBinaryStream(getColIdxByName(columnName), x, length);5351}53525353/**5354* Sets the designated column in either the current row or the insert5355* row of this <code>CachedRowSetImpl</code> object with the given5356* <code>java.io.Reader</code> object.5357* <P>5358* This method updates a column value in either the current row or5359* the insert row of this rowset, but it does not update the5360* database. If the cursor is on a row in the rowset, the5361* method {@link #updateRow} must be called to update the database.5362* If the cursor is on the insert row, the method {@link #insertRow}5363* must be called, which will insert the new row into both this rowset5364* and the database. Both of these methods must be called before the5365* cursor moves to another row.5366*5367* @param columnName a <code>String</code> object that must match the5368* SQL name of a column in this rowset, ignoring case5369* @param reader the new column value; must be a5370* <code>java.io.Reader</code> containing <code>BINARY</code>,5371* <code>VARBINARY</code>, <code>LONGVARBINARY</code>, <code>CHAR</code>,5372* <code>VARCHAR</code>, or <code>LONGVARCHAR</code> data5373* @param length the length of the stream in characters5374* @throws SQLException if (1) the given column name does not match the5375* name of a column in this rowset, (2) the cursor is not on5376* one of this rowset's rows or its insert row, (3) the data5377* in the stream is not a binary or character type, or (4) this5378* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5379*/5380public void updateCharacterStream(String columnName,5381java.io.Reader reader,5382int length) throws SQLException {5383updateCharacterStream(getColIdxByName(columnName), reader, length);5384}53855386/**5387* Sets the designated column in either the current row or the insert5388* row of this <code>CachedRowSetImpl</code> object with the given5389* <code>Object</code> value. The <code>scale</code> parameter5390* indicates the number of digits to the right of the decimal point5391* and is ignored if the new column value is not a type that will be5392* mapped to an SQL <code>DECIMAL</code> or <code>NUMERIC</code> value.5393* <P>5394* This method updates a column value in either the current row or5395* the insert row of this rowset, but it does not update the5396* database. If the cursor is on a row in the rowset, the5397* method {@link #updateRow} must be called to update the database.5398* If the cursor is on the insert row, the method {@link #insertRow}5399* must be called, which will insert the new row into both this rowset5400* and the database. Both of these methods must be called before the5401* cursor moves to another row.5402*5403* @param columnName a <code>String</code> object that must match the5404* SQL name of a column in this rowset, ignoring case5405* @param x the new column value5406* @param scale the number of digits to the right of the decimal point (for5407* <code>DECIMAL</code> and <code>NUMERIC</code> types only)5408* @throws SQLException if (1) the given column name does not match the5409* name of a column in this rowset, (2) the cursor is not on5410* one of this rowset's rows or its insert row, or (3) this5411* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5412*/5413public void updateObject(String columnName, Object x, int scale) throws SQLException {5414updateObject(getColIdxByName(columnName), x, scale);5415}54165417/**5418* Sets the designated column in either the current row or the insert5419* row of this <code>CachedRowSetImpl</code> object with the given5420* <code>Object</code> value.5421* <P>5422* This method updates a column value in either the current row or5423* the insert row of this rowset, but it does not update the5424* database. If the cursor is on a row in the rowset, the5425* method {@link #updateRow} must be called to update the database.5426* If the cursor is on the insert row, the method {@link #insertRow}5427* must be called, which will insert the new row into both this rowset5428* and the database. Both of these methods must be called before the5429* cursor moves to another row.5430*5431* @param columnName a <code>String</code> object that must match the5432* SQL name of a column in this rowset, ignoring case5433* @param x the new column value5434* @throws SQLException if (1) the given column name does not match the5435* name of a column in this rowset, (2) the cursor is not on5436* one of this rowset's rows or its insert row, or (3) this5437* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5438*/5439public void updateObject(String columnName, Object x) throws SQLException {5440updateObject(getColIdxByName(columnName), x);5441}54425443/**5444* Inserts the contents of this <code>CachedRowSetImpl</code> object's insert5445* row into this rowset immediately following the current row.5446* If the current row is the5447* position after the last row or before the first row, the new row will5448* be inserted at the end of the rowset. This method also notifies5449* listeners registered with this rowset that the row has changed.5450* <P>5451* The cursor must be on the insert row when this method is called.5452*5453* @throws SQLException if (1) the cursor is not on the insert row,5454* (2) one or more of the non-nullable columns in the insert5455* row has not been given a value, or (3) this rowset is5456* <code>ResultSet.CONCUR_READ_ONLY</code>5457*/5458public void insertRow() throws SQLException {5459int pos;54605461if (onInsertRow == false ||5462insertRow.isCompleteRow(RowSetMD) == false) {5463throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.failedins").toString());5464}5465// Added the setting of parameters that are passed5466// to setXXX methods after an empty CRS Object is5467// created through RowSetMetaData object5468Object [] toInsert = getParams();54695470for(int i = 0;i < toInsert.length; i++) {5471insertRow.setColumnObject(i+1,toInsert[i]);5472}54735474Row insRow = new Row(RowSetMD.getColumnCount(),5475insertRow.getOrigRow());5476insRow.setInserted();5477/*5478* The new row is inserted into the RowSet5479* immediately following the current row.5480*5481* If we are afterlast then the rows are5482* inserted at the end.5483*/5484if (currentRow >= numRows || currentRow < 0) {5485pos = numRows;5486} else {5487pos = currentRow;5488}54895490rvh.add(pos, insRow);5491++numRows;5492// notify the listeners that the row changed.5493notifyRowChanged();5494}54955496/**5497* Marks the current row of this <code>CachedRowSetImpl</code> object as5498* updated and notifies listeners registered with this rowset that the5499* row has changed.5500* <P>5501* This method cannot be called when the cursor is on the insert row, and5502* it should be called before the cursor moves to another row. If it is5503* called after the cursor moves to another row, this method has no effect,5504* and the updates made before the cursor moved will be lost.5505*5506* @throws SQLException if the cursor is on the insert row or this5507* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5508*/5509public void updateRow() throws SQLException {5510// make sure we aren't on the insert row5511if (onInsertRow == true) {5512throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.updateins").toString());5513}55145515((Row)getCurrentRow()).setUpdated();55165517// notify the listeners that the row changed.5518notifyRowChanged();5519}55205521/**5522* Deletes the current row from this <code>CachedRowSetImpl</code> object and5523* notifies listeners registered with this rowset that a row has changed.5524* This method cannot be called when the cursor is on the insert row.5525* <P>5526* This method marks the current row as deleted, but it does not delete5527* the row from the underlying data source. The method5528* <code>acceptChanges</code> must be called to delete the row in5529* the data source.5530*5531* @throws SQLException if (1) this method is called when the cursor5532* is on the insert row, before the first row, or after the5533* last row or (2) this rowset is5534* <code>ResultSet.CONCUR_READ_ONLY</code>5535*/5536public void deleteRow() throws SQLException {5537// make sure the cursor is on a valid row5538checkCursor();55395540((Row)getCurrentRow()).setDeleted();5541++numDeleted;55425543// notify the listeners that the row changed.5544notifyRowChanged();5545}55465547/**5548* Sets the current row with its original value and marks the row as5549* not updated, thus undoing any changes made to the row since the5550* last call to the methods <code>updateRow</code> or <code>deleteRow</code>.5551* This method should be called only when the cursor is on a row in5552* this rowset.5553*5554* @throws SQLException if the cursor is on the insert row, before the5555* first row, or after the last row5556*/5557public void refreshRow() throws SQLException {5558// make sure we are on a row5559checkCursor();55605561// don't want this to happen...5562if (onInsertRow == true) {5563throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());5564}55655566Row currentRow = (Row)getCurrentRow();5567// just undo any changes made to this row.5568currentRow.clearUpdated();55695570}55715572/**5573* Rolls back any updates made to the current row of this5574* <code>CachedRowSetImpl</code> object and notifies listeners that5575* a row has changed. To have an effect, this method5576* must be called after an <code>updateXXX</code> method has been5577* called and before the method <code>updateRow</code> has been called.5578* If no updates have been made or the method <code>updateRow</code>5579* has already been called, this method has no effect.5580*5581* @throws SQLException if the cursor is on the insert row, before the5582* first row, or after the last row5583*/5584public void cancelRowUpdates() throws SQLException {5585// make sure we are on a row5586checkCursor();55875588// don't want this to happen...5589if (onInsertRow == true) {5590throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());5591}55925593Row currentRow = (Row)getCurrentRow();5594if (currentRow.getUpdated() == true) {5595currentRow.clearUpdated();5596notifyRowChanged();5597}5598}55995600/**5601* Moves the cursor for this <code>CachedRowSetImpl</code> object5602* to the insert row. The current row in the rowset is remembered5603* while the cursor is on the insert row.5604* <P>5605* The insert row is a special row associated with an updatable5606* rowset. It is essentially a buffer where a new row may5607* be constructed by calling the appropriate <code>updateXXX</code>5608* methods to assign a value to each column in the row. A complete5609* row must be constructed; that is, every column that is not nullable5610* must be assigned a value. In order for the new row to become part5611* of this rowset, the method <code>insertRow</code> must be called5612* before the cursor is moved back to the rowset.5613* <P>5614* Only certain methods may be invoked while the cursor is on the insert5615* row; many methods throw an exception if they are called while the5616* cursor is there. In addition to the <code>updateXXX</code>5617* and <code>insertRow</code> methods, only the <code>getXXX</code> methods5618* may be called when the cursor is on the insert row. A <code>getXXX</code>5619* method should be called on a column only after an <code>updateXXX</code>5620* method has been called on that column; otherwise, the value returned is5621* undetermined.5622*5623* @throws SQLException if this <code>CachedRowSetImpl</code> object is5624* <code>ResultSet.CONCUR_READ_ONLY</code>5625*/5626public void moveToInsertRow() throws SQLException {5627if (getConcurrency() == ResultSet.CONCUR_READ_ONLY) {5628throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins").toString());5629}5630if (insertRow == null) {5631if (RowSetMD == null)5632throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins1").toString());5633int numCols = RowSetMD.getColumnCount();5634if (numCols > 0) {5635insertRow = new InsertRow(numCols);5636} else {5637throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins2").toString());5638}5639}5640onInsertRow = true;5641// %%% setCurrentRow called in BaseRow56425643currentRow = cursorPos;5644cursorPos = -1;56455646insertRow.initInsertRow();5647}56485649/**5650* Moves the cursor for this <code>CachedRowSetImpl</code> object to5651* the current row. The current row is the row the cursor was on5652* when the method <code>moveToInsertRow</code> was called.5653* <P>5654* Calling this method has no effect unless it is called while the5655* cursor is on the insert row.5656*5657* @throws SQLException if an error occurs5658*/5659public void moveToCurrentRow() throws SQLException {5660if (onInsertRow == false) {5661return;5662} else {5663cursorPos = currentRow;5664onInsertRow = false;5665}5666}56675668/**5669* Returns <code>null</code>.5670*5671* @return <code>null</code>5672* @throws SQLException if an error occurs5673*/5674public Statement getStatement() throws SQLException {5675return null;5676}56775678/**5679* Retrieves the value of the designated column in this5680* <code>CachedRowSetImpl</code> object as an <code>Object</code> in5681* the Java programming language, using the given5682* <code>java.util.Map</code> object to custom map the value if5683* appropriate.5684*5685* @param columnIndex the first column is <code>1</code>, the second5686* is <code>2</code>, and so on; must be <code>1</code> or larger5687* and equal to or less than the number of columns in this rowset5688* @param map a <code>java.util.Map</code> object showing the mapping5689* from SQL type names to classes in the Java programming5690* language5691* @return an <code>Object</code> representing the SQL value5692* @throws SQLException if the given column index is out of bounds or5693* the cursor is not on one of this rowset's rows or its5694* insert row5695*/5696public Object getObject(int columnIndex,5697java.util.Map<String,Class<?>> map)5698throws SQLException5699{5700Object value;57015702// sanity check.5703checkIndex(columnIndex);5704// make sure the cursor is on a valid row5705checkCursor();57065707setLastValueNull(false);5708value = getCurrentRow().getColumnObject(columnIndex);57095710// check for SQL NULL5711if (value == null) {5712setLastValueNull(true);5713return null;5714}5715if (value instanceof Struct) {5716Struct s = (Struct)value;57175718// look up the class in the map5719Class<?> c = map.get(s.getSQLTypeName());5720if (c != null) {5721// create new instance of the class5722SQLData obj = null;5723try {5724ReflectUtil.checkPackageAccess(c);5725@SuppressWarnings("deprecation")5726Object tmp = c.newInstance();5727obj = (SQLData) tmp;5728} catch(Exception ex) {5729throw new SQLException("Unable to Instantiate: ", ex);5730}5731// get the attributes from the struct5732Object attribs[] = s.getAttributes(map);5733// create the SQLInput "stream"5734SQLInputImpl sqlInput = new SQLInputImpl(attribs, map);5735// read the values...5736obj.readSQL(sqlInput, s.getSQLTypeName());5737return (Object)obj;5738}5739}5740return value;5741}57425743/**5744* Retrieves the value of the designated column in this5745* <code>CachedRowSetImpl</code> object as a <code>Ref</code> object5746* in the Java programming language.5747*5748* @param columnIndex the first column is <code>1</code>, the second5749* is <code>2</code>, and so on; must be <code>1</code> or larger5750* and equal to or less than the number of columns in this rowset5751* @return a <code>Ref</code> object representing an SQL<code> REF</code> value5752* @throws SQLException if (1) the given column index is out of bounds,5753* (2) the cursor is not on one of this rowset's rows or its5754* insert row, or (3) the designated column does not store an5755* SQL <code>REF</code> value5756* @see #getRef(String)5757*/5758public Ref getRef(int columnIndex) throws SQLException {5759Ref value;57605761// sanity check.5762checkIndex(columnIndex);5763// make sure the cursor is on a valid row5764checkCursor();57655766if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.REF) {5767throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());5768}57695770setLastValueNull(false);5771value = (Ref)(getCurrentRow().getColumnObject(columnIndex));57725773// check for SQL NULL5774if (value == null) {5775setLastValueNull(true);5776return null;5777}57785779return value;5780}57815782/**5783* Retrieves the value of the designated column in this5784* <code>CachedRowSetImpl</code> object as a <code>Blob</code> object5785* in the Java programming language.5786*5787* @param columnIndex the first column is <code>1</code>, the second5788* is <code>2</code>, and so on; must be <code>1</code> or larger5789* and equal to or less than the number of columns in this rowset5790* @return a <code>Blob</code> object representing an SQL <code>BLOB</code> value5791* @throws SQLException if (1) the given column index is out of bounds,5792* (2) the cursor is not on one of this rowset's rows or its5793* insert row, or (3) the designated column does not store an5794* SQL <code>BLOB</code> value5795* @see #getBlob(String)5796*/5797public Blob getBlob(int columnIndex) throws SQLException {5798Blob value;57995800// sanity check.5801checkIndex(columnIndex);5802// make sure the cursor is on a valid row5803checkCursor();58045805if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.BLOB) {5806System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex)));5807throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());5808}58095810setLastValueNull(false);5811value = (Blob)(getCurrentRow().getColumnObject(columnIndex));58125813// check for SQL NULL5814if (value == null) {5815setLastValueNull(true);5816return null;5817}58185819return value;5820}58215822/**5823* Retrieves the value of the designated column in this5824* <code>CachedRowSetImpl</code> object as a <code>Clob</code> object5825* in the Java programming language.5826*5827* @param columnIndex the first column is <code>1</code>, the second5828* is <code>2</code>, and so on; must be <code>1</code> or larger5829* and equal to or less than the number of columns in this rowset5830* @return a <code>Clob</code> object representing an SQL <code>CLOB</code> value5831* @throws SQLException if (1) the given column index is out of bounds,5832* (2) the cursor is not on one of this rowset's rows or its5833* insert row, or (3) the designated column does not store an5834* SQL <code>CLOB</code> value5835* @see #getClob(String)5836*/5837public Clob getClob(int columnIndex) throws SQLException {5838Clob value;58395840// sanity check.5841checkIndex(columnIndex);5842// make sure the cursor is on a valid row5843checkCursor();58445845if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.CLOB) {5846System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex)));5847throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());5848}58495850setLastValueNull(false);5851value = (Clob)(getCurrentRow().getColumnObject(columnIndex));58525853// check for SQL NULL5854if (value == null) {5855setLastValueNull(true);5856return null;5857}58585859return value;5860}58615862/**5863* Retrieves the value of the designated column in this5864* <code>CachedRowSetImpl</code> object as an <code>Array</code> object5865* in the Java programming language.5866*5867* @param columnIndex the first column is <code>1</code>, the second5868* is <code>2</code>, and so on; must be <code>1</code> or larger5869* and equal to or less than the number of columns in this rowset5870* @return an <code>Array</code> object representing an SQL5871* <code>ARRAY</code> value5872* @throws SQLException if (1) the given column index is out of bounds,5873* (2) the cursor is not on one of this rowset's rows or its5874* insert row, or (3) the designated column does not store an5875* SQL <code>ARRAY</code> value5876* @see #getArray(String)5877*/5878public Array getArray(int columnIndex) throws SQLException {5879java.sql.Array value;58805881// sanity check.5882checkIndex(columnIndex);5883// make sure the cursor is on a valid row5884checkCursor();58855886if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.ARRAY) {5887throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());5888}58895890setLastValueNull(false);5891value = (java.sql.Array)(getCurrentRow().getColumnObject(columnIndex));58925893// check for SQL NULL5894if (value == null) {5895setLastValueNull(true);5896return null;5897}58985899return value;5900}59015902/**5903* Retrieves the value of the designated column in this5904* <code>CachedRowSetImpl</code> object as an <code>Object</code> in5905* the Java programming language, using the given5906* <code>java.util.Map</code> object to custom map the value if5907* appropriate.5908*5909* @param columnName a <code>String</code> object that must match the5910* SQL name of a column in this rowset, ignoring case5911* @param map a <code>java.util.Map</code> object showing the mapping5912* from SQL type names to classes in the Java programming5913* language5914* @return an <code>Object</code> representing the SQL value5915* @throws SQLException if the given column name is not the name of5916* a column in this rowset or the cursor is not on one of5917* this rowset's rows or its insert row5918*/5919public Object getObject(String columnName,5920java.util.Map<String,Class<?>> map)5921throws SQLException {5922return getObject(getColIdxByName(columnName), map);5923}59245925/**5926* Retrieves the value of the designated column in this5927* <code>CachedRowSetImpl</code> object as a <code>Ref</code> object5928* in the Java programming language.5929*5930* @param colName a <code>String</code> object that must match the5931* SQL name of a column in this rowset, ignoring case5932* @return a <code>Ref</code> object representing an SQL<code> REF</code> value5933* @throws SQLException if (1) the given column name is not the name of5934* a column in this rowset, (2) the cursor is not on one of5935* this rowset's rows or its insert row, or (3) the column value5936* is not an SQL <code>REF</code> value5937* @see #getRef(int)5938*/5939public Ref getRef(String colName) throws SQLException {5940return getRef(getColIdxByName(colName));5941}59425943/**5944* Retrieves the value of the designated column in this5945* <code>CachedRowSetImpl</code> object as a <code>Blob</code> object5946* in the Java programming language.5947*5948* @param colName a <code>String</code> object that must match the5949* SQL name of a column in this rowset, ignoring case5950* @return a <code>Blob</code> object representing an SQL <code>BLOB</code> value5951* @throws SQLException if (1) the given column name is not the name of5952* a column in this rowset, (2) the cursor is not on one of5953* this rowset's rows or its insert row, or (3) the designated5954* column does not store an SQL <code>BLOB</code> value5955* @see #getBlob(int)5956*/5957public Blob getBlob(String colName) throws SQLException {5958return getBlob(getColIdxByName(colName));5959}59605961/**5962* Retrieves the value of the designated column in this5963* <code>CachedRowSetImpl</code> object as a <code>Clob</code> object5964* in the Java programming language.5965*5966* @param colName a <code>String</code> object that must match the5967* SQL name of a column in this rowset, ignoring case5968* @return a <code>Clob</code> object representing an SQL5969* <code>CLOB</code> value5970* @throws SQLException if (1) the given column name is not the name of5971* a column in this rowset, (2) the cursor is not on one of5972* this rowset's rows or its insert row, or (3) the designated5973* column does not store an SQL <code>CLOB</code> value5974* @see #getClob(int)5975*/5976public Clob getClob(String colName) throws SQLException {5977return getClob(getColIdxByName(colName));5978}59795980/**5981* Retrieves the value of the designated column in this5982* <code>CachedRowSetImpl</code> object as an <code>Array</code> object5983* in the Java programming langugage.5984*5985* @param colName a <code>String</code> object that must match the5986* SQL name of a column in this rowset, ignoring case5987* @return an <code>Array</code> object representing an SQL5988* <code>ARRAY</code> value5989* @throws SQLException if (1) the given column name is not the name of5990* a column in this rowset, (2) the cursor is not on one of5991* this rowset's rows or its insert row, or (3) the designated5992* column does not store an SQL <code>ARRAY</code> value5993* @see #getArray(int)5994*/5995public Array getArray(String colName) throws SQLException {5996return getArray(getColIdxByName(colName));5997}59985999/**6000* Retrieves the value of the designated column in the current row6001* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Date</code>6002* object, using the given <code>Calendar</code> object to construct an6003* appropriate millisecond value for the date.6004*6005* @param columnIndex the first column is <code>1</code>, the second6006* is <code>2</code>, and so on; must be <code>1</code> or larger6007* and equal to or less than the number of columns in the rowset6008* @param cal the <code>java.util.Calendar</code> object to use in6009* constructing the date6010* @return the column value; if the value is SQL <code>NULL</code>,6011* the result is <code>null</code>6012* @throws SQLException if (1) the given column name is not the name of6013* a column in this rowset, (2) the cursor is not on one of6014* this rowset's rows or its insert row, or (3) the designated6015* column does not store an SQL <code>DATE</code> or6016* <code>TIMESTAMP</code> value6017*/6018public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException {6019Object value;60206021// sanity check.6022checkIndex(columnIndex);6023// make sure the cursor is on a valid row6024checkCursor();60256026setLastValueNull(false);6027value = getCurrentRow().getColumnObject(columnIndex);60286029// check for SQL NULL6030if (value == null) {6031setLastValueNull(true);6032return null;6033}60346035value = convertTemporal(value,6036RowSetMD.getColumnType(columnIndex),6037java.sql.Types.DATE);60386039// create a default calendar6040Calendar defaultCal = Calendar.getInstance();6041// set this Calendar to the time we have6042defaultCal.setTime((java.util.Date)value);60436044/*6045* Now we can pull the pieces of the date out6046* of the default calendar and put them into6047* the user provided calendar6048*/6049cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR));6050cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH));6051cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH));60526053/*6054* This looks a little odd but it is correct -6055* Calendar.getTime() returns a Date...6056*/6057return new java.sql.Date(cal.getTime().getTime());6058}60596060/**6061* Retrieves the value of the designated column in the current row6062* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Date</code>6063* object, using the given <code>Calendar</code> object to construct an6064* appropriate millisecond value for the date.6065*6066* @param columnName a <code>String</code> object that must match the6067* SQL name of a column in this rowset, ignoring case6068* @param cal the <code>java.util.Calendar</code> object to use in6069* constructing the date6070* @return the column value; if the value is SQL <code>NULL</code>,6071* the result is <code>null</code>6072* @throws SQLException if (1) the given column name is not the name of6073* a column in this rowset, (2) the cursor is not on one of6074* this rowset's rows or its insert row, or (3) the designated6075* column does not store an SQL <code>DATE</code> or6076* <code>TIMESTAMP</code> value6077*/6078public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException {6079return getDate(getColIdxByName(columnName), cal);6080}60816082/**6083* Retrieves the value of the designated column in the current row6084* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Time</code>6085* object, using the given <code>Calendar</code> object to construct an6086* appropriate millisecond value for the date.6087*6088* @param columnIndex the first column is <code>1</code>, the second6089* is <code>2</code>, and so on; must be <code>1</code> or larger6090* and equal to or less than the number of columns in the rowset6091* @param cal the <code>java.util.Calendar</code> object to use in6092* constructing the date6093* @return the column value; if the value is SQL <code>NULL</code>,6094* the result is <code>null</code>6095* @throws SQLException if (1) the given column name is not the name of6096* a column in this rowset, (2) the cursor is not on one of6097* this rowset's rows or its insert row, or (3) the designated6098* column does not store an SQL <code>TIME</code> or6099* <code>TIMESTAMP</code> value6100*/6101public java.sql.Time getTime(int columnIndex, Calendar cal) throws SQLException {6102Object value;61036104// sanity check.6105checkIndex(columnIndex);6106// make sure the cursor is on a valid row6107checkCursor();61086109setLastValueNull(false);6110value = getCurrentRow().getColumnObject(columnIndex);61116112// check for SQL NULL6113if (value == null) {6114setLastValueNull(true);6115return null;6116}61176118value = convertTemporal(value,6119RowSetMD.getColumnType(columnIndex),6120java.sql.Types.TIME);61216122// create a default calendar6123Calendar defaultCal = Calendar.getInstance();6124// set the time in the default calendar6125defaultCal.setTime((java.util.Date)value);61266127/*6128* Now we can pull the pieces of the date out6129* of the default calendar and put them into6130* the user provided calendar6131*/6132cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY));6133cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE));6134cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND));61356136return new java.sql.Time(cal.getTime().getTime());6137}61386139/**6140* Retrieves the value of the designated column in the current row6141* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Time</code>6142* object, using the given <code>Calendar</code> object to construct an6143* appropriate millisecond value for the date.6144*6145* @param columnName a <code>String</code> object that must match the6146* SQL name of a column in this rowset, ignoring case6147* @param cal the <code>java.util.Calendar</code> object to use in6148* constructing the date6149* @return the column value; if the value is SQL <code>NULL</code>,6150* the result is <code>null</code>6151* @throws SQLException if (1) the given column name is not the name of6152* a column in this rowset, (2) the cursor is not on one of6153* this rowset's rows or its insert row, or (3) the designated6154* column does not store an SQL <code>TIME</code> or6155* <code>TIMESTAMP</code> value6156*/6157public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException {6158return getTime(getColIdxByName(columnName), cal);6159}61606161/**6162* Retrieves the value of the designated column in the current row6163* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Timestamp</code>6164* object, using the given <code>Calendar</code> object to construct an6165* appropriate millisecond value for the date.6166*6167* @param columnIndex the first column is <code>1</code>, the second6168* is <code>2</code>, and so on; must be <code>1</code> or larger6169* and equal to or less than the number of columns in the rowset6170* @param cal the <code>java.util.Calendar</code> object to use in6171* constructing the date6172* @return the column value; if the value is SQL <code>NULL</code>,6173* the result is <code>null</code>6174* @throws SQLException if (1) the given column name is not the name of6175* a column in this rowset, (2) the cursor is not on one of6176* this rowset's rows or its insert row, or (3) the designated6177* column does not store an SQL <code>TIME</code> or6178* <code>TIMESTAMP</code> value6179*/6180public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {6181Object value;61826183// sanity check.6184checkIndex(columnIndex);6185// make sure the cursor is on a valid row6186checkCursor();61876188setLastValueNull(false);6189value = getCurrentRow().getColumnObject(columnIndex);61906191// check for SQL NULL6192if (value == null) {6193setLastValueNull(true);6194return null;6195}61966197value = convertTemporal(value,6198RowSetMD.getColumnType(columnIndex),6199java.sql.Types.TIMESTAMP);62006201// create a default calendar6202Calendar defaultCal = Calendar.getInstance();6203// set the time in the default calendar6204defaultCal.setTime((java.util.Date)value);62056206/*6207* Now we can pull the pieces of the date out6208* of the default calendar and put them into6209* the user provided calendar6210*/6211cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR));6212cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH));6213cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH));6214cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY));6215cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE));6216cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND));62176218return new java.sql.Timestamp(cal.getTime().getTime());6219}62206221/**6222* Retrieves the value of the designated column in the current row6223* of this <code>CachedRowSetImpl</code> object as a6224* <code>java.sql.Timestamp</code> object, using the given6225* <code>Calendar</code> object to construct an appropriate6226* millisecond value for the date.6227*6228* @param columnName a <code>String</code> object that must match the6229* SQL name of a column in this rowset, ignoring case6230* @param cal the <code>java.util.Calendar</code> object to use in6231* constructing the date6232* @return the column value; if the value is SQL <code>NULL</code>,6233* the result is <code>null</code>6234* @throws SQLException if (1) the given column name is not the name of6235* a column in this rowset, (2) the cursor is not on one of6236* this rowset's rows or its insert row, or (3) the designated6237* column does not store an SQL <code>DATE</code>,6238* <code>TIME</code>, or <code>TIMESTAMP</code> value6239*/6240public java.sql.Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {6241return getTimestamp(getColIdxByName(columnName), cal);6242}62436244/*6245* RowSetInternal Interface6246*/62476248/**6249* Retrieves the <code>Connection</code> object passed to this6250* <code>CachedRowSetImpl</code> object. This connection may be6251* used to populate this rowset with data or to write data back6252* to its underlying data source.6253*6254* @return the <code>Connection</code> object passed to this rowset;6255* may be <code>null</code> if there is no connection6256* @throws SQLException if an error occurs6257*/6258public Connection getConnection() throws SQLException{6259return conn;6260}62616262/**6263* Sets the metadata for this <code>CachedRowSetImpl</code> object6264* with the given <code>RowSetMetaData</code> object.6265*6266* @param md a <code>RowSetMetaData</code> object instance containing6267* metadata about the columsn in the rowset6268* @throws SQLException if invalid meta data is supplied to the6269* rowset6270*/6271public void setMetaData(RowSetMetaData md) throws SQLException {6272RowSetMD =(RowSetMetaDataImpl) md;6273}62746275/**6276* Returns a result set containing the original value of the rowset. The6277* original value is the state of the <code>CachedRowSetImpl</code> after the6278* last population or synchronization (whichever occurred most recently) with6279* the data source.6280* <p>6281* The cursor is positioned before the first row in the result set.6282* Only rows contained in the result set returned by <code>getOriginal()</code>6283* are said to have an original value.6284*6285* @return the original result set of the rowset6286* @throws SQLException if an error occurs produce the6287* <code>ResultSet</code> object6288*/6289public ResultSet getOriginal() throws SQLException {6290CachedRowSetImpl crs = new CachedRowSetImpl();6291crs.RowSetMD = RowSetMD;6292crs.numRows = numRows;6293crs.cursorPos = 0;62946295// make sure we don't get someone playing with these6296// %%% is this now necessary ???6297//crs.setReader(null);6298//crs.setWriter(null);6299int colCount = RowSetMD.getColumnCount();6300Row orig;63016302for (Iterator<?> i = rvh.iterator(); i.hasNext();) {6303orig = new Row(colCount, ((Row)i.next()).getOrigRow());6304crs.rvh.add(orig);6305}6306return (ResultSet)crs;6307}63086309/**6310* Returns a result set containing the original value of the current6311* row only.6312* The original value is the state of the <code>CachedRowSetImpl</code> after6313* the last population or synchronization (whichever occurred most recently)6314* with the data source.6315*6316* @return the original result set of the row6317* @throws SQLException if there is no current row6318* @see #setOriginalRow6319*/6320public ResultSet getOriginalRow() throws SQLException {6321CachedRowSetImpl crs = new CachedRowSetImpl();6322crs.RowSetMD = RowSetMD;6323crs.numRows = 1;6324crs.cursorPos = 0;6325crs.setTypeMap(this.getTypeMap());63266327// make sure we don't get someone playing with these6328// %%% is this now necessary ???6329//crs.setReader(null);6330//crs.setWriter(null);63316332Row orig = new Row(RowSetMD.getColumnCount(),6333getCurrentRow().getOrigRow());63346335crs.rvh.add(orig);63366337return (ResultSet)crs;63386339}63406341/**6342* Marks the current row in this rowset as being an original row.6343*6344* @throws SQLException if there is no current row6345* @see #getOriginalRow6346*/6347public void setOriginalRow() throws SQLException {6348if (onInsertRow == true) {6349throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());6350}63516352Row row = (Row)getCurrentRow();6353makeRowOriginal(row);63546355// this can happen if deleted rows are being shown6356if (row.getDeleted() == true) {6357removeCurrentRow();6358}6359}63606361/**6362* Makes the given row of this rowset the original row by clearing any6363* settings that mark the row as having been inserted, deleted, or updated.6364* This method is called internally by the methods6365* <code>setOriginalRow</code>6366* and <code>setOriginal</code>.6367*6368* @param row the row to be made the original row6369*/6370private void makeRowOriginal(Row row) {6371if (row.getInserted() == true) {6372row.clearInserted();6373}63746375if (row.getUpdated() == true) {6376row.moveCurrentToOrig();6377}6378}63796380/**6381* Marks all rows in this rowset as being original rows. Any updates6382* made to the rows become the original values for the rowset.6383* Calls to the method <code>setOriginal</code> connot be reversed.6384*6385* @throws SQLException if an error occurs6386*/6387public void setOriginal() throws SQLException {6388for (Iterator<?> i = rvh.iterator(); i.hasNext();) {6389Row row = (Row)i.next();6390makeRowOriginal(row);6391// remove deleted rows from the collection.6392if (row.getDeleted() == true) {6393i.remove();6394--numRows;6395}6396}6397numDeleted = 0;63986399// notify any listeners that the rowset has changed6400notifyRowSetChanged();6401}64026403/**6404* Returns an identifier for the object (table) that was used to create this6405* rowset.6406*6407* @return a <code>String</code> object that identifies the table from6408* which this <code>CachedRowSetImpl</code> object was derived6409* @throws SQLException if an error occurs6410*/6411public String getTableName() throws SQLException {6412return tableName;6413}64146415/**6416* Sets the identifier for the table from which this rowset was derived6417* to the given table name.6418*6419* @param tabName a <code>String</code> object that identifies the6420* table from which this <code>CachedRowSetImpl</code> object6421* was derived6422* @throws SQLException if an error occurs6423*/6424public void setTableName(String tabName) throws SQLException {6425if (tabName == null)6426throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString());6427else6428tableName = tabName;6429}64306431/**6432* Returns the columns that make a key to uniquely identify a6433* row in this <code>CachedRowSetImpl</code> object.6434*6435* @return an array of column numbers that constitutes a primary6436* key for this rowset. This array should be empty6437* if no column is representitive of a primary key6438* @throws SQLException if the rowset is empty or no columns6439* are designated as primary keys6440* @see #setKeyColumns6441*/6442public int[] getKeyColumns() throws SQLException {6443int[]keyColumns = this.keyCols;6444return (keyColumns == null) ? null : Arrays.copyOf(keyColumns, keyColumns.length);6445}644664476448/**6449* Sets this <code>CachedRowSetImpl</code> object's6450* <code>keyCols</code> field with the given array of column6451* numbers, which forms a key for uniquely identifying a row6452* in this rowset.6453*6454* @param keys an array of <code>int</code> indicating the6455* columns that form a primary key for this6456* <code>CachedRowSetImpl</code> object; every6457* element in the array must be greater than6458* <code>0</code> and less than or equal to the number6459* of columns in this rowset6460* @throws SQLException if any of the numbers in the6461* given array is not valid for this rowset6462* @see #getKeyColumns6463*/6464public void setKeyColumns(int [] keys) throws SQLException {6465int numCols = 0;6466if (RowSetMD != null) {6467numCols = RowSetMD.getColumnCount();6468if (keys.length > numCols)6469throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.keycols").toString());6470}6471keyCols = new int[keys.length];6472for (int i = 0; i < keys.length; i++) {6473if (RowSetMD != null && (keys[i] <= 0 ||6474keys[i] > numCols)) {6475throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString() +6476keys[i]);6477}6478keyCols[i] = keys[i];6479}6480}64816482/**6483* Sets the designated column in either the current row or the insert6484* row of this <code>CachedRowSetImpl</code> object with the given6485* <code>Ref</code> value.6486*6487* This method updates a column value in either the current row or6488* the insert row of this rowset, but it does not update the6489* database. If the cursor is on a row in the rowset, the6490* method {@link #updateRow} must be called to update the database.6491* If the cursor is on the insert row, the method {@link #insertRow}6492* must be called, which will insert the new row into both this rowset6493* and the database. Both of these methods must be called before the6494* cursor moves to another row.6495*6496* @param columnIndex the first column is <code>1</code>, the second6497* is <code>2</code>, and so on; must be <code>1</code> or larger6498* and equal to or less than the number of columns in this rowset6499* @param ref the new column <code>java.sql.Ref</code> value6500* @throws SQLException if (1) the given column index is out of bounds,6501* (2) the cursor is not on one of this rowset's rows or its6502* insert row, or (3) this rowset is6503* <code>ResultSet.CONCUR_READ_ONLY</code>6504*/6505public void updateRef(int columnIndex, java.sql.Ref ref) throws SQLException {6506// sanity check.6507checkIndex(columnIndex);6508// make sure the cursor is on a valid row6509checkCursor();65106511// SerialClob will help in getting the byte array and storing it.6512// We need to be checking DatabaseMetaData.locatorsUpdatorCopy()6513// or through RowSetMetaData.locatorsUpdatorCopy()6514getCurrentRow().setColumnObject(columnIndex, new SerialRef(ref));6515}65166517/**6518* Sets the designated column in either the current row or the insert6519* row of this <code>CachedRowSetImpl</code> object with the given6520* <code>double</code> value.6521*6522* This method updates a column value in either the current row or6523* the insert row of this rowset, but it does not update the6524* database. If the cursor is on a row in the rowset, the6525* method {@link #updateRow} must be called to update the database.6526* If the cursor is on the insert row, the method {@link #insertRow}6527* must be called, which will insert the new row into both this rowset6528* and the database. Both of these methods must be called before the6529* cursor moves to another row.6530*6531* @param columnName a <code>String</code> object that must match the6532* SQL name of a column in this rowset, ignoring case6533* @param ref the new column <code>java.sql.Ref</code> value6534* @throws SQLException if (1) the given column name does not match the6535* name of a column in this rowset, (2) the cursor is not on6536* one of this rowset's rows or its insert row, or (3) this6537* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>6538*/6539public void updateRef(String columnName, java.sql.Ref ref) throws SQLException {6540updateRef(getColIdxByName(columnName), ref);6541}65426543/**6544* Sets the designated column in either the current row or the insert6545* row of this <code>CachedRowSetImpl</code> object with the given6546* <code>double</code> value.6547*6548* This method updates a column value in either the current row or6549* the insert row of this rowset, but it does not update the6550* database. If the cursor is on a row in the rowset, the6551* method {@link #updateRow} must be called to update the database.6552* If the cursor is on the insert row, the method {@link #insertRow}6553* must be called, which will insert the new row into both this rowset6554* and the database. Both of these methods must be called before the6555* cursor moves to another row.6556*6557* @param columnIndex the first column is <code>1</code>, the second6558* is <code>2</code>, and so on; must be <code>1</code> or larger6559* and equal to or less than the number of columns in this rowset6560* @param c the new column <code>Clob</code> value6561* @throws SQLException if (1) the given column index is out of bounds,6562* (2) the cursor is not on one of this rowset's rows or its6563* insert row, or (3) this rowset is6564* <code>ResultSet.CONCUR_READ_ONLY</code>6565*/6566public void updateClob(int columnIndex, Clob c) throws SQLException {6567// sanity check.6568checkIndex(columnIndex);6569// make sure the cursor is on a valid row6570checkCursor();65716572// SerialClob will help in getting the byte array and storing it.6573// We need to be checking DatabaseMetaData.locatorsUpdatorCopy()6574// or through RowSetMetaData.locatorsUpdatorCopy()65756576if(dbmslocatorsUpdateCopy){6577getCurrentRow().setColumnObject(columnIndex, new SerialClob(c));6578}6579else{6580throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString());6581}6582}65836584/**6585* Sets the designated column in either the current row or the insert6586* row of this <code>CachedRowSetImpl</code> object with the given6587* <code>double</code> value.6588*6589* This method updates a column value in either the current row or6590* the insert row of this rowset, but it does not update the6591* database. If the cursor is on a row in the rowset, the6592* method {@link #updateRow} must be called to update the database.6593* If the cursor is on the insert row, the method {@link #insertRow}6594* must be called, which will insert the new row into both this rowset6595* and the database. Both of these methods must be called before the6596* cursor moves to another row.6597*6598* @param columnName a <code>String</code> object that must match the6599* SQL name of a column in this rowset, ignoring case6600* @param c the new column <code>Clob</code> value6601* @throws SQLException if (1) the given column name does not match the6602* name of a column in this rowset, (2) the cursor is not on6603* one of this rowset's rows or its insert row, or (3) this6604* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>6605*/6606public void updateClob(String columnName, Clob c) throws SQLException {6607updateClob(getColIdxByName(columnName), c);6608}66096610/**6611* Sets the designated column in either the current row or the insert6612* row of this <code>CachedRowSetImpl</code> object with the given6613* <code>java.sql.Blob</code> value.6614*6615* This method updates a column value in either the current row or6616* the insert row of this rowset, but it does not update the6617* database. If the cursor is on a row in the rowset, the6618* method {@link #updateRow} must be called to update the database.6619* If the cursor is on the insert row, the method {@link #insertRow}6620* must be called, which will insert the new row into both this rowset6621* and the database. Both of these methods must be called before the6622* cursor moves to another row.6623*6624* @param columnIndex the first column is <code>1</code>, the second6625* is <code>2</code>, and so on; must be <code>1</code> or larger6626* and equal to or less than the number of columns in this rowset6627* @param b the new column <code>Blob</code> value6628* @throws SQLException if (1) the given column index is out of bounds,6629* (2) the cursor is not on one of this rowset's rows or its6630* insert row, or (3) this rowset is6631* <code>ResultSet.CONCUR_READ_ONLY</code>6632*/6633public void updateBlob(int columnIndex, Blob b) throws SQLException {6634// sanity check.6635checkIndex(columnIndex);6636// make sure the cursor is on a valid row6637checkCursor();66386639// SerialBlob will help in getting the byte array and storing it.6640// We need to be checking DatabaseMetaData.locatorsUpdatorCopy()6641// or through RowSetMetaData.locatorsUpdatorCopy()66426643if(dbmslocatorsUpdateCopy){6644getCurrentRow().setColumnObject(columnIndex, new SerialBlob(b));6645}6646else{6647throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString());6648}6649}66506651/**6652* Sets the designated column in either the current row or the insert6653* row of this <code>CachedRowSetImpl</code> object with the given6654* <code>java.sql.Blob </code> value.6655*6656* This method updates a column value in either the current row or6657* the insert row of this rowset, but it does not update the6658* database. If the cursor is on a row in the rowset, the6659* method {@link #updateRow} must be called to update the database.6660* If the cursor is on the insert row, the method {@link #insertRow}6661* must be called, which will insert the new row into both this rowset6662* and the database. Both of these methods must be called before the6663* cursor moves to another row.6664*6665* @param columnName a <code>String</code> object that must match the6666* SQL name of a column in this rowset, ignoring case6667* @param b the new column <code>Blob</code> value6668* @throws SQLException if (1) the given column name does not match the6669* name of a column in this rowset, (2) the cursor is not on6670* one of this rowset's rows or its insert row, or (3) this6671* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>6672*/6673public void updateBlob(String columnName, Blob b) throws SQLException {6674updateBlob(getColIdxByName(columnName), b);6675}66766677/**6678* Sets the designated column in either the current row or the insert6679* row of this <code>CachedRowSetImpl</code> object with the given6680* <code>java.sql.Array</code> values.6681*6682* This method updates a column value in either the current row or6683* the insert row of this rowset, but it does not update the6684* database. If the cursor is on a row in the rowset, the6685* method {@link #updateRow} must be called to update the database.6686* If the cursor is on the insert row, the method {@link #insertRow}6687* must be called, which will insert the new row into both this rowset6688* and the database. Both of these methods must be called before the6689* cursor moves to another row.6690*6691* @param columnIndex the first column is <code>1</code>, the second6692* is <code>2</code>, and so on; must be <code>1</code> or larger6693* and equal to or less than the number of columns in this rowset6694* @param a the new column <code>Array</code> value6695* @throws SQLException if (1) the given column index is out of bounds,6696* (2) the cursor is not on one of this rowset's rows or its6697* insert row, or (3) this rowset is6698* <code>ResultSet.CONCUR_READ_ONLY</code>6699*/6700public void updateArray(int columnIndex, Array a) throws SQLException {6701// sanity check.6702checkIndex(columnIndex);6703// make sure the cursor is on a valid row6704checkCursor();67056706// SerialArray will help in getting the byte array and storing it.6707// We need to be checking DatabaseMetaData.locatorsUpdatorCopy()6708// or through RowSetMetaData.locatorsUpdatorCopy()6709getCurrentRow().setColumnObject(columnIndex, new SerialArray(a));6710}67116712/**6713* Sets the designated column in either the current row or the insert6714* row of this <code>CachedRowSetImpl</code> object with the given6715* <code>java.sql.Array</code> value.6716*6717* This method updates a column value in either the current row or6718* the insert row of this rowset, but it does not update the6719* database. If the cursor is on a row in the rowset, the6720* method {@link #updateRow} must be called to update the database.6721* If the cursor is on the insert row, the method {@link #insertRow}6722* must be called, which will insert the new row into both this rowset6723* and the database. Both of these methods must be called before the6724* cursor moves to another row.6725*6726* @param columnName a <code>String</code> object that must match the6727* SQL name of a column in this rowset, ignoring case6728* @param a the new column <code>Array</code> value6729* @throws SQLException if (1) the given column name does not match the6730* name of a column in this rowset, (2) the cursor is not on6731* one of this rowset's rows or its insert row, or (3) this6732* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>6733*/6734public void updateArray(String columnName, Array a) throws SQLException {6735updateArray(getColIdxByName(columnName), a);6736}673767386739/**6740* Retrieves the value of the designated column in this6741* <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object6742* in the Java programming language.6743*6744* @return a java.net.URL object containing the resource reference described by6745* the URL6746* @throws SQLException if (1) the given column index is out of bounds,6747* (2) the cursor is not on one of this rowset's rows or its6748* insert row, or (3) the designated column does not store an6749* SQL <code>DATALINK</code> value.6750* @see #getURL(String)6751*/6752public java.net.URL getURL(int columnIndex) throws SQLException {6753//throw new SQLException("Operation not supported");67546755java.net.URL value;67566757// sanity check.6758checkIndex(columnIndex);6759// make sure the cursor is on a valid row6760checkCursor();67616762if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.DATALINK) {6763throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());6764}67656766setLastValueNull(false);6767value = (java.net.URL)(getCurrentRow().getColumnObject(columnIndex));67686769// check for SQL NULL6770if (value == null) {6771setLastValueNull(true);6772return null;6773}67746775return value;6776}67776778/**6779* Retrieves the value of the designated column in this6780* <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object6781* in the Java programming language.6782*6783* @return a java.net.URL object containing the resource reference described by6784* the URL6785* @throws SQLException if (1) the given column name not the name of a column6786* in this rowset, or6787* (2) the cursor is not on one of this rowset's rows or its6788* insert row, or (3) the designated column does not store an6789* SQL <code>DATALINK</code> value.6790* @see #getURL(int)6791*/6792public java.net.URL getURL(String columnName) throws SQLException {6793return getURL(getColIdxByName(columnName));67946795}67966797/**6798* The first warning reported by calls on this <code>CachedRowSetImpl</code>6799* object is returned. Subsequent <code>CachedRowSetImpl</code> warnings will6800* be chained to this <code>SQLWarning</code>. All <code>RowSetWarnings</code>6801* warnings are generated in the disconnected environment and remain a6802* seperate warning chain to that provided by the <code>getWarnings</code>6803* method.6804*6805* <P>The warning chain is automatically cleared each time a new6806* row is read.6807*6808* <P><B>Note:</B> This warning chain only covers warnings caused6809* by <code>CachedRowSet</code> (and their child interface)6810* methods. All <code>SQLWarnings</code> can be obtained using the6811* <code>getWarnings</code> method which tracks warnings generated6812* by the underlying JDBC driver.6813* @return the first SQLWarning or null6814*6815*/6816public RowSetWarning getRowSetWarnings() {6817try {6818notifyCursorMoved();6819} catch (SQLException e) {} // mask exception6820return rowsetWarning;6821}682268236824/**6825* The function tries to isolate the tablename when only setCommand6826* is set and not setTablename is called provided there is only one table6827* name in the query else just leaves the setting of table name as such.6828* If setTablename is set later it will over ride this table name6829* value so retrieved.6830*6831* @return the tablename if only one table in query else return ""6832*/6833private String buildTableName(String command) throws SQLException {68346835// If we have a query from one table,6836// we set the table name implicitly6837// else user has to explicitly set the table name.68386839int indexFrom, indexComma;6840String strTablename ="";6841command = command.trim();68426843// Query can be a select, insert or update68446845if(command.toLowerCase().startsWith("select")) {6846// look for "from" keyword, after that look for a6847// comma after from. If comma is there don't set6848// table name else isolate table name.68496850indexFrom = command.toLowerCase().indexOf("from");6851indexComma = command.indexOf(',', indexFrom);68526853if(indexComma == -1) {6854// implies only one table6855strTablename = (command.substring(indexFrom+"from".length(),command.length())).trim();68566857String tabName = strTablename;68586859int idxWhere = tabName.toLowerCase().indexOf("where");68606861/**6862* Adding the addtional check for conditions following the table name.6863* If a condition is found truncate it.6864**/68656866if(idxWhere != -1)6867{6868tabName = tabName.substring(0,idxWhere).trim();6869}68706871strTablename = tabName;68726873} else {6874//strTablename="";6875}68766877} else if(command.toLowerCase().startsWith("insert")) {6878//strTablename="";6879} else if(command.toLowerCase().startsWith("update")) {6880//strTablename="";6881}6882return strTablename;6883}68846885/**6886* Commits all changes performed by the <code>acceptChanges()</code>6887* methods6888*6889* @see java.sql.Connection#commit6890*/6891public void commit() throws SQLException {6892conn.commit();6893}68946895/**6896* Rolls back all changes performed by the <code>acceptChanges()</code>6897* methods6898*6899* @see java.sql.Connection#rollback6900*/6901public void rollback() throws SQLException {6902conn.rollback();6903}69046905/**6906* Rolls back all changes performed by the <code>acceptChanges()</code>6907* to the last <code>Savepoint</code> transaction marker.6908*6909* @see java.sql.Connection#rollback(Savepoint)6910*/6911public void rollback(Savepoint s) throws SQLException {6912conn.rollback(s);6913}69146915/**6916* Unsets the designated parameter to the given int array.6917* This was set using <code>setMatchColumn</code>6918* as the column which will form the basis of the join.6919* <P>6920* The parameter value unset by this method should be same6921* as was set.6922*6923* @param columnIdxes the index into this rowset6924* object's internal representation of parameter values6925* @throws SQLException if an error occurs or the6926* parameter index is out of bounds or if the columnIdx is6927* not the same as set using <code>setMatchColumn(int [])</code>6928*/6929public void unsetMatchColumn(int[] columnIdxes) throws SQLException {69306931int i_val;6932for( int j= 0 ;j < columnIdxes.length; j++) {6933i_val = (Integer.parseInt(iMatchColumns.get(j).toString()));6934if(columnIdxes[j] != i_val) {6935throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString());6936}6937}69386939for( int i = 0;i < columnIdxes.length ;i++) {6940iMatchColumns.set(i, -1);6941}6942}69436944/**6945* Unsets the designated parameter to the given String array.6946* This was set using <code>setMatchColumn</code>6947* as the column which will form the basis of the join.6948* <P>6949* The parameter value unset by this method should be same6950* as was set.6951*6952* @param columnIdxes the index into this rowset6953* object's internal representation of parameter values6954* @throws SQLException if an error occurs or the6955* parameter index is out of bounds or if the columnName is6956* not the same as set using <code>setMatchColumn(String [])</code>6957*/6958public void unsetMatchColumn(String[] columnIdxes) throws SQLException {69596960for(int j = 0 ;j < columnIdxes.length; j++) {6961if( !columnIdxes[j].equals(strMatchColumns.get(j)) ){6962throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString());6963}6964}69656966for(int i = 0 ; i < columnIdxes.length; i++) {6967strMatchColumns.set(i,null);6968}6969}69706971/**6972* Retrieves the column name as <code>String</code> array6973* that was set using <code>setMatchColumn(String [])</code>6974* for this rowset.6975*6976* @return a <code>String</code> array object that contains the column names6977* for the rowset which has this the match columns6978*6979* @throws SQLException if an error occurs or column name is not set6980*/6981public String[] getMatchColumnNames() throws SQLException {69826983String []str_temp = new String[strMatchColumns.size()];69846985if( strMatchColumns.get(0) == null) {6986throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString());6987}69886989strMatchColumns.copyInto(str_temp);6990return str_temp;6991}69926993/**6994* Retrieves the column id as <code>int</code> array that was set using6995* <code>setMatchColumn(int [])</code> for this rowset.6996*6997* @return a <code>int</code> array object that contains the column ids6998* for the rowset which has this as the match columns.6999*7000* @throws SQLException if an error occurs or column index is not set7001*/7002public int[] getMatchColumnIndexes() throws SQLException {70037004Integer []int_temp = new Integer[iMatchColumns.size()];7005int [] i_temp = new int[iMatchColumns.size()];7006int i_val;70077008i_val = iMatchColumns.get(0);70097010if( i_val == -1 ) {7011throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString());7012}701370147015iMatchColumns.copyInto(int_temp);70167017for(int i = 0; i < int_temp.length; i++) {7018i_temp[i] = (int_temp[i]).intValue();7019}70207021return i_temp;7022}70237024/**7025* Sets the designated parameter to the given int array.7026* This forms the basis of the join for the7027* <code>JoinRowSet</code> as the column which will form the basis of the7028* join.7029* <P>7030* The parameter value set by this method is stored internally and7031* will be supplied as the appropriate parameter in this rowset's7032* command when the method <code>getMatchColumnIndexes</code> is called.7033*7034* @param columnIdxes the indexes into this rowset7035* object's internal representation of parameter values; the7036* first parameter is 0, the second is 1, and so on; must be7037* <code>0</code> or greater7038* @throws SQLException if an error occurs or the7039* parameter index is out of bounds7040*/7041public void setMatchColumn(int[] columnIdxes) throws SQLException {70427043for(int j = 0 ; j < columnIdxes.length; j++) {7044if( columnIdxes[j] < 0 ) {7045throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString());7046}7047}7048for(int i = 0 ;i < columnIdxes.length; i++) {7049iMatchColumns.add(i,columnIdxes[i]);7050}7051}70527053/**7054* Sets the designated parameter to the given String array.7055* This forms the basis of the join for the7056* <code>JoinRowSet</code> as the column which will form the basis of the7057* join.7058* <P>7059* The parameter value set by this method is stored internally and7060* will be supplied as the appropriate parameter in this rowset's7061* command when the method <code>getMatchColumn</code> is called.7062*7063* @param columnNames the name of the column into this rowset7064* object's internal representation of parameter values7065* @throws SQLException if an error occurs or the7066* parameter index is out of bounds7067*/7068public void setMatchColumn(String[] columnNames) throws SQLException {70697070for(int j = 0; j < columnNames.length; j++) {7071if( columnNames[j] == null || columnNames[j].isEmpty()) {7072throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());7073}7074}7075for( int i = 0; i < columnNames.length; i++) {7076strMatchColumns.add(i,columnNames[i]);7077}7078}707970807081/**7082* Sets the designated parameter to the given <code>int</code>7083* object. This forms the basis of the join for the7084* <code>JoinRowSet</code> as the column which will form the basis of the7085* join.7086* <P>7087* The parameter value set by this method is stored internally and7088* will be supplied as the appropriate parameter in this rowset's7089* command when the method <code>getMatchColumn</code> is called.7090*7091* @param columnIdx the index into this rowset7092* object's internal representation of parameter values; the7093* first parameter is 0, the second is 1, and so on; must be7094* <code>0</code> or greater7095* @throws SQLException if an error occurs or the7096* parameter index is out of bounds7097*/7098public void setMatchColumn(int columnIdx) throws SQLException {7099// validate, if col is ok to be set7100if(columnIdx < 0) {7101throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString());7102} else {7103// set iMatchColumn7104iMatchColumns.set(0, columnIdx);7105//strMatchColumn = null;7106}7107}71087109/**7110* Sets the designated parameter to the given <code>String</code>7111* object. This forms the basis of the join for the7112* <code>JoinRowSet</code> as the column which will form the basis of the7113* join.7114* <P>7115* The parameter value set by this method is stored internally and7116* will be supplied as the appropriate parameter in this rowset's7117* command when the method <code>getMatchColumn</code> is called.7118*7119* @param columnName the name of the column into this rowset7120* object's internal representation of parameter values7121* @throws SQLException if an error occurs or the7122* parameter index is out of bounds7123*/7124public void setMatchColumn(String columnName) throws SQLException {7125// validate, if col is ok to be set7126if(columnName == null || (columnName= columnName.trim()).isEmpty() ) {7127throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());7128} else {7129// set strMatchColumn7130strMatchColumns.set(0, columnName);7131//iMatchColumn = -1;7132}7133}71347135/**7136* Unsets the designated parameter to the given <code>int</code>7137* object. This was set using <code>setMatchColumn</code>7138* as the column which will form the basis of the join.7139* <P>7140* The parameter value unset by this method should be same7141* as was set.7142*7143* @param columnIdx the index into this rowset7144* object's internal representation of parameter values7145* @throws SQLException if an error occurs or the7146* parameter index is out of bounds or if the columnIdx is7147* not the same as set using <code>setMatchColumn(int)</code>7148*/7149public void unsetMatchColumn(int columnIdx) throws SQLException {7150// check if we are unsetting the SAME column7151if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) {7152throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString());7153} else if(strMatchColumns.get(0) != null) {7154throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString());7155} else {7156// that is, we are unsetting it.7157iMatchColumns.set(0, -1);7158}7159}71607161/**7162* Unsets the designated parameter to the given <code>String</code>7163* object. This was set using <code>setMatchColumn</code>7164* as the column which will form the basis of the join.7165* <P>7166* The parameter value unset by this method should be same7167* as was set.7168*7169* @param columnName the index into this rowset7170* object's internal representation of parameter values7171* @throws SQLException if an error occurs or the7172* parameter index is out of bounds or if the columnName is7173* not the same as set using <code>setMatchColumn(String)</code>7174*/7175public void unsetMatchColumn(String columnName) throws SQLException {7176// check if we are unsetting the same column7177columnName = columnName.trim();71787179if(!((strMatchColumns.get(0)).equals(columnName))) {7180throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString());7181} else if(iMatchColumns.get(0) > 0) {7182throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch2").toString());7183} else {7184strMatchColumns.set(0, null); // that is, we are unsetting it.7185}7186}71877188/**7189* Notifies registered listeners that a RowSet object in the given RowSetEvent7190* object has populated a number of additional rows. The <code>numRows</code> parameter7191* ensures that this event will only be fired every <code>numRow</code>.7192* <p>7193* The source of the event can be retrieved with the method event.getSource.7194*7195* @param event a <code>RowSetEvent</code> object that contains the7196* <code>RowSet</code> object that is the source of the events7197* @param numRows when populating, the number of rows interval on which the7198* <code>CachedRowSet</code> populated should fire; the default value7199* is zero; cannot be less than <code>fetchSize</code> or zero7200*/7201public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException {72027203if( numRows < 0 || numRows < getFetchSize()) {7204throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.numrows").toString());7205}72067207if(size() % numRows == 0) {7208RowSetEvent event_temp = new RowSetEvent(this);7209event = event_temp;7210notifyRowSetChanged();7211}7212}72137214/**7215* Populates this <code>CachedRowSet</code> object with data from7216* the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code>7217* method, an additional parameter is provided to allow starting position within7218* the <code>ResultSet</code> from where to populate the CachedRowSet7219* instance.7220*7221* This method is an alternative to the method <code>execute</code>7222* for filling the rowset with data. The method <code>populate</code>7223* does not require that the properties needed by the method7224* <code>execute</code>, such as the <code>command</code> property,7225* be set. This is true because the method <code>populate</code>7226* is given the <code>ResultSet</code> object from7227* which to get data and thus does not need to use the properties7228* required for setting up a connection and executing this7229* <code>CachedRowSetImpl</code> object's command.7230* <P>7231* After populating this rowset with data, the method7232* <code>populate</code> sets the rowset's metadata and7233* then sends a <code>RowSetChangedEvent</code> object7234* to all registered listeners prior to returning.7235*7236* @param data the <code>ResultSet</code> object containing the data7237* to be read into this <code>CachedRowSetImpl</code> object7238* @param start the integer specifing the position in the7239* <code>ResultSet</code> object to popultate the7240* <code>CachedRowSetImpl</code> object.7241* @throws SQLException if an error occurs; or the max row setting is7242* violated while populating the RowSet.Also id the start position7243* is negative.7244* @see #execute7245*/7246public void populate(ResultSet data, int start) throws SQLException{72477248int rowsFetched;7249Row currentRow;7250int numCols;7251int i;7252Map<String, Class<?>> map = getTypeMap();7253Object obj;7254int mRows;72557256cursorPos = 0;7257if(populatecallcount == 0){7258if(start < 0){7259throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.startpos").toString());7260}7261if(getMaxRows() == 0){7262data.absolute(start);7263while(data.next()){7264totalRows++;7265}7266totalRows++;7267}7268startPos = start;7269}7270populatecallcount = populatecallcount +1;7271resultSet = data;7272if((endPos - startPos) >= getMaxRows() && (getMaxRows() > 0)){7273endPos = prevEndPos;7274pagenotend = false;7275return;7276}72777278if((maxRowsreached != getMaxRows() || maxRowsreached != totalRows) && pagenotend) {7279startPrev = start - getPageSize();7280}72817282if( pageSize == 0){7283prevEndPos = endPos;7284endPos = start + getMaxRows() ;7285}7286else{7287prevEndPos = endPos;7288endPos = start + getPageSize();7289}729072917292if (start == 1){7293resultSet.beforeFirst();7294}7295else {7296resultSet.absolute(start -1);7297}7298if( pageSize == 0) {7299rvh = new Vector<Object>(getMaxRows());73007301}7302else{7303rvh = new Vector<Object>(getPageSize());7304}73057306if (data == null) {7307throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString());7308}73097310// get the meta data for this ResultSet7311RSMD = data.getMetaData();73127313// set up the metadata7314RowSetMD = new RowSetMetaDataImpl();7315initMetaData(RowSetMD, RSMD);73167317// release the meta-data so that aren't tempted to use it.7318RSMD = null;7319numCols = RowSetMD.getColumnCount();7320mRows = this.getMaxRows();7321rowsFetched = 0;7322currentRow = null;73237324if(!data.next() && mRows == 0){7325endPos = prevEndPos;7326pagenotend = false;7327return;7328}73297330data.previous();73317332while ( data.next()) {73337334currentRow = new Row(numCols);7335if(pageSize == 0){7336if ( rowsFetched >= mRows && mRows > 0) {7337rowsetWarning.setNextException(new SQLException("Populating rows "7338+ "setting has exceeded max row setting"));7339break;7340}7341}7342else {7343if ( (rowsFetched >= pageSize) ||( maxRowsreached >= mRows && mRows > 0)) {7344rowsetWarning.setNextException(new SQLException("Populating rows "7345+ "setting has exceeded max row setting"));7346break;7347}7348}73497350for ( i = 1; i <= numCols; i++) {7351/*7352* check if the user has set a map. If no map7353* is set then use plain getObject. This lets7354* us work with drivers that do not support7355* getObject with a map in fairly sensible way7356*/7357if (map == null) {7358obj = data.getObject(i);7359} else {7360obj = data.getObject(i, map);7361}7362/*7363* the following block checks for the various7364* types that we have to serialize in order to7365* store - right now only structs have been tested7366*/7367if (obj instanceof Struct) {7368obj = new SerialStruct((Struct)obj, map);7369} else if (obj instanceof SQLData) {7370obj = new SerialStruct((SQLData)obj, map);7371} else if (obj instanceof Blob) {7372obj = new SerialBlob((Blob)obj);7373} else if (obj instanceof Clob) {7374obj = new SerialClob((Clob)obj);7375} else if (obj instanceof java.sql.Array) {7376obj = new SerialArray((java.sql.Array)obj, map);7377}73787379currentRow.initColumnObject(i, obj);7380}7381rowsFetched++;7382maxRowsreached++;7383rvh.add(currentRow);7384}7385numRows = rowsFetched ;7386// Also rowsFetched should be equal to rvh.size()7387// notify any listeners that the rowset has changed7388notifyRowSetChanged();73897390}73917392/**7393* The nextPage gets the next page, that is a <code>CachedRowSetImpl</code> object7394* containing the number of rows specified by page size.7395* @return boolean value true indicating whether there are more pages to come and7396* false indicating that this is the last page.7397* @throws SQLException if an error occurs or this called before calling populate.7398*/7399public boolean nextPage() throws SQLException {74007401if (populatecallcount == 0){7402throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString());7403}7404// Fix for 65541867405onFirstPage = false;7406if(callWithCon){7407crsReader.setStartPosition(endPos);7408crsReader.readData((RowSetInternal)this);7409resultSet = null;7410}7411else {7412populate(resultSet,endPos);7413}7414return pagenotend;7415}74167417/**7418* This is the setter function for setting the size of the page, which specifies7419* how many rows have to be retrived at a time.7420*7421* @param size which is the page size7422* @throws SQLException if size is less than zero or greater than max rows.7423*/7424public void setPageSize (int size) throws SQLException {7425if (size < 0) {7426throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize").toString());7427}7428if (size > getMaxRows() && getMaxRows() != 0) {7429throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize1").toString());7430}7431pageSize = size;7432}74337434/**7435* This is the getter function for the size of the page.7436*7437* @return an integer that is the page size.7438*/7439public int getPageSize() {7440return pageSize;7441}744274437444/**7445* Retrieves the data present in the page prior to the page from where it is7446* called.7447* @return boolean value true if it retrieves the previous page, flase if it7448* is on the first page.7449* @throws SQLException if it is called before populate is called or ResultSet7450* is of type <code>ResultSet.TYPE_FORWARD_ONLY</code> or if an error7451* occurs.7452*/7453public boolean previousPage() throws SQLException {7454int pS;7455int mR;7456int rem;74577458pS = getPageSize();7459mR = maxRowsreached;74607461if (populatecallcount == 0){7462throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString());7463}74647465if( !callWithCon){7466if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY){7467throw new SQLException (resBundle.handleGetObject("cachedrowsetimpl.fwdonly").toString());7468}7469}74707471pagenotend = true;74727473if(startPrev < startPos ){7474onFirstPage = true;7475return false;7476}74777478if(onFirstPage){7479return false;7480}74817482rem = mR % pS;74837484if(rem == 0){7485maxRowsreached -= (2 * pS);7486if(callWithCon){7487crsReader.setStartPosition(startPrev);7488crsReader.readData((RowSetInternal)this);7489resultSet = null;7490}7491else {7492populate(resultSet,startPrev);7493}7494return true;7495}7496else7497{7498maxRowsreached -= (pS + rem);7499if(callWithCon){7500crsReader.setStartPosition(startPrev);7501crsReader.readData((RowSetInternal)this);7502resultSet = null;7503}7504else {7505populate(resultSet,startPrev);7506}7507return true;7508}7509}75107511/**7512* Goes to the page number passed as the parameter7513* @param page , the page loaded on a call to this function7514* @return true if the page exists false otherwise7515* @throws SQLException if an error occurs7516*/7517/*7518public boolean absolutePage(int page) throws SQLException{75197520boolean isAbs = true, retVal = true;7521int counter;75227523if( page <= 0 ){7524throw new SQLException("Absolute positoin is invalid");7525}7526counter = 0;75277528firstPage();7529counter++;7530while((counter < page) && isAbs) {7531isAbs = nextPage();7532counter ++;7533}75347535if( !isAbs && counter < page){7536retVal = false;7537}7538else if(counter == page){7539retVal = true;7540}75417542return retVal;7543}7544*/754575467547/**7548* Goes to the page number passed as the parameter from the current page.7549* The parameter can take postive or negative value accordingly.7550* @param page , the page loaded on a call to this function7551* @return true if the page exists false otherwise7552* @throws SQLException if an error occurs7553*/7554/*7555public boolean relativePage(int page) throws SQLException {75567557boolean isRel = true,retVal = true;7558int counter;75597560if(page > 0){7561counter = 0;7562while((counter < page) && isRel){7563isRel = nextPage();7564counter++;7565}75667567if(!isRel && counter < page){7568retVal = false;7569}7570else if( counter == page){7571retVal = true;7572}7573return retVal;7574}7575else {7576counter = page;7577isRel = true;7578while((counter < 0) && isRel){7579isRel = previousPage();7580counter++;7581}75827583if( !isRel && counter < 0){7584retVal = false;7585}7586else if(counter == 0){7587retVal = true;7588}7589return retVal;7590}7591}7592*/75937594/**7595* Retrieves the first page of data as specified by the page size.7596* @return boolean value true if present on first page, false otherwise7597* @throws SQLException if it called before populate or ResultSet is of7598* type <code>ResultSet.TYPE_FORWARD_ONLY</code> or an error occurs7599*/7600/*7601public boolean firstPage() throws SQLException {7602if (populatecallcount == 0){7603throw new SQLException("Populate the data before calling ");7604}7605if( !callWithCon){7606if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY) {7607throw new SQLException("Result of type forward only");7608}7609}7610endPos = 0;7611maxRowsreached = 0;7612pagenotend = true;7613if(callWithCon){7614crsReader.setStartPosition(startPos);7615crsReader.readData((RowSetInternal)this);7616resultSet = null;7617}7618else {7619populate(resultSet,startPos);7620}7621onFirstPage = true;7622return onFirstPage;7623}7624*/76257626/**7627* Retrives the last page of data as specified by the page size.7628* @return boolean value tur if present on the last page, false otherwise7629* @throws SQLException if called before populate or if an error occurs.7630*/7631/*7632public boolean lastPage() throws SQLException{7633int pS;7634int mR;7635int quo;7636int rem;76377638pS = getPageSize();7639mR = getMaxRows();76407641if(pS == 0){7642onLastPage = true;7643return onLastPage;7644}76457646if(getMaxRows() == 0){7647mR = totalRows;7648}76497650if (populatecallcount == 0){7651throw new SQLException("Populate the data before calling ");7652}76537654onFirstPage = false;76557656if((mR % pS) == 0){7657quo = mR / pS;7658int start = startPos + (pS * (quo - 1));7659maxRowsreached = mR - pS;7660if(callWithCon){7661crsReader.setStartPosition(start);7662crsReader.readData((RowSetInternal)this);7663resultSet = null;7664}7665else {7666populate(resultSet,start);7667}7668onLastPage = true;7669return onLastPage;7670}7671else {7672quo = mR /pS;7673rem = mR % pS;7674int start = startPos + (pS * quo);7675maxRowsreached = mR - (rem);7676if(callWithCon){7677crsReader.setStartPosition(start);7678crsReader.readData((RowSetInternal)this);7679resultSet = null;7680}7681else {7682populate(resultSet,start);7683}7684onLastPage = true;7685return onLastPage;7686}7687}7688*/76897690/**7691* Sets the status for the row on which the cursor is positioned. The insertFlag is used7692* to mention the toggle status for this row7693* @param insertFlag if it is true - marks this row as inserted7694* if it is false - marks it as not a newly inserted row7695* @throws SQLException if an error occurs while doing this operation7696*/7697public void setRowInserted(boolean insertFlag) throws SQLException {76987699checkCursor();77007701if(onInsertRow == true)7702throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());77037704if( insertFlag ) {7705((Row)getCurrentRow()).setInserted();7706} else {7707((Row)getCurrentRow()).clearInserted();7708}7709}77107711/**7712* Retrieves the value of the designated <code>SQL XML</code> parameter as a7713* <code>SQLXML</code> object in the Java programming language.7714* @param columnIndex the first column is 1, the second is 2, ...7715* @return a SQLXML object that maps an SQL XML value7716* @throws SQLException if a database access error occurs7717* @since 1.67718*/7719public SQLXML getSQLXML(int columnIndex) throws SQLException {7720throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7721}77227723/**7724* Retrieves the value of the designated <code>SQL XML</code> parameter as a7725* <code>SQLXML</code> object in the Java programming language.7726* @param colName the name of the column from which to retrieve the value7727* @return a SQLXML object that maps an SQL XML value7728* @throws SQLException if a database access error occurs7729*/7730public SQLXML getSQLXML(String colName) throws SQLException {7731throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7732}77337734/**7735* Retrieves the value of the designated column in the current row of this7736* <code>ResultSet</code> object as a java.sql.RowId object in the Java7737* programming language.7738*7739* @param columnIndex the first column is 1, the second 2, ...7740* @return the column value if the value is a SQL <code>NULL</code> the7741* value returned is <code>null</code>7742* @throws SQLException if a database access error occurs7743* @since 1.67744*/7745public RowId getRowId(int columnIndex) throws SQLException {7746throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7747}77487749/**7750* Retrieves the value of the designated column in the current row of this7751* <code>ResultSet</code> object as a java.sql.RowId object in the Java7752* programming language.7753*7754* @param columnName the name of the column7755* @return the column value if the value is a SQL <code>NULL</code> the7756* value returned is <code>null</code>7757* @throws SQLException if a database access error occurs7758* @since 1.67759*/7760public RowId getRowId(String columnName) throws SQLException {7761throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7762}77637764/**7765* Updates the designated column with a <code>RowId</code> value. The updater7766* methods are used to update column values in the current row or the insert7767* row. The updater methods do not update the underlying database; instead7768* the {@code updateRow} or {@code insertRow} methods are called7769* to update the database.7770*7771* @param columnIndex the first column is 1, the second 2, ...7772* @param x the column value7773* @throws SQLException if a database access occurs7774* @since 1.67775*/7776public void updateRowId(int columnIndex, RowId x) throws SQLException {7777throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7778}77797780/**7781* Updates the designated column with a <code>RowId</code> value. The updater7782* methods are used to update column values in the current row or the insert7783* row. The updater methods do not update the underlying database; instead7784* the {@code updateRow} or {@code insertRow} methods are called7785* to update the database.7786*7787* @param columnName the name of the column7788* @param x the column value7789* @throws SQLException if a database access occurs7790* @since 1.67791*/7792public void updateRowId(String columnName, RowId x) throws SQLException {7793throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7794}77957796/**7797* Retrieves the holdability of this ResultSet object7798* @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT7799* @throws SQLException if a database error occurs7800* @since 1.67801*/7802public int getHoldability() throws SQLException {7803throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7804}78057806/**7807* Retrieves whether this ResultSet object has been closed. A ResultSet is closed if the7808* method close has been called on it, or if it is automatically closed.7809* @return true if this ResultSet object is closed; false if it is still open7810* @throws SQLException if a database access error occurs7811* @since 1.67812*/7813public boolean isClosed() throws SQLException {7814throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7815}78167817/**7818* This method is used for updating columns that support National Character sets.7819* It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns.7820* @param columnIndex the first column is 1, the second 2, ...7821* @param nString the value for the column to be updated7822* @throws SQLException if a database access error occurs7823* @since 1.67824*/7825public void updateNString(int columnIndex, String nString) throws SQLException {7826throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7827}78287829/**7830* This method is used for updating columns that support National Character sets.7831* It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns.7832* @param columnName name of the Column7833* @param nString the value for the column to be updated7834* @throws SQLException if a database access error occurs7835* @since 1.67836*/7837public void updateNString(String columnName, String nString) throws SQLException {7838throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7839}784078417842/*o7843* This method is used for updating SQL <code>NCLOB</code> type that maps7844* to <code>java.sql.Types.NCLOB</code>7845* @param columnIndex the first column is 1, the second 2, ...7846* @param nClob the value for the column to be updated7847* @throws SQLException if a database access error occurs7848* @since 1.67849*/7850public void updateNClob(int columnIndex, NClob nClob) throws SQLException {7851throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7852}78537854/**7855* This method is used for updating SQL <code>NCLOB</code> type that maps7856* to <code>java.sql.Types.NCLOB</code>7857* @param columnName name of the column7858* @param nClob the value for the column to be updated7859* @throws SQLException if a database access error occurs7860* @since 1.67861*/7862public void updateNClob(String columnName, NClob nClob) throws SQLException {7863throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7864}78657866/**7867* Retrieves the value of the designated column in the current row7868* of this <code>ResultSet</code> object as a <code>NClob</code> object7869* in the Java programming language.7870*7871* @param i the first column is 1, the second is 2, ...7872* @return a <code>NClob</code> object representing the SQL7873* <code>NCLOB</code> value in the specified column7874* @exception SQLException if a database access error occurs7875* @since 1.67876*/7877public NClob getNClob(int i) throws SQLException {7878throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7879}788078817882/**7883* Retrieves the value of the designated column in the current row7884* of this <code>ResultSet</code> object as a <code>NClob</code> object7885* in the Java programming language.7886*7887* @param colName the name of the column from which to retrieve the value7888* @return a <code>NClob</code> object representing the SQL <code>NCLOB</code>7889* value in the specified column7890* @exception SQLException if a database access error occurs7891* @since 1.67892*/7893public NClob getNClob(String colName) throws SQLException {7894throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7895}78967897public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {7898return null;7899}79007901public boolean isWrapperFor(Class<?> interfaces) throws SQLException {7902return false;7903}790479057906/**7907* Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an7908* SQL <code>XML</code> value when it sends it to the database.7909* @param parameterIndex index of the first parameter is 1, the second is 2, ...7910* @param xmlObject a <code>SQLXML</code> object that maps an SQL <code>XML</code> value7911* @throws SQLException if a database access error occurs7912* @since 1.67913*/7914public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {7915throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7916}79177918/**7919* Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an7920* <code>SQL XML</code> value when it sends it to the database.7921* @param parameterName the name of the parameter7922* @param xmlObject a <code>SQLXML</code> object that maps an <code>SQL XML</code> value7923* @throws SQLException if a database access error occurs7924* @since 1.67925*/7926public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException {7927throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7928}792979307931/**7932* Sets the designated parameter to the given <code>java.sql.RowId</code> object. The7933* driver converts this to a SQL <code>ROWID</code> value when it sends it7934* to the database7935*7936* @param parameterIndex the first parameter is 1, the second is 2, ...7937* @param x the parameter value7938* @throws SQLException if a database access error occurs7939*7940* @since 1.67941*/7942public void setRowId(int parameterIndex, RowId x) throws SQLException {7943throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7944}794579467947/**7948* Sets the designated parameter to the given <code>java.sql.RowId</code> object. The7949* driver converts this to a SQL <code>ROWID</code> when it sends it to the7950* database.7951*7952* @param parameterName the name of the parameter7953* @param x the parameter value7954* @throws SQLException if a database access error occurs7955* @since 1.67956*/7957public void setRowId(String parameterName, RowId x) throws SQLException {7958throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7959}796079617962/**7963* Sets the designated parameter to a <code>Reader</code> object. The7964* <code>Reader</code> reads the data till end-of-file is reached. The7965* driver does the necessary conversion from Java character format to7966* the national character set in the database.79677968* <P><B>Note:</B> This stream object can either be a standard7969* Java stream object or your own subclass that implements the7970* standard interface.7971* <P><B>Note:</B> Consult your JDBC driver documentation to determine if7972* it might be more efficient to use a version of7973* <code>setNCharacterStream</code> which takes a length parameter.7974*7975* @param parameterIndex of the first parameter is 1, the second is 2, ...7976* @param value the parameter value7977* @throws SQLException if the driver does not support national7978* character sets; if the driver can detect that a data conversion7979* error could occur ; if a database access error occurs; or7980* this method is called on a closed <code>PreparedStatement</code>7981* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method7982* @since 1.67983*/7984public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {7985throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());7986}798779887989/**7990* Sets the designated parameter to a <code>java.sql.NClob</code> object. The object7991* implements the <code>java.sql.NClob</code> interface. This <code>NClob</code>7992* object maps to a SQL <code>NCLOB</code>.7993* @param parameterName the name of the column to be set7994* @param value the parameter value7995* @throws SQLException if the driver does not support national7996* character sets; if the driver can detect that a data conversion7997* error could occur; or if a database access error occurs7998* @since 1.67999*/8000public void setNClob(String parameterName, NClob value) throws SQLException {8001throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8002}800380048005/**8006* Retrieves the value of the designated column in the current row8007* of this <code>ResultSet</code> object as a8008* <code>java.io.Reader</code> object.8009* It is intended for use when8010* accessing <code>NCHAR</code>,<code>NVARCHAR</code>8011* and <code>LONGNVARCHAR</code> columns.8012*8013* @return a <code>java.io.Reader</code> object that contains the column8014* value; if the value is SQL <code>NULL</code>, the value returned is8015* <code>null</code> in the Java programming language.8016* @param columnIndex the first column is 1, the second is 2, ...8017* @exception SQLException if a database access error occurs8018* @since 1.68019*/8020public java.io.Reader getNCharacterStream(int columnIndex) throws SQLException {8021throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8022}802380248025/**8026* Retrieves the value of the designated column in the current row8027* of this <code>ResultSet</code> object as a8028* <code>java.io.Reader</code> object.8029* It is intended for use when8030* accessing <code>NCHAR</code>,<code>NVARCHAR</code>8031* and <code>LONGNVARCHAR</code> columns.8032*8033* @param columnName the name of the column8034* @return a <code>java.io.Reader</code> object that contains the column8035* value; if the value is SQL <code>NULL</code>, the value returned is8036* <code>null</code> in the Java programming language8037* @exception SQLException if a database access error occurs8038* @since 1.68039*/8040public java.io.Reader getNCharacterStream(String columnName) throws SQLException {8041throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8042}804380448045/**8046* Updates the designated column with a <code>java.sql.SQLXML</code> value.8047* The updater8048* methods are used to update column values in the current row or the insert8049* row. The updater methods do not update the underlying database; instead8050* the <code>updateRow</code> or <code>insertRow</code> methods are called8051* to update the database.8052* @param columnIndex the first column is 1, the second 2, ...8053* @param xmlObject the value for the column to be updated8054* @throws SQLException if a database access error occurs8055* @since 1.68056*/8057public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {8058throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8059}80608061/**8062* Updates the designated column with a <code>java.sql.SQLXML</code> value.8063* The updater8064* methods are used to update column values in the current row or the insert8065* row. The updater methods do not update the underlying database; instead8066* the <code>updateRow</code> or <code>insertRow</code> methods are called8067* to update the database.8068*8069* @param columnName the name of the column8070* @param xmlObject the column value8071* @throws SQLException if a database access occurs8072* @since 1.68073*/8074public void updateSQLXML(String columnName, SQLXML xmlObject) throws SQLException {8075throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8076}80778078/**8079* Retrieves the value of the designated column in the current row8080* of this <code>ResultSet</code> object as8081* a <code>String</code> in the Java programming language.8082* It is intended for use when8083* accessing <code>NCHAR</code>,<code>NVARCHAR</code>8084* and <code>LONGNVARCHAR</code> columns.8085*8086* @param columnIndex the first column is 1, the second is 2, ...8087* @return the column value; if the value is SQL <code>NULL</code>, the8088* value returned is <code>null</code>8089* @exception SQLException if a database access error occurs8090* @since 1.68091*/8092public String getNString(int columnIndex) throws SQLException {8093throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8094}80958096/**8097* Retrieves the value of the designated column in the current row8098* of this <code>ResultSet</code> object as8099* a <code>String</code> in the Java programming language.8100* It is intended for use when8101* accessing <code>NCHAR</code>,<code>NVARCHAR</code>8102* and <code>LONGNVARCHAR</code> columns.8103*8104* @param columnName the SQL name of the column8105* @return the column value; if the value is SQL <code>NULL</code>, the8106* value returned is <code>null</code>8107* @exception SQLException if a database access error occurs8108* @since 1.68109*/8110public String getNString(String columnName) throws SQLException {8111throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8112}81138114/**8115* Updates the designated column with a character stream value, which will8116* have the specified number of bytes. The driver does the necessary conversion8117* from Java character format to the national character set in the database.8118* It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns.8119* The updater methods are used to update column values in the current row or8120* the insert row. The updater methods do not update the underlying database;8121* instead the updateRow or insertRow methods are called to update the database.8122*8123* @param columnIndex - the first column is 1, the second is 2, ...8124* @param x - the new column value8125* @param length - the length of the stream8126* @exception SQLException if a database access error occurs8127* @since 1.68128*/8129public void updateNCharacterStream(int columnIndex,8130java.io.Reader x,8131long length)8132throws SQLException {8133throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8134}81358136/**8137* Updates the designated column with a character stream value, which will8138* have the specified number of bytes. The driver does the necessary conversion8139* from Java character format to the national character set in the database.8140* It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns.8141* The updater methods are used to update column values in the current row or8142* the insert row. The updater methods do not update the underlying database;8143* instead the updateRow or insertRow methods are called to update the database.8144*8145* @param columnName - name of the Column8146* @param x - the new column value8147* @param length - the length of the stream8148* @exception SQLException if a database access error occurs8149* @since 1.68150*/8151public void updateNCharacterStream(String columnName,8152java.io.Reader x,8153long length)8154throws SQLException {8155throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8156}81578158/**8159* Updates the designated column with a character stream value. The8160* driver does the necessary conversion from Java character format to8161* the national character set in the database.8162* It is intended for use when8163* updating <code>NCHAR</code>,<code>NVARCHAR</code>8164* and <code>LONGNVARCHAR</code> columns.8165*8166* The updater methods are used to update column values in the8167* current row or the insert row. The updater methods do not8168* update the underlying database; instead the <code>updateRow</code> or8169* <code>insertRow</code> methods are called to update the database.8170*8171* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8172* it might be more efficient to use a version of8173* <code>updateNCharacterStream</code> which takes a length parameter.8174*8175* @param columnIndex the first column is 1, the second is 2, ...8176* @param x the new column value8177* @exception SQLException if a database access error occurs,8178* the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set8179* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8180* this method8181* @since 1.68182*/8183public void updateNCharacterStream(int columnIndex,8184java.io.Reader x) throws SQLException {8185throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8186}81878188/**8189* Updates the designated column with a character stream value. The8190* driver does the necessary conversion from Java character format to8191* the national character set in the database.8192* It is intended for use when8193* updating <code>NCHAR</code>,<code>NVARCHAR</code>8194* and <code>LONGNVARCHAR</code> columns.8195*8196* The updater methods are used to update column values in the8197* current row or the insert row. The updater methods do not8198* update the underlying database; instead the <code>updateRow</code> or8199* <code>insertRow</code> methods are called to update the database.8200*8201* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8202* it might be more efficient to use a version of8203* <code>updateNCharacterStream</code> which takes a length parameter.8204*8205* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8206bel is the name of the column8207* @param reader the <code>java.io.Reader</code> object containing8208* the new column value8209* @exception SQLException if a database access error occurs,8210* the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set8211* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8212* this method8213* @since 1.68214*/8215public void updateNCharacterStream(String columnLabel,8216java.io.Reader reader) throws SQLException {8217throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8218}82198220//////////////////////////82218222/**8223* Updates the designated column using the given input stream, which8224* will have the specified number of bytes.8225* When a very large ASCII value is input to a <code>LONGVARCHAR</code>8226* parameter, it may be more practical to send it via a8227* <code>java.io.InputStream</code>. Data will be read from the stream8228* as needed until end-of-file is reached. The JDBC driver will8229* do any necessary conversion from ASCII to the database char format.8230*8231* <P><B>Note:</B> This stream object can either be a standard8232* Java stream object or your own subclass that implements the8233* standard interface.8234* <p>8235* The updater methods are used to update column values in the8236* current row or the insert row. The updater methods do not8237* update the underlying database; instead the <code>updateRow</code> or8238* <code>insertRow</code> methods are called to update the database.8239*8240* @param columnIndex the first column is 1, the second is 2, ...8241* @param inputStream An object that contains the data to set the parameter8242* value to.8243* @param length the number of bytes in the parameter data.8244* @exception SQLException if a database access error occurs,8245* the result set concurrency is <code>CONCUR_READ_ONLY</code>8246* or this method is called on a closed result set8247* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8248* this method8249* @since 1.68250*/8251public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException{8252throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8253}82548255/**8256* Updates the designated column using the given input stream, which8257* will have the specified number of bytes.8258* When a very large ASCII value is input to a <code>LONGVARCHAR</code>8259* parameter, it may be more practical to send it via a8260* <code>java.io.InputStream</code>. Data will be read from the stream8261* as needed until end-of-file is reached. The JDBC driver will8262* do any necessary conversion from ASCII to the database char format.8263*8264* <P><B>Note:</B> This stream object can either be a standard8265* Java stream object or your own subclass that implements the8266* standard interface.8267* <p>8268* The updater methods are used to update column values in the8269* current row or the insert row. The updater methods do not8270* update the underlying database; instead the <code>updateRow</code> or8271* <code>insertRow</code> methods are called to update the database.8272*8273* @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 column8274* @param inputStream An object that contains the data to set the parameter8275* value to.8276* @param length the number of bytes in the parameter data.8277* @exception SQLException if a database access error occurs,8278* the result set concurrency is <code>CONCUR_READ_ONLY</code>8279* or this method is called on a closed result set8280* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8281* this method8282* @since 1.68283*/8284public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {8285throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8286}82878288/**8289* Updates the designated column using the given input stream.8290* When a very large ASCII value is input to a <code>LONGVARCHAR</code>8291* parameter, it may be more practical to send it via a8292* <code>java.io.InputStream</code>. Data will be read from the stream8293* as needed until end-of-file is reached. The JDBC driver will8294* do any necessary conversion from ASCII to the database char format.8295*8296* <P><B>Note:</B> This stream object can either be a standard8297* Java stream object or your own subclass that implements the8298* standard interface.8299*8300* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8301* it might be more efficient to use a version of8302* <code>updateBlob</code> which takes a length parameter.8303* <p>8304* The updater methods are used to update column values in the8305* current row or the insert row. The updater methods do not8306* update the underlying database; instead the <code>updateRow</code> or8307* <code>insertRow</code> methods are called to update the database.8308*8309* @param columnIndex the first column is 1, the second is 2, ...8310* @param inputStream An object that contains the data to set the parameter8311* value to.8312* @exception SQLException if a database access error occurs,8313* the result set concurrency is <code>CONCUR_READ_ONLY</code>8314* or this method is called on a closed result set8315* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8316* this method8317* @since 1.68318*/8319public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {8320throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8321}83228323/**8324* Updates the designated column using the given input stream.8325* When a very large ASCII value is input to a <code>LONGVARCHAR</code>8326* parameter, it may be more practical to send it via a8327* <code>java.io.InputStream</code>. Data will be read from the stream8328* as needed until end-of-file is reached. The JDBC driver will8329* do any necessary conversion from ASCII to the database char format.8330*8331* <P><B>Note:</B> This stream object can either be a standard8332* Java stream object or your own subclass that implements the8333* standard interface.8334* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8335* it might be more efficient to use a version of8336* <code>updateBlob</code> which takes a length parameter.8337* <p>8338* The updater methods are used to update column values in the8339* current row or the insert row. The updater methods do not8340* update the underlying database; instead the <code>updateRow</code> or8341* <code>insertRow</code> methods are called to update the database.8342*8343* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8344bel is the name of the column8345* @param inputStream An object that contains the data to set the parameter8346* value to.8347* @exception SQLException if a database access error occurs,8348* the result set concurrency is <code>CONCUR_READ_ONLY</code>8349* or this method is called on a closed result set8350* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8351* this method8352* @since 1.68353*/8354public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {8355throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8356}83578358/**8359* Updates the designated column using the given <code>Reader</code>8360* object, which is the given number of characters long.8361* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8362* parameter, it may be more practical to send it via a8363* <code>java.io.Reader</code> object. The data will be read from the stream8364* as needed until end-of-file is reached. The JDBC driver will8365* do any necessary conversion from UNICODE to the database char format.8366*8367* <P><B>Note:</B> This stream object can either be a standard8368* Java stream object or your own subclass that implements the8369* standard interface.8370* <p>8371* The updater methods are used to update column values in the8372* current row or the insert row. The updater methods do not8373* update the underlying database; instead the <code>updateRow</code> or8374* <code>insertRow</code> methods are called to update the database.8375*8376* @param columnIndex the first column is 1, the second is 2, ...8377* @param reader An object that contains the data to set the parameter value to.8378* @param length the number of characters in the parameter data.8379* @exception SQLException if a database access error occurs,8380* the result set concurrency is <code>CONCUR_READ_ONLY</code>8381* or this method is called on a closed result set8382* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8383* this method8384* @since 1.68385*/8386public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {8387throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8388}83898390/**8391* Updates the designated column using the given <code>Reader</code>8392* object, which is the given number of characters long.8393* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8394* parameter, it may be more practical to send it via a8395* <code>java.io.Reader</code> object. The data will be read from the stream8396* as needed until end-of-file is reached. The JDBC driver will8397* do any necessary conversion from UNICODE to the database char format.8398*8399* <P><B>Note:</B> This stream object can either be a standard8400* Java stream object or your own subclass that implements the8401* standard interface.8402* <p>8403* The updater methods are used to update column values in the8404* current row or the insert row. The updater methods do not8405* update the underlying database; instead the <code>updateRow</code> or8406* <code>insertRow</code> methods are called to update the database.8407*8408* @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 column8409* @param reader An object that contains the data to set the parameter value to.8410* @param length the number of characters in the parameter data.8411* @exception SQLException if a database access error occurs,8412* the result set concurrency is <code>CONCUR_READ_ONLY</code>8413* or this method is called on a closed result set8414* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8415* this method8416* @since 1.68417*/8418public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {8419throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8420}84218422/**8423* Updates the designated column using the given <code>Reader</code>8424* object.8425* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8426* parameter, it may be more practical to send it via a8427* <code>java.io.Reader</code> object. The data will be read from the stream8428* as needed until end-of-file is reached. The JDBC driver will8429* do any necessary conversion from UNICODE to the database char format.8430*8431* <P><B>Note:</B> This stream object can either be a standard8432* Java stream object or your own subclass that implements the8433* standard interface.8434* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8435* it might be more efficient to use a version of8436* <code>updateClob</code> which takes a length parameter.8437* <p>8438* The updater methods are used to update column values in the8439* current row or the insert row. The updater methods do not8440* update the underlying database; instead the <code>updateRow</code> or8441* <code>insertRow</code> methods are called to update the database.8442*8443* @param columnIndex the first column is 1, the second is 2, ...8444* @param reader An object that contains the data to set the parameter value to.8445* @exception SQLException if a database access error occurs,8446* the result set concurrency is <code>CONCUR_READ_ONLY</code>8447* or this method is called on a closed result set8448* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8449* this method8450* @since 1.68451*/8452public void updateClob(int columnIndex, Reader reader) throws SQLException {8453throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8454}84558456/**8457* Updates the designated column using the given <code>Reader</code>8458* object.8459* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8460* parameter, it may be more practical to send it via a8461* <code>java.io.Reader</code> object. The data will be read from the stream8462* as needed until end-of-file is reached. The JDBC driver will8463* do any necessary conversion from UNICODE to the database char format.8464*8465* <P><B>Note:</B> This stream object can either be a standard8466* Java stream object or your own subclass that implements the8467* standard interface.8468* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8469* it might be more efficient to use a version of8470* <code>updateClob</code> which takes a length parameter.8471* <p>8472* The updater methods are used to update column values in the8473* current row or the insert row. The updater methods do not8474* update the underlying database; instead the <code>updateRow</code> or8475* <code>insertRow</code> methods are called to update the database.8476*8477* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8478bel is the name of the column8479* @param reader An object that contains the data to set the parameter value to.8480* @exception SQLException if a database access error occurs,8481* the result set concurrency is <code>CONCUR_READ_ONLY</code>8482* or this method is called on a closed result set8483* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8484* this method8485* @since 1.68486*/8487public void updateClob(String columnLabel, Reader reader) throws SQLException {8488throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8489}84908491/**8492* Updates the designated column using the given <code>Reader</code>8493* object, which is the given number of characters long.8494* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8495* parameter, it may be more practical to send it via a8496* <code>java.io.Reader</code> object. The data will be read from the stream8497* as needed until end-of-file is reached. The JDBC driver will8498* do any necessary conversion from UNICODE to the database char format.8499*8500* <P><B>Note:</B> This stream object can either be a standard8501* Java stream object or your own subclass that implements the8502* standard interface.8503* <p>8504* The updater methods are used to update column values in the8505* current row or the insert row. The updater methods do not8506* update the underlying database; instead the <code>updateRow</code> or8507* <code>insertRow</code> methods are called to update the database.8508*8509* @param columnIndex the first column is 1, the second 2, ...8510* @param reader An object that contains the data to set the parameter value to.8511* @param length the number of characters in the parameter data.8512* @throws SQLException if the driver does not support national8513* character sets; if the driver can detect that a data conversion8514* error could occur; this method is called on a closed result set,8515* if a database access error occurs or8516* the result set concurrency is <code>CONCUR_READ_ONLY</code>8517* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8518* this method8519* @since 1.68520*/8521public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {8522throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8523}85248525/**8526* Updates the designated column using the given <code>Reader</code>8527* object, which is the given number of characters long.8528* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8529* parameter, it may be more practical to send it via a8530* <code>java.io.Reader</code> object. The data will be read from the stream8531* as needed until end-of-file is reached. The JDBC driver will8532* do any necessary conversion from UNICODE to the database char format.8533*8534* <P><B>Note:</B> This stream object can either be a standard8535* Java stream object or your own subclass that implements the8536* standard interface.8537* <p>8538* The updater methods are used to update column values in the8539* current row or the insert row. The updater methods do not8540* update the underlying database; instead the <code>updateRow</code> or8541* <code>insertRow</code> methods are called to update the database.8542*8543* @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 column8544* @param reader An object that contains the data to set the parameter value to.8545* @param length the number of characters in the parameter data.8546* @throws SQLException if the driver does not support national8547* character sets; if the driver can detect that a data conversion8548* error could occur; this method is called on a closed result set;8549* if a database access error occurs or8550* the result set concurrency is <code>CONCUR_READ_ONLY</code>8551* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8552* this method8553* @since 1.68554*/8555public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {8556throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8557}85588559/**8560* Updates the designated column using the given <code>Reader</code>8561* object.8562* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8563* parameter, it may be more practical to send it via a8564* <code>java.io.Reader</code> object. The data will be read from the stream8565* as needed until end-of-file is reached. The JDBC driver will8566* do any necessary conversion from UNICODE to the database char format.8567*8568* <P><B>Note:</B> This stream object can either be a standard8569* Java stream object or your own subclass that implements the8570* standard interface.8571* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8572* it might be more efficient to use a version of8573* <code>updateNClob</code> which takes a length parameter.8574* <p>8575* The updater methods are used to update column values in the8576* current row or the insert row. The updater methods do not8577* update the underlying database; instead the <code>updateRow</code> or8578* <code>insertRow</code> methods are called to update the database.8579*8580* @param columnIndex the first column is 1, the second 2, ...8581* @param reader An object that contains the data to set the parameter value to.8582* @throws SQLException if the driver does not support national8583* character sets; if the driver can detect that a data conversion8584* error could occur; this method is called on a closed result set,8585* if a database access error occurs or8586* the result set concurrency is <code>CONCUR_READ_ONLY</code>8587* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8588* this method8589* @since 1.68590*/8591public void updateNClob(int columnIndex, Reader reader) throws SQLException {8592throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8593}85948595/**8596* Updates the designated column using the given <code>Reader</code>8597* object.8598* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8599* parameter, it may be more practical to send it via a8600* <code>java.io.Reader</code> object. The data will be read from the stream8601* as needed until end-of-file is reached. The JDBC driver will8602* do any necessary conversion from UNICODE to the database char format.8603*8604* <P><B>Note:</B> This stream object can either be a standard8605* Java stream object or your own subclass that implements the8606* standard interface.8607* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8608* it might be more efficient to use a version of8609* <code>updateNClob</code> which takes a length parameter.8610* <p>8611* The updater methods are used to update column values in the8612* current row or the insert row. The updater methods do not8613* update the underlying database; instead the <code>updateRow</code> or8614* <code>insertRow</code> methods are called to update the database.8615*8616* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8617bel is the name of the column8618* @param reader An object that contains the data to set the parameter value to.8619* @throws SQLException if the driver does not support national8620* character sets; if the driver can detect that a data conversion8621* error could occur; this method is called on a closed result set;8622* if a database access error occurs or8623* the result set concurrency is <code>CONCUR_READ_ONLY</code>8624* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8625* this method8626* @since 1.68627*/8628public void updateNClob(String columnLabel, Reader reader) throws SQLException {8629throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8630}86318632/**8633* Updates the designated column with an ascii stream value, which will have8634* the specified number of bytes.8635* The updater methods are used to update column values in the8636* current row or the insert row. The updater methods do not8637* update the underlying database; instead the <code>updateRow</code> or8638* <code>insertRow</code> methods are called to update the database.8639*8640* @param columnIndex the first column is 1, the second is 2, ...8641* @param x the new column value8642* @param length the length of the stream8643* @exception SQLException if a database access error occurs,8644* the result set concurrency is <code>CONCUR_READ_ONLY</code>8645* or this method is called on a closed result set8646* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8647* this method8648* @since 1.68649*/8650public void updateAsciiStream(int columnIndex,8651java.io.InputStream x,8652long length) throws SQLException {86538654}86558656/**8657* Updates the designated column with a binary stream value, which will have8658* the specified number of bytes.8659* The updater methods are used to update column values in the8660* current row or the insert row. The updater methods do not8661* update the underlying database; instead the <code>updateRow</code> or8662* <code>insertRow</code> methods are called to update the database.8663*8664* @param columnIndex the first column is 1, the second is 2, ...8665* @param x the new column value8666* @param length the length of the stream8667* @exception SQLException if a database access error occurs,8668* the result set concurrency is <code>CONCUR_READ_ONLY</code>8669* or this method is called on a closed result set8670* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8671* this method8672* @since 1.68673*/8674public void updateBinaryStream(int columnIndex,8675java.io.InputStream x,8676long length) throws SQLException {8677}86788679/**8680* Updates the designated column with a character stream value, which will have8681* the specified number of bytes.8682* The updater methods are used to update column values in the8683* current row or the insert row. The updater methods do not8684* update the underlying database; instead the <code>updateRow</code> or8685* <code>insertRow</code> methods are called to update the database.8686*8687* @param columnIndex the first column is 1, the second is 2, ...8688* @param x the new column value8689* @param length the length of the stream8690* @exception SQLException if a database access error occurs,8691* the result set concurrency is <code>CONCUR_READ_ONLY</code>8692* or this method is called on a closed result set8693* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8694* this method8695* @since 1.68696*/8697public void updateCharacterStream(int columnIndex,8698java.io.Reader x,8699long length) throws SQLException {8700throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8701}87028703/**8704* Updates the designated column with a character stream value, which will have8705* the specified number of bytes.8706* The updater methods are used to update column values in the8707* current row or the insert row. The updater methods do not8708* update the underlying database; instead the <code>updateRow</code> or8709* <code>insertRow</code> methods are called to update the database.8710*8711* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8712bel is the name of the column8713* @param reader the <code>java.io.Reader</code> object containing8714* the new column value8715* @param length the length of the stream8716* @exception SQLException if a database access error occurs,8717* the result set concurrency is <code>CONCUR_READ_ONLY</code>8718* or this method is called on a closed result set8719* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8720* this method8721* @since 1.68722*/8723public void updateCharacterStream(String columnLabel,8724java.io.Reader reader,8725long length) throws SQLException {8726throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8727}8728/**8729* Updates the designated column with an ascii stream value, which will have8730* the specified number of bytes..8731* The updater methods are used to update column values in the8732* current row or the insert row. The updater methods do not8733* update the underlying database; instead the <code>updateRow</code> or8734* <code>insertRow</code> methods are called to update the database.8735*8736* @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 column8737* @param x the new column value8738* @param length the length of the stream8739* @exception SQLException if a database access error occurs,8740* the result set concurrency is <code>CONCUR_READ_ONLY</code>8741* or this method is called on a closed result set8742* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8743* this method8744* @since 1.68745*/8746public void updateAsciiStream(String columnLabel,8747java.io.InputStream x,8748long length) throws SQLException {8749}87508751/**8752* Updates the designated column with a binary stream value, which will have8753* the specified number of bytes.8754* The updater methods are used to update column values in the8755* current row or the insert row. The updater methods do not8756* update the underlying database; instead the <code>updateRow</code> or8757* <code>insertRow</code> methods are called to update the database.8758*8759* @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 column8760* @param x the new column value8761* @param length the length of the stream8762* @exception SQLException if a database access error occurs,8763* the result set concurrency is <code>CONCUR_READ_ONLY</code>8764* or this method is called on a closed result set8765* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8766* this method8767* @since 1.68768*/8769public void updateBinaryStream(String columnLabel,8770java.io.InputStream x,8771long length) throws SQLException {8772}87738774/**8775* Updates the designated column with a binary stream value.8776* The updater methods are used to update column values in the8777* current row or the insert row. The updater methods do not8778* update the underlying database; instead the <code>updateRow</code> or8779* <code>insertRow</code> methods are called to update the database.8780*8781* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8782* it might be more efficient to use a version of8783* <code>updateBinaryStream</code> which takes a length parameter.8784*8785* @param columnIndex the first column is 1, the second is 2, ...8786* @param x the new column value8787* @exception SQLException if a database access error occurs,8788* the result set concurrency is <code>CONCUR_READ_ONLY</code>8789* or this method is called on a closed result set8790* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8791* this method8792* @since 1.68793*/8794public void updateBinaryStream(int columnIndex,8795java.io.InputStream x) throws SQLException {8796throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8797}879887998800/**8801* Updates the designated column with a binary stream value.8802* The updater methods are used to update column values in the8803* current row or the insert row. The updater methods do not8804* update the underlying database; instead the <code>updateRow</code> or8805* <code>insertRow</code> methods are called to update the database.8806*8807* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8808* it might be more efficient to use a version of8809* <code>updateBinaryStream</code> which takes a length parameter.8810*8811* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8812bel is the name of the column8813* @param x the new column value8814* @exception SQLException if a database access error occurs,8815* the result set concurrency is <code>CONCUR_READ_ONLY</code>8816* or this method is called on a closed result set8817* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8818* this method8819* @since 1.68820*/8821public void updateBinaryStream(String columnLabel,8822java.io.InputStream x) throws SQLException {8823throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8824}88258826/**8827* Updates the designated column with a character stream value.8828* The updater methods are used to update column values in the8829* current row or the insert row. The updater methods do not8830* update the underlying database; instead the <code>updateRow</code> or8831* <code>insertRow</code> methods are called to update the database.8832*8833* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8834* it might be more efficient to use a version of8835* <code>updateCharacterStream</code> which takes a length parameter.8836*8837* @param columnIndex the first column is 1, the second is 2, ...8838* @param x the new column value8839* @exception SQLException if a database access error occurs,8840* the result set concurrency is <code>CONCUR_READ_ONLY</code>8841* or this method is called on a closed result set8842* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8843* this method8844* @since 1.68845*/8846public void updateCharacterStream(int columnIndex,8847java.io.Reader x) throws SQLException {8848throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8849}88508851/**8852* Updates the designated column with a character stream value.8853* The updater methods are used to update column values in the8854* current row or the insert row. The updater methods do not8855* update the underlying database; instead the <code>updateRow</code> or8856* <code>insertRow</code> methods are called to update the database.8857*8858* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8859* it might be more efficient to use a version of8860* <code>updateCharacterStream</code> which takes a length parameter.8861*8862* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8863bel is the name of the column8864* @param reader the <code>java.io.Reader</code> object containing8865* the new column value8866* @exception SQLException if a database access error occurs,8867* the result set concurrency is <code>CONCUR_READ_ONLY</code>8868* or this method is called on a closed result set8869* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8870* this method8871* @since 1.68872*/8873public void updateCharacterStream(String columnLabel,8874java.io.Reader reader) throws SQLException {8875throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8876}88778878/**8879* Updates the designated column with an ascii stream value.8880* The updater methods are used to update column values in the8881* current row or the insert row. The updater methods do not8882* update the underlying database; instead the <code>updateRow</code> or8883* <code>insertRow</code> methods are called to update the database.8884*8885* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8886* it might be more efficient to use a version of8887* <code>updateAsciiStream</code> which takes a length parameter.8888*8889* @param columnIndex the first column is 1, the second is 2, ...8890* @param x the new column value8891* @exception SQLException if a database access error occurs,8892* the result set concurrency is <code>CONCUR_READ_ONLY</code>8893* or this method is called on a closed result set8894* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8895* this method8896* @since 1.68897*/8898public void updateAsciiStream(int columnIndex,8899java.io.InputStream x) throws SQLException {8900throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8901}89028903/**8904* Updates the designated column with an ascii stream value.8905* The updater methods are used to update column values in the8906* current row or the insert row. The updater methods do not8907* update the underlying database; instead the <code>updateRow</code> or8908* <code>insertRow</code> methods are called to update the database.8909*8910* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8911* it might be more efficient to use a version of8912* <code>updateAsciiStream</code> which takes a length parameter.8913*8914* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8915bel is the name of the column8916* @param x the new column value8917* @exception SQLException if a database access error occurs,8918* the result set concurrency is <code>CONCUR_READ_ONLY</code>8919* or this method is called on a closed result set8920* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8921* this method8922* @since 1.68923*/8924public void updateAsciiStream(String columnLabel,8925java.io.InputStream x) throws SQLException {89268927}89288929/**8930* Sets the designated parameter to the given <code>java.net.URL</code> value.8931* The driver converts this to an SQL <code>DATALINK</code> value8932* when it sends it to the database.8933*8934* @param parameterIndex the first parameter is 1, the second is 2, ...8935* @param x the <code>java.net.URL</code> object to be set8936* @exception SQLException if a database access error occurs or8937* this method is called on a closed <code>PreparedStatement</code>8938* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method8939* @since 1.48940*/8941public void setURL(int parameterIndex, java.net.URL x) throws SQLException{8942throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8943}89448945/**8946* Sets the designated parameter to a <code>Reader</code> object.8947* This method differs from the <code>setCharacterStream (int, Reader)</code> method8948* because it informs the driver that the parameter value should be sent to8949* the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the8950* driver may have to do extra work to determine whether the parameter8951* data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>8952* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8953* it might be more efficient to use a version of8954* <code>setNClob</code> which takes a length parameter.8955*8956* @param parameterIndex index of the first parameter is 1, the second is 2, ...8957* @param reader An object that contains the data to set the parameter value to.8958* @throws SQLException if parameterIndex does not correspond to a parameter8959* marker in the SQL statement;8960* if the driver does not support national character sets;8961* if the driver can detect that a data conversion8962* error could occur; if a database access error occurs or8963* this method is called on a closed <code>PreparedStatement</code>8964* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method8965*8966* @since 1.68967*/8968public void setNClob(int parameterIndex, Reader reader)8969throws SQLException{8970throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8971}89728973/**8974* Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number8975* of characters specified by length otherwise a <code>SQLException</code> will be8976* generated when the <code>CallableStatement</code> is executed.8977* This method differs from the <code>setCharacterStream (int, Reader, int)</code> method8978* because it informs the driver that the parameter value should be sent to8979* the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the8980* driver may have to do extra work to determine whether the parameter8981* data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>8982*8983* @param parameterName the name of the parameter to be set8984* @param reader An object that contains the data to set the parameter value to.8985* @param length the number of characters in the parameter data.8986* @throws SQLException if parameterIndex does not correspond to a parameter8987* marker in the SQL statement; if the length specified is less than zero;8988* if the driver does not support national8989* character sets; if the driver can detect that a data conversion8990* error could occur; if a database access error occurs or8991* this method is called on a closed <code>CallableStatement</code>8992* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8993* this method8994* @since 1.68995*/8996public void setNClob(String parameterName, Reader reader, long length)8997throws SQLException{8998throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8999}900090019002/**9003* Sets the designated parameter to a <code>Reader</code> object.9004* This method differs from the <code>setCharacterStream (int, Reader)</code> method9005* because it informs the driver that the parameter value should be sent to9006* the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the9007* driver may have to do extra work to determine whether the parameter9008* data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>9009* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9010* it might be more efficient to use a version of9011* <code>setNClob</code> which takes a length parameter.9012*9013* @param parameterName the name of the parameter9014* @param reader An object that contains the data to set the parameter value to.9015* @throws SQLException if the driver does not support national character sets;9016* if the driver can detect that a data conversion9017* error could occur; if a database access error occurs or9018* this method is called on a closed <code>CallableStatement</code>9019* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9020*9021* @since 1.69022*/9023public void setNClob(String parameterName, Reader reader)9024throws SQLException{9025throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9026}902790289029/**9030* Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number9031* of characters specified by length otherwise a <code>SQLException</code> will be9032* generated when the <code>PreparedStatement</code> is executed.9033* This method differs from the <code>setCharacterStream (int, Reader, int)</code> method9034* because it informs the driver that the parameter value should be sent to9035* the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the9036* driver may have to do extra work to determine whether the parameter9037* data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>9038* @param parameterIndex index of the first parameter is 1, the second is 2, ...9039* @param reader An object that contains the data to set the parameter value to.9040* @param length the number of characters in the parameter data.9041* @throws SQLException if parameterIndex does not correspond to a parameter9042* marker in the SQL statement; if the length specified is less than zero;9043* if the driver does not support national character sets;9044* if the driver can detect that a data conversion9045* error could occur; if a database access error occurs or9046* this method is called on a closed <code>PreparedStatement</code>9047* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9048*9049* @since 1.69050*/9051public void setNClob(int parameterIndex, Reader reader, long length)9052throws SQLException{9053throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9054}905590569057/**9058* Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this to9059a9060* SQL <code>NCLOB</code> value when it sends it to the database.9061* @param parameterIndex of the first parameter is 1, the second is 2, ...9062* @param value the parameter value9063* @throws SQLException if the driver does not support national9064* character sets; if the driver can detect that a data conversion9065* error could occur ; or if a database access error occurs9066* @since 1.69067*/9068public void setNClob(int parameterIndex, NClob value) throws SQLException{9069throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9070}907190729073/**9074* Sets the designated parameter to the given <code>String</code> object.9075* The driver converts this to a SQL <code>NCHAR</code> or9076* <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value9077* (depending on the argument's9078* size relative to the driver's limits on <code>NVARCHAR</code> values)9079* when it sends it to the database.9080*9081* @param parameterIndex of the first parameter is 1, the second is 2, ...9082* @param value the parameter value9083* @throws SQLException if the driver does not support national9084* character sets; if the driver can detect that a data conversion9085* error could occur ; or if a database access error occurs9086* @since 1.69087*/9088public void setNString(int parameterIndex, String value) throws SQLException{9089throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9090}909190929093/**9094* Sets the designated parameter to the given <code>String</code> object.9095* The driver converts this to a SQL <code>NCHAR</code> or9096* <code>NVARCHAR</code> or <code>LONGNVARCHAR</code>9097* @param parameterName the name of the column to be set9098* @param value the parameter value9099* @throws SQLException if the driver does not support national9100* character sets; if the driver can detect that a data conversion9101* error could occur; or if a database access error occurs9102* @since 1.69103*/9104public void setNString(String parameterName, String value)9105throws SQLException{9106throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9107}910891099110/**9111* Sets the designated parameter to a <code>Reader</code> object. The9112* <code>Reader</code> reads the data till end-of-file is reached. The9113* driver does the necessary conversion from Java character format to9114* the national character set in the database.9115* @param parameterIndex of the first parameter is 1, the second is 2, ...9116* @param value the parameter value9117* @param length the number of characters in the parameter data.9118* @throws SQLException if the driver does not support national9119* character sets; if the driver can detect that a data conversion9120* error could occur ; or if a database access error occurs9121* @since 1.69122*/9123public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException{9124throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9125}912691279128/**9129* Sets the designated parameter to a <code>Reader</code> object. The9130* <code>Reader</code> reads the data till end-of-file is reached. The9131* driver does the necessary conversion from Java character format to9132* the national character set in the database.9133* @param parameterName the name of the column to be set9134* @param value the parameter value9135* @param length the number of characters in the parameter data.9136* @throws SQLException if the driver does not support national9137* character sets; if the driver can detect that a data conversion9138* error could occur; or if a database access error occurs9139* @since 1.69140*/9141public void setNCharacterStream(String parameterName, Reader value, long length)9142throws SQLException{9143throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9144}91459146/**9147* Sets the designated parameter to a <code>Reader</code> object. The9148* <code>Reader</code> reads the data till end-of-file is reached. The9149* driver does the necessary conversion from Java character format to9150* the national character set in the database.91519152* <P><B>Note:</B> This stream object can either be a standard9153* Java stream object or your own subclass that implements the9154* standard interface.9155* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9156* it might be more efficient to use a version of9157* <code>setNCharacterStream</code> which takes a length parameter.9158*9159* @param parameterName the name of the parameter9160* @param value the parameter value9161* @throws SQLException if the driver does not support national9162* character sets; if the driver can detect that a data conversion9163* error could occur ; if a database access error occurs; or9164* this method is called on a closed <code>CallableStatement</code>9165* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9166* @since 1.69167*/9168public void setNCharacterStream(String parameterName, Reader value) throws SQLException{9169throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9170}91719172/**9173* Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,9174* using the given <code>Calendar</code> object. The driver uses9175* the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value,9176* which the driver then sends to the database. With a9177* a <code>Calendar</code> object, the driver can calculate the timestamp9178* taking into account a custom timezone. If no9179* <code>Calendar</code> object is specified, the driver uses the default9180* timezone, which is that of the virtual machine running the application.9181*9182* @param parameterName the name of the parameter9183* @param x the parameter value9184* @param cal the <code>Calendar</code> object the driver will use9185* to construct the timestamp9186* @exception SQLException if a database access error occurs or9187* this method is called on a closed <code>CallableStatement</code>9188* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9189* this method9190* @see #getTimestamp9191* @since 1.49192*/9193public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)9194throws SQLException{9195throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9196}91979198/**9199* Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number9200* of characters specified by length otherwise a <code>SQLException</code> will be9201* generated when the <code>CallableStatement</code> is executed.9202* This method differs from the <code>setCharacterStream (int, Reader, int)</code> method9203* because it informs the driver that the parameter value should be sent to9204* the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the9205* driver may have to do extra work to determine whether the parameter9206* data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>9207* @param parameterName the name of the parameter to be set9208* @param reader An object that contains the data to set the parameter value to.9209* @param length the number of characters in the parameter data.9210* @throws SQLException if parameterIndex does not correspond to a parameter9211* marker in the SQL statement; if the length specified is less than zero;9212* a database access error occurs or9213* this method is called on a closed <code>CallableStatement</code>9214* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9215* this method9216*9217* @since 1.69218*/9219public void setClob(String parameterName, Reader reader, long length)9220throws SQLException{9221throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9222}922392249225/**9226* Sets the designated parameter to the given <code>java.sql.Clob</code> object.9227* The driver converts this to an SQL <code>CLOB</code> value when it9228* sends it to the database.9229*9230* @param parameterName the name of the parameter9231* @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value9232* @exception SQLException if a database access error occurs or9233* this method is called on a closed <code>CallableStatement</code>9234* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9235* this method9236* @since 1.69237*/9238public void setClob (String parameterName, Clob x) throws SQLException{9239throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9240}924192429243/**9244* Sets the designated parameter to a <code>Reader</code> object.9245* This method differs from the <code>setCharacterStream (int, Reader)</code> method9246* because it informs the driver that the parameter value should be sent to9247* the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the9248* driver may have to do extra work to determine whether the parameter9249* data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>9250*9251* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9252* it might be more efficient to use a version of9253* <code>setClob</code> which takes a length parameter.9254*9255* @param parameterName the name of the parameter9256* @param reader An object that contains the data to set the parameter value to.9257* @throws SQLException if a database access error occurs or this method is called on9258* a closed <code>CallableStatement</code>9259*9260* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9261* @since 1.69262*/9263public void setClob(String parameterName, Reader reader)9264throws SQLException{9265throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9266}926792689269/**9270* Sets the designated parameter to the given <code>java.sql.Date</code> value9271* using the default time zone of the virtual machine that is running9272* the application.9273* The driver converts this9274* to an SQL <code>DATE</code> value when it sends it to the database.9275*9276* @param parameterName the name of the parameter9277* @param x the parameter value9278* @exception SQLException if a database access error occurs or9279* this method is called on a closed <code>CallableStatement</code>9280* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9281* this method9282* @see #getDate9283* @since 1.49284*/9285public void setDate(String parameterName, java.sql.Date x)9286throws SQLException{9287throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9288}928992909291/**9292* Sets the designated parameter to the given <code>java.sql.Date</code> value,9293* using the given <code>Calendar</code> object. The driver uses9294* the <code>Calendar</code> object to construct an SQL <code>DATE</code> value,9295* which the driver then sends to the database. With a9296* a <code>Calendar</code> object, the driver can calculate the date9297* taking into account a custom timezone. If no9298* <code>Calendar</code> object is specified, the driver uses the default9299* timezone, which is that of the virtual machine running the application.9300*9301* @param parameterName the name of the parameter9302* @param x the parameter value9303* @param cal the <code>Calendar</code> object the driver will use9304* to construct the date9305* @exception SQLException if a database access error occurs or9306* this method is called on a closed <code>CallableStatement</code>9307* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9308* this method9309* @see #getDate9310* @since 1.49311*/9312public void setDate(String parameterName, java.sql.Date x, Calendar cal)9313throws SQLException{9314throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9315}931693179318/**9319* Sets the designated parameter to the given <code>java.sql.Time</code> value.9320* The driver converts this9321* to an SQL <code>TIME</code> value when it sends it to the database.9322*9323* @param parameterName the name of the parameter9324* @param x the parameter value9325* @exception SQLException if a database access error occurs or9326* this method is called on a closed <code>CallableStatement</code>9327* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9328* this method9329* @see #getTime9330* @since 1.49331*/9332public void setTime(String parameterName, java.sql.Time x)9333throws SQLException{9334throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9335}933693379338/**9339* Sets the designated parameter to the given <code>java.sql.Time</code> value,9340* using the given <code>Calendar</code> object. The driver uses9341* the <code>Calendar</code> object to construct an SQL <code>TIME</code> value,9342* which the driver then sends to the database. With a9343* a <code>Calendar</code> object, the driver can calculate the time9344* taking into account a custom timezone. If no9345* <code>Calendar</code> object is specified, the driver uses the default9346* timezone, which is that of the virtual machine running the application.9347*9348* @param parameterName the name of the parameter9349* @param x the parameter value9350* @param cal the <code>Calendar</code> object the driver will use9351* to construct the time9352* @exception SQLException if a database access error occurs or9353* this method is called on a closed <code>CallableStatement</code>9354* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9355* this method9356* @see #getTime9357* @since 1.49358*/9359public void setTime(String parameterName, java.sql.Time x, Calendar cal)9360throws SQLException{9361throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9362}93639364/**9365* Sets the designated parameter to a <code>Reader</code> object.9366* This method differs from the <code>setCharacterStream (int, Reader)</code> method9367* because it informs the driver that the parameter value should be sent to9368* the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the9369* driver may have to do extra work to determine whether the parameter9370* data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>9371*9372* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9373* it might be more efficient to use a version of9374* <code>setClob</code> which takes a length parameter.9375*9376* @param parameterIndex index of the first parameter is 1, the second is 2, ...9377* @param reader An object that contains the data to set the parameter value to.9378* @throws SQLException if a database access error occurs, this method is called on9379* a closed <code>PreparedStatement</code>or if parameterIndex does not correspond to a parameter9380* marker in the SQL statement9381*9382* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9383* @since 1.69384*/9385public void setClob(int parameterIndex, Reader reader)9386throws SQLException{9387throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9388}93899390/**9391* Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number9392* of characters specified by length otherwise a <code>SQLException</code> will be9393* generated when the <code>PreparedStatement</code> is executed.9394*This method differs from the <code>setCharacterStream (int, Reader, int)</code> method9395* because it informs the driver that the parameter value should be sent to9396* the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the9397* driver may have to do extra work to determine whether the parameter9398* data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>9399* @param parameterIndex index of the first parameter is 1, the second is 2, ...9400* @param reader An object that contains the data to set the parameter value to.9401* @param length the number of characters in the parameter data.9402* @throws SQLException if a database access error occurs, this method is called on9403* a closed <code>PreparedStatement</code>, if parameterIndex does not correspond to a parameter9404* marker in the SQL statement, or if the length specified is less than zero.9405*9406* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9407* @since 1.69408*/9409public void setClob(int parameterIndex, Reader reader, long length)9410throws SQLException{9411throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9412}941394149415/**9416* Sets the designated parameter to a <code>InputStream</code> object. The inputstream must contain the number9417* of characters specified by length otherwise a <code>SQLException</code> will be9418* generated when the <code>PreparedStatement</code> is executed.9419* This method differs from the <code>setBinaryStream (int, InputStream, int)</code>9420* method because it informs the driver that the parameter value should be9421* sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used,9422* the driver may have to do extra work to determine whether the parameter9423* data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>9424* @param parameterIndex index of the first parameter is 1,9425* the second is 2, ...9426* @param inputStream An object that contains the data to set the parameter9427* value to.9428* @param length the number of bytes in the parameter data.9429* @throws SQLException if a database access error occurs,9430* this method is called on a closed <code>PreparedStatement</code>,9431* if parameterIndex does not correspond9432* to a parameter marker in the SQL statement, if the length specified9433* is less than zero or if the number of bytes in the inputstream does not match9434* the specified length.9435* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9436*9437* @since 1.69438*/9439public void setBlob(int parameterIndex, InputStream inputStream, long length)9440throws SQLException{9441throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9442}944394449445/**9446* Sets the designated parameter to a <code>InputStream</code> object.9447* This method differs from the <code>setBinaryStream (int, InputStream)</code>9448* method because it informs the driver that the parameter value should be9449* sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used,9450* the driver may have to do extra work to determine whether the parameter9451* data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>9452*9453* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9454* it might be more efficient to use a version of9455* <code>setBlob</code> which takes a length parameter.9456*9457* @param parameterIndex index of the first parameter is 1,9458* the second is 2, ...9459* @param inputStream An object that contains the data to set the parameter9460* value to.9461* @throws SQLException if a database access error occurs,9462* this method is called on a closed <code>PreparedStatement</code> or9463* if parameterIndex does not correspond9464* to a parameter marker in the SQL statement,9465* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9466*9467* @since 1.69468*/9469public void setBlob(int parameterIndex, InputStream inputStream)9470throws SQLException{9471throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9472}947394749475/**9476* Sets the designated parameter to a <code>InputStream</code> object. The <code>inputstream</code> must contain the number9477* of characters specified by length, otherwise a <code>SQLException</code> will be9478* generated when the <code>CallableStatement</code> is executed.9479* This method differs from the <code>setBinaryStream (int, InputStream, int)</code>9480* method because it informs the driver that the parameter value should be9481* sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used,9482* the driver may have to do extra work to determine whether the parameter9483* data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>9484*9485* @param parameterName the name of the parameter to be set9486* the second is 2, ...9487*9488* @param inputStream An object that contains the data to set the parameter9489* value to.9490* @param length the number of bytes in the parameter data.9491* @throws SQLException if parameterIndex does not correspond9492* to a parameter marker in the SQL statement, or if the length specified9493* is less than zero; if the number of bytes in the inputstream does not match9494* the specified length; if a database access error occurs or9495* this method is called on a closed <code>CallableStatement</code>9496* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9497* this method9498*9499* @since 1.69500*/9501public void setBlob(String parameterName, InputStream inputStream, long length)9502throws SQLException{9503throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9504}950595069507/**9508* Sets the designated parameter to the given <code>java.sql.Blob</code> object.9509* The driver converts this to an SQL <code>BLOB</code> value when it9510* sends it to the database.9511*9512* @param parameterName the name of the parameter9513* @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value9514* @exception SQLException if a database access error occurs or9515* this method is called on a closed <code>CallableStatement</code>9516* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9517* this method9518* @since 1.69519*/9520public void setBlob (String parameterName, Blob x) throws SQLException{9521throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9522}952395249525/**9526* Sets the designated parameter to a <code>InputStream</code> object.9527* This method differs from the <code>setBinaryStream (int, InputStream)</code>9528* method because it informs the driver that the parameter value should be9529* sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used,9530* the driver may have to do extra work to determine whether the parameter9531* data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>9532*9533* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9534* it might be more efficient to use a version of9535* <code>setBlob</code> which takes a length parameter.9536*9537* @param parameterName the name of the parameter9538* @param inputStream An object that contains the data to set the parameter9539* value to.9540* @throws SQLException if a database access error occurs or9541* this method is called on a closed <code>CallableStatement</code>9542* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9543*9544* @since 1.69545*/9546public void setBlob(String parameterName, InputStream inputStream)9547throws SQLException{9548throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9549}95509551/**9552* Sets the value of the designated parameter with the given object. The second9553* argument must be an object type; for integral values, the9554* <code>java.lang</code> equivalent objects should be used.9555*9556* <p>The given Java object will be converted to the given targetSqlType9557* before being sent to the database.9558*9559* If the object has a custom mapping (is of a class implementing the9560* interface <code>SQLData</code>),9561* the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it9562* to the SQL data stream.9563* If, on the other hand, the object is of a class implementing9564* <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>,9565* <code>Struct</code>, <code>java.net.URL</code>,9566* or <code>Array</code>, the driver should pass it to the database as a9567* value of the corresponding SQL type.9568* <P>9569* Note that this method may be used to pass datatabase-9570* specific abstract data types.9571*9572* @param parameterName the name of the parameter9573* @param x the object containing the input parameter value9574* @param targetSqlType the SQL type (as defined in java.sql.Types) to be9575* sent to the database. The scale argument may further qualify this type.9576* @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,9577* this is the number of digits after the decimal point. For all other9578* types, this value will be ignored.9579* @exception SQLException if a database access error occurs or9580* this method is called on a closed <code>CallableStatement</code>9581* @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is9582* a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,9583* <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,9584* <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,9585* <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>9586* or <code>STRUCT</code> data type and the JDBC driver does not support9587* this data type9588* @see Types9589* @see #getObject9590* @since 1.49591*/9592public void setObject(String parameterName, Object x, int targetSqlType, int scale)9593throws SQLException{9594throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9595}9596959795989599/**9600* Sets the value of the designated parameter with the given object.9601* This method is like the method <code>setObject</code>9602* above, except that it assumes a scale of zero.9603*9604* @param parameterName the name of the parameter9605* @param x the object containing the input parameter value9606* @param targetSqlType the SQL type (as defined in java.sql.Types) to be9607* sent to the database9608* @exception SQLException if a database access error occurs or9609* this method is called on a closed <code>CallableStatement</code>9610* @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is9611* a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,9612* <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,9613* <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,9614* <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>9615* or <code>STRUCT</code> data type and the JDBC driver does not support9616* this data type9617* @see #getObject9618* @since 1.49619*/9620public void setObject(String parameterName, Object x, int targetSqlType)9621throws SQLException{9622throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9623}962496259626/**9627* Sets the value of the designated parameter with the given object.9628* The second parameter must be of type <code>Object</code>; therefore, the9629* <code>java.lang</code> equivalent objects should be used for built-in types.9630*9631* <p>The JDBC specification specifies a standard mapping from9632* Java <code>Object</code> types to SQL types. The given argument9633* will be converted to the corresponding SQL type before being9634* sent to the database.9635*9636* <p>Note that this method may be used to pass datatabase-9637* specific abstract data types, by using a driver-specific Java9638* type.9639*9640* If the object is of a class implementing the interface <code>SQLData</code>,9641* the JDBC driver should call the method <code>SQLData.writeSQL</code>9642* to write it to the SQL data stream.9643* If, on the other hand, the object is of a class implementing9644* <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>,9645* <code>Struct</code>, <code>java.net.URL</code>,9646* or <code>Array</code>, the driver should pass it to the database as a9647* value of the corresponding SQL type.9648* <P>9649* This method throws an exception if there is an ambiguity, for example, if the9650* object is of a class implementing more than one of the interfaces named above.9651*9652* @param parameterName the name of the parameter9653* @param x the object containing the input parameter value9654* @exception SQLException if a database access error occurs,9655* this method is called on a closed <code>CallableStatement</code> or if the given9656* <code>Object</code> parameter is ambiguous9657* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9658* this method9659* @see #getObject9660* @since 1.49661*/9662public void setObject(String parameterName, Object x) throws SQLException{9663throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9664}96659666/**9667* Sets the designated parameter to the given input stream, which will have9668* the specified number of bytes.9669* When a very large ASCII value is input to a <code>LONGVARCHAR</code>9670* parameter, it may be more practical to send it via a9671* <code>java.io.InputStream</code>. Data will be read from the stream9672* as needed until end-of-file is reached. The JDBC driver will9673* do any necessary conversion from ASCII to the database char format.9674*9675* <P><B>Note:</B> This stream object can either be a standard9676* Java stream object or your own subclass that implements the9677* standard interface.9678*9679* @param parameterName the name of the parameter9680* @param x the Java input stream that contains the ASCII parameter value9681* @param length the number of bytes in the stream9682* @exception SQLException if a database access error occurs or9683* this method is called on a closed <code>CallableStatement</code>9684* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9685* this method9686* @since 1.49687*/9688public void setAsciiStream(String parameterName, java.io.InputStream x, int length)9689throws SQLException{9690throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9691}969296939694/**9695* Sets the designated parameter to the given input stream, which will have9696* the specified number of bytes.9697* When a very large binary value is input to a <code>LONGVARBINARY</code>9698* parameter, it may be more practical to send it via a9699* <code>java.io.InputStream</code> object. The data will be read from the stream9700* as needed until end-of-file is reached.9701*9702* <P><B>Note:</B> This stream object can either be a standard9703* Java stream object or your own subclass that implements the9704* standard interface.9705*9706* @param parameterName the name of the parameter9707* @param x the java input stream which contains the binary parameter value9708* @param length the number of bytes in the stream9709* @exception SQLException if a database access error occurs or9710* this method is called on a closed <code>CallableStatement</code>9711* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9712* this method9713* @since 1.49714*/9715public void setBinaryStream(String parameterName, java.io.InputStream x,9716int length) throws SQLException{9717throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9718}971997209721/**9722* Sets the designated parameter to the given <code>Reader</code>9723* object, which is the given number of characters long.9724* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>9725* parameter, it may be more practical to send it via a9726* <code>java.io.Reader</code> object. The data will be read from the stream9727* as needed until end-of-file is reached. The JDBC driver will9728* do any necessary conversion from UNICODE to the database char format.9729*9730* <P><B>Note:</B> This stream object can either be a standard9731* Java stream object or your own subclass that implements the9732* standard interface.9733*9734* @param parameterName the name of the parameter9735* @param reader the <code>java.io.Reader</code> object that9736* contains the UNICODE data used as the designated parameter9737* @param length the number of characters in the stream9738* @exception SQLException if a database access error occurs or9739* this method is called on a closed <code>CallableStatement</code>9740* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9741* this method9742* @since 1.49743*/9744public void setCharacterStream(String parameterName,9745java.io.Reader reader,9746int length) throws SQLException{9747throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9748}974997509751/**9752* Sets the designated parameter to the given input stream.9753* When a very large ASCII value is input to a <code>LONGVARCHAR</code>9754* parameter, it may be more practical to send it via a9755* <code>java.io.InputStream</code>. Data will be read from the stream9756* as needed until end-of-file is reached. The JDBC driver will9757* do any necessary conversion from ASCII to the database char format.9758*9759* <P><B>Note:</B> This stream object can either be a standard9760* Java stream object or your own subclass that implements the9761* standard interface.9762* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9763* it might be more efficient to use a version of9764* <code>setAsciiStream</code> which takes a length parameter.9765*9766* @param parameterName the name of the parameter9767* @param x the Java input stream that contains the ASCII parameter value9768* @exception SQLException if a database access error occurs or9769* this method is called on a closed <code>CallableStatement</code>9770* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9771* @since 1.69772*/9773public void setAsciiStream(String parameterName, java.io.InputStream x)9774throws SQLException{9775throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9776}977797789779/**9780* Sets the designated parameter to the given input stream.9781* When a very large binary value is input to a <code>LONGVARBINARY</code>9782* parameter, it may be more practical to send it via a9783* <code>java.io.InputStream</code> object. The data will be read from the9784* stream as needed until end-of-file is reached.9785*9786* <P><B>Note:</B> This stream object can either be a standard9787* Java stream object or your own subclass that implements the9788* standard interface.9789* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9790* it might be more efficient to use a version of9791* <code>setBinaryStream</code> which takes a length parameter.9792*9793* @param parameterName the name of the parameter9794* @param x the java input stream which contains the binary parameter value9795* @exception SQLException if a database access error occurs or9796* this method is called on a closed <code>CallableStatement</code>9797* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9798* @since 1.69799*/9800public void setBinaryStream(String parameterName, java.io.InputStream x)9801throws SQLException{9802throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9803}9804980598069807/**9808* Sets the designated parameter to the given <code>Reader</code>9809* object.9810* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>9811* parameter, it may be more practical to send it via a9812* <code>java.io.Reader</code> object. The data will be read from the stream9813* as needed until end-of-file is reached. The JDBC driver will9814* do any necessary conversion from UNICODE to the database char format.9815*9816* <P><B>Note:</B> This stream object can either be a standard9817* Java stream object or your own subclass that implements the9818* standard interface.9819* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9820* it might be more efficient to use a version of9821* <code>setCharacterStream</code> which takes a length parameter.9822*9823* @param parameterName the name of the parameter9824* @param reader the <code>java.io.Reader</code> object that contains the9825* Unicode data9826* @exception SQLException if a database access error occurs or9827* this method is called on a closed <code>CallableStatement</code>9828* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9829* @since 1.69830*/9831public void setCharacterStream(String parameterName,9832java.io.Reader reader) throws SQLException{9833throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9834}98359836/**9837* Sets the designated parameter to the given9838* <code>java.math.BigDecimal</code> value.9839* The driver converts this to an SQL <code>NUMERIC</code> value when9840* it sends it to the database.9841*9842* @param parameterName the name of the parameter9843* @param x the parameter value9844* @exception SQLException if a database access error occurs or9845* this method is called on a closed <code>CallableStatement</code>9846* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9847* this method9848* @see #getBigDecimal9849* @since 1.49850*/9851public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{9852throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9853}9854985598569857/**9858* Sets the designated parameter to the given Java <code>String</code> value.9859* The driver converts this9860* to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value9861* (depending on the argument's9862* size relative to the driver's limits on <code>VARCHAR</code> values)9863* when it sends it to the database.9864*9865* @param parameterName the name of the parameter9866* @param x the parameter value9867* @exception SQLException if a database access error occurs or9868* this method is called on a closed <code>CallableStatement</code>9869* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9870* this method9871* @see #getString9872* @since 1.49873*/9874public void setString(String parameterName, String x) throws SQLException{9875throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9876}9877987898799880/**9881* Sets the designated parameter to the given Java array of bytes.9882* The driver converts this to an SQL <code>VARBINARY</code> or9883* <code>LONGVARBINARY</code> (depending on the argument's size relative9884* to the driver's limits on <code>VARBINARY</code> values) when it sends9885* it to the database.9886*9887* @param parameterName the name of the parameter9888* @param x the parameter value9889* @exception SQLException if a database access error occurs or9890* this method is called on a closed <code>CallableStatement</code>9891* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9892* this method9893* @see #getBytes9894* @since 1.49895*/9896public void setBytes(String parameterName, byte x[]) throws SQLException{9897throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9898}9899990099019902/**9903* Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.9904* The driver9905* converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the9906* database.9907*9908* @param parameterName the name of the parameter9909* @param x the parameter value9910* @exception SQLException if a database access error occurs or9911* this method is called on a closed <code>CallableStatement</code>9912* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9913* this method9914* @see #getTimestamp9915* @since 1.49916*/9917public void setTimestamp(String parameterName, java.sql.Timestamp x)9918throws SQLException{9919throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9920}99219922/**9923* Sets the designated parameter to SQL <code>NULL</code>.9924*9925* <P><B>Note:</B> You must specify the parameter's SQL type.9926*9927* @param parameterName the name of the parameter9928* @param sqlType the SQL type code defined in <code>java.sql.Types</code>9929* @exception SQLException if a database access error occurs or9930* this method is called on a closed <code>CallableStatement</code>9931* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9932* this method9933* @since 1.49934*/9935public void setNull(String parameterName, int sqlType) throws SQLException {9936throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9937}993899399940/**9941* Sets the designated parameter to SQL <code>NULL</code>.9942* This version of the method <code>setNull</code> should9943* be used for user-defined types and REF type parameters. Examples9944* of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and9945* named array types.9946*9947* <P><B>Note:</B> To be portable, applications must give the9948* SQL type code and the fully-qualified SQL type name when specifying9949* a NULL user-defined or REF parameter. In the case of a user-defined type9950* the name is the type name of the parameter itself. For a REF9951* parameter, the name is the type name of the referenced type. If9952* a JDBC driver does not need the type code or type name information,9953* it may ignore it.9954*9955* Although it is intended for user-defined and Ref parameters,9956* this method may be used to set a null parameter of any JDBC type.9957* If the parameter does not have a user-defined or REF type, the given9958* typeName is ignored.9959*9960*9961* @param parameterName the name of the parameter9962* @param sqlType a value from <code>java.sql.Types</code>9963* @param typeName the fully-qualified name of an SQL user-defined type;9964* ignored if the parameter is not a user-defined type or9965* SQL <code>REF</code> value9966* @exception SQLException if a database access error occurs or9967* this method is called on a closed <code>CallableStatement</code>9968* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9969* this method9970* @since 1.49971*/9972public void setNull (String parameterName, int sqlType, String typeName)9973throws SQLException{9974throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9975}9976997799789979/**9980* Sets the designated parameter to the given Java <code>boolean</code> value.9981* The driver converts this9982* to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database.9983*9984* @param parameterName the name of the parameter9985* @param x the parameter value9986* @exception SQLException if a database access error occurs or9987* this method is called on a closed <code>CallableStatement</code>9988* @see #getBoolean9989* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9990* this method9991* @since 1.49992*/9993public void setBoolean(String parameterName, boolean x) throws SQLException{9994throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9995}9996999799989999/**10000* Sets the designated parameter to the given Java <code>byte</code> value.10001* The driver converts this10002* to an SQL <code>TINYINT</code> value when it sends it to the database.10003*10004* @param parameterName the name of the parameter10005* @param x the parameter value10006* @exception SQLException if a database access error occurs or10007* this method is called on a closed <code>CallableStatement</code>10008* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10009* this method10010* @see #getByte10011* @since 1.410012*/10013public void setByte(String parameterName, byte x) throws SQLException{10014throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10015}10016100171001810019/**10020* Sets the designated parameter to the given Java <code>short</code> value.10021* The driver converts this10022* to an SQL <code>SMALLINT</code> value when it sends it to the database.10023*10024* @param parameterName the name of the parameter10025* @param x the parameter value10026* @exception SQLException if a database access error occurs or10027* this method is called on a closed <code>CallableStatement</code>10028* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10029* this method10030* @see #getShort10031* @since 1.410032*/10033public void setShort(String parameterName, short x) throws SQLException{10034throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10035}100361003710038/**10039* Sets the designated parameter to the given Java <code>int</code> value.10040* The driver converts this10041* to an SQL <code>INTEGER</code> value when it sends it to the database.10042*10043* @param parameterName the name of the parameter10044* @param x the parameter value10045* @exception SQLException if a database access error occurs or10046* this method is called on a closed <code>CallableStatement</code>10047* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10048* this method10049* @see #getInt10050* @since 1.410051*/10052public void setInt(String parameterName, int x) throws SQLException{10053throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10054}100551005610057/**10058* Sets the designated parameter to the given Java <code>long</code> value.10059* The driver converts this10060* to an SQL <code>BIGINT</code> value when it sends it to the database.10061*10062* @param parameterName the name of the parameter10063* @param x the parameter value10064* @exception SQLException if a database access error occurs or10065* this method is called on a closed <code>CallableStatement</code>10066* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10067* this method10068* @see #getLong10069* @since 1.410070*/10071public void setLong(String parameterName, long x) throws SQLException{10072throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10073}100741007510076/**10077* Sets the designated parameter to the given Java <code>float</code> value.10078* The driver converts this10079* to an SQL <code>FLOAT</code> value when it sends it to the database.10080*10081* @param parameterName the name of the parameter10082* @param x the parameter value10083* @exception SQLException if a database access error occurs or10084* this method is called on a closed <code>CallableStatement</code>10085* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10086* this method10087* @see #getFloat10088* @since 1.410089*/10090public void setFloat(String parameterName, float x) throws SQLException{10091throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10092}100931009410095/**10096* Sets the designated parameter to the given Java <code>double</code> value.10097* The driver converts this10098* to an SQL <code>DOUBLE</code> value when it sends it to the database.10099*10100* @param parameterName the name of the parameter10101* @param x the parameter value10102* @exception SQLException if a database access error occurs or10103* this method is called on a closed <code>CallableStatement</code>10104* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10105* this method10106* @see #getDouble10107* @since 1.410108*/10109public void setDouble(String parameterName, double x) throws SQLException{10110throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10111}1011210113/**10114* This method re populates the resBundle10115* during the deserialization process10116*10117*/10118private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {10119// Default state initialization happens here10120ois.defaultReadObject();10121// Initialization of transient Res Bundle happens here .10122try {10123resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();10124} catch(IOException ioe) {10125throw new RuntimeException(ioe);10126}1012710128}1012910130//------------------------- JDBC 4.1 -----------------------------------10131public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {10132throw new SQLFeatureNotSupportedException("Not supported yet.");10133}1013410135public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {10136throw new SQLFeatureNotSupportedException("Not supported yet.");10137}1013810139static final long serialVersionUID =1884577171200622428L;10140}101411014210143