Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/rowset/CachedRowSetImpl.java
38919 views
/*1* Copyright (c) 2003, 2013, 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.*;3334import javax.sql.rowset.*;35import javax.sql.rowset.spi.*;36import javax.sql.rowset.serial.*;37import com.sun.rowset.internal.*;38import com.sun.rowset.providers.*;39import sun.reflect.misc.ReflectUtil;4041/**42* The standard implementation of the <code>CachedRowSet</code> interface.43*44* See interface definition for full behavior and implementation requirements.45* This reference implementation has made provision for a one-to-one write back46* facility and it is curremtly be possible to change the peristence provider47* during the life-time of any CachedRowSetImpl.48*49* @author Jonathan Bruce, Amit Handa50*/5152public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetInternal, Serializable, Cloneable, CachedRowSet {5354/**55* The <code>SyncProvider</code> used by the CachedRowSet56*/57private SyncProvider provider;5859/**60* The <code>RowSetReaderImpl</code> object that is the reader61* for this rowset. The method <code>execute</code> uses this62* reader as part of its implementation.63* @serial64*/65private RowSetReader rowSetReader;6667/**68* The <code>RowSetWriterImpl</code> object that is the writer69* for this rowset. The method <code>acceptChanges</code> uses70* this writer as part of its implementation.71* @serial72*/73private RowSetWriter rowSetWriter;7475/**76* The <code>Connection</code> object that connects with this77* <code>CachedRowSetImpl</code> object's current underlying data source.78*/79private transient Connection conn;8081/**82* The <code>ResultSetMetaData</code> object that contains information83* about the columns in the <code>ResultSet</code> object that is the84* current source of data for this <code>CachedRowSetImpl</code> object.85*/86private transient ResultSetMetaData RSMD;8788/**89* The <code>RowSetMetaData</code> object that contains information about90* the columns in this <code>CachedRowSetImpl</code> object.91* @serial92*/93private RowSetMetaDataImpl RowSetMD;9495// Properties of this RowSet9697/**98* An array containing the columns in this <code>CachedRowSetImpl</code>99* object that form a unique identifier for a row. This array100* is used by the writer.101* @serial102*/103private int keyCols[];104105/**106* The name of the table in the underlying database to which updates107* should be written. This name is needed because most drivers108* do not return this information in a <code>ResultSetMetaData</code>109* object.110* @serial111*/112private String tableName;113114/**115* A <code>Vector</code> object containing the <code>Row</code>116* objects that comprise this <code>CachedRowSetImpl</code> object.117* @serial118*/119private Vector<Object> rvh;120121/**122* The current position of the cursor in this <code>CachedRowSetImpl</code>123* object.124* @serial125*/126private int cursorPos;127128/**129* The current position of the cursor in this <code>CachedRowSetImpl</code>130* object not counting rows that have been deleted, if any.131* <P>132* For example, suppose that the cursor is on the last row of a rowset133* that started with five rows and subsequently had the second and third134* rows deleted. The <code>absolutePos</code> would be <code>3</code>,135* whereas the <code>cursorPos</code> would be <code>5</code>.136* @serial137*/138private int absolutePos;139140/**141* The number of deleted rows currently in this <code>CachedRowSetImpl</code>142* object.143* @serial144*/145private int numDeleted;146147/**148* The total number of rows currently in this <code>CachedRowSetImpl</code>149* object.150* @serial151*/152private int numRows;153154/**155* A special row used for constructing a new row. A new156* row is constructed by using <code>ResultSet.updateXXX</code>157* methods to insert column values into the insert row.158* @serial159*/160private InsertRow insertRow;161162/**163* A <code>boolean</code> indicating whether the cursor is164* currently on the insert row.165* @serial166*/167private boolean onInsertRow;168169/**170* The field that temporarily holds the last position of the171* cursor before it moved to the insert row, thus preserving172* the number of the current row to which the cursor may return.173* @serial174*/175private int currentRow;176177/**178* A <code>boolean</code> indicating whether the last value179* returned was an SQL <code>NULL</code>.180* @serial181*/182private boolean lastValueNull;183184/**185* A <code>SQLWarning</code> which logs on the warnings186*/187private SQLWarning sqlwarn;188189/**190* Used to track match column for JoinRowSet consumption191*/192private String strMatchColumn ="";193194/**195* Used to track match column for JoinRowSet consumption196*/197private int iMatchColumn = -1;198199/**200* A <code>RowSetWarning</code> which logs on the warnings201*/202private RowSetWarning rowsetWarning;203204/**205* The default SyncProvider for the RI CachedRowSetImpl206*/207private String DEFAULT_SYNC_PROVIDER = "com.sun.rowset.providers.RIOptimisticProvider";208209/**210* The boolean variable indicating locatorsUpdateValue211*/212private boolean dbmslocatorsUpdateCopy;213214/**215* The <code>ResultSet</code> object that is used to maintain the data when216* a ResultSet and start position are passed as parameters to the populate function217*/218private transient ResultSet resultSet;219220/**221* The integer value indicating the end position in the ResultSetwhere the picking222* up of rows for populating a CachedRowSet object was left off.223*/224private int endPos;225226/**227* The integer value indicating the end position in the ResultSetwhere the picking228* up of rows for populating a CachedRowSet object was left off.229*/230private int prevEndPos;231232/**233* The integer value indicating the position in the ResultSet, to populate the234* CachedRowSet object.235*/236private int startPos;237238/**239* The integer value indicating the position from where the page prior to this240* was populated.241*/242private int startPrev;243244/**245* The integer value indicating size of the page.246*/247private int pageSize;248249/**250* The integer value indicating number of rows that have been processed so far.251* Used for checking whether maxRows has been reached or not.252*/253private int maxRowsreached;254/**255* The boolean value when true signifies that pages are still to follow and a256* false value indicates that this is the last page.257*/258private boolean pagenotend = true;259260/**261* The boolean value indicating whether this is the first page or not.262*/263private boolean onFirstPage;264265/**266* The boolean value indicating whether this is the last page or not.267*/268private boolean onLastPage;269270/**271* The integer value indicating how many times the populate function has been called.272*/273private int populatecallcount;274275/**276* The integer value indicating the total number of rows to be processed in the277* ResultSet object passed to the populate function.278*/279private int totalRows;280281/**282* The boolean value indicating how the CahedRowSet object has been populated for283* paging purpose. True indicates that connection parameter is passed.284*/285private boolean callWithCon;286287/**288* CachedRowSet reader object to read the data from the ResultSet when a connection289* parameter is passed to populate the CachedRowSet object for paging.290*/291private CachedRowSetReader crsReader;292293/**294* The Vector holding the Match Columns295*/296private Vector<Integer> iMatchColumns;297298/**299* The Vector that will hold the Match Column names.300*/301private Vector<String> strMatchColumns;302303/**304* Trigger that indicates whether the active SyncProvider is exposes the305* additional TransactionalWriter method306*/307private boolean tXWriter = false;308309/**310* The field object for a transactional RowSet writer311*/312private TransactionalWriter tWriter = null;313314protected transient JdbcRowSetResourceBundle resBundle;315316private boolean updateOnInsert;317318319320/**321* Constructs a new default <code>CachedRowSetImpl</code> object with322* the capacity to hold 100 rows. This new object has no metadata323* and has the following default values:324* <pre>325* onInsertRow = false326* insertRow = null327* cursorPos = 0328* numRows = 0329* showDeleted = false330* queryTimeout = 0331* maxRows = 0332* maxFieldSize = 0333* rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE334* concurrency = ResultSet.CONCUR_UPDATABLE335* readOnly = false336* isolation = Connection.TRANSACTION_READ_COMMITTED337* escapeProcessing = true338* onInsertRow = false339* insertRow = null340* cursorPos = 0341* absolutePos = 0342* numRows = 0343* </pre>344* A <code>CachedRowSetImpl</code> object is configured to use the default345* <code>RIOptimisticProvider</code> implementation to provide connectivity346* and synchronization capabilities to the set data source.347* <P>348* @throws SQLException if an error occurs349*/350public CachedRowSetImpl() throws SQLException {351352try {353resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();354} catch(IOException ioe) {355throw new RuntimeException(ioe);356}357358// set the Reader, this maybe overridden latter359provider =360SyncFactory.getInstance(DEFAULT_SYNC_PROVIDER);361362if (!(provider instanceof RIOptimisticProvider)) {363throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidp").toString());364}365366rowSetReader = (CachedRowSetReader)provider.getRowSetReader();367rowSetWriter = (CachedRowSetWriter)provider.getRowSetWriter();368369// allocate the parameters collection370initParams();371372initContainer();373374// set up some default values375initProperties();376377// insert row setup378onInsertRow = false;379insertRow = null;380381// set the warninings382sqlwarn = new SQLWarning();383rowsetWarning = new RowSetWarning();384385}386387/**388* Provides a <code>CachedRowSetImpl</code> instance with the same default properties as389* as the zero parameter constructor.390* <pre>391* onInsertRow = false392* insertRow = null393* cursorPos = 0394* numRows = 0395* showDeleted = false396* queryTimeout = 0397* maxRows = 0398* maxFieldSize = 0399* rowSetType = ResultSet.TYPE_SCROLL_INSENSITIVE400* concurrency = ResultSet.CONCUR_UPDATABLE401* readOnly = false402* isolation = Connection.TRANSACTION_READ_COMMITTED403* escapeProcessing = true404* onInsertRow = false405* insertRow = null406* cursorPos = 0407* absolutePos = 0408* numRows = 0409* </pre>410*411* However, applications will have the means to specify at runtime the412* desired <code>SyncProvider</code> object.413* <p>414* For example, creating a <code>CachedRowSetImpl</code> object as follows ensures415* that a it is established with the <code>com.foo.provider.Impl</code> synchronization416* implementation providing the synchronization mechanism for this disconnected417* <code>RowSet</code> object.418* <pre>419* Hashtable env = new Hashtable();420* env.put(javax.sql.rowset.spi.SyncFactory.ROWSET_PROVIDER_NAME,421* "com.foo.provider.Impl");422* CachedRowSetImpl crs = new CachedRowSet(env);423* </pre>424* <p>425* Calling this constructor with a <code>null</code> parameter will426* cause the <code>SyncFactory</code> to provide the reference427* optimistic provider <code>com.sun.rowset.providers.RIOptimisticProvider</code>.428* <p>429* In addition, the following properties can be associated with the430* provider to assist in determining the choice of the synchronizaton431* provider such as:432* <ul>433* <li><code>ROWSET_SYNC_PROVIDER</code> - the property specifying the the434* <code>SyncProvider</code> class name to be instantiated by the435* <code>SyncFacttory</code>436* <li><code>ROWSET_SYNC_VENDOR</code> - the property specifying the software437* vendor associated with a <code>SyncProvider</code> implementation.438* <li><code>ROWSET_SYNC_PROVIDER_VER</code> - the property specifying the439* version of the <code>SyncProvider</code> implementation provided by the440* software vendor.441* </ul>442* More specific detailes are available in the <code>SyncFactory</code>443* and <code>SyncProvider</code> specificiations later in this document.444* <p>445* @param env a <code>Hashtable</code> object with a list of desired446* synchronization providers447* @throws SQLException if the requested provider cannot be found by the448* synchronization factory449* @see SyncProvider450*/451public CachedRowSetImpl(@SuppressWarnings("rawtypes") Hashtable env) throws SQLException {452453454try {455resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();456} catch(IOException ioe) {457throw new RuntimeException(ioe);458}459460if (env == null) {461throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nullhash").toString());462}463464String providerName = (String)env.get(465javax.sql.rowset.spi.SyncFactory.ROWSET_SYNC_PROVIDER);466467// set the Reader, this maybe overridden latter468provider =469SyncFactory.getInstance(providerName);470471rowSetReader = provider.getRowSetReader();472rowSetWriter = provider.getRowSetWriter();473474initParams(); // allocate the parameters collection475initContainer();476initProperties(); // set up some default values477}478479/**480* Sets the <code>rvh</code> field to a new <code>Vector</code>481* object with a capacity of 100 and sets the482* <code>cursorPos</code> and <code>numRows</code> fields to zero.483*/484private void initContainer() {485486rvh = new Vector<Object>(100);487cursorPos = 0;488absolutePos = 0;489numRows = 0;490numDeleted = 0;491}492493/**494* Sets the properties for this <code>CachedRowSetImpl</code> object to495* their default values. This method is called internally by the496* default constructor.497*/498499private void initProperties() throws SQLException {500501if(resBundle == null) {502try {503resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();504} catch(IOException ioe) {505throw new RuntimeException(ioe);506}507}508setShowDeleted(false);509setQueryTimeout(0);510setMaxRows(0);511setMaxFieldSize(0);512setType(ResultSet.TYPE_SCROLL_INSENSITIVE);513setConcurrency(ResultSet.CONCUR_UPDATABLE);514if((rvh.size() > 0) && (isReadOnly() == false))515setReadOnly(false);516else517setReadOnly(true);518setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);519setEscapeProcessing(true);520//setTypeMap(null);521checkTransactionalWriter();522523//Instantiating the vector for MatchColumns524525iMatchColumns = new Vector<Integer>(10);526for(int i = 0; i < 10 ; i++) {527iMatchColumns.add(i, -1);528}529530strMatchColumns = new Vector<String>(10);531for(int j = 0; j < 10; j++) {532strMatchColumns.add(j,null);533}534}535536/**537* Determine whether the SyncProvider's writer implements the538* <code>TransactionalWriter<code> interface539*/540private void checkTransactionalWriter() {541if (rowSetWriter != null) {542Class<?> c = rowSetWriter.getClass();543if (c != null) {544Class<?>[] theInterfaces = c.getInterfaces();545for (int i = 0; i < theInterfaces.length; i++) {546if ((theInterfaces[i].getName()).indexOf("TransactionalWriter") > 0) {547tXWriter = true;548establishTransactionalWriter();549}550}551}552}553}554555/**556* Sets an private field to all transaction bounddaries to be set557*/558private void establishTransactionalWriter() {559tWriter = (TransactionalWriter)provider.getRowSetWriter();560}561562//-----------------------------------------------------------------------563// Properties564//-----------------------------------------------------------------------565566/**567* Sets this <code>CachedRowSetImpl</code> object's command property568* to the given <code>String</code> object and clears the parameters,569* if any, that were set for the previous command.570* <P>571* The command property may not be needed572* if the rowset is produced by a data source, such as a spreadsheet,573* that does not support commands. Thus, this property is optional574* and may be <code>null</code>.575*576* @param cmd a <code>String</code> object containing an SQL query577* that will be set as the command; may be <code>null</code>578* @throws SQLException if an error occurs579*/580public void setCommand(String cmd) throws SQLException {581582super.setCommand(cmd);583584if(!buildTableName(cmd).equals("")) {585this.setTableName(buildTableName(cmd));586}587}588589590//---------------------------------------------------------------------591// Reading and writing data592//---------------------------------------------------------------------593594/**595* Populates this <code>CachedRowSetImpl</code> object with data from596* the given <code>ResultSet</code> object. This597* method is an alternative to the method <code>execute</code>598* for filling the rowset with data. The method <code>populate</code>599* does not require that the properties needed by the method600* <code>execute</code>, such as the <code>command</code> property,601* be set. This is true because the method <code>populate</code>602* is given the <code>ResultSet</code> object from603* which to get data and thus does not need to use the properties604* required for setting up a connection and executing this605* <code>CachedRowSetImpl</code> object's command.606* <P>607* After populating this rowset with data, the method608* <code>populate</code> sets the rowset's metadata and609* then sends a <code>RowSetChangedEvent</code> object610* to all registered listeners prior to returning.611*612* @param data the <code>ResultSet</code> object containing the data613* to be read into this <code>CachedRowSetImpl</code> object614* @throws SQLException if an error occurs; or the max row setting is615* violated while populating the RowSet616* @see #execute617*/618619public void populate(ResultSet data) throws SQLException {620int rowsFetched;621Row currentRow;622int numCols;623int i;624Map<String, Class<?>> map = getTypeMap();625Object obj;626int mRows;627628if (data == null) {629throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString());630}631this.resultSet = data;632633// get the meta data for this ResultSet634RSMD = data.getMetaData();635636// set up the metadata637RowSetMD = new RowSetMetaDataImpl();638initMetaData(RowSetMD, RSMD);639640// release the meta-data so that aren't tempted to use it.641RSMD = null;642numCols = RowSetMD.getColumnCount();643mRows = this.getMaxRows();644rowsFetched = 0;645currentRow = null;646647while ( data.next()) {648649currentRow = new Row(numCols);650651if ( rowsFetched > mRows && mRows > 0) {652rowsetWarning.setNextWarning(new RowSetWarning("Populating rows "653+ "setting has exceeded max row setting"));654}655for ( i = 1; i <= numCols; i++) {656/*657* check if the user has set a map. If no map658* is set then use plain getObject. This lets659* us work with drivers that do not support660* getObject with a map in fairly sensible way661*/662if (map == null || map.isEmpty()) {663obj = data.getObject(i);664} else {665obj = data.getObject(i, map);666}667/*668* the following block checks for the various669* types that we have to serialize in order to670* store - right now only structs have been tested671*/672if (obj instanceof Struct) {673obj = new SerialStruct((Struct)obj, map);674} else if (obj instanceof SQLData) {675obj = new SerialStruct((SQLData)obj, map);676} else if (obj instanceof Blob) {677obj = new SerialBlob((Blob)obj);678} else if (obj instanceof Clob) {679obj = new SerialClob((Clob)obj);680} else if (obj instanceof java.sql.Array) {681if(map != null)682obj = new SerialArray((java.sql.Array)obj, map);683else684obj = new SerialArray((java.sql.Array)obj);685}686687currentRow.initColumnObject(i, obj);688}689rowsFetched++;690rvh.add(currentRow);691}692693numRows = rowsFetched ;694// Also rowsFetched should be equal to rvh.size()695696// notify any listeners that the rowset has changed697notifyRowSetChanged();698699700}701702/**703* Initializes the given <code>RowSetMetaData</code> object with the values704* in the given <code>ResultSetMetaData</code> object.705*706* @param md the <code>RowSetMetaData</code> object for this707* <code>CachedRowSetImpl</code> object, which will be set with708* values from rsmd709* @param rsmd the <code>ResultSetMetaData</code> object from which new710* values for md will be read711* @throws SQLException if an error occurs712*/713private void initMetaData(RowSetMetaDataImpl md, ResultSetMetaData rsmd) throws SQLException {714int numCols = rsmd.getColumnCount();715716md.setColumnCount(numCols);717for (int col=1; col <= numCols; col++) {718md.setAutoIncrement(col, rsmd.isAutoIncrement(col));719if(rsmd.isAutoIncrement(col))720updateOnInsert = true;721md.setCaseSensitive(col, rsmd.isCaseSensitive(col));722md.setCurrency(col, rsmd.isCurrency(col));723md.setNullable(col, rsmd.isNullable(col));724md.setSigned(col, rsmd.isSigned(col));725md.setSearchable(col, rsmd.isSearchable(col));726/*727* The PostgreSQL drivers sometimes return negative columnDisplaySize,728* which causes an exception to be thrown. Check for it.729*/730int size = rsmd.getColumnDisplaySize(col);731if (size < 0) {732size = 0;733}734md.setColumnDisplaySize(col, size);735md.setColumnLabel(col, rsmd.getColumnLabel(col));736md.setColumnName(col, rsmd.getColumnName(col));737md.setSchemaName(col, rsmd.getSchemaName(col));738/*739* Drivers return some strange values for precision, for non-numeric data, including reports of740* non-integer values; maybe we should check type, & set to 0 for non-numeric types.741*/742int precision = rsmd.getPrecision(col);743if (precision < 0) {744precision = 0;745}746md.setPrecision(col, precision);747748/*749* It seems, from a bug report, that a driver can sometimes return a negative750* value for scale. javax.sql.rowset.RowSetMetaDataImpl will throw an exception751* if we attempt to set a negative value. As such, we'll check for this case.752*/753int scale = rsmd.getScale(col);754if (scale < 0) {755scale = 0;756}757md.setScale(col, scale);758md.setTableName(col, rsmd.getTableName(col));759md.setCatalogName(col, rsmd.getCatalogName(col));760md.setColumnType(col, rsmd.getColumnType(col));761md.setColumnTypeName(col, rsmd.getColumnTypeName(col));762}763764if( conn != null){765// JDBC 4.0 mandates as does the Java EE spec that all DataBaseMetaData methods766// must be implemented, therefore, the previous fix for 5055528 is being backed out767dbmslocatorsUpdateCopy = conn.getMetaData().locatorsUpdateCopy();768}769}770771/**772* Populates this <code>CachedRowSetImpl</code> object with data,773* using the given connection to produce the result set from774* which data will be read. A second form of this method,775* which takes no arguments, uses the values from this rowset's776* user, password, and either url or data source properties to777* create a new database connection. The form of <code>execute</code>778* that is given a connection ignores these properties.779*780* @param conn A standard JDBC <code>Connection</code> object that this781* <code>CachedRowSet</code> object can pass to a synchronization provider782* to establish a connection to the data source783* @throws SQLException if an invalid <code>Connection</code> is supplied784* or an error occurs in establishing the connection to the785* data source786* @see #populate787* @see java.sql.Connection788*/789public void execute(Connection conn) throws SQLException {790// store the connection so the reader can find it.791setConnection(conn);792793if(getPageSize() != 0){794crsReader = (CachedRowSetReader)provider.getRowSetReader();795crsReader.setStartPosition(1);796callWithCon = true;797crsReader.readData((RowSetInternal)this);798}799800// Now call the current reader's readData method801else {802rowSetReader.readData((RowSetInternal)this);803}804RowSetMD = (RowSetMetaDataImpl)this.getMetaData();805806if(conn != null){807// JDBC 4.0 mandates as does the Java EE spec that all DataBaseMetaData methods808// must be implemented, therefore, the previous fix for 5055528 is being backed out809dbmslocatorsUpdateCopy = conn.getMetaData().locatorsUpdateCopy();810}811812}813814/**815* Sets this <code>CachedRowSetImpl</code> object's connection property816* to the given <code>Connection</code> object. This method is called817* internally by the version of the method <code>execute</code> that takes a818* <code>Connection</code> object as an argument. The reader for this819* <code>CachedRowSetImpl</code> object can retrieve the connection stored820* in the rowset's connection property by calling its821* <code>getConnection</code> method.822*823* @param connection the <code>Connection</code> object that was passed in824* to the method <code>execute</code> and is to be stored825* in this <code>CachedRowSetImpl</code> object's connection826* property827*/828private void setConnection (Connection connection) {829conn = connection;830}831832833/**834* Propagates all row update, insert, and delete changes to the835* underlying data source backing this <code>CachedRowSetImpl</code>836* object.837* <P>838* <b>Note</b>In the reference implementation an optimistic concurrency implementation839* is provided as a sample implementation of a the <code>SyncProvider</code>840* abstract class.841* <P>842* This method fails if any of the updates cannot be propagated back843* to the data source. When it fails, the caller can assume that844* none of the updates are reflected in the data source.845* When an exception is thrown, the current row846* is set to the first "updated" row that resulted in an exception847* unless the row that caused the exception is a "deleted" row.848* In that case, when deleted rows are not shown, which is usually true,849* the current row is not affected.850* <P>851* If no <code>SyncProvider</code> is configured, the reference implementation852* leverages the <code>RIOptimisticProvider</code> available which provides the853* default and reference synchronization capabilities for disconnected854* <code>RowSets</code>.855*856* @throws SQLException if the cursor is on the insert row or the underlying857* reference synchronization provider fails to commit the updates858* to the datasource859* @throws SyncProviderException if an internal error occurs within the860* <code>SyncProvider</code> instance during either during the861* process or at any time when the <code>SyncProvider</code>862* instance touches the data source.863* @see #acceptChanges(java.sql.Connection)864* @see javax.sql.RowSetWriter865* @see javax.sql.rowset.spi.SyncProvider866*/867public void acceptChanges() throws SyncProviderException {868if (onInsertRow == true) {869throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());870}871872int saveCursorPos = cursorPos;873boolean success = false;874boolean conflict = false;875876try {877if (rowSetWriter != null) {878saveCursorPos = cursorPos;879conflict = rowSetWriter.writeData((RowSetInternal)this);880cursorPos = saveCursorPos;881}882883if (tXWriter) {884// do commit/rollback's here885if (!conflict) {886tWriter = (TransactionalWriter)rowSetWriter;887tWriter.rollback();888success = false;889} else {890tWriter = (TransactionalWriter)rowSetWriter;891if (tWriter instanceof CachedRowSetWriter) {892((CachedRowSetWriter)tWriter).commit(this, updateOnInsert);893} else {894tWriter.commit();895}896897success = true;898}899}900901if (success == true) {902setOriginal();903} else if (!(success) ) {904throw new SyncProviderException(resBundle.handleGetObject("cachedrowsetimpl.accfailed").toString());905}906907} catch (SyncProviderException spe) {908throw spe;909} catch (SQLException e) {910e.printStackTrace();911throw new SyncProviderException(e.getMessage());912} catch (SecurityException e) {913throw new SyncProviderException(e.getMessage());914}915}916917/**918* Propagates all row update, insert, and delete changes to the919* data source backing this <code>CachedRowSetImpl</code> object920* using the given <code>Connection</code> object.921* <P>922* The reference implementation <code>RIOptimisticProvider</code>923* modifies its synchronization to a write back function given924* the updated connection925* The reference implementation modifies its synchronization behaviour926* via the <code>SyncProvider</code> to ensure the synchronization927* occurs according to the updated JDBC <code>Connection</code>928* properties.929*930* @param con a standard JDBC <code>Connection</code> object931* @throws SQLException if the cursor is on the insert row or the underlying932* synchronization provider fails to commit the updates933* back to the data source934* @see #acceptChanges935* @see javax.sql.RowSetWriter936* @see javax.sql.rowset.spi.SyncFactory937* @see javax.sql.rowset.spi.SyncProvider938*/939public void acceptChanges(Connection con) throws SyncProviderException{940setConnection(con);941acceptChanges();942}943944/**945* Restores this <code>CachedRowSetImpl</code> object to its original state,946* that is, its state before the last set of changes.947* <P>948* Before returning, this method moves the cursor before the first row949* and sends a <code>rowSetChanged</code> event to all registered950* listeners.951* @throws SQLException if an error is occurs rolling back the RowSet952* state to the definied original value.953* @see javax.sql.RowSetListener#rowSetChanged954*/955public void restoreOriginal() throws SQLException {956Row currentRow;957for (Iterator<?> i = rvh.iterator(); i.hasNext();) {958currentRow = (Row)i.next();959if (currentRow.getInserted() == true) {960i.remove();961--numRows;962} else {963if (currentRow.getDeleted() == true) {964currentRow.clearDeleted();965}966if (currentRow.getUpdated() == true) {967currentRow.clearUpdated();968}969}970}971// move to before the first972cursorPos = 0;973974// notify any listeners975notifyRowSetChanged();976}977978/**979* Releases the current contents of this <code>CachedRowSetImpl</code>980* object and sends a <code>rowSetChanged</code> event object to all981* registered listeners.982*983* @throws SQLException if an error occurs flushing the contents of984* RowSet.985* @see javax.sql.RowSetListener#rowSetChanged986*/987public void release() throws SQLException {988initContainer();989notifyRowSetChanged();990}991992/**993* Cancels deletion of the current row and notifies listeners that994* a row has changed.995* <P>996* Note: This method can be ignored if deleted rows are not being shown,997* which is the normal case.998*999* @throws SQLException if the cursor is not on a valid row1000*/1001public void undoDelete() throws SQLException {1002if (getShowDeleted() == false) {1003return;1004}1005// make sure we are on a row1006checkCursor();10071008// don't want this to happen...1009if (onInsertRow == true) {1010throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());1011}10121013Row currentRow = (Row)getCurrentRow();1014if (currentRow.getDeleted() == true) {1015currentRow.clearDeleted();1016--numDeleted;1017notifyRowChanged();1018}1019}10201021/**1022* Immediately removes the current row from this1023* <code>CachedRowSetImpl</code> object if the row has been inserted, and1024* also notifies listeners the a row has changed. An exception is thrown1025* if the row is not a row that has been inserted or the cursor is before1026* the first row, after the last row, or on the insert row.1027* <P>1028* This operation cannot be undone.1029*1030* @throws SQLException if an error occurs,1031* the cursor is not on a valid row,1032* or the row has not been inserted1033*/1034public void undoInsert() throws SQLException {1035// make sure we are on a row1036checkCursor();10371038// don't want this to happen...1039if (onInsertRow == true) {1040throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());1041}10421043Row currentRow = (Row)getCurrentRow();1044if (currentRow.getInserted() == true) {1045rvh.remove(cursorPos-1);1046--numRows;1047notifyRowChanged();1048} else {1049throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.illegalop").toString());1050}1051}10521053/**1054* Immediately reverses the last update operation if the1055* row has been modified. This method can be1056* called to reverse updates on a all columns until all updates in a row have1057* been rolled back to their originating state since the last synchronization1058* (<code>acceptChanges</code>) or population. This method may also be called1059* while performing updates to the insert row.1060* <P>1061* <code>undoUpdate</code may be called at any time during the life-time of a1062* rowset, however after a synchronization has occurs this method has no1063* affect until further modification to the RowSet data occurs.1064*1065* @throws SQLException if cursor is before the first row, after the last1066* row in rowset.1067* @see #undoDelete1068* @see #undoInsert1069* @see java.sql.ResultSet#cancelRowUpdates1070*/1071public void undoUpdate() throws SQLException {1072// if on insert row, cancel the insert row1073// make the insert row flag,1074// cursorPos back to the current row1075moveToCurrentRow();10761077// else if not on insert row1078// call undoUpdate or undoInsert1079undoDelete();10801081undoInsert();10821083}10841085//--------------------------------------------------------------------1086// Views1087//--------------------------------------------------------------------10881089/**1090* Returns a new <code>RowSet</code> object backed by the same data as1091* that of this <code>CachedRowSetImpl</code> object and sharing a set of cursors1092* with it. This allows cursors to interate over a shared set of rows, providing1093* multiple views of the underlying data.1094*1095* @return a <code>RowSet</code> object that is a copy of this <code>CachedRowSetImpl</code>1096* object and shares a set of cursors with it1097* @throws SQLException if an error occurs or cloning is1098* not supported1099* @see javax.sql.RowSetEvent1100* @see javax.sql.RowSetListener1101*/1102public RowSet createShared() throws SQLException {1103RowSet clone;1104try {1105clone = (RowSet)clone();1106} catch (CloneNotSupportedException ex) {1107throw new SQLException(ex.getMessage());1108}1109return clone;1110}11111112/**1113* Returns a new <code>RowSet</code> object containing by the same data1114* as this <code>CachedRowSetImpl</code> object. This method1115* differs from the method <code>createCopy</code> in that it throws a1116* <code>CloneNotSupportedException</code> object instead of an1117* <code>SQLException</code> object, as the method <code>createShared</code>1118* does. This <code>clone</code>1119* method is called internally by the method <code>createShared</code>,1120* which catches the <code>CloneNotSupportedException</code> object1121* and in turn throws a new <code>SQLException</code> object.1122*1123* @return a copy of this <code>CachedRowSetImpl</code> object1124* @throws CloneNotSupportedException if an error occurs when1125* attempting to clone this <code>CachedRowSetImpl</code> object1126* @see #createShared1127*/1128protected Object clone() throws CloneNotSupportedException {1129return (super.clone());1130}11311132/**1133* Creates a <code>RowSet</code> object that is a deep copy of1134* this <code>CachedRowSetImpl</code> object's data, including1135* constraints. Updates made1136* on a copy are not visible to the original rowset;1137* a copy of a rowset is completely independent from the original.1138* <P>1139* Making a copy saves the cost of creating an identical rowset1140* from first principles, which can be quite expensive.1141* For example, it can eliminate the need to query a1142* remote database server.1143* @return a new <code>CachedRowSet</code> object that is a deep copy1144* of this <code>CachedRowSet</code> object and is1145* completely independent from this <code>CachedRowSetImpl</code>1146* object.1147* @throws SQLException if an error occurs in generating the copy of this1148* of the <code>CachedRowSetImpl</code>1149* @see #createShared1150* @see javax.sql.RowSetEvent1151* @see javax.sql.RowSetListener1152*/1153public CachedRowSet createCopy() throws SQLException {1154ObjectOutputStream out;1155ByteArrayOutputStream bOut = new ByteArrayOutputStream();1156try {1157out = new ObjectOutputStream(bOut);1158out.writeObject(this);1159} catch (IOException ex) {1160throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1161}11621163ObjectInputStream in;11641165try {1166ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());1167in = new ObjectInputStream(bIn);1168} catch (StreamCorruptedException ex) {1169throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1170} catch (IOException ex) {1171throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1172}11731174try {1175//return ((CachedRowSet)(in.readObject()));1176CachedRowSetImpl crsTemp = (CachedRowSetImpl)in.readObject();1177crsTemp.resBundle = this.resBundle;1178return ((CachedRowSet)crsTemp);11791180} catch (ClassNotFoundException ex) {1181throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.clonefail").toString() , ex.getMessage()));1182} catch (OptionalDataException 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}1187}11881189/**1190* Creates a <code>RowSet</code> object that is a copy of1191* this <code>CachedRowSetImpl</code> object's table structure1192* and the constraints only.1193* There will be no data in the object being returned.1194* Updates made on a copy are not visible to the original rowset.1195* <P>1196* This helps in getting the underlying XML schema which can1197* be used as the basis for populating a <code>WebRowSet</code>.1198*1199* @return a new <code>CachedRowSet</code> object that is a copy1200* of this <code>CachedRowSetImpl</code> object's schema and1201* retains all the constraints on the original rowset but contains1202* no data1203* @throws SQLException if an error occurs in generating the copy1204* of the <code>CachedRowSet</code> object1205* @see #createShared1206* @see #createCopy1207* @see #createCopyNoConstraints1208* @see javax.sql.RowSetEvent1209* @see javax.sql.RowSetListener1210*/1211public CachedRowSet createCopySchema() throws SQLException {1212// Copy everything except data i.e all constraints12131214// Store the number of rows of "this"1215// and make numRows equals zero.1216// and make data also zero.1217int nRows = numRows;1218numRows = 0;12191220CachedRowSet crs = this.createCopy();12211222// reset this object back to number of rows.1223numRows = nRows;12241225return crs;1226}12271228/**1229* Creates a <code>CachedRowSet</code> object that is a copy of1230* this <code>CachedRowSetImpl</code> object's data only.1231* All constraints set in this object will not be there1232* in the returning object. Updates made1233* on a copy are not visible to the original rowset.1234*1235* @return a new <code>CachedRowSet</code> object that is a deep copy1236* of this <code>CachedRowSetImpl</code> object and is1237* completely independent from this <code>CachedRowSetImpl</code> object1238* @throws SQLException if an error occurs in generating the copy of the1239* of the <code>CachedRowSet</code>1240* @see #createShared1241* @see #createCopy1242* @see #createCopySchema1243* @see javax.sql.RowSetEvent1244* @see javax.sql.RowSetListener1245*/1246public CachedRowSet createCopyNoConstraints() throws SQLException {1247// Copy the whole data ONLY without any constraints.1248CachedRowSetImpl crs;1249crs = (CachedRowSetImpl)this.createCopy();12501251crs.initProperties();1252try {1253crs.unsetMatchColumn(crs.getMatchColumnIndexes());1254} catch(SQLException sqle) {1255//do nothing, if the setMatchColumn is not set.1256}12571258try {1259crs.unsetMatchColumn(crs.getMatchColumnNames());1260} catch(SQLException sqle) {1261//do nothing, if the setMatchColumn is not set.1262}12631264return crs;1265}12661267/**1268* Converts this <code>CachedRowSetImpl</code> object to a collection1269* of tables. The sample implementation utilitizes the <code>TreeMap</code>1270* collection type.1271* This class guarantees that the map will be in ascending key order,1272* sorted according to the natural order for the key's class.1273*1274* @return a <code>Collection</code> object consisting of tables,1275* each of which is a copy of a row in this1276* <code>CachedRowSetImpl</code> object1277* @throws SQLException if an error occurs in generating the collection1278* @see #toCollection(int)1279* @see #toCollection(String)1280* @see java.util.TreeMap1281*/1282public Collection<?> toCollection() throws SQLException {12831284TreeMap<Integer, Object> tMap = new TreeMap<>();12851286for (int i = 0; i<numRows; i++) {1287tMap.put(i, rvh.get(i));1288}12891290return (tMap.values());1291}12921293/**1294* Returns the specified column of this <code>CachedRowSetImpl</code> object1295* as a <code>Collection</code> object. This method makes a copy of the1296* column's data and utilitizes the <code>Vector</code> to establish the1297* collection. The <code>Vector</code> class implements a growable array1298* objects allowing the individual components to be accessed using an1299* an integer index similar to that of an array.1300*1301* @return a <code>Collection</code> object that contains the value(s)1302* stored in the specified column of this1303* <code>CachedRowSetImpl</code>1304* object1305* @throws SQLException if an error occurs generated the collection; or1306* an invalid column is provided.1307* @see #toCollection()1308* @see #toCollection(String)1309* @see java.util.Vector1310*/1311public Collection<?> toCollection(int column) throws SQLException {13121313int nRows = numRows;1314Vector<Object> vec = new Vector<>(nRows);13151316// create a copy1317CachedRowSetImpl crsTemp;1318crsTemp = (CachedRowSetImpl) this.createCopy();13191320while(nRows!=0) {1321crsTemp.next();1322vec.add(crsTemp.getObject(column));1323nRows--;1324}13251326return (Collection)vec;1327}13281329/**1330* Returns the specified column of this <code>CachedRowSetImpl</code> object1331* as a <code>Collection</code> object. This method makes a copy of the1332* column's data and utilitizes the <code>Vector</code> to establish the1333* collection. The <code>Vector</code> class implements a growable array1334* objects allowing the individual components to be accessed using an1335* an integer index similar to that of an array.1336*1337* @return a <code>Collection</code> object that contains the value(s)1338* stored in the specified column of this1339* <code>CachedRowSetImpl</code>1340* object1341* @throws SQLException if an error occurs generated the collection; or1342* an invalid column is provided.1343* @see #toCollection()1344* @see #toCollection(int)1345* @see java.util.Vector1346*/1347public Collection<?> toCollection(String column) throws SQLException {1348return toCollection(getColIdxByName(column));1349}13501351//--------------------------------------------------------------------1352// Advanced features1353//--------------------------------------------------------------------135413551356/**1357* Returns the <code>SyncProvider</code> implementation being used1358* with this <code>CachedRowSetImpl</code> implementation rowset.1359*1360* @return the SyncProvider used by the rowset. If not provider was1361* set when the rowset was instantiated, the reference1362* implementation (default) provider is returned.1363* @throws SQLException if error occurs while return the1364* <code>SyncProvider</code> instance.1365*/1366public SyncProvider getSyncProvider() throws SQLException {1367return provider;1368}13691370/**1371* Sets the active <code>SyncProvider</code> and attempts to load1372* load the new provider using the <code>SyncFactory</code> SPI.1373*1374* @throws SQLException if an error occurs while resetting the1375* <code>SyncProvider</code>.1376*/1377public void setSyncProvider(String providerStr) throws SQLException {1378provider =1379SyncFactory.getInstance(providerStr);13801381rowSetReader = provider.getRowSetReader();1382rowSetWriter = provider.getRowSetWriter();1383}138413851386//-----------------1387// methods inherited from RowSet1388//-----------------1389139013911392139313941395//---------------------------------------------------------------------1396// Reading and writing data1397//---------------------------------------------------------------------13981399/**1400* Populates this <code>CachedRowSetImpl</code> object with data.1401* This form of the method uses the rowset's user, password, and url or1402* data source name properties to create a database1403* connection. If properties that are needed1404* have not been set, this method will throw an exception.1405* <P>1406* Another form of this method uses an existing JDBC <code>Connection</code>1407* object instead of creating a new one; therefore, it ignores the1408* properties used for establishing a new connection.1409* <P>1410* The query specified by the command property is executed to create a1411* <code>ResultSet</code> object from which to retrieve data.1412* The current contents of the rowset are discarded, and the1413* rowset's metadata is also (re)set. If there are outstanding updates,1414* they are also ignored.1415* <P>1416* The method <code>execute</code> closes any database connections that it1417* creates.1418*1419* @throws SQLException if an error occurs or the1420* necessary properties have not been set1421*/1422public void execute() throws SQLException {1423execute(null);1424}1425142614271428//-----------------------------------1429// Methods inherited from ResultSet1430//-----------------------------------14311432/**1433* Moves the cursor down one row from its current position and1434* returns <code>true</code> if the new cursor position is a1435* valid row.1436* The cursor for a new <code>ResultSet</code> object is initially1437* positioned before the first row. The first call to the method1438* <code>next</code> moves the cursor to the first row, making it1439* the current row; the second call makes the second row the1440* current row, and so on.1441*1442* <P>If an input stream from the previous row is open, it is1443* implicitly closed. The <code>ResultSet</code> object's warning1444* chain is cleared when a new row is read.1445*1446* @return <code>true</code> if the new current row is valid;1447* <code>false</code> if there are no more rows1448* @throws SQLException if an error occurs or1449* the cursor is not positioned in the rowset, before1450* the first row, or after the last row1451*/1452public boolean next() throws SQLException {1453/*1454* make sure things look sane. The cursor must be1455* positioned in the rowset or before first (0) or1456* after last (numRows + 1)1457*/1458if (cursorPos < 0 || cursorPos >= numRows + 1) {1459throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());1460}1461// now move and notify1462boolean ret = this.internalNext();1463notifyCursorMoved();14641465return ret;1466}14671468/**1469* Moves this <code>CachedRowSetImpl</code> object's cursor to the next1470* row and returns <code>true</code> if the cursor is still in the rowset;1471* returns <code>false</code> if the cursor has moved to the position after1472* the last row.1473* <P>1474* This method handles the cases where the cursor moves to a row that1475* has been deleted.1476* If this rowset shows deleted rows and the cursor moves to a row1477* that has been deleted, this method moves the cursor to the next1478* row until the cursor is on a row that has not been deleted.1479* <P>1480* The method <code>internalNext</code> is called by methods such as1481* <code>next</code>, <code>absolute</code>, and <code>relative</code>,1482* and, as its name implies, is only called internally.1483* <p>1484* This is a implementation only method and is not required as a standard1485* implementation of the <code>CachedRowSet</code> interface.1486*1487* @return <code>true</code> if the cursor is on a valid row in this1488* rowset; <code>false</code> if it is after the last row1489* @throws SQLException if an error occurs1490*/1491protected boolean internalNext() throws SQLException {1492boolean ret = false;14931494do {1495if (cursorPos < numRows) {1496++cursorPos;1497ret = true;1498} else if (cursorPos == numRows) {1499// increment to after last1500++cursorPos;1501ret = false;1502break;1503}1504} while ((getShowDeleted() == false) && (rowDeleted() == true));15051506/* each call to internalNext may increment cursorPos multiple1507* times however, the absolutePos only increments once per call.1508*/1509if (ret == true)1510absolutePos++;1511else1512absolutePos = 0;15131514return ret;1515}15161517/**1518* Closes this <code>CachedRowSetImpl</code> objecy and releases any resources1519* it was using.1520*1521* @throws SQLException if an error occurs when releasing any resources in use1522* by this <code>CachedRowSetImpl</code> object1523*/1524public void close() throws SQLException {15251526// close all data structures holding1527// the disconnected rowset15281529cursorPos = 0;1530absolutePos = 0;1531numRows = 0;1532numDeleted = 0;15331534// set all insert(s), update(s) & delete(s),1535// if at all, to their initial values.1536initProperties();15371538// clear the vector of it's present contents1539rvh.clear();15401541// this will make it eligible for gc1542// rvh = null;1543}15441545/**1546* Reports whether the last column read was SQL <code>NULL</code>.1547* Note that you must first call the method <code>getXXX</code>1548* on a column to try to read its value and then call the method1549* <code>wasNull</code> to determine whether the value was1550* SQL <code>NULL</code>.1551*1552* @return <code>true</code> if the value in the last column read1553* was SQL <code>NULL</code>; <code>false</code> otherwise1554* @throws SQLException if an error occurs1555*/1556public boolean wasNull() throws SQLException {1557return lastValueNull;1558}15591560/**1561* Sets the field <code>lastValueNull</code> to the given1562* <code>boolean</code> value.1563*1564* @param value <code>true</code> to indicate that the value of1565* the last column read was SQL <code>NULL</code>;1566* <code>false</code> to indicate that it was not1567*/1568private void setLastValueNull(boolean value) {1569lastValueNull = value;1570}15711572// Methods for accessing results by column index15731574/**1575* Checks to see whether the given index is a valid column number1576* in this <code>CachedRowSetImpl</code> object and throws1577* an <code>SQLException</code> if it is not. The index is out of bounds1578* if it is less than <code>1</code> or greater than the number of1579* columns in this rowset.1580* <P>1581* This method is called internally by the <code>getXXX</code> and1582* <code>updateXXX</code> methods.1583*1584* @param idx the number of a column in this <code>CachedRowSetImpl</code>1585* object; must be between <code>1</code> and the number of1586* rows in this rowset1587* @throws SQLException if the given index is out of bounds1588*/1589private void checkIndex(int idx) throws SQLException {1590if (idx < 1 || idx > RowSetMD.getColumnCount()) {1591throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString());1592}1593}15941595/**1596* Checks to see whether the cursor for this <code>CachedRowSetImpl</code>1597* object is on a row in the rowset and throws an1598* <code>SQLException</code> if it is not.1599* <P>1600* This method is called internally by <code>getXXX</code> methods, by1601* <code>updateXXX</code> methods, and by methods that update, insert,1602* or delete a row or that cancel a row update, insert, or delete.1603*1604* @throws SQLException if the cursor for this <code>CachedRowSetImpl</code>1605* object is not on a valid row1606*/1607private void checkCursor() throws SQLException {1608if (isAfterLast() == true || isBeforeFirst() == true) {1609throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());1610}1611}16121613/**1614* Returns the column number of the column with the given name in this1615* <code>CachedRowSetImpl</code> object. This method throws an1616* <code>SQLException</code> if the given name is not the name of1617* one of the columns in this rowset.1618*1619* @param name a <code>String</code> object that is the name of a column in1620* this <code>CachedRowSetImpl</code> object1621* @throws SQLException if the given name does not match the name of one of1622* the columns in this rowset1623*/1624private int getColIdxByName(String name) throws SQLException {1625RowSetMD = (RowSetMetaDataImpl)this.getMetaData();1626int cols = RowSetMD.getColumnCount();16271628for (int i=1; i <= cols; ++i) {1629String colName = RowSetMD.getColumnName(i);1630if (colName != null)1631if (name.equalsIgnoreCase(colName))1632return (i);1633else1634continue;1635}1636throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalcolnm").toString());16371638}16391640/**1641* Returns the insert row or the current row of this1642* <code>CachedRowSetImpl</code>object.1643*1644* @return the <code>Row</code> object on which this <code>CachedRowSetImpl</code>1645* objects's cursor is positioned1646*/1647protected BaseRow getCurrentRow() {1648if (onInsertRow == true) {1649return (BaseRow)insertRow;1650} else {1651return (BaseRow)(rvh.get(cursorPos - 1));1652}1653}16541655/**1656* Removes the row on which the cursor is positioned.1657* <p>1658* This is a implementation only method and is not required as a standard1659* implementation of the <code>CachedRowSet</code> interface.1660*1661* @throws SQLException if the cursor is positioned on the insert1662* row1663*/1664protected void removeCurrentRow() {1665((Row)getCurrentRow()).setDeleted();1666rvh.remove(cursorPos - 1);1667--numRows;1668}166916701671/**1672* Retrieves the value of the designated column in the current row1673* of this <code>CachedRowSetImpl</code> object as a1674* <code>String</code> object.1675*1676* @param columnIndex the first column is <code>1</code>, the second1677* is <code>2</code>, and so on; must be <code>1</code> or larger1678* and equal to or less than the number of columns in the rowset1679* @return the column value; if the value is SQL <code>NULL</code>, the1680* result is <code>null</code>1681* @throws SQLException if (1) the given column index is out of bounds,1682* (2) the cursor is not on one of this rowset's rows or its1683* insert row, or (3) the designated column does not store an1684* SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL,1685* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, <b>CHAR</b>, <b>VARCHAR</b></code>1686* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1687* recommended return type.1688*/1689public String getString(int columnIndex) throws SQLException {1690Object value;16911692// sanity check.1693checkIndex(columnIndex);1694// make sure the cursor is on a valid row1695checkCursor();16961697setLastValueNull(false);1698value = getCurrentRow().getColumnObject(columnIndex);16991700// check for SQL NULL1701if (value == null) {1702setLastValueNull(true);1703return null;1704}17051706return value.toString();1707}17081709/**1710* Retrieves the value of the designated column in the current row1711* of this <code>CachedRowSetImpl</code> object as a1712* <code>boolean</code> value.1713*1714* @param columnIndex the first column is <code>1</code>, the second1715* is <code>2</code>, and so on; must be <code>1</code> or larger1716* and equal to or less than the number of columns in the rowset1717* @return the column value as a <code>boolean</code> in the Java progamming language;1718* if the value is SQL <code>NULL</code>, the result is <code>false</code>1719* @throws SQLException if (1) the given column index is out of bounds,1720* (2) the cursor is not on one of this rowset's rows or its1721* insert row, or (3) the designated column does not store an1722* SQL <code>BOOLEAN</code> value1723* @see #getBoolean(String)1724*/1725public boolean getBoolean(int columnIndex) throws SQLException {1726Object value;17271728// sanity check.1729checkIndex(columnIndex);1730// make sure the cursor is on a valid row1731checkCursor();17321733setLastValueNull(false);1734value = getCurrentRow().getColumnObject(columnIndex);17351736// check for SQL NULL1737if (value == null) {1738setLastValueNull(true);1739return false;1740}17411742// check for Boolean...1743if (value instanceof Boolean) {1744return ((Boolean)value).booleanValue();1745}17461747// convert to a Double and compare to zero1748try {1749return Double.compare(Double.parseDouble(value.toString()), 0) != 0;1750} catch (NumberFormatException ex) {1751throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.boolfail").toString(),1752new Object[] {value.toString().trim(), columnIndex}));1753}1754}17551756/**1757* Retrieves the value of the designated column in the current row1758* of this <code>CachedRowSetImpl</code> object as a1759* <code>byte</code> value.1760*1761* @param columnIndex the first column is <code>1</code>, the second1762* is <code>2</code>, and so on; must be <code>1</code> or larger1763* and equal to or less than the number of columns in the rowset1764* @return the column value as a <code>byte</code> in the Java programming1765* language; if the value is SQL <code>NULL</code>, the result is <code>0</code>1766* @throws SQLException if (1) the given column index is out of bounds,1767* (2) the cursor is not on one of this rowset's rows or its1768* insert row, or (3) the designated column does not store an1769* SQL <code><b>TINYINT</b>, SMALLINT, INTEGER, BIGINT, REAL,1770* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1771* or <code>LONGVARCHAR</code> value. The bold SQL type1772* designates the recommended return type.1773* @see #getByte(String)1774*/1775public byte getByte(int columnIndex) throws SQLException {1776Object value;17771778// sanity check.1779checkIndex(columnIndex);1780// make sure the cursor is on a valid row1781checkCursor();17821783setLastValueNull(false);1784value = getCurrentRow().getColumnObject(columnIndex);17851786// check for SQL NULL1787if (value == null) {1788setLastValueNull(true);1789return (byte)0;1790}1791try {1792return ((Byte.valueOf(value.toString())).byteValue());1793} catch (NumberFormatException ex) {1794throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.bytefail").toString(),1795new Object[] {value.toString().trim(), columnIndex}));1796}1797}17981799/**1800* Retrieves the value of the designated column in the current row1801* of this <code>CachedRowSetImpl</code> object as a1802* <code>short</code> value.1803*1804* @param columnIndex the first column is <code>1</code>, the second1805* is <code>2</code>, and so on; must be <code>1</code> or larger1806* and equal to or less than the number of columns in the rowset1807* @return the column value; if the value is SQL <code>NULL</code>, the1808* result is <code>0</code>1809* @throws SQLException if (1) the given column index is out of bounds,1810* (2) the cursor is not on one of this rowset's rows or its1811* insert row, or (3) the designated column does not store an1812* SQL <code>TINYINT, <b>SMALLINT</b>, INTEGER, BIGINT, REAL1813* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1814* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1815* recommended return type.1816* @see #getShort(String)1817*/1818public short getShort(int columnIndex) throws SQLException {1819Object value;18201821// sanity check.1822checkIndex(columnIndex);1823// make sure the cursor is on a valid row1824checkCursor();18251826setLastValueNull(false);1827value = getCurrentRow().getColumnObject(columnIndex);18281829// check for SQL NULL1830if (value == null) {1831setLastValueNull(true);1832return (short)0;1833}18341835try {1836return ((Short.valueOf(value.toString().trim())).shortValue());1837} catch (NumberFormatException ex) {1838throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.shortfail").toString(),1839new Object[] {value.toString().trim(), columnIndex}));1840}1841}18421843/**1844* Retrieves the value of the designated column in the current row1845* of this <code>CachedRowSetImpl</code> object as an1846* <code>int</code> value.1847*1848* @param columnIndex the first column is <code>1</code>, the second1849* is <code>2</code>, and so on; must be <code>1</code> or larger1850* and equal to or less than the number of columns in the rowset1851* @return the column value; if the value is SQL <code>NULL</code>, the1852* result is <code>0</code>1853* @throws SQLException if (1) the given column index is out of bounds,1854* (2) the cursor is not on one of this rowset's rows or its1855* insert row, or (3) the designated column does not store an1856* SQL <code>TINYINT, SMALLINT, <b>INTEGER</b>, BIGINT, REAL1857* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1858* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1859* recommended return type.1860*/1861public int getInt(int columnIndex) throws SQLException {1862Object value;18631864// sanity check.1865checkIndex(columnIndex);1866// make sure the cursor is on a valid row1867checkCursor();18681869setLastValueNull(false);1870value = getCurrentRow().getColumnObject(columnIndex);18711872// check for SQL NULL1873if (value == null) {1874setLastValueNull(true);1875return 0;1876}18771878try {1879return ((Integer.valueOf(value.toString().trim())).intValue());1880} catch (NumberFormatException ex) {1881throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.intfail").toString(),1882new Object[] {value.toString().trim(), columnIndex}));1883}1884}18851886/**1887* Retrieves the value of the designated column in the current row1888* of this <code>CachedRowSetImpl</code> object as a1889* <code>long</code> value.1890*1891* @param columnIndex the first column is <code>1</code>, the second1892* is <code>2</code>, and so on; must be <code>1</code> or larger1893* and equal to or less than the number of columns in the rowset1894* @return the column value; if the value is SQL <code>NULL</code>, the1895* result is <code>0</code>1896* @throws SQLException if (1) the given column index is out of bounds,1897* (2) the cursor is not on one of this rowset's rows or its1898* insert row, or (3) the designated column does not store an1899* SQL <code>TINYINT, SMALLINT, INTEGER, <b>BIGINT</b>, REAL1900* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1901* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1902* recommended return type.1903* @see #getLong(String)1904*/1905public long getLong(int columnIndex) throws SQLException {1906Object value;19071908// sanity check.1909checkIndex(columnIndex);1910// make sure the cursor is on a valid row1911checkCursor();19121913setLastValueNull(false);1914value = getCurrentRow().getColumnObject(columnIndex);19151916// check for SQL NULL1917if (value == null) {1918setLastValueNull(true);1919return (long)0;1920}1921try {1922return ((Long.valueOf(value.toString().trim())).longValue());1923} catch (NumberFormatException ex) {1924throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.longfail").toString(),1925new Object[] {value.toString().trim(), columnIndex}));1926}1927}19281929/**1930* Retrieves the value of the designated column in the current row1931* of this <code>CachedRowSetImpl</code> object as a1932* <code>float</code> value.1933*1934* @param columnIndex the first column is <code>1</code>, the second1935* is <code>2</code>, and so on; must be <code>1</code> or larger1936* and equal to or less than the number of columns in the rowset1937* @return the column value; if the value is SQL <code>NULL</code>, the1938* result is <code>0</code>1939* @throws SQLException if (1) the given column index is out of bounds,1940* (2) the cursor is not on one of this rowset's rows or its1941* insert row, or (3) the designated column does not store an1942* SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, <b>REAL</b>,1943* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1944* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1945* recommended return type.1946* @see #getFloat(String)1947*/1948public float getFloat(int columnIndex) throws SQLException {1949Object value;19501951// sanity check.1952checkIndex(columnIndex);1953// make sure the cursor is on a valid row1954checkCursor();19551956setLastValueNull(false);1957value = getCurrentRow().getColumnObject(columnIndex);19581959// check for SQL NULL1960if (value == null) {1961setLastValueNull(true);1962return (float)0;1963}1964try {1965return ((new Float(value.toString())).floatValue());1966} catch (NumberFormatException ex) {1967throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.floatfail").toString(),1968new Object[] {value.toString().trim(), columnIndex}));1969}1970}19711972/**1973* Retrieves the value of the designated column in the current row1974* of this <code>CachedRowSetImpl</code> object as a1975* <code>double</code> value.1976*1977* @param columnIndex the first column is <code>1</code>, the second1978* is <code>2</code>, and so on; must be <code>1</code> or larger1979* and equal to or less than the number of columns in the rowset1980* @return the column value; if the value is SQL <code>NULL</code>, the1981* result is <code>0</code>1982* @throws SQLException if (1) the given column index is out of bounds,1983* (2) the cursor is not on one of this rowset's rows or its1984* insert row, or (3) the designated column does not store an1985* SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL,1986* <b>FLOAT</b>, <b>DOUBLE</b>, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>1987* or <code>LONGVARCHAR</code> value. The bold SQL type designates the1988* recommended return type.1989* @see #getDouble(String)1990*1991*/1992public double getDouble(int columnIndex) throws SQLException {1993Object value;19941995// sanity check.1996checkIndex(columnIndex);1997// make sure the cursor is on a valid row1998checkCursor();19992000setLastValueNull(false);2001value = getCurrentRow().getColumnObject(columnIndex);20022003// check for SQL NULL2004if (value == null) {2005setLastValueNull(true);2006return (double)0;2007}2008try {2009return ((new Double(value.toString().trim())).doubleValue());2010} catch (NumberFormatException ex) {2011throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(),2012new Object[] {value.toString().trim(), columnIndex}));2013}2014}20152016/**2017* Retrieves the value of the designated column in the current row2018* of this <code>CachedRowSetImpl</code> object as a2019* <code>java.math.BigDecimal</code> object.2020* <P>2021* This method is deprecated; use the version of <code>getBigDecimal</code>2022* that does not take a scale parameter and returns a value with full2023* precision.2024*2025* @param columnIndex the first column is <code>1</code>, the second2026* is <code>2</code>, and so on; must be <code>1</code> or larger2027* and equal to or less than the number of columns in the rowset2028* @param scale the number of digits to the right of the decimal point in the2029* value returned2030* @return the column value with the specified number of digits to the right2031* of the decimal point; if the value is SQL <code>NULL</code>, the2032* result is <code>null</code>2033* @throws SQLException if the given column index is out of bounds,2034* the cursor is not on a valid row, or this method fails2035* @deprecated2036*/2037@Deprecated2038public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {2039Object value;2040BigDecimal bDecimal, retVal;20412042// sanity check.2043checkIndex(columnIndex);2044// make sure the cursor is on a valid row2045checkCursor();20462047setLastValueNull(false);2048value = getCurrentRow().getColumnObject(columnIndex);20492050// check for SQL NULL2051if (value == null) {2052setLastValueNull(true);2053return (new BigDecimal(0));2054}20552056bDecimal = this.getBigDecimal(columnIndex);20572058retVal = bDecimal.setScale(scale);20592060return retVal;2061}20622063/**2064* Retrieves the value of the designated column in the current row2065* of this <code>CachedRowSetImpl</code> object as a2066* <code>byte</code> array value.2067*2068* @param columnIndex the first column is <code>1</code>, the second2069* is <code>2</code>, and so on; must be <code>1</code> or larger2070* and equal to or less than the number of columns in the rowset2071* @return the column value as a <code>byte</code> array in the Java programming2072* language; if the value is SQL <code>NULL</code>, the2073* result is <code>null</code>2074*2075* @throws SQLException if (1) the given column index is out of bounds,2076* (2) the cursor is not on one of this rowset's rows or its2077* insert row, or (3) the designated column does not store an2078* SQL <code><b>BINARY</b>, <b>VARBINARY</b> or2079* LONGVARBINARY</code> value.2080* The bold SQL type designates the recommended return type.2081* @see #getBytes(String)2082*/2083public byte[] getBytes(int columnIndex) throws SQLException {2084// sanity check.2085checkIndex(columnIndex);2086// make sure the cursor is on a valid row2087checkCursor();20882089if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) {2090throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());2091}20922093return (byte[])(getCurrentRow().getColumnObject(columnIndex));2094}20952096/**2097* Retrieves the value of the designated column in the current row2098* of this <code>CachedRowSetImpl</code> object as a2099* <code>java.sql.Date</code> object.2100*2101* @param columnIndex the first column is <code>1</code>, the second2102* is <code>2</code>, and so on; must be <code>1</code> or larger2103* and equal to or less than the number of columns in the rowset2104* @return the column value as a <code>java.sql.Data</code> object; if2105* the value is SQL <code>NULL</code>, the2106* result is <code>null</code>2107* @throws SQLException if the given column index is out of bounds,2108* the cursor is not on a valid row, or this method fails2109*/2110public java.sql.Date getDate(int columnIndex) throws SQLException {2111Object value;21122113// sanity check.2114checkIndex(columnIndex);2115// make sure the cursor is on a valid row2116checkCursor();21172118setLastValueNull(false);2119value = getCurrentRow().getColumnObject(columnIndex);21202121// check for SQL NULL2122if (value == null) {2123setLastValueNull(true);2124return null;2125}21262127/*2128* The object coming back from the db could be2129* a date, a timestamp, or a char field variety.2130* If it's a date type return it, a timestamp2131* we turn into a long and then into a date,2132* char strings we try to parse. Yuck.2133*/2134switch (RowSetMD.getColumnType(columnIndex)) {2135case java.sql.Types.DATE: {2136long sec = ((java.sql.Date)value).getTime();2137return new java.sql.Date(sec);2138}2139case java.sql.Types.TIMESTAMP: {2140long sec = ((java.sql.Timestamp)value).getTime();2141return new java.sql.Date(sec);2142}2143case java.sql.Types.CHAR:2144case java.sql.Types.VARCHAR:2145case java.sql.Types.LONGVARCHAR: {2146try {2147DateFormat df = DateFormat.getDateInstance();2148return ((java.sql.Date)(df.parse(value.toString())));2149} catch (ParseException ex) {2150throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(),2151new Object[] {value.toString().trim(), columnIndex}));2152}2153}2154default: {2155throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.datefail").toString(),2156new Object[] {value.toString().trim(), columnIndex}));2157}2158}2159}21602161/**2162* Retrieves the value of the designated column in the current row2163* of this <code>CachedRowSetImpl</code> object as a2164* <code>java.sql.Time</code> object.2165*2166* @param columnIndex the first column is <code>1</code>, the second2167* is <code>2</code>, and so on; must be <code>1</code> or larger2168* and equal to or less than the number of columns in the rowset2169* @return the column value; if the value is SQL <code>NULL</code>, the2170* result is <code>null</code>2171* @throws SQLException if the given column index is out of bounds,2172* the cursor is not on a valid row, or this method fails2173*/2174public java.sql.Time getTime(int columnIndex) throws SQLException {2175Object value;21762177// sanity check.2178checkIndex(columnIndex);2179// make sure the cursor is on a valid row2180checkCursor();21812182setLastValueNull(false);2183value = getCurrentRow().getColumnObject(columnIndex);21842185// check for SQL NULL2186if (value == null) {2187setLastValueNull(true);2188return null;2189}21902191/*2192* The object coming back from the db could be2193* a date, a timestamp, or a char field variety.2194* If it's a date type return it, a timestamp2195* we turn into a long and then into a date,2196* char strings we try to parse. Yuck.2197*/2198switch (RowSetMD.getColumnType(columnIndex)) {2199case java.sql.Types.TIME: {2200return (java.sql.Time)value;2201}2202case java.sql.Types.TIMESTAMP: {2203long sec = ((java.sql.Timestamp)value).getTime();2204return new java.sql.Time(sec);2205}2206case java.sql.Types.CHAR:2207case java.sql.Types.VARCHAR:2208case java.sql.Types.LONGVARCHAR: {2209try {2210DateFormat tf = DateFormat.getTimeInstance();2211return ((java.sql.Time)(tf.parse(value.toString())));2212} catch (ParseException ex) {2213throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(),2214new Object[] {value.toString().trim(), columnIndex}));2215}2216}2217default: {2218throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(),2219new Object[] {value.toString().trim(), columnIndex}));2220}2221}2222}22232224/**2225* Retrieves the value of the designated column in the current row2226* of this <code>CachedRowSetImpl</code> object as a2227* <code>java.sql.Timestamp</code> object.2228*2229* @param columnIndex the first column is <code>1</code>, the second2230* is <code>2</code>, and so on; must be <code>1</code> or larger2231* and equal to or less than the number of columns in the rowset2232* @return the column value; if the value is SQL <code>NULL</code>, the2233* result is <code>null</code>2234* @throws SQLException if the given column index is out of bounds,2235* the cursor is not on a valid row, or this method fails2236*/2237public java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException {2238Object value;22392240// sanity check.2241checkIndex(columnIndex);2242// make sure the cursor is on a valid row2243checkCursor();22442245setLastValueNull(false);2246value = getCurrentRow().getColumnObject(columnIndex);22472248// check for SQL NULL2249if (value == null) {2250setLastValueNull(true);2251return null;2252}22532254/*2255* The object coming back from the db could be2256* a date, a timestamp, or a char field variety.2257* If it's a date type return it; a timestamp2258* we turn into a long and then into a date;2259* char strings we try to parse. Yuck.2260*/2261switch (RowSetMD.getColumnType(columnIndex)) {2262case java.sql.Types.TIMESTAMP: {2263return (java.sql.Timestamp)value;2264}2265case java.sql.Types.TIME: {2266long sec = ((java.sql.Time)value).getTime();2267return new java.sql.Timestamp(sec);2268}2269case java.sql.Types.DATE: {2270long sec = ((java.sql.Date)value).getTime();2271return new java.sql.Timestamp(sec);2272}2273case java.sql.Types.CHAR:2274case java.sql.Types.VARCHAR:2275case java.sql.Types.LONGVARCHAR: {2276try {2277DateFormat tf = DateFormat.getTimeInstance();2278return ((java.sql.Timestamp)(tf.parse(value.toString())));2279} catch (ParseException ex) {2280throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(),2281new Object[] {value.toString().trim(), columnIndex}));2282}2283}2284default: {2285throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.timefail").toString(),2286new Object[] {value.toString().trim(), columnIndex}));2287}2288}2289}22902291/**2292* Retrieves the value of the designated column in the current row of this2293* <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code>2294* object.2295*2296* A column value can be retrieved as a stream of ASCII characters2297* and then read in chunks from the stream. This method is particularly2298* suitable for retrieving large <code>LONGVARCHAR</code> values. The JDBC2299* driver will do any necessary conversion from the database format into ASCII.2300*2301* <P><B>Note:</B> All the data in the returned stream must be2302* read prior to getting the value of any other column. The next2303* call to a get method implicitly closes the stream. . Also, a2304* stream may return <code>0</code> for <code>CachedRowSetImpl.available()</code>2305* whether there is data available or not.2306*2307* @param columnIndex the first column is <code>1</code>, the second2308* is <code>2</code>, and so on; must be <code>1</code> or larger2309* and equal to or less than the number of columns in this rowset2310* @return a Java input stream that delivers the database column value2311* as a stream of one-byte ASCII characters. If the value is SQL2312* <code>NULL</code>, the result is <code>null</code>.2313* @throws SQLException if (1) the given column index is out of bounds,2314* (2) the cursor is not on one of this rowset's rows or its2315* insert row, or (3) the designated column does not store an2316* SQL <code>CHAR, VARCHAR</code>, <code><b>LONGVARCHAR</b></code>2317* <code>BINARY, VARBINARY</code> or <code>LONGVARBINARY</code> value. The2318* bold SQL type designates the recommended return types that this method is2319* used to retrieve.2320* @see #getAsciiStream(String)2321*/2322public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException {2323Object value;23242325// always free an old stream2326asciiStream = null;23272328// sanity check2329checkIndex(columnIndex);2330//make sure the cursor is on a vlid row2331checkCursor();23322333value = getCurrentRow().getColumnObject(columnIndex);2334if (value == null) {2335lastValueNull = true;2336return null;2337}23382339try {2340if (isString(RowSetMD.getColumnType(columnIndex))) {2341asciiStream = new ByteArrayInputStream(((String)value).getBytes("ASCII"));2342} else {2343throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());2344}2345} catch (java.io.UnsupportedEncodingException ex) {2346throw new SQLException(ex.getMessage());2347}23482349return asciiStream;2350}23512352/**2353* A column value can be retrieved as a stream of Unicode characters2354* and then read in chunks from the stream. This method is particularly2355* suitable for retrieving large LONGVARCHAR values. The JDBC driver will2356* do any necessary conversion from the database format into Unicode.2357*2358* <P><B>Note:</B> All the data in the returned stream must be2359* read prior to getting the value of any other column. The next2360* call to a get method implicitly closes the stream. . Also, a2361* stream may return 0 for available() whether there is data2362* available or not.2363*2364* @param columnIndex the first column is <code>1</code>, the second2365* is <code>2</code>, and so on; must be <code>1</code> or larger2366* and equal to or less than the number of columns in this rowset2367* @return a Java input stream that delivers the database column value2368* as a stream of two byte Unicode characters. If the value is SQL NULL2369* then the result is null.2370* @throws SQLException if an error occurs2371* @deprecated2372*/2373@Deprecated2374public java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException {2375// always free an old stream2376unicodeStream = null;23772378// sanity check.2379checkIndex(columnIndex);2380// make sure the cursor is on a valid row2381checkCursor();23822383if (isBinary(RowSetMD.getColumnType(columnIndex)) == false &&2384isString(RowSetMD.getColumnType(columnIndex)) == false) {2385throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());2386}23872388Object value = getCurrentRow().getColumnObject(columnIndex);2389if (value == null) {2390lastValueNull = true;2391return null;2392}23932394unicodeStream = new StringBufferInputStream(value.toString());23952396return unicodeStream;2397}23982399/**2400* Retrieves the value of the designated column in the current row of this2401* <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code>2402* object.2403* <P>2404* A column value can be retrieved as a stream of uninterpreted bytes2405* and then read in chunks from the stream. This method is particularly2406* suitable for retrieving large <code>LONGVARBINARY</code> values.2407*2408* <P><B>Note:</B> All the data in the returned stream must be2409* read prior to getting the value of any other column. The next2410* call to a get method implicitly closes the stream. Also, a2411* stream may return <code>0</code> for2412* <code>CachedRowSetImpl.available()</code> whether there is data2413* available or not.2414*2415* @param columnIndex the first column is <code>1</code>, the second2416* is <code>2</code>, and so on; must be <code>1</code> or larger2417* and equal to or less than the number of columns in the rowset2418* @return a Java input stream that delivers the database column value2419* as a stream of uninterpreted bytes. If the value is SQL <code>NULL</code>2420* then the result is <code>null</code>.2421* @throws SQLException if (1) the given column index is out of bounds,2422* (2) the cursor is not on one of this rowset's rows or its2423* insert row, or (3) the designated column does not store an2424* SQL <code>BINARY, VARBINARY</code> or <code><b>LONGVARBINARY</b></code>2425* The bold type indicates the SQL type that this method is recommened2426* to retrieve.2427* @see #getBinaryStream(String)2428*/2429public java.io.InputStream getBinaryStream(int columnIndex) throws SQLException {24302431// always free an old stream2432binaryStream = null;24332434// sanity check.2435checkIndex(columnIndex);2436// make sure the cursor is on a valid row2437checkCursor();24382439if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) {2440throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());2441}24422443Object value = getCurrentRow().getColumnObject(columnIndex);2444if (value == null) {2445lastValueNull = true;2446return null;2447}24482449binaryStream = new ByteArrayInputStream((byte[])value);24502451return binaryStream;24522453}245424552456// Methods for accessing results by column name24572458/**2459* Retrieves the value stored in the designated column2460* of the current row as a <code>String</code> object.2461*2462* @param columnName a <code>String</code> object giving the SQL name of2463* a column in this <code>CachedRowSetImpl</code> object2464* @return the column value; if the value is SQL <code>NULL</code>,2465* the result is <code>null</code>2466* @throws SQLException if (1) the given column name is not the name of2467* a column in this rowset, (2) the cursor is not on one of2468* this rowset's rows or its insert row, or (3) the designated2469* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER2470* BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, <b>CHAR</b>,2471* <b>VARCHAR</b></code> or <code>LONGVARCHAR<</code> value. The bold SQL type2472* designates the recommended return type.2473*/2474public String getString(String columnName) throws SQLException {2475return getString(getColIdxByName(columnName));2476}24772478/**2479* Retrieves the value stored in the designated column2480* of the current row as a <code>boolean</code> value.2481*2482* @param columnName a <code>String</code> object giving the SQL name of2483* a column in this <code>CachedRowSetImpl</code> object2484* @return the column value as a <code>boolean</code> in the Java programming2485* language; if the value is SQL <code>NULL</code>,2486* the result is <code>false</code>2487* @throws SQLException if (1) the given column name is not the name of2488* a column in this rowset, (2) the cursor is not on one of2489* this rowset's rows or its insert row, or (3) the designated2490* column does not store an SQL <code>BOOLEAN</code> value2491* @see #getBoolean(int)2492*/2493public boolean getBoolean(String columnName) throws SQLException {2494return getBoolean(getColIdxByName(columnName));2495}24962497/**2498* Retrieves the value stored in the designated column2499* of the current row as a <code>byte</code> value.2500*2501* @param columnName a <code>String</code> object giving the SQL name of2502* a column in this <code>CachedRowSetImpl</code> object2503* @return the column value as a <code>byte</code> in the Java programming2504* language; if the value is SQL <code>NULL</code>, the result is <code>0</code>2505* @throws SQLException if (1) the given column name is not the name of2506* a column in this rowset, (2) the cursor is not on one of2507* this rowset's rows or its insert row, or (3) the designated2508* column does not store an SQL <code><B>TINYINT</B>, SMALLINT, INTEGER,2509* BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR,2510* VARCHAR</code> or <code>LONGVARCHAR</code> value. The2511* bold type designates the recommended return type2512*/2513public byte getByte(String columnName) throws SQLException {2514return getByte(getColIdxByName(columnName));2515}25162517/**2518* Retrieves the value stored in the designated column2519* of the current row as a <code>short</code> value.2520*2521* @param columnName a <code>String</code> object giving the SQL name of2522* a column in this <code>CachedRowSetImpl</code> object2523* @return the column value; if the value is SQL <code>NULL</code>,2524* the result is <code>0</code>2525* @throws SQLException if (1) the given column name is not the name of2526* a column in this rowset, (2) the cursor is not on one of2527* this rowset's rows or its insert row, or (3) the designated2528* column does not store an SQL <code>TINYINT, <b>SMALLINT</b>, INTEGER2529* BIGINT, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR,2530* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2531* designates the recommended return type.2532* @see #getShort(int)2533*/2534public short getShort(String columnName) throws SQLException {2535return getShort(getColIdxByName(columnName));2536}25372538/**2539* Retrieves the value stored in the designated column2540* of the current row as an <code>int</code> value.2541*2542* @param columnName a <code>String</code> object giving the SQL name of2543* a column in this <code>CachedRowSetImpl</code> object2544* @return the column value; if the value is SQL <code>NULL</code>,2545* the result is <code>0</code>2546* @throws SQLException if (1) the given column name is not the name2547* of a column in this rowset,2548* (2) the cursor is not on one of this rowset's rows or its2549* insert row, or (3) the designated column does not store an2550* SQL <code>TINYINT, SMALLINT, <b>INTEGER</b>, BIGINT, REAL2551* FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR, VARCHAR</code>2552* or <code>LONGVARCHAR</code> value. The bold SQL type designates the2553* recommended return type.2554*/2555public int getInt(String columnName) throws SQLException {2556return getInt(getColIdxByName(columnName));2557}25582559/**2560* Retrieves the value stored in the designated column2561* of the current row as a <code>long</code> value.2562*2563* @param columnName a <code>String</code> object giving the SQL name of2564* a column in this <code>CachedRowSetImpl</code> object2565* @return the column value; if the value is SQL <code>NULL</code>,2566* the result is <code>0</code>2567* @throws SQLException if (1) the given column name is not the name of2568* a column in this rowset, (2) the cursor is not on one of2569* this rowset's rows or its insert row, or (3) the designated2570* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER2571* <b>BIGINT</b>, REAL, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR,2572* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2573* designates the recommended return type.2574* @see #getLong(int)2575*/2576public long getLong(String columnName) throws SQLException {2577return getLong(getColIdxByName(columnName));2578}25792580/**2581* Retrieves the value stored in the designated column2582* of the current row as a <code>float</code> value.2583*2584* @param columnName a <code>String</code> object giving the SQL name of2585* a column in this <code>CachedRowSetImpl</code> object2586* @return the column value; if the value is SQL <code>NULL</code>,2587* the result is <code>0</code>2588* @throws SQLException if (1) the given column name is not the name of2589* a column in this rowset, (2) the cursor is not on one of2590* this rowset's rows or its insert row, or (3) the designated2591* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER2592* BIGINT, <b>REAL</b>, FLOAT, DOUBLE, DECIMAL, NUMERIC, BIT, CHAR,2593* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2594* designates the recommended return type.2595* @see #getFloat(String)2596*/2597public float getFloat(String columnName) throws SQLException {2598return getFloat(getColIdxByName(columnName));2599}26002601/**2602* Retrieves the value stored in the designated column2603* of the current row of this <code>CachedRowSetImpl</code> object2604* as a <code>double</code> value.2605*2606* @param columnName a <code>String</code> object giving the SQL name of2607* a column in this <code>CachedRowSetImpl</code> object2608* @return the column value; if the value is SQL <code>NULL</code>,2609* the result is <code>0</code>2610* @throws SQLException if (1) the given column name is not the name of2611* a column in this rowset, (2) the cursor is not on one of2612* this rowset's rows or its insert row, or (3) the designated2613* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER2614* BIGINT, REAL, <b>FLOAT</b>, <b>DOUBLE</b>, DECIMAL, NUMERIC, BIT, CHAR,2615* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2616* designates the recommended return types.2617* @see #getDouble(int)2618*/2619public double getDouble(String columnName) throws SQLException {2620return getDouble(getColIdxByName(columnName));2621}26222623/**2624* Retrieves the value stored in the designated column2625* of the current row as a <code>java.math.BigDecimal</code> object.2626*2627* @param columnName a <code>String</code> object giving the SQL name of2628* a column in this <code>CachedRowSetImpl</code> object2629* @param scale the number of digits to the right of the decimal point2630* @return a java.math.BugDecimal object with <code><i>scale</i></code>2631* number of digits to the right of the decimal point.2632* @throws SQLException if (1) the given column name is not the name of2633* a column in this rowset, (2) the cursor is not on one of2634* this rowset's rows or its insert row, or (3) the designated2635* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER2636* BIGINT, REAL, FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT CHAR,2637* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type2638* designates the recommended return type that this method is used to2639* retrieve.2640* @deprecated Use the <code>getBigDecimal(String columnName)</code>2641* method instead2642*/2643@Deprecated2644public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {2645return getBigDecimal(getColIdxByName(columnName), scale);2646}26472648/**2649* Retrieves the value stored in the designated column2650* of the current row as a <code>byte</code> array.2651* The bytes represent the raw values returned by the driver.2652*2653* @param columnName a <code>String</code> object giving the SQL name of2654* a column in this <code>CachedRowSetImpl</code> object2655* @return the column value as a <code>byte</code> array in the Java programming2656* language; if the value is SQL <code>NULL</code>, the result is <code>null</code>2657* @throws SQLException if (1) the given column name is not the name of2658* a column in this rowset, (2) the cursor is not on one of2659* this rowset's rows or its insert row, or (3) the designated2660* column does not store an SQL <code><b>BINARY</b>, <b>VARBINARY</b>2661* </code> or <code>LONGVARBINARY</code> values2662* The bold SQL type designates the recommended return type.2663* @see #getBytes(int)2664*/2665public byte[] getBytes(String columnName) throws SQLException {2666return getBytes(getColIdxByName(columnName));2667}26682669/**2670* Retrieves the value stored in the designated column2671* of the current row as a <code>java.sql.Date</code> object.2672*2673* @param columnName a <code>String</code> object giving the SQL name of2674* a column in this <code>CachedRowSetImpl</code> object2675* @return the column value; if the value is SQL <code>NULL</code>,2676* the result is <code>null</code>2677* @throws SQLException if (1) the given column name is not the name of2678* a column in this rowset, (2) the cursor is not on one of2679* this rowset's rows or its insert row, or (3) the designated2680* column does not store an SQL <code>DATE</code> or2681* <code>TIMESTAMP</code> value2682*/2683public java.sql.Date getDate(String columnName) throws SQLException {2684return getDate(getColIdxByName(columnName));2685}26862687/**2688* Retrieves the value stored in the designated column2689* of the current row as a <code>java.sql.Time</code> object.2690*2691* @param columnName a <code>String</code> object giving the SQL name of2692* a column in this <code>CachedRowSetImpl</code> object2693* @return the column value; if the value is SQL <code>NULL</code>,2694* the result is <code>null</code>2695* @throws SQLException if the given column name does not match one of2696* this rowset's column names or the cursor is not on one of2697* this rowset's rows or its insert row2698*/2699public java.sql.Time getTime(String columnName) throws SQLException {2700return getTime(getColIdxByName(columnName));2701}27022703/**2704* Retrieves the value stored in the designated column2705* of the current row as a <code>java.sql.Timestamp</code> object.2706*2707* @param columnName a <code>String</code> object giving the SQL name of2708* a column in this <code>CachedRowSetImpl</code> object2709* @return the column value; if the value is SQL <code>NULL</code>,2710* the result is <code>null</code>2711* @throws SQLException if the given column name does not match one of2712* this rowset's column names or the cursor is not on one of2713* this rowset's rows or its insert row2714*/2715public java.sql.Timestamp getTimestamp(String columnName) throws SQLException {2716return getTimestamp(getColIdxByName(columnName));2717}27182719/**2720* Retrieves the value of the designated column in the current row of this2721* <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code>2722* object.2723*2724* A column value can be retrieved as a stream of ASCII characters2725* and then read in chunks from the stream. This method is particularly2726* suitable for retrieving large <code>LONGVARCHAR</code> values. The2727* <code>SyncProvider</code> will rely on the JDBC driver to do any necessary2728* conversion from the database format into ASCII format.2729*2730* <P><B>Note:</B> All the data in the returned stream must2731* be read prior to getting the value of any other column. The2732* next call to a <code>getXXX</code> method implicitly closes the stream.2733*2734* @param columnName a <code>String</code> object giving the SQL name of2735* a column in this <code>CachedRowSetImpl</code> object2736* @return a Java input stream that delivers the database column value2737* as a stream of one-byte ASCII characters. If the value is SQL2738* <code>NULL</code>, the result is <code>null</code>.2739* @throws SQLException if (1) the given column name is not the name of2740* a column in this rowset2741* (2) the cursor is not on one of this rowset's rows or its2742* insert row, or (3) the designated column does not store an2743* SQL <code>CHAR, VARCHAR</code>, <code><b>LONGVARCHAR</b></code>2744* <code>BINARY, VARBINARY</code> or <code>LONGVARBINARY</code> value. The2745* bold SQL type designates the recommended return types that this method is2746* used to retrieve.2747* @see #getAsciiStream(int)2748*/2749public java.io.InputStream getAsciiStream(String columnName) throws SQLException {2750return getAsciiStream(getColIdxByName(columnName));27512752}27532754/**2755* A column value can be retrieved as a stream of Unicode characters2756* and then read in chunks from the stream. This method is particularly2757* suitable for retrieving large <code>LONGVARCHAR</code> values.2758* The JDBC driver will do any necessary conversion from the database2759* format into Unicode.2760*2761* <P><B>Note:</B> All the data in the returned stream must2762* be read prior to getting the value of any other column. The2763* next call to a <code>getXXX</code> method implicitly closes the stream.2764*2765* @param columnName a <code>String</code> object giving the SQL name of2766* a column in this <code>CachedRowSetImpl</code> object2767* @return a Java input stream that delivers the database column value2768* as a stream of two-byte Unicode characters. If the value is2769* SQL <code>NULL</code>, the result is <code>null</code>.2770* @throws SQLException if the given column name does not match one of2771* this rowset's column names or the cursor is not on one of2772* this rowset's rows or its insert row2773* @deprecated use the method <code>getCharacterStream</code> instead2774*/2775@Deprecated2776public java.io.InputStream getUnicodeStream(String columnName) throws SQLException {2777return getUnicodeStream(getColIdxByName(columnName));2778}27792780/**2781* Retrieves the value of the designated column in the current row of this2782* <code>CachedRowSetImpl</code> object as a <code>java.io.InputStream</code>2783* object.2784* <P>2785* A column value can be retrieved as a stream of uninterpreted bytes2786* and then read in chunks from the stream. This method is particularly2787* suitable for retrieving large <code>LONGVARBINARY</code> values.2788*2789* <P><B>Note:</B> All the data in the returned stream must be2790* read prior to getting the value of any other column. The next2791* call to a get method implicitly closes the stream. Also, a2792* stream may return <code>0</code> for <code>CachedRowSetImpl.available()</code>2793* whether there is data available or not.2794*2795* @param columnName a <code>String</code> object giving the SQL name of2796* a column in this <code>CachedRowSetImpl</code> object2797* @return a Java input stream that delivers the database column value2798* as a stream of uninterpreted bytes. If the value is SQL2799* <code>NULL</code>, the result is <code>null</code>.2800* @throws SQLException if (1) the given column name is unknown,2801* (2) the cursor is not on one of this rowset's rows or its2802* insert row, or (3) the designated column does not store an2803* SQL <code>BINARY, VARBINARY</code> or <code><b>LONGVARBINARY</b></code>2804* The bold type indicates the SQL type that this method is recommened2805* to retrieve.2806* @see #getBinaryStream(int)2807*2808*/2809public java.io.InputStream getBinaryStream(String columnName) throws SQLException {2810return getBinaryStream(getColIdxByName(columnName));2811}281228132814// Advanced features:28152816/**2817* The first warning reported by calls on this <code>CachedRowSetImpl</code>2818* object is returned. Subsequent <code>CachedRowSetImpl</code> warnings will2819* be chained to this <code>SQLWarning</code>.2820*2821* <P>The warning chain is automatically cleared each time a new2822* row is read.2823*2824* <P><B>Note:</B> This warning chain only covers warnings caused2825* by <code>ResultSet</code> methods. Any warning caused by statement2826* methods (such as reading OUT parameters) will be chained on the2827* <code>Statement</code> object.2828*2829* @return the first SQLWarning or null2830*/2831public SQLWarning getWarnings() {2832return sqlwarn;2833}28342835/**2836* Clears all the warnings reporeted for the <code>CachedRowSetImpl</code>2837* object. After a call to this method, the <code>getWarnings</code> method2838* returns <code>null</code> until a new warning is reported for this2839* <code>CachedRowSetImpl</code> object.2840*/2841public void clearWarnings() {2842sqlwarn = null;2843}28442845/**2846* Retrieves the name of the SQL cursor used by this2847* <code>CachedRowSetImpl</code> object.2848*2849* <P>In SQL, a result table is retrieved through a cursor that is2850* named. The current row of a <code>ResultSet</code> can be updated or deleted2851* using a positioned update/delete statement that references the2852* cursor name. To ensure that the cursor has the proper isolation2853* level to support an update operation, the cursor's <code>SELECT</code>2854* statement should be of the form <code>select for update</code>.2855* If the <code>for update</code> clause2856* is omitted, positioned updates may fail.2857*2858* <P>JDBC supports this SQL feature by providing the name of the2859* SQL cursor used by a <code>ResultSet</code> object. The current row2860* of a result set is also the current row of this SQL cursor.2861*2862* <P><B>Note:</B> If positioned updates are not supported, an2863* <code>SQLException</code> is thrown.2864*2865* @return the SQL cursor name for this <code>CachedRowSetImpl</code> object's2866* cursor2867* @throws SQLException if an error occurs2868*/2869public String getCursorName() throws SQLException {2870throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.posupdate").toString());2871}28722873/**2874* Retrieves a <code>ResultSetMetaData</code> object instance that2875* contains information about the <code>CachedRowSet</code> object.2876* However, applications should cast the returned object to a2877* <code>RowSetMetaData</code> interface implementation. In the2878* reference implementation, this cast can be done on the2879* <code>RowSetMetaDataImpl</code> class.2880* <P>2881* For example:2882* <pre>2883* CachedRowSet crs = new CachedRowSetImpl();2884* RowSetMetaDataImpl metaData =2885* (RowSetMetaDataImpl)crs.getMetaData();2886* // Set the number of columns in the RowSet object for2887* // which this RowSetMetaDataImpl object was created to the2888* // given number.2889* metaData.setColumnCount(3);2890* crs.setMetaData(metaData);2891* </pre>2892*2893* @return the <code>ResultSetMetaData</code> object that describes this2894* <code>CachedRowSetImpl</code> object's columns2895* @throws SQLException if an error occurs in generating the RowSet2896* meta data; or if the <code>CachedRowSetImpl</code> is empty.2897* @see javax.sql.RowSetMetaData2898*/2899public ResultSetMetaData getMetaData() throws SQLException {2900return (ResultSetMetaData)RowSetMD;2901}290229032904/**2905* Retrieves the value of the designated column in the current row2906* of this <code>CachedRowSetImpl</code> object as an2907* <code>Object</code> value.2908* <P>2909* The type of the <code>Object</code> will be the default2910* Java object type corresponding to the column's SQL type,2911* following the mapping for built-in types specified in the JDBC 3.02912* specification.2913* <P>2914* This method may also be used to read datatabase-specific2915* abstract data types.2916* <P>2917* This implementation of the method <code>getObject</code> extends its2918* behavior so that it gets the attributes of an SQL structured type2919* as an array of <code>Object</code> values. This method also custom2920* maps SQL user-defined types to classes in the Java programming language.2921* When the specified column contains2922* a structured or distinct value, the behavior of this method is as2923* if it were a call to the method <code>getObject(columnIndex,2924* this.getStatement().getConnection().getTypeMap())</code>.2925*2926* @param columnIndex the first column is <code>1</code>, the second2927* is <code>2</code>, and so on; must be <code>1</code> or larger2928* and equal to or less than the number of columns in the rowset2929* @return a <code>java.lang.Object</code> holding the column value;2930* if the value is SQL <code>NULL</code>, the result is <code>null</code>2931* @throws SQLException if the given column index is out of bounds,2932* the cursor is not on a valid row, or there is a problem getting2933* the <code>Class</code> object for a custom mapping2934* @see #getObject(String)2935*/2936public Object getObject(int columnIndex) throws SQLException {2937Object value;2938Map<String, Class<?>> map;29392940// sanity check.2941checkIndex(columnIndex);2942// make sure the cursor is on a valid row2943checkCursor();29442945setLastValueNull(false);2946value = getCurrentRow().getColumnObject(columnIndex);29472948// check for SQL NULL2949if (value == null) {2950setLastValueNull(true);2951return null;2952}2953if (value instanceof Struct) {2954Struct s = (Struct)value;2955map = getTypeMap();2956// look up the class in the map2957Class<?> c = map.get(s.getSQLTypeName());2958if (c != null) {2959// create new instance of the class2960SQLData obj = null;2961try {2962obj = (SQLData) ReflectUtil.newInstance(c);2963} catch(Exception ex) {2964throw new SQLException("Unable to Instantiate: ", ex);2965}2966// get the attributes from the struct2967Object attribs[] = s.getAttributes(map);2968// create the SQLInput "stream"2969SQLInputImpl sqlInput = new SQLInputImpl(attribs, map);2970// read the values...2971obj.readSQL(sqlInput, s.getSQLTypeName());2972return (Object)obj;2973}2974}2975return value;2976}29772978/**2979* Retrieves the value of the designated column in the current row2980* of this <code>CachedRowSetImpl</code> object as an2981* <code>Object</code> value.2982* <P>2983* The type of the <code>Object</code> will be the default2984* Java object type corresponding to the column's SQL type,2985* following the mapping for built-in types specified in the JDBC 3.02986* specification.2987* <P>2988* This method may also be used to read datatabase-specific2989* abstract data types.2990* <P>2991* This implementation of the method <code>getObject</code> extends its2992* behavior so that it gets the attributes of an SQL structured type2993* as an array of <code>Object</code> values. This method also custom2994* maps SQL user-defined types to classes2995* in the Java programming language. When the specified column contains2996* a structured or distinct value, the behavior of this method is as2997* if it were a call to the method <code>getObject(columnIndex,2998* this.getStatement().getConnection().getTypeMap())</code>.2999*3000* @param columnName a <code>String</code> object that must match the3001* SQL name of a column in this rowset, ignoring case3002* @return a <code>java.lang.Object</code> holding the column value;3003* if the value is SQL <code>NULL</code>, the result is <code>null</code>3004* @throws SQLException if (1) the given column name does not match one of3005* this rowset's column names, (2) the cursor is not3006* on a valid row, or (3) there is a problem getting3007* the <code>Class</code> object for a custom mapping3008* @see #getObject(int)3009*/3010public Object getObject(String columnName) throws SQLException {3011return getObject(getColIdxByName(columnName));3012}30133014//----------------------------------------------------------------30153016/**3017* Maps the given column name for one of this <code>CachedRowSetImpl</code>3018* object's columns to its column number.3019*3020* @param columnName a <code>String</code> object that must match the3021* SQL name of a column in this rowset, ignoring case3022* @return the column index of the given column name3023* @throws SQLException if the given column name does not match one3024* of this rowset's column names3025*/3026public int findColumn(String columnName) throws SQLException {3027return getColIdxByName(columnName);3028}302930303031//--------------------------JDBC 2.0-----------------------------------30323033//---------------------------------------------------------------------3034// Getter's and Setter's3035//---------------------------------------------------------------------30363037/**3038* Retrieves the value stored in the designated column3039* of the current row as a <code>java.io.Reader</code> object.3040*3041* <P><B>Note:</B> All the data in the returned stream must3042* be read prior to getting the value of any other column. The3043* next call to a <code>getXXX</code> method implicitly closes the stream.3044*3045* @param columnIndex the first column is <code>1</code>, the second3046* is <code>2</code>, and so on; must be <code>1</code> or larger3047* and equal to or less than the number of columns in the rowset3048* @return a Java character stream that delivers the database column value3049* as a stream of two-byte unicode characters in a3050* <code>java.io.Reader</code> object. If the value is3051* SQL <code>NULL</code>, the result is <code>null</code>.3052* @throws SQLException if (1) the given column index is out of bounds,3053* (2) the cursor is not on one of this rowset's rows or its3054* insert row, or (3) the designated column does not store an3055* SQL <code>CHAR, VARCHAR, <b>LONGVARCHAR</b>, BINARY, VARBINARY</code> or3056* <code>LONGVARBINARY</code> value.3057* The bold SQL type designates the recommended return type.3058* @see #getCharacterStream(String)3059*/3060public java.io.Reader getCharacterStream(int columnIndex) throws SQLException{30613062// sanity check.3063checkIndex(columnIndex);3064// make sure the cursor is on a valid row3065checkCursor();30663067if (isBinary(RowSetMD.getColumnType(columnIndex))) {3068Object value = getCurrentRow().getColumnObject(columnIndex);3069if (value == null) {3070lastValueNull = true;3071return null;3072}3073charStream = new InputStreamReader3074(new ByteArrayInputStream((byte[])value));3075} else if (isString(RowSetMD.getColumnType(columnIndex))) {3076Object value = getCurrentRow().getColumnObject(columnIndex);3077if (value == null) {3078lastValueNull = true;3079return null;3080}3081charStream = new StringReader(value.toString());3082} else {3083throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());3084}30853086return charStream;3087}30883089/**3090* Retrieves the value stored in the designated column3091* of the current row as a <code>java.io.Reader</code> object.3092*3093* <P><B>Note:</B> All the data in the returned stream must3094* be read prior to getting the value of any other column. The3095* next call to a <code>getXXX</code> method implicitly closes the stream.3096*3097* @param columnName a <code>String</code> object giving the SQL name of3098* a column in this <code>CachedRowSetImpl</code> object3099* @return a Java input stream that delivers the database column value3100* as a stream of two-byte Unicode characters. If the value is3101* SQL <code>NULL</code>, the result is <code>null</code>.3102* @throws SQLException if (1) the given column name is not the name of3103* a column in this rowset, (2) the cursor is not on one of3104* this rowset's rows or its insert row, or (3) the designated3105* column does not store an SQL <code>CHAR, VARCHAR, <b>LONGVARCHAR</b>,3106* BINARY, VARYBINARY</code> or <code>LONGVARBINARY</code> value.3107* The bold SQL type designates the recommended return type.3108*/3109public java.io.Reader getCharacterStream(String columnName) throws SQLException {3110return getCharacterStream(getColIdxByName(columnName));3111}31123113/**3114* Retrieves the value of the designated column in the current row3115* of this <code>CachedRowSetImpl</code> object as a3116* <code>java.math.BigDecimal</code> object.3117*3118* @param columnIndex the first column is <code>1</code>, the second3119* is <code>2</code>, and so on; must be <code>1</code> or larger3120* and equal to or less than the number of columns in the rowset3121* @return a <code>java.math.BigDecimal</code> value with full precision;3122* if the value is SQL <code>NULL</code>, the result is <code>null</code>3123* @throws SQLException if (1) the given column index is out of bounds,3124* (2) the cursor is not on one of this rowset's rows or its3125* insert row, or (3) the designated column does not store an3126* SQL <code>TINYINT, SMALLINT, INTEGER, BIGINT, REAL,3127* FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT, CHAR, VARCHAR</code>3128* or <code>LONGVARCHAR</code> value. The bold SQL type designates the3129* recommended return types that this method is used to retrieve.3130* @see #getBigDecimal(String)3131*/3132public BigDecimal getBigDecimal(int columnIndex) throws SQLException {3133Object value;31343135// sanity check.3136checkIndex(columnIndex);3137// make sure the cursor is on a valid row3138checkCursor();31393140setLastValueNull(false);3141value = getCurrentRow().getColumnObject(columnIndex);31423143// check for SQL NULL3144if (value == null) {3145setLastValueNull(true);3146return null;3147}3148try {3149return (new BigDecimal(value.toString().trim()));3150} catch (NumberFormatException ex) {3151throw new SQLException(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.doublefail").toString(),3152new Object[] {value.toString().trim(), columnIndex}));3153}3154}31553156/**3157* Retrieves the value of the designated column in the current row3158* of this <code>CachedRowSetImpl</code> object as a3159* <code>java.math.BigDecimal</code> object.3160*3161* @param columnName a <code>String</code> object that must match the3162* SQL name of a column in this rowset, ignoring case3163* @return a <code>java.math.BigDecimal</code> value with full precision;3164* if the value is SQL <code>NULL</code>, the result is <code>null</code>3165* @throws SQLException if (1) the given column name is not the name of3166* a column in this rowset, (2) the cursor is not on one of3167* this rowset's rows or its insert row, or (3) the designated3168* column does not store an SQL <code>TINYINT, SMALLINT, INTEGER3169* BIGINT, REAL, FLOAT, DOUBLE, <b>DECIMAL</b>, <b>NUMERIC</b>, BIT CHAR,3170* VARCHAR</code> or <code>LONGVARCHAR</code> value. The bold SQL type3171* designates the recommended return type that this method is used to3172* retrieve3173* @see #getBigDecimal(int)3174*/3175public BigDecimal getBigDecimal(String columnName) throws SQLException {3176return getBigDecimal(getColIdxByName(columnName));3177}31783179//---------------------------------------------------------------------3180// Traversal/Positioning3181//---------------------------------------------------------------------31823183/**3184* Returns the number of rows in this <code>CachedRowSetImpl</code> object.3185*3186* @return number of rows in the rowset3187*/3188public int size() {3189return numRows;3190}31913192/**3193* Indicates whether the cursor is before the first row in this3194* <code>CachedRowSetImpl</code> object.3195*3196* @return <code>true</code> if the cursor is before the first row;3197* <code>false</code> otherwise or if the rowset contains no rows3198* @throws SQLException if an error occurs3199*/3200public boolean isBeforeFirst() throws SQLException {3201if (cursorPos == 0 && numRows > 0) {3202return true;3203} else {3204return false;3205}3206}32073208/**3209* Indicates whether the cursor is after the last row in this3210* <code>CachedRowSetImpl</code> object.3211*3212* @return <code>true</code> if the cursor is after the last row;3213* <code>false</code> otherwise or if the rowset contains no rows3214* @throws SQLException if an error occurs3215*/3216public boolean isAfterLast() throws SQLException {3217if (cursorPos == numRows+1 && numRows > 0) {3218return true;3219} else {3220return false;3221}3222}32233224/**3225* Indicates whether the cursor is on the first row in this3226* <code>CachedRowSetImpl</code> object.3227*3228* @return <code>true</code> if the cursor is on the first row;3229* <code>false</code> otherwise or if the rowset contains no rows3230* @throws SQLException if an error occurs3231*/3232public boolean isFirst() throws SQLException {3233// this becomes nasty because of deletes.3234int saveCursorPos = cursorPos;3235int saveAbsoluteCursorPos = absolutePos;3236internalFirst();3237if (cursorPos == saveCursorPos) {3238return true;3239} else {3240cursorPos = saveCursorPos;3241absolutePos = saveAbsoluteCursorPos;3242return false;3243}3244}32453246/**3247* Indicates whether the cursor is on the last row in this3248* <code>CachedRowSetImpl</code> object.3249* <P>3250* Note: Calling the method <code>isLast</code> may be expensive3251* because the JDBC driver might need to fetch ahead one row in order3252* to determine whether the current row is the last row in this rowset.3253*3254* @return <code>true</code> if the cursor is on the last row;3255* <code>false</code> otherwise or if this rowset contains no rows3256* @throws SQLException if an error occurs3257*/3258public boolean isLast() throws SQLException {3259int saveCursorPos = cursorPos;3260int saveAbsoluteCursorPos = absolutePos;3261boolean saveShowDeleted = getShowDeleted();3262setShowDeleted(true);3263internalLast();3264if (cursorPos == saveCursorPos) {3265setShowDeleted(saveShowDeleted);3266return true;3267} else {3268setShowDeleted(saveShowDeleted);3269cursorPos = saveCursorPos;3270absolutePos = saveAbsoluteCursorPos;3271return false;3272}3273}32743275/**3276* Moves this <code>CachedRowSetImpl</code> object's cursor to the front of3277* the rowset, just before the first row. This method has no effect if3278* this rowset contains no rows.3279*3280* @throws SQLException if an error occurs or the type of this rowset3281* is <code>ResultSet.TYPE_FORWARD_ONLY</code>3282*/3283public void beforeFirst() throws SQLException {3284if (getType() == ResultSet.TYPE_FORWARD_ONLY) {3285throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.beforefirst").toString());3286}3287cursorPos = 0;3288absolutePos = 0;3289notifyCursorMoved();3290}32913292/**3293* Moves this <code>CachedRowSetImpl</code> object's cursor to the end of3294* the rowset, just after the last row. This method has no effect if3295* this rowset contains no rows.3296*3297* @throws SQLException if an error occurs3298*/3299public void afterLast() throws SQLException {3300if (numRows > 0) {3301cursorPos = numRows + 1;3302absolutePos = 0;3303notifyCursorMoved();3304}3305}33063307/**3308* Moves this <code>CachedRowSetImpl</code> object's cursor to the first row3309* and returns <code>true</code> if the operation was successful. This3310* method also notifies registered listeners that the cursor has moved.3311*3312* @return <code>true</code> if the cursor is on a valid row;3313* <code>false</code> otherwise or if there are no rows in this3314* <code>CachedRowSetImpl</code> object3315* @throws SQLException if the type of this rowset3316* is <code>ResultSet.TYPE_FORWARD_ONLY</code>3317*/3318public boolean first() throws SQLException {3319if(getType() == ResultSet.TYPE_FORWARD_ONLY) {3320throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.first").toString());3321}33223323// move and notify3324boolean ret = this.internalFirst();3325notifyCursorMoved();33263327return ret;3328}33293330/**3331* Moves this <code>CachedRowSetImpl</code> object's cursor to the first3332* row and returns <code>true</code> if the operation is successful.3333* <P>3334* This method is called internally by the methods <code>first</code>,3335* <code>isFirst</code>, and <code>absolute</code>.3336* It in turn calls the method <code>internalNext</code> in order to3337* handle the case where the first row is a deleted row that is not visible.3338* <p>3339* This is a implementation only method and is not required as a standard3340* implementation of the <code>CachedRowSet</code> interface.3341*3342* @return <code>true</code> if the cursor moved to the first row;3343* <code>false</code> otherwise3344* @throws SQLException if an error occurs3345*/3346protected boolean internalFirst() throws SQLException {3347boolean ret = false;33483349if (numRows > 0) {3350cursorPos = 1;3351if ((getShowDeleted() == false) && (rowDeleted() == true)) {3352ret = internalNext();3353} else {3354ret = true;3355}3356}33573358if (ret == true)3359absolutePos = 1;3360else3361absolutePos = 0;33623363return ret;3364}33653366/**3367* Moves this <code>CachedRowSetImpl</code> object's cursor to the last row3368* and returns <code>true</code> if the operation was successful. This3369* method also notifies registered listeners that the cursor has moved.3370*3371* @return <code>true</code> if the cursor is on a valid row;3372* <code>false</code> otherwise or if there are no rows in this3373* <code>CachedRowSetImpl</code> object3374* @throws SQLException if the type of this rowset3375* is <code>ResultSet.TYPE_FORWARD_ONLY</code>3376*/3377public boolean last() throws SQLException {3378if (getType() == ResultSet.TYPE_FORWARD_ONLY) {3379throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString());3380}33813382// move and notify3383boolean ret = this.internalLast();3384notifyCursorMoved();33853386return ret;3387}33883389/**3390* Moves this <code>CachedRowSetImpl</code> object's cursor to the last3391* row and returns <code>true</code> if the operation is successful.3392* <P>3393* This method is called internally by the method <code>last</code>3394* when rows have been deleted and the deletions are not visible.3395* The method <code>internalLast</code> handles the case where the3396* last row is a deleted row that is not visible by in turn calling3397* the method <code>internalPrevious</code>.3398* <p>3399* This is a implementation only method and is not required as a standard3400* implementation of the <code>CachedRowSet</code> interface.3401*3402* @return <code>true</code> if the cursor moved to the last row;3403* <code>false</code> otherwise3404* @throws SQLException if an error occurs3405*/3406protected boolean internalLast() throws SQLException {3407boolean ret = false;34083409if (numRows > 0) {3410cursorPos = numRows;3411if ((getShowDeleted() == false) && (rowDeleted() == true)) {3412ret = internalPrevious();3413} else {3414ret = true;3415}3416}3417if (ret == true)3418absolutePos = numRows - numDeleted;3419else3420absolutePos = 0;3421return ret;3422}34233424/**3425* Returns the number of the current row in this <code>CachedRowSetImpl</code>3426* object. The first row is number 1, the second number 2, and so on.3427*3428* @return the number of the current row; <code>0</code> if there is no3429* current row3430* @throws SQLException if an error occurs; or if the <code>CacheRowSetImpl</code>3431* is empty3432*/3433public int getRow() throws SQLException {3434// are we on a valid row? Valid rows are between first and last3435if (numRows > 0 &&3436cursorPos > 0 &&3437cursorPos < (numRows + 1) &&3438(getShowDeleted() == false && rowDeleted() == false)) {3439return absolutePos;3440} else if (getShowDeleted() == true) {3441return cursorPos;3442} else {3443return 0;3444}3445}34463447/**3448* Moves this <code>CachedRowSetImpl</code> object's cursor to the row number3449* specified.3450*3451* <p>If the number is positive, the cursor moves to an absolute row with3452* respect to the beginning of the rowset. The first row is row 1, the second3453* is row 2, and so on. For example, the following command, in which3454* <code>crs</code> is a <code>CachedRowSetImpl</code> object, moves the cursor3455* to the fourth row, starting from the beginning of the rowset.3456* <PRE><code>3457*3458* crs.absolute(4);3459*3460* </code> </PRE>3461* <P>3462* If the number is negative, the cursor moves to an absolute row position3463* with respect to the end of the rowset. For example, calling3464* <code>absolute(-1)</code> positions the cursor on the last row,3465* <code>absolute(-2)</code> moves it on the next-to-last row, and so on.3466* If the <code>CachedRowSetImpl</code> object <code>crs</code> has five rows,3467* the following command moves the cursor to the fourth-to-last row, which3468* in the case of a rowset with five rows, is also the second row, counting3469* from the beginning.3470* <PRE><code>3471*3472* crs.absolute(-4);3473*3474* </code> </PRE>3475*3476* If the number specified is larger than the number of rows, the cursor3477* will move to the position after the last row. If the number specified3478* would move the cursor one or more rows before the first row, the cursor3479* moves to the position before the first row.3480* <P>3481* Note: Calling <code>absolute(1)</code> is the same as calling the3482* method <code>first()</code>. Calling <code>absolute(-1)</code> is the3483* same as calling <code>last()</code>.3484*3485* @param row a positive number to indicate the row, starting row numbering from3486* the first row, which is <code>1</code>; a negative number to indicate3487* the row, starting row numbering from the last row, which is3488* <code>-1</code>; it must not be <code>0</code>3489* @return <code>true</code> if the cursor is on the rowset; <code>false</code>3490* otherwise3491* @throws SQLException if the given cursor position is <code>0</code> or the3492* type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code>3493*/3494public boolean absolute( int row ) throws SQLException {3495if (row == 0 || getType() == ResultSet.TYPE_FORWARD_ONLY) {3496throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.absolute").toString());3497}34983499if (row > 0) { // we are moving foward3500if (row > numRows) {3501// fell off the end3502afterLast();3503return false;3504} else {3505if (absolutePos <= 0)3506internalFirst();3507}3508} else { // we are moving backward3509if (cursorPos + row < 0) {3510// fell off the front3511beforeFirst();3512return false;3513} else {3514if (absolutePos >= 0)3515internalLast();3516}3517}35183519// Now move towards the absolute row that we're looking for3520while (absolutePos != row) {3521if (absolutePos < row) {3522if (!internalNext())3523break;3524}3525else {3526if (!internalPrevious())3527break;3528}3529}35303531notifyCursorMoved();35323533if (isAfterLast() || isBeforeFirst()) {3534return false;3535} else {3536return true;3537}3538}35393540/**3541* Moves the cursor the specified number of rows from the current3542* position, with a positive number moving it forward and a3543* negative number moving it backward.3544* <P>3545* If the number is positive, the cursor moves the specified number of3546* rows toward the end of the rowset, starting at the current row.3547* For example, the following command, in which3548* <code>crs</code> is a <code>CachedRowSetImpl</code> object with 100 rows,3549* moves the cursor forward four rows from the current row. If the3550* current row is 50, the cursor would move to row 54.3551* <PRE><code>3552*3553* crs.relative(4);3554*3555* </code> </PRE>3556* <P>3557* If the number is negative, the cursor moves back toward the beginning3558* the specified number of rows, starting at the current row.3559* For example, calling the method3560* <code>absolute(-1)</code> positions the cursor on the last row,3561* <code>absolute(-2)</code> moves it on the next-to-last row, and so on.3562* If the <code>CachedRowSetImpl</code> object <code>crs</code> has five rows,3563* the following command moves the cursor to the fourth-to-last row, which3564* in the case of a rowset with five rows, is also the second row3565* from the beginning.3566* <PRE><code>3567*3568* crs.absolute(-4);3569*3570* </code> </PRE>3571*3572* If the number specified is larger than the number of rows, the cursor3573* will move to the position after the last row. If the number specified3574* would move the cursor one or more rows before the first row, the cursor3575* moves to the position before the first row. In both cases, this method3576* throws an <code>SQLException</code>.3577* <P>3578* Note: Calling <code>absolute(1)</code> is the same as calling the3579* method <code>first()</code>. Calling <code>absolute(-1)</code> is the3580* same as calling <code>last()</code>. Calling <code>relative(0)</code>3581* is valid, but it does not change the cursor position.3582*3583* @param rows an <code>int</code> indicating the number of rows to move3584* the cursor, starting at the current row; a positive number3585* moves the cursor forward; a negative number moves the cursor3586* backward; must not move the cursor past the valid3587* rows3588* @return <code>true</code> if the cursor is on a row in this3589* <code>CachedRowSetImpl</code> object; <code>false</code>3590* otherwise3591* @throws SQLException if there are no rows in this rowset, the cursor is3592* positioned either before the first row or after the last row, or3593* the rowset is type <code>ResultSet.TYPE_FORWARD_ONLY</code>3594*/3595public boolean relative(int rows) throws SQLException {3596if (numRows == 0 || isBeforeFirst() ||3597isAfterLast() || getType() == ResultSet.TYPE_FORWARD_ONLY) {3598throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.relative").toString());3599}36003601if (rows == 0) {3602return true;3603}36043605if (rows > 0) { // we are moving forward3606if (cursorPos + rows > numRows) {3607// fell off the end3608afterLast();3609} else {3610for (int i=0; i < rows; i++) {3611if (!internalNext())3612break;3613}3614}3615} else { // we are moving backward3616if (cursorPos + rows < 0) {3617// fell off the front3618beforeFirst();3619} else {3620for (int i=rows; i < 0; i++) {3621if (!internalPrevious())3622break;3623}3624}3625}3626notifyCursorMoved();36273628if (isAfterLast() || isBeforeFirst()) {3629return false;3630} else {3631return true;3632}3633}36343635/**3636* Moves this <code>CachedRowSetImpl</code> object's cursor to the3637* previous row and returns <code>true</code> if the cursor is on3638* a valid row or <code>false</code> if it is not.3639* This method also notifies all listeners registered with this3640* <code>CachedRowSetImpl</code> object that its cursor has moved.3641* <P>3642* Note: calling the method <code>previous()</code> is not the same3643* as calling the method <code>relative(-1)</code>. This is true3644* because it is possible to call <code>previous()</code> from the insert3645* row, from after the last row, or from the current row, whereas3646* <code>relative</code> may only be called from the current row.3647* <P>3648* The method <code>previous</code> may used in a <code>while</code>3649* loop to iterate through a rowset starting after the last row3650* and moving toward the beginning. The loop ends when <code>previous</code>3651* returns <code>false</code>, meaning that there are no more rows.3652* For example, the following code fragment retrieves all the data in3653* the <code>CachedRowSetImpl</code> object <code>crs</code>, which has3654* three columns. Note that the cursor must initially be positioned3655* after the last row so that the first call to the method3656* <code>previous</code> places the cursor on the last line.3657* <PRE> <code>3658*3659* crs.afterLast();3660* while (previous()) {3661* String name = crs.getString(1);3662* int age = crs.getInt(2);3663* short ssn = crs.getShort(3);3664* System.out.println(name + " " + age + " " + ssn);3665* }3666*3667* </code> </PRE>3668* This method throws an <code>SQLException</code> if the cursor is not3669* on a row in the rowset, before the first row, or after the last row.3670*3671* @return <code>true</code> if the cursor is on a valid row;3672* <code>false</code> if it is before the first row or after the3673* last row3674* @throws SQLException if the cursor is not on a valid position or the3675* type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code>3676*/3677public boolean previous() throws SQLException {3678if (getType() == ResultSet.TYPE_FORWARD_ONLY) {3679throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.last").toString());3680}3681/*3682* make sure things look sane. The cursor must be3683* positioned in the rowset or before first (0) or3684* after last (numRows + 1)3685*/3686if (cursorPos < 0 || cursorPos > numRows + 1) {3687throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());3688}3689// move and notify3690boolean ret = this.internalPrevious();3691notifyCursorMoved();36923693return ret;3694}36953696/**3697* Moves the cursor to the previous row in this <code>CachedRowSetImpl</code>3698* object, skipping past deleted rows that are not visible; returns3699* <code>true</code> if the cursor is on a row in this rowset and3700* <code>false</code> when the cursor goes before the first row.3701* <P>3702* This method is called internally by the method <code>previous</code>.3703* <P>3704* This is a implementation only method and is not required as a standard3705* implementation of the <code>CachedRowSet</code> interface.3706*3707* @return <code>true</code> if the cursor is on a row in this rowset;3708* <code>false</code> when the cursor reaches the position before3709* the first row3710* @throws SQLException if an error occurs3711*/3712protected boolean internalPrevious() throws SQLException {3713boolean ret = false;37143715do {3716if (cursorPos > 1) {3717--cursorPos;3718ret = true;3719} else if (cursorPos == 1) {3720// decrement to before first3721--cursorPos;3722ret = false;3723break;3724}3725} while ((getShowDeleted() == false) && (rowDeleted() == true));37263727/*3728* Each call to internalPrevious may move the cursor3729* over multiple rows, the absolute position moves one one row3730*/3731if (ret == true)3732--absolutePos;3733else3734absolutePos = 0;37353736return ret;3737}373837393740//---------------------------------------------------------------------3741// Updates3742//---------------------------------------------------------------------37433744/**3745* Indicates whether the current row of this <code>CachedRowSetImpl</code>3746* object has been updated. The value returned3747* depends on whether this rowset can detect updates: <code>false</code>3748* will always be returned if it does not detect updates.3749*3750* @return <code>true</code> if the row has been visibly updated3751* by the owner or another and updates are detected;3752* <code>false</code> otherwise3753* @throws SQLException if the cursor is on the insert row or not3754* not on a valid row3755*3756* @see DatabaseMetaData#updatesAreDetected3757*/3758public boolean rowUpdated() throws SQLException {3759// make sure the cursor is on a valid row3760checkCursor();3761if (onInsertRow == true) {3762throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());3763}3764return(((Row)getCurrentRow()).getUpdated());3765}37663767/**3768* Indicates whether the designated column of the current row of3769* this <code>CachedRowSetImpl</code> object has been updated. The3770* value returned depends on whether this rowset can detcted updates:3771* <code>false</code> will always be returned if it does not detect updates.3772*3773* @param idx the index identifier of the column that may be have been updated.3774* @return <code>true</code> is the designated column has been updated3775* and the rowset detects updates; <code>false</code> if the rowset has not3776* been updated or the rowset does not detect updates3777* @throws SQLException if the cursor is on the insert row or not3778* on a valid row3779* @see DatabaseMetaData#updatesAreDetected3780*/3781public boolean columnUpdated(int idx) throws SQLException {3782// make sure the cursor is on a valid row3783checkCursor();3784if (onInsertRow == true) {3785throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());3786}3787return (((Row)getCurrentRow()).getColUpdated(idx - 1));3788}37893790/**3791* Indicates whether the designated column of the current row of3792* this <code>CachedRowSetImpl</code> object has been updated. The3793* value returned depends on whether this rowset can detcted updates:3794* <code>false</code> will always be returned if it does not detect updates.3795*3796* @param columnName the <code>String</code> column name column that may be have3797* been updated.3798* @return <code>true</code> is the designated column has been updated3799* and the rowset detects updates; <code>false</code> if the rowset has not3800* been updated or the rowset does not detect updates3801* @throws SQLException if the cursor is on the insert row or not3802* on a valid row3803* @see DatabaseMetaData#updatesAreDetected3804*/3805public boolean columnUpdated(String columnName) throws SQLException {3806return columnUpdated(getColIdxByName(columnName));3807}38083809/**3810* Indicates whether the current row has been inserted. The value returned3811* depends on whether or not the rowset can detect visible inserts.3812*3813* @return <code>true</code> if a row has been inserted and inserts are detected;3814* <code>false</code> otherwise3815* @throws SQLException if the cursor is on the insert row or not3816* not on a valid row3817*3818* @see DatabaseMetaData#insertsAreDetected3819*/3820public boolean rowInserted() throws SQLException {3821// make sure the cursor is on a valid row3822checkCursor();3823if (onInsertRow == true) {3824throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());3825}3826return(((Row)getCurrentRow()).getInserted());3827}38283829/**3830* Indicates whether the current row has been deleted. A deleted row3831* may leave a visible "hole" in a rowset. This method can be used to3832* detect such holes if the rowset can detect deletions. This method3833* will always return <code>false</code> if this rowset cannot detect3834* deletions.3835*3836* @return <code>true</code> if (1)the current row is blank, indicating that3837* the row has been deleted, and (2)deletions are detected;3838* <code>false</code> otherwise3839* @throws SQLException if the cursor is on a valid row in this rowset3840* @see DatabaseMetaData#deletesAreDetected3841*/3842public boolean rowDeleted() throws SQLException {3843// make sure the cursor is on a valid row38443845if (isAfterLast() == true ||3846isBeforeFirst() == true ||3847onInsertRow == true) {38483849throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());3850}3851return(((Row)getCurrentRow()).getDeleted());3852}38533854/**3855* Indicates whether the given SQL data type is a numberic type.3856*3857* @param type one of the constants from <code>java.sql.Types</code>3858* @return <code>true</code> if the given type is <code>NUMERIC</code>,'3859* <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>,3860* <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>,3861* <code>REAL</code>, <code>DOUBLE</code>, or <code>FLOAT</code>;3862* <code>false</code> otherwise3863*/3864private boolean isNumeric(int type) {3865switch (type) {3866case java.sql.Types.NUMERIC:3867case java.sql.Types.DECIMAL:3868case java.sql.Types.BIT:3869case java.sql.Types.TINYINT:3870case java.sql.Types.SMALLINT:3871case java.sql.Types.INTEGER:3872case java.sql.Types.BIGINT:3873case java.sql.Types.REAL:3874case java.sql.Types.DOUBLE:3875case java.sql.Types.FLOAT:3876return true;3877default:3878return false;3879}3880}38813882/**3883* Indicates whether the given SQL data type is a string type.3884*3885* @param type one of the constants from <code>java.sql.Types</code>3886* @return <code>true</code> if the given type is <code>CHAR</code>,'3887* <code>VARCHAR</code>, or <code>LONGVARCHAR</code>;3888* <code>false</code> otherwise3889*/3890private boolean isString(int type) {3891switch (type) {3892case java.sql.Types.CHAR:3893case java.sql.Types.VARCHAR:3894case java.sql.Types.LONGVARCHAR:3895return true;3896default:3897return false;3898}3899}39003901/**3902* Indicates whether the given SQL data type is a binary type.3903*3904* @param type one of the constants from <code>java.sql.Types</code>3905* @return <code>true</code> if the given type is <code>BINARY</code>,'3906* <code>VARBINARY</code>, or <code>LONGVARBINARY</code>;3907* <code>false</code> otherwise3908*/3909private boolean isBinary(int type) {3910switch (type) {3911case java.sql.Types.BINARY:3912case java.sql.Types.VARBINARY:3913case java.sql.Types.LONGVARBINARY:3914return true;3915default:3916return false;3917}3918}39193920/**3921* Indicates whether the given SQL data type is a temporal type.3922* This method is called internally by the conversion methods3923* <code>convertNumeric</code> and <code>convertTemporal</code>.3924*3925* @param type one of the constants from <code>java.sql.Types</code>3926* @return <code>true</code> if the given type is <code>DATE</code>,3927* <code>TIME</code>, or <code>TIMESTAMP</code>;3928* <code>false</code> otherwise3929*/3930private boolean isTemporal(int type) {3931switch (type) {3932case java.sql.Types.DATE:3933case java.sql.Types.TIME:3934case java.sql.Types.TIMESTAMP:3935return true;3936default:3937return false;3938}3939}39403941/**3942* Indicates whether the given SQL data type is a boolean type.3943* This method is called internally by the conversion methods3944* <code>convertNumeric</code> and <code>convertBoolean</code>.3945*3946* @param type one of the constants from <code>java.sql.Types</code>3947* @return <code>true</code> if the given type is <code>BIT</code>,3948* , or <code>BOOLEAN</code>;3949* <code>false</code> otherwise3950*/3951private boolean isBoolean(int type) {3952switch (type) {3953case java.sql.Types.BIT:3954case java.sql.Types.BOOLEAN:3955return true;3956default:3957return false;3958}3959}396039613962/**3963* Converts the given <code>Object</code> in the Java programming language3964* to the standard mapping for the specified SQL target data type.3965* The conversion must be to a string or numeric type, but there are no3966* restrictions on the type to be converted. If the source type and target3967* type are the same, the given object is simply returned.3968*3969* @param srcObj the <code>Object</code> in the Java programming language3970* that is to be converted to the target type3971* @param srcType the data type that is the standard mapping in SQL of the3972* object to be converted; must be one of the constants in3973* <code>java.sql.Types</code>3974* @param trgType the SQL data type to which to convert the given object;3975* must be one of the following constants in3976* <code>java.sql.Types</code>: <code>NUMERIC</code>,3977* <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>,3978* <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>,3979* <code>REAL</code>, <code>DOUBLE</code>, <code>FLOAT</code>,3980* <code>VARCHAR</code>, <code>LONGVARCHAR</code>, or <code>CHAR</code>3981* @return an <code>Object</code> value.that is3982* the standard object mapping for the target SQL type3983* @throws SQLException if the given target type is not one of the string or3984* numeric types in <code>java.sql.Types</code>3985*/3986private Object convertNumeric(Object srcObj, int srcType,3987int trgType) throws SQLException {39883989if (srcType == trgType) {3990return srcObj;3991}39923993if (isNumeric(trgType) == false && isString(trgType) == false) {3994throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType);3995}39963997try {3998switch (trgType) {3999case java.sql.Types.BIT:4000Integer i = Integer.valueOf(srcObj.toString().trim());4001return i.equals(0) ?4002Boolean.valueOf(false) :4003Boolean.valueOf(true);4004case java.sql.Types.TINYINT:4005return Byte.valueOf(srcObj.toString().trim());4006case java.sql.Types.SMALLINT:4007return Short.valueOf(srcObj.toString().trim());4008case java.sql.Types.INTEGER:4009return Integer.valueOf(srcObj.toString().trim());4010case java.sql.Types.BIGINT:4011return Long.valueOf(srcObj.toString().trim());4012case java.sql.Types.NUMERIC:4013case java.sql.Types.DECIMAL:4014return new BigDecimal(srcObj.toString().trim());4015case java.sql.Types.REAL:4016case java.sql.Types.FLOAT:4017return new Float(srcObj.toString().trim());4018case java.sql.Types.DOUBLE:4019return new Double(srcObj.toString().trim());4020case java.sql.Types.CHAR:4021case java.sql.Types.VARCHAR:4022case java.sql.Types.LONGVARCHAR:4023return srcObj.toString();4024default:4025throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);4026}4027} catch (NumberFormatException ex) {4028throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType);4029}4030}40314032/**4033* Converts the given <code>Object</code> in the Java programming language4034* to the standard object mapping for the specified SQL target data type.4035* The conversion must be to a string or temporal type, and there are also4036* restrictions on the type to be converted.4037* <P>4038* <TABLE ALIGN="CENTER" BORDER CELLPADDING=10 BORDERCOLOR="#0000FF"4039* <CAPTION ALIGN="CENTER"><B>Parameters and Return Values</B></CAPTION>4040* <TR>4041* <TD><B>Source SQL Type</B>4042* <TD><B>Target SQL Type</B>4043* <TD><B>Object Returned</B>4044* </TR>4045* <TR>4046* <TD><code>TIMESTAMP</code>4047* <TD><code>DATE</code>4048* <TD><code>java.sql.Date</code>4049* </TR>4050* <TR>4051* <TD><code>TIMESTAMP</code>4052* <TD><code>TIME</code>4053* <TD><code>java.sql.Time</code>4054* </TR>4055* <TR>4056* <TD><code>TIME</code>4057* <TD><code>TIMESTAMP</code>4058* <TD><code>java.sql.Timestamp</code>4059* </TR>4060* <TR>4061* <TD><code>DATE</code>, <code>TIME</code>, or <code>TIMESTAMP</code>4062* <TD><code>CHAR</code>, <code>VARCHAR</code>, or <code>LONGVARCHAR</code>4063* <TD><code>java.lang.String</code>4064* </TR>4065* </TABLE>4066* <P>4067* If the source type and target type are the same,4068* the given object is simply returned.4069*4070* @param srcObj the <code>Object</code> in the Java programming language4071* that is to be converted to the target type4072* @param srcType the data type that is the standard mapping in SQL of the4073* object to be converted; must be one of the constants in4074* <code>java.sql.Types</code>4075* @param trgType the SQL data type to which to convert the given object;4076* must be one of the following constants in4077* <code>java.sql.Types</code>: <code>DATE</code>,4078* <code>TIME</code>, <code>TIMESTAMP</code>, <code>CHAR</code>,4079* <code>VARCHAR</code>, or <code>LONGVARCHAR</code>4080* @return an <code>Object</code> value.that is4081* the standard object mapping for the target SQL type4082* @throws SQLException if the given target type is not one of the string or4083* temporal types in <code>java.sql.Types</code>4084*/4085private Object convertTemporal(Object srcObj,4086int srcType, int trgType) throws SQLException {40874088if (srcType == trgType) {4089return srcObj;4090}40914092if (isNumeric(trgType) == true ||4093(isString(trgType) == false && isTemporal(trgType) == false)) {4094throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4095}40964097try {4098switch (trgType) {4099case java.sql.Types.DATE:4100if (srcType == java.sql.Types.TIMESTAMP) {4101return new java.sql.Date(((java.sql.Timestamp)srcObj).getTime());4102} else {4103throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4104}4105case java.sql.Types.TIMESTAMP:4106if (srcType == java.sql.Types.TIME) {4107return new Timestamp(((java.sql.Time)srcObj).getTime());4108} else {4109return new Timestamp(((java.sql.Date)srcObj).getTime());4110}4111case java.sql.Types.TIME:4112if (srcType == java.sql.Types.TIMESTAMP) {4113return new Time(((java.sql.Timestamp)srcObj).getTime());4114} else {4115throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4116}4117case java.sql.Types.CHAR:4118case java.sql.Types.VARCHAR:4119case java.sql.Types.LONGVARCHAR:4120return srcObj.toString();4121default:4122throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4123}4124} catch (NumberFormatException ex) {4125throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4126}41274128}41294130/**4131* Converts the given <code>Object</code> in the Java programming language4132* to the standard mapping for the specified SQL target data type.4133* The conversion must be to a string or numeric type, but there are no4134* restrictions on the type to be converted. If the source type and target4135* type are the same, the given object is simply returned.4136*4137* @param srcObj the <code>Object</code> in the Java programming language4138* that is to be converted to the target type4139* @param srcType the data type that is the standard mapping in SQL of the4140* object to be converted; must be one of the constants in4141* <code>java.sql.Types</code>4142* @param trgType the SQL data type to which to convert the given object;4143* must be one of the following constants in4144* <code>java.sql.Types</code>: <code>BIT</code>,4145* or <code>BOOLEAN</code>4146* @return an <code>Object</code> value.that is4147* the standard object mapping for the target SQL type4148* @throws SQLException if the given target type is not one of the Boolean4149* types in <code>java.sql.Types</code>4150*/4151private Object convertBoolean(Object srcObj, int srcType,4152int trgType) throws SQLException {41534154if (srcType == trgType) {4155return srcObj;4156}41574158if (isNumeric(trgType) == true ||4159(isString(trgType) == false && isBoolean(trgType) == false)) {4160throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4161}416241634164try {4165switch (trgType) {4166case java.sql.Types.BIT:4167Integer i = Integer.valueOf(srcObj.toString().trim());4168return i.equals(0) ?4169Boolean.valueOf(false) :4170Boolean.valueOf(true);4171case java.sql.Types.BOOLEAN:4172return Boolean.valueOf(srcObj.toString().trim());4173default:4174throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString()+ trgType);4175}4176} catch (NumberFormatException ex) {4177throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString() + trgType);4178}4179}41804181/**4182* Sets the designated nullable column in the current row or the4183* insert row of this <code>CachedRowSetImpl</code> object with4184* <code>null</code> value.4185* <P>4186* This method updates a column value in the current row or the insert4187* row of this rowset; however, another method must be called to complete4188* the update process. If the cursor is on a row in the rowset, the4189* method {@link #updateRow} must be called to mark the row as updated4190* and to notify listeners that the row has changed.4191* If the cursor is on the insert row, the method {@link #insertRow}4192* must be called to insert the new row into this rowset and to notify4193* listeners that a row has changed.4194* <P>4195* In order to propagate updates in this rowset to the underlying4196* data source, an application must call the method {@link #acceptChanges}4197* after it calls either <code>updateRow</code> or <code>insertRow</code>.4198*4199* @param columnIndex the first column is <code>1</code>, the second4200* is <code>2</code>, and so on; must be <code>1</code> or larger4201* and equal to or less than the number of columns in this rowset4202* @throws SQLException if (1) the given column index is out of bounds,4203* (2) the cursor is not on one of this rowset's rows or its4204* insert row, or (3) this rowset is4205* <code>ResultSet.CONCUR_READ_ONLY</code>4206*/4207public void updateNull(int columnIndex) throws SQLException {4208// sanity check.4209checkIndex(columnIndex);4210// make sure the cursor is on a valid row4211checkCursor();42124213BaseRow row = getCurrentRow();4214row.setColumnObject(columnIndex, null);42154216}42174218/**4219* Sets the designated column in either the current row or the insert4220* row of this <code>CachedRowSetImpl</code> object with the given4221* <code>boolean</code> value.4222* <P>4223* This method updates a column value in the current row or the insert4224* row of this rowset, but it does not update the database.4225* If the cursor is on a row in the rowset, the4226* method {@link #updateRow} must be called to update the database.4227* If the cursor is on the insert row, the method {@link #insertRow}4228* must be called, which will insert the new row into both this rowset4229* and the database. Both of these methods must be called before the4230* cursor moves to another row.4231*4232* @param columnIndex the first column is <code>1</code>, the second4233* is <code>2</code>, and so on; must be <code>1</code> or larger4234* and equal to or less than the number of columns in this rowset4235* @param x the new column value4236* @throws SQLException if (1) the given column index is out of bounds,4237* (2) the cursor is not on one of this rowset's rows or its4238* insert row, or (3) this rowset is4239* <code>ResultSet.CONCUR_READ_ONLY</code>4240*/4241public void updateBoolean(int columnIndex, boolean x) throws SQLException {4242// sanity check.4243checkIndex(columnIndex);4244// make sure the cursor is on a valid row4245checkCursor();4246Object obj = convertBoolean(Boolean.valueOf(x),4247java.sql.Types.BIT,4248RowSetMD.getColumnType(columnIndex));42494250getCurrentRow().setColumnObject(columnIndex, obj);4251}42524253/**4254* Sets the designated column in either the current row or the insert4255* row of this <code>CachedRowSetImpl</code> object with the given4256* <code>byte</code> value.4257* <P>4258* This method updates a column value in the current row or the insert4259* row of this rowset, but it does not update the database.4260* If the cursor is on a row in the rowset, the4261* method {@link #updateRow} must be called to update the database.4262* If the cursor is on the insert row, the method {@link #insertRow}4263* must be called, which will insert the new row into both this rowset4264* and the database. Both of these methods must be called before the4265* cursor moves to another row.4266*4267* @param columnIndex the first column is <code>1</code>, the second4268* is <code>2</code>, and so on; must be <code>1</code> or larger4269* and equal to or less than the number of columns in this rowset4270* @param x the new column value4271* @throws SQLException if (1) the given column index is out of bounds,4272* (2) the cursor is not on one of this rowset's rows or its4273* insert row, or (3) this rowset is4274* <code>ResultSet.CONCUR_READ_ONLY</code>4275*/4276public void updateByte(int columnIndex, byte x) throws SQLException {4277// sanity check.4278checkIndex(columnIndex);4279// make sure the cursor is on a valid row4280checkCursor();42814282Object obj = convertNumeric(Byte.valueOf(x),4283java.sql.Types.TINYINT,4284RowSetMD.getColumnType(columnIndex));42854286getCurrentRow().setColumnObject(columnIndex, obj);4287}42884289/**4290* Sets the designated column in either the current row or the insert4291* row of this <code>CachedRowSetImpl</code> object with the given4292* <code>short</code> value.4293* <P>4294* This method updates a column value in the current row or the insert4295* row of this rowset, but it does not update the database.4296* If the cursor is on a row in the rowset, the4297* method {@link #updateRow} must be called to update the database.4298* If the cursor is on the insert row, the method {@link #insertRow}4299* must be called, which will insert the new row into both this rowset4300* and the database. Both of these methods must be called before the4301* cursor moves to another row.4302*4303* @param columnIndex the first column is <code>1</code>, the second4304* is <code>2</code>, and so on; must be <code>1</code> or larger4305* and equal to or less than the number of columns in this rowset4306* @param x the new column value4307* @throws SQLException if (1) the given column index is out of bounds,4308* (2) the cursor is not on one of this rowset's rows or its4309* insert row, or (3) this rowset is4310* <code>ResultSet.CONCUR_READ_ONLY</code>4311*/4312public void updateShort(int columnIndex, short x) throws SQLException {4313// sanity check.4314checkIndex(columnIndex);4315// make sure the cursor is on a valid row4316checkCursor();43174318Object obj = convertNumeric(Short.valueOf(x),4319java.sql.Types.SMALLINT,4320RowSetMD.getColumnType(columnIndex));43214322getCurrentRow().setColumnObject(columnIndex, obj);4323}43244325/**4326* Sets the designated column in either the current row or the insert4327* row of this <code>CachedRowSetImpl</code> object with the given4328* <code>int</code> value.4329* <P>4330* This method updates a column value in the current row or the insert4331* row of this rowset, but it does not update the database.4332* If the cursor is on a row in the rowset, the4333* method {@link #updateRow} must be called to update the database.4334* If the cursor is on the insert row, the method {@link #insertRow}4335* must be called, which will insert the new row into both this rowset4336* and the database. Both of these methods must be called before the4337* cursor moves to another row.4338*4339* @param columnIndex the first column is <code>1</code>, the second4340* is <code>2</code>, and so on; must be <code>1</code> or larger4341* and equal to or less than the number of columns in this rowset4342* @param x the new column value4343* @throws SQLException if (1) the given column index is out of bounds,4344* (2) the cursor is not on one of this rowset's rows or its4345* insert row, or (3) this rowset is4346* <code>ResultSet.CONCUR_READ_ONLY</code>4347*/4348public void updateInt(int columnIndex, int x) throws SQLException {4349// sanity check.4350checkIndex(columnIndex);4351// make sure the cursor is on a valid row4352checkCursor();4353Object obj = convertNumeric(x,4354java.sql.Types.INTEGER,4355RowSetMD.getColumnType(columnIndex));43564357getCurrentRow().setColumnObject(columnIndex, obj);4358}43594360/**4361* Sets the designated column in either the current row or the insert4362* row of this <code>CachedRowSetImpl</code> object with the given4363* <code>long</code> value.4364* <P>4365* This method updates a column value in the current row or the insert4366* row of this rowset, but it does not update the database.4367* If the cursor is on a row in the rowset, the4368* method {@link #updateRow} must be called to update the database.4369* If the cursor is on the insert row, the method {@link #insertRow}4370* must be called, which will insert the new row into both this rowset4371* and the database. Both of these methods must be called before the4372* cursor moves to another row.4373*4374* @param columnIndex the first column is <code>1</code>, the second4375* is <code>2</code>, and so on; must be <code>1</code> or larger4376* and equal to or less than the number of columns in this rowset4377* @param x the new column value4378* @throws SQLException if (1) the given column index is out of bounds,4379* (2) the cursor is not on one of this rowset's rows or its4380* insert row, or (3) this rowset is4381* <code>ResultSet.CONCUR_READ_ONLY</code>4382*/4383public void updateLong(int columnIndex, long x) throws SQLException {4384// sanity check.4385checkIndex(columnIndex);4386// make sure the cursor is on a valid row4387checkCursor();43884389Object obj = convertNumeric(Long.valueOf(x),4390java.sql.Types.BIGINT,4391RowSetMD.getColumnType(columnIndex));43924393getCurrentRow().setColumnObject(columnIndex, obj);43944395}43964397/**4398* Sets the designated column in either the current row or the insert4399* row of this <code>CachedRowSetImpl</code> object with the given4400* <code>float</code> value.4401* <P>4402* This method updates a column value in the current row or the insert4403* row of this rowset, but it does not update the database.4404* If the cursor is on a row in the rowset, the4405* method {@link #updateRow} must be called to update the database.4406* If the cursor is on the insert row, the method {@link #insertRow}4407* must be called, which will insert the new row into both this rowset4408* and the database. Both of these methods must be called before the4409* cursor moves to another row.4410*4411* @param columnIndex the first column is <code>1</code>, the second4412* is <code>2</code>, and so on; must be <code>1</code> or larger4413* and equal to or less than the number of columns in this rowset4414* @param x the new column value4415* @throws SQLException if (1) the given column index is out of bounds,4416* (2) the cursor is not on one of this rowset's rows or its4417* insert row, or (3) this rowset is4418* <code>ResultSet.CONCUR_READ_ONLY</code>4419*/4420public void updateFloat(int columnIndex, float x) throws SQLException {4421// sanity check.4422checkIndex(columnIndex);4423// make sure the cursor is on a valid row4424checkCursor();44254426Object obj = convertNumeric(Float.valueOf(x),4427java.sql.Types.REAL,4428RowSetMD.getColumnType(columnIndex));44294430getCurrentRow().setColumnObject(columnIndex, obj);4431}44324433/**4434* Sets the designated column in either the current row or the insert4435* row of this <code>CachedRowSetImpl</code> object with the given4436* <code>double</code> value.4437*4438* This method updates a column value in either the current row or4439* the insert row of this rowset, but it does not update the4440* database. If the cursor is on a row in the rowset, the4441* method {@link #updateRow} must be called to update the database.4442* If the cursor is on the insert row, the method {@link #insertRow}4443* must be called, which will insert the new row into both this rowset4444* and the database. Both of these methods must be called before the4445* cursor moves to another row.4446*4447* @param columnIndex the first column is <code>1</code>, the second4448* is <code>2</code>, and so on; must be <code>1</code> or larger4449* and equal to or less than the number of columns in this rowset4450* @param x the new column value4451* @throws SQLException if (1) the given column index is out of bounds,4452* (2) the cursor is not on one of this rowset's rows or its4453* insert row, or (3) this rowset is4454* <code>ResultSet.CONCUR_READ_ONLY</code>4455*/4456public void updateDouble(int columnIndex, double x) throws SQLException {4457// sanity check.4458checkIndex(columnIndex);4459// make sure the cursor is on a valid row4460checkCursor();4461Object obj = convertNumeric(Double.valueOf(x),4462java.sql.Types.DOUBLE,4463RowSetMD.getColumnType(columnIndex));44644465getCurrentRow().setColumnObject(columnIndex, obj);4466}44674468/**4469* Sets the designated column in either the current row or the insert4470* row of this <code>CachedRowSetImpl</code> object with the given4471* <code>java.math.BigDecimal</code> object.4472* <P>4473* This method updates a column value in the current row or the insert4474* row of this rowset, but it does not update the database.4475* If the cursor is on a row in the rowset, the4476* method {@link #updateRow} must be called to update the database.4477* If the cursor is on the insert row, the method {@link #insertRow}4478* must be called, which will insert the new row into both this rowset4479* and the database. Both of these methods must be called before the4480* cursor moves to another row.4481*4482* @param columnIndex the first column is <code>1</code>, the second4483* is <code>2</code>, and so on; must be <code>1</code> or larger4484* and equal to or less than the number of columns in this rowset4485* @param x the new column value4486* @throws SQLException if (1) the given column index is out of bounds,4487* (2) the cursor is not on one of this rowset's rows or its4488* insert row, or (3) this rowset is4489* <code>ResultSet.CONCUR_READ_ONLY</code>4490*/4491public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {4492// sanity check.4493checkIndex(columnIndex);4494// make sure the cursor is on a valid row4495checkCursor();44964497Object obj = convertNumeric(x,4498java.sql.Types.NUMERIC,4499RowSetMD.getColumnType(columnIndex));45004501getCurrentRow().setColumnObject(columnIndex, obj);4502}45034504/**4505* Sets the designated column in either the current row or the insert4506* row of this <code>CachedRowSetImpl</code> object with the given4507* <code>String</code> object.4508* <P>4509* This method updates a column value in either the current row or4510* the insert row of this rowset, but it does not update the4511* database. If the cursor is on a row in the rowset, the4512* method {@link #updateRow} must be called to mark the row as updated.4513* If the cursor is on the insert row, the method {@link #insertRow}4514* must be called to insert the new row into this rowset and mark it4515* as inserted. Both of these methods must be called before the4516* cursor moves to another row.4517* <P>4518* The method <code>acceptChanges</code> must be called if the4519* updated values are to be written back to the underlying database.4520*4521* @param columnIndex the first column is <code>1</code>, the second4522* is <code>2</code>, and so on; must be <code>1</code> or larger4523* and equal to or less than the number of columns in this rowset4524* @param x the new column value4525* @throws SQLException if (1) the given column index is out of bounds,4526* (2) the cursor is not on one of this rowset's rows or its4527* insert row, or (3) this rowset is4528* <code>ResultSet.CONCUR_READ_ONLY</code>4529*/4530public void updateString(int columnIndex, String x) throws SQLException {4531// sanity check.4532checkIndex(columnIndex);4533// make sure the cursor is on a valid row4534checkCursor();45354536getCurrentRow().setColumnObject(columnIndex, x);4537}45384539/**4540* Sets the designated column in either the current row or the insert4541* row of this <code>CachedRowSetImpl</code> object with the given4542* <code>byte</code> array.4543*4544* This method updates a column value in either the current row or4545* the insert row of this rowset, but it does not update the4546* database. If the cursor is on a row in the rowset, the4547* method {@link #updateRow} must be called to update the database.4548* If the cursor is on the insert row, the method {@link #insertRow}4549* must be called, which will insert the new row into both this rowset4550* and the database. Both of these methods must be called before the4551* cursor moves to another row.4552*4553* @param columnIndex the first column is <code>1</code>, the second4554* is <code>2</code>, and so on; must be <code>1</code> or larger4555* and equal to or less than the number of columns in this rowset4556* @param x the new column value4557* @throws SQLException if (1) the given column index is out of bounds,4558* (2) the cursor is not on one of this rowset's rows or its4559* insert row, or (3) this rowset is4560* <code>ResultSet.CONCUR_READ_ONLY</code>4561*/4562public void updateBytes(int columnIndex, byte x[]) throws SQLException {4563// sanity check.4564checkIndex(columnIndex);4565// make sure the cursor is on a valid row4566checkCursor();45674568if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) {4569throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4570}45714572getCurrentRow().setColumnObject(columnIndex, x);4573}45744575/**4576* Sets the designated column in either the current row or the insert4577* row of this <code>CachedRowSetImpl</code> object with the given4578* <code>Date</code> object.4579*4580* This method updates a column value in either the current row or4581* the insert row of this rowset, but it does not update the4582* database. If the cursor is on a row in the rowset, the4583* method {@link #updateRow} must be called to update the database.4584* If the cursor is on the insert row, the method {@link #insertRow}4585* must be called, which will insert the new row into both this rowset4586* and the database. Both of these methods must be called before the4587* cursor moves to another row.4588*4589* @param columnIndex the first column is <code>1</code>, the second4590* is <code>2</code>, and so on; must be <code>1</code> or larger4591* and equal to or less than the number of columns in this rowset4592* @param x the new column value4593* @throws SQLException if (1) the given column index is out of bounds,4594* (2) the cursor is not on one of this rowset's rows or its4595* insert row, (3) the type of the designated column is not4596* an SQL <code>DATE</code> or <code>TIMESTAMP</code>, or4597* (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4598*/4599public void updateDate(int columnIndex, java.sql.Date x) throws SQLException {4600// sanity check.4601checkIndex(columnIndex);4602// make sure the cursor is on a valid row4603checkCursor();46044605Object obj = convertTemporal(x,4606java.sql.Types.DATE,4607RowSetMD.getColumnType(columnIndex));46084609getCurrentRow().setColumnObject(columnIndex, obj);4610}46114612/**4613* Sets the designated column in either the current row or the insert4614* row of this <code>CachedRowSetImpl</code> object with the given4615* <code>Time</code> object.4616*4617* This method updates a column value in either the current row or4618* the insert row of this rowset, but it does not update the4619* database. If the cursor is on a row in the rowset, the4620* method {@link #updateRow} must be called to update the database.4621* If the cursor is on the insert row, the method {@link #insertRow}4622* must be called, which will insert the new row into both this rowset4623* and the database. Both of these methods must be called before the4624* cursor moves to another row.4625*4626* @param columnIndex the first column is <code>1</code>, the second4627* is <code>2</code>, and so on; must be <code>1</code> or larger4628* and equal to or less than the number of columns in this rowset4629* @param x the new column value4630* @throws SQLException if (1) the given column index is out of bounds,4631* (2) the cursor is not on one of this rowset's rows or its4632* insert row, (3) the type of the designated column is not4633* an SQL <code>TIME</code> or <code>TIMESTAMP</code>, or4634* (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4635*/4636public void updateTime(int columnIndex, java.sql.Time x) throws SQLException {4637// sanity check.4638checkIndex(columnIndex);4639// make sure the cursor is on a valid row4640checkCursor();46414642Object obj = convertTemporal(x,4643java.sql.Types.TIME,4644RowSetMD.getColumnType(columnIndex));46454646getCurrentRow().setColumnObject(columnIndex, obj);4647}46484649/**4650* Sets the designated column in either the current row or the insert4651* row of this <code>CachedRowSetImpl</code> object with the given4652* <code>Timestamp</code> object.4653*4654* This method updates a column value in either the current row or4655* the insert row of this rowset, but it does not update the4656* database. If the cursor is on a row in the rowset, the4657* method {@link #updateRow} must be called to update the database.4658* If the cursor is on the insert row, the method {@link #insertRow}4659* must be called, which will insert the new row into both this rowset4660* and the database. Both of these methods must be called before the4661* cursor moves to another row.4662*4663* @param columnIndex the first column is <code>1</code>, the second4664* is <code>2</code>, and so on; must be <code>1</code> or larger4665* and equal to or less than the number of columns in this rowset4666* @param x the new column value4667* @throws SQLException if (1) the given column index is out of bounds,4668* (2) the cursor is not on one of this rowset's rows or its4669* insert row, (3) the type of the designated column is not4670* an SQL <code>DATE</code>, <code>TIME</code>, or4671* <code>TIMESTAMP</code>, or (4) this rowset is4672* <code>ResultSet.CONCUR_READ_ONLY</code>4673*/4674public void updateTimestamp(int columnIndex, java.sql.Timestamp x) throws SQLException {4675// sanity check.4676checkIndex(columnIndex);4677// make sure the cursor is on a valid row4678checkCursor();46794680Object obj = convertTemporal(x,4681java.sql.Types.TIMESTAMP,4682RowSetMD.getColumnType(columnIndex));46834684getCurrentRow().setColumnObject(columnIndex, obj);4685}46864687/**4688* Sets the designated column in either the current row or the insert4689* row of this <code>CachedRowSetImpl</code> object with the given4690* ASCII stream value.4691* <P>4692* This method updates a column value in either the current row or4693* the insert row of this rowset, but it does not update the4694* database. If the cursor is on a row in the rowset, the4695* method {@link #updateRow} must be called to update the database.4696* If the cursor is on the insert row, the method {@link #insertRow}4697* must be called, which will insert the new row into both this rowset4698* and the database. Both of these methods must be called before the4699* cursor moves to another row.4700*4701* @param columnIndex the first column is <code>1</code>, the second4702* is <code>2</code>, and so on; must be <code>1</code> or larger4703* and equal to or less than the number of columns in this rowset4704* @param x the new column value4705* @param length the number of one-byte ASCII characters in the stream4706* @throws SQLException if this method is invoked4707*/4708public void updateAsciiStream(int columnIndex, java.io.InputStream x, int length) throws SQLException {4709// sanity Check4710checkIndex(columnIndex);4711// make sure the cursor is on a valid row4712checkCursor();471347144715if (isString(RowSetMD.getColumnType(columnIndex)) == false &&4716isBinary(RowSetMD.getColumnType(columnIndex)) == false) {4717throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4718}47194720byte buf[] = new byte[length];4721try {4722int charsRead = 0;4723do {4724charsRead += x.read(buf, charsRead, length - charsRead);4725} while (charsRead != length);4726//Changed the condition check to check for length instead of -14727} catch (java.io.IOException ex) {4728throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.asciistream").toString());4729}4730String str = new String(buf);47314732getCurrentRow().setColumnObject(columnIndex, str);47334734}47354736/**4737* Sets the designated column in either the current row or the insert4738* row of this <code>CachedRowSetImpl</code> object with the given4739* <code>java.io.InputStream</code> object.4740* <P>4741* This method updates a column value in either the current row or4742* the insert row of this rowset, but it does not update the4743* database. If the cursor is on a row in the rowset, the4744* method {@link #updateRow} must be called to update the database.4745* If the cursor is on the insert row, the method {@link #insertRow}4746* must be called, which will insert the new row into both this rowset4747* and the database. Both of these methods must be called before the4748* cursor moves to another row.4749*4750* @param columnIndex the first column is <code>1</code>, the second4751* is <code>2</code>, and so on; must be <code>1</code> or larger4752* and equal to or less than the number of columns in this rowset4753* @param x the new column value; must be a <code>java.io.InputStream</code>4754* containing <code>BINARY</code>, <code>VARBINARY</code>, or4755* <code>LONGVARBINARY</code> data4756* @param length the length of the stream in bytes4757* @throws SQLException if (1) the given column index is out of bounds,4758* (2) the cursor is not on one of this rowset's rows or its4759* insert row, (3) the data in the stream is not binary, or4760* (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4761*/4762public void updateBinaryStream(int columnIndex, java.io.InputStream x,int length) throws SQLException {4763// sanity Check4764checkIndex(columnIndex);4765// make sure the cursor is on a valid row4766checkCursor();47674768if (isBinary(RowSetMD.getColumnType(columnIndex)) == false) {4769throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4770}47714772byte buf[] = new byte[length];4773try {4774int bytesRead = 0;4775do {4776bytesRead += x.read(buf, bytesRead, length - bytesRead);4777} while (bytesRead != -1);4778} catch (java.io.IOException ex) {4779throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString());4780}47814782getCurrentRow().setColumnObject(columnIndex, buf);4783}47844785/**4786* Sets the designated column in either the current row or the insert4787* row of this <code>CachedRowSetImpl</code> object with the given4788* <code>java.io.Reader</code> object.4789* <P>4790* This method updates a column value in either the current row or4791* the insert row of this rowset, but it does not update the4792* database. If the cursor is on a row in the rowset, the4793* method {@link #updateRow} must be called to update the database.4794* If the cursor is on the insert row, the method {@link #insertRow}4795* must be called, which will insert the new row into both this rowset4796* and the database. Both of these methods must be called before the4797* cursor moves to another row.4798*4799* @param columnIndex the first column is <code>1</code>, the second4800* is <code>2</code>, and so on; must be <code>1</code> or larger4801* and equal to or less than the number of columns in this rowset4802* @param x the new column value; must be a <code>java.io.Reader</code>4803* containing <code>BINARY</code>, <code>VARBINARY</code>,4804* <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,4805* or <code>LONGVARCHAR</code> data4806* @param length the length of the stream in characters4807* @throws SQLException if (1) the given column index is out of bounds,4808* (2) the cursor is not on one of this rowset's rows or its4809* insert row, (3) the data in the stream is not a binary or4810* character type, or (4) this rowset is4811* <code>ResultSet.CONCUR_READ_ONLY</code>4812*/4813public void updateCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException {4814// sanity Check4815checkIndex(columnIndex);4816// make sure the cursor is on a valid row4817checkCursor();48184819if (isString(RowSetMD.getColumnType(columnIndex)) == false &&4820isBinary(RowSetMD.getColumnType(columnIndex)) == false) {4821throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());4822}48234824char buf[] = new char[length];4825try {4826int charsRead = 0;4827do {4828charsRead += x.read(buf, charsRead, length - charsRead);4829} while (charsRead != length);4830//Changed the condition checking to check for length instead of -14831} catch (java.io.IOException ex) {4832throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.binstream").toString());4833}4834String str = new String(buf);48354836getCurrentRow().setColumnObject(columnIndex, str);4837}48384839/**4840* Sets the designated column in either the current row or the insert4841* row of this <code>CachedRowSetImpl</code> object with the given4842* <code>Object</code> value. The <code>scale</code> parameter indicates4843* the number of digits to the right of the decimal point and is ignored4844* if the new column value is not a type that will be mapped to an SQL4845* <code>DECIMAL</code> or <code>NUMERIC</code> value.4846* <P>4847* This method updates a column value in either the current row or4848* the insert row of this rowset, but it does not update the4849* database. If the cursor is on a row in the rowset, the4850* method {@link #updateRow} must be called to update the database.4851* If the cursor is on the insert row, the method {@link #insertRow}4852* must be called, which will insert the new row into both this rowset4853* and the database. Both of these methods must be called before the4854* cursor moves to another row.4855*4856* @param columnIndex the first column is <code>1</code>, the second4857* is <code>2</code>, and so on; must be <code>1</code> or larger4858* and equal to or less than the number of columns in this rowset4859* @param x the new column value4860* @param scale the number of digits to the right of the decimal point (for4861* <code>DECIMAL</code> and <code>NUMERIC</code> types only)4862* @throws SQLException if (1) the given column index is out of bounds,4863* (2) the cursor is not on one of this rowset's rows or its4864* insert row, or (3) this rowset is4865* <code>ResultSet.CONCUR_READ_ONLY</code>4866*/4867public void updateObject(int columnIndex, Object x, int scale) throws SQLException {4868// sanity check.4869checkIndex(columnIndex);4870// make sure the cursor is on a valid row4871checkCursor();48724873int type = RowSetMD.getColumnType(columnIndex);4874if (type == Types.DECIMAL || type == Types.NUMERIC) {4875((java.math.BigDecimal)x).setScale(scale);4876}4877getCurrentRow().setColumnObject(columnIndex, x);4878}48794880/**4881* Sets the designated column in either the current row or the insert4882* row of this <code>CachedRowSetImpl</code> object with the given4883* <code>Object</code> value.4884* <P>4885* This method updates a column value in either the current row or4886* the insert row of this rowset, but it does not update the4887* database. If the cursor is on a row in the rowset, the4888* method {@link #updateRow} must be called to update the database.4889* If the cursor is on the insert row, the method {@link #insertRow}4890* must be called, which will insert the new row into both this rowset4891* and the database. Both of these methods must be called before the4892* cursor moves to another row.4893*4894* @param columnIndex the first column is <code>1</code>, the second4895* is <code>2</code>, and so on; must be <code>1</code> or larger4896* and equal to or less than the number of columns in this rowset4897* @param x the new column value4898* @throws SQLException if (1) the given column index is out of bounds,4899* (2) the cursor is not on one of this rowset's rows or its4900* insert row, or (3) this rowset is4901* <code>ResultSet.CONCUR_READ_ONLY</code>4902*/4903public void updateObject(int columnIndex, Object x) throws SQLException {4904// sanity check.4905checkIndex(columnIndex);4906// make sure the cursor is on a valid row4907checkCursor();49084909getCurrentRow().setColumnObject(columnIndex, x);4910}49114912/**4913* Sets the designated nullable column in the current row or the4914* insert row of this <code>CachedRowSetImpl</code> object with4915* <code>null</code> value.4916* <P>4917* This method updates a column value in the current row or the insert4918* row of this rowset, but it does not update the database.4919* If the cursor is on a row in the rowset, the4920* method {@link #updateRow} must be called to update the database.4921* If the cursor is on the insert row, the method {@link #insertRow}4922* must be called, which will insert the new row into both this rowset4923* and the database.4924*4925* @param columnName a <code>String</code> object that must match the4926* SQL name of a column in this rowset, ignoring case4927* @throws SQLException if (1) the given column name does not match the4928* name of a column in this rowset, (2) the cursor is not on4929* one of this rowset's rows or its insert row, or (3) this4930* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4931*/4932public void updateNull(String columnName) throws SQLException {4933updateNull(getColIdxByName(columnName));4934}49354936/**4937* Sets the designated column in either the current row or the insert4938* row of this <code>CachedRowSetImpl</code> object with the given4939* <code>boolean</code> value.4940* <P>4941* This method updates a column value in the current row or the insert4942* row of this rowset, but it does not update the database.4943* If the cursor is on a row in the rowset, the4944* method {@link #updateRow} must be called to update the database.4945* If the cursor is on the insert row, the method {@link #insertRow}4946* must be called, which will insert the new row into both this rowset4947* and the database. Both of these methods must be called before the4948* cursor moves to another row.4949*4950* @param columnName a <code>String</code> object that must match the4951* SQL name of a column in this rowset, ignoring case4952* @param x the new column value4953* @throws SQLException if (1) the given column name does not match the4954* name of a column in this rowset, (2) the cursor is not on4955* one of this rowset's rows or its insert row, or (3) this4956* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4957*/4958public void updateBoolean(String columnName, boolean x) throws SQLException {4959updateBoolean(getColIdxByName(columnName), x);4960}49614962/**4963* Sets the designated column in either the current row or the insert4964* row of this <code>CachedRowSetImpl</code> object with the given4965* <code>byte</code> value.4966* <P>4967* This method updates a column value in the current row or the insert4968* row of this rowset, but it does not update the database.4969* If the cursor is on a row in the rowset, the4970* method {@link #updateRow} must be called to update the database.4971* If the cursor is on the insert row, the method {@link #insertRow}4972* must be called, which will insert the new row into both this rowset4973* and the database. Both of these methods must be called before the4974* cursor moves to another row.4975*4976* @param columnName a <code>String</code> object that must match the4977* SQL name of a column in this rowset, ignoring case4978* @param x the new column value4979* @throws SQLException if (1) the given column name does not match the4980* name of a column in this rowset, (2) the cursor is not on4981* one of this rowset's rows or its insert row, or (3) this4982* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>4983*/4984public void updateByte(String columnName, byte x) throws SQLException {4985updateByte(getColIdxByName(columnName), x);4986}49874988/**4989* Sets the designated column in either the current row or the insert4990* row of this <code>CachedRowSetImpl</code> object with the given4991* <code>short</code> value.4992* <P>4993* This method updates a column value in the current row or the insert4994* row of this rowset, but it does not update the database.4995* If the cursor is on a row in the rowset, the4996* method {@link #updateRow} must be called to update the database.4997* If the cursor is on the insert row, the method {@link #insertRow}4998* must be called, which will insert the new row into both this rowset4999* and the database. Both of these methods must be called before the5000* cursor moves to another row.5001*5002* @param columnName a <code>String</code> object that must match the5003* SQL name of a column in this rowset, ignoring case5004* @param x the new column value5005* @throws SQLException if (1) the given column name does not match the5006* name of a column in this rowset, (2) the cursor is not on5007* one of this rowset's rows or its insert row, or (3) this5008* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5009*/5010public void updateShort(String columnName, short x) throws SQLException {5011updateShort(getColIdxByName(columnName), x);5012}50135014/**5015* Sets the designated column in either the current row or the insert5016* row of this <code>CachedRowSetImpl</code> object with the given5017* <code>int</code> value.5018* <P>5019* This method updates a column value in the current row or the insert5020* row of this rowset, but it does not update the database.5021* If the cursor is on a row in the rowset, the5022* method {@link #updateRow} must be called to update the database.5023* If the cursor is on the insert row, the method {@link #insertRow}5024* must be called, which will insert the new row into both this rowset5025* and the database. Both of these methods must be called before the5026* cursor moves to another row.5027*5028* @param columnName a <code>String</code> object that must match the5029* SQL name of a column in this rowset, ignoring case5030* @param x the new column value5031* @throws SQLException if (1) the given column name does not match the5032* name of a column in this rowset, (2) the cursor is not on5033* one of this rowset's rows or its insert row, or (3) this5034* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5035*/5036public void updateInt(String columnName, int x) throws SQLException {5037updateInt(getColIdxByName(columnName), x);5038}50395040/**5041* Sets the designated column in either the current row or the insert5042* row of this <code>CachedRowSetImpl</code> object with the given5043* <code>long</code> value.5044* <P>5045* This method updates a column value in the current row or the insert5046* row of this rowset, but it does not update the database.5047* If the cursor is on a row in the rowset, the5048* method {@link #updateRow} must be called to update the database.5049* If the cursor is on the insert row, the method {@link #insertRow}5050* must be called, which will insert the new row into both this rowset5051* and the database. Both of these methods must be called before the5052* cursor moves to another row.5053*5054* @param columnName a <code>String</code> object that must match the5055* SQL name of a column in this rowset, ignoring case5056* @param x the new column value5057* @throws SQLException if (1) the given column name does not match the5058* name of a column in this rowset, (2) the cursor is not on5059* one of this rowset's rows or its insert row, or (3) this5060* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5061*/5062public void updateLong(String columnName, long x) throws SQLException {5063updateLong(getColIdxByName(columnName), x);5064}50655066/**5067* Sets the designated column in either the current row or the insert5068* row of this <code>CachedRowSetImpl</code> object with the given5069* <code>float</code> value.5070* <P>5071* This method updates a column value in the current row or the insert5072* row of this rowset, but it does not update the database.5073* If the cursor is on a row in the rowset, the5074* method {@link #updateRow} must be called to update the database.5075* If the cursor is on the insert row, the method {@link #insertRow}5076* must be called, which will insert the new row into both this rowset5077* and the database. Both of these methods must be called before the5078* cursor moves to another row.5079*5080* @param columnName a <code>String</code> object that must match the5081* SQL name of a column in this rowset, ignoring case5082* @param x the new column value5083* @throws SQLException if (1) the given column name does not match the5084* name of a column in this rowset, (2) the cursor is not on5085* one of this rowset's rows or its insert row, or (3) this5086* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5087*/5088public void updateFloat(String columnName, float x) throws SQLException {5089updateFloat(getColIdxByName(columnName), x);5090}50915092/**5093* Sets the designated column in either the current row or the insert5094* row of this <code>CachedRowSetImpl</code> object with the given5095* <code>double</code> value.5096*5097* This method updates a column value in either the current row or5098* the insert row of this rowset, but it does not update the5099* database. If the cursor is on a row in the rowset, the5100* method {@link #updateRow} must be called to update the database.5101* If the cursor is on the insert row, the method {@link #insertRow}5102* must be called, which will insert the new row into both this rowset5103* and the database. Both of these methods must be called before the5104* cursor moves to another row.5105*5106* @param columnName a <code>String</code> object that must match the5107* SQL name of a column in this rowset, ignoring case5108* @param x the new column value5109* @throws SQLException if (1) the given column name does not match the5110* name of a column in this rowset, (2) the cursor is not on5111* one of this rowset's rows or its insert row, or (3) this5112* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5113*/5114public void updateDouble(String columnName, double x) throws SQLException {5115updateDouble(getColIdxByName(columnName), x);5116}51175118/**5119* Sets the designated column in either the current row or the insert5120* row of this <code>CachedRowSetImpl</code> object with the given5121* <code>java.math.BigDecimal</code> object.5122* <P>5123* This method updates a column value in the current row or the insert5124* row of this rowset, but it does not update the database.5125* If the cursor is on a row in the rowset, the5126* method {@link #updateRow} must be called to update the database.5127* If the cursor is on the insert row, the method {@link #insertRow}5128* must be called, which will insert the new row into both this rowset5129* and the database. Both of these methods must be called before the5130* cursor moves to another row.5131*5132* @param columnName a <code>String</code> object that must match the5133* SQL name of a column in this rowset, ignoring case5134* @param x the new column value5135* @throws SQLException if (1) the given column name does not match the5136* name of a column in this rowset, (2) the cursor is not on5137* one of this rowset's rows or its insert row, or (3) this5138* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5139*/5140public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {5141updateBigDecimal(getColIdxByName(columnName), x);5142}51435144/**5145* Sets the designated column in either the current row or the insert5146* row of this <code>CachedRowSetImpl</code> object with the given5147* <code>String</code> object.5148*5149* This method updates a column value in either the current row or5150* the insert row of this rowset, but it does not update the5151* database. If the cursor is on a row in the rowset, the5152* method {@link #updateRow} must be called to update the database.5153* If the cursor is on the insert row, the method {@link #insertRow}5154* must be called, which will insert the new row into both this rowset5155* and the database. Both of these methods must be called before the5156* cursor moves to another row.5157*5158* @param columnName a <code>String</code> object that must match the5159* SQL name of a column in this rowset, ignoring case5160* @param x the new column value5161* @throws SQLException if (1) the given column name does not match the5162* name of a column in this rowset, (2) the cursor is not on5163* one of this rowset's rows or its insert row, or (3) this5164* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5165*/5166public void updateString(String columnName, String x) throws SQLException {5167updateString(getColIdxByName(columnName), x);5168}51695170/**5171* Sets the designated column in either the current row or the insert5172* row of this <code>CachedRowSetImpl</code> object with the given5173* <code>byte</code> array.5174*5175* This method updates a column value in either the current row or5176* the insert row of this rowset, but it does not update the5177* database. If the cursor is on a row in the rowset, the5178* method {@link #updateRow} must be called to update the database.5179* If the cursor is on the insert row, the method {@link #insertRow}5180* must be called, which will insert the new row into both this rowset5181* and the database. Both of these methods must be called before the5182* cursor moves to another row.5183*5184* @param columnName a <code>String</code> object that must match the5185* SQL name of a column in this rowset, ignoring case5186* @param x the new column value5187* @throws SQLException if (1) the given column name does not match the5188* name of a column in this rowset, (2) the cursor is not on5189* one of this rowset's rows or its insert row, or (3) this5190* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5191*/5192public void updateBytes(String columnName, byte x[]) throws SQLException {5193updateBytes(getColIdxByName(columnName), x);5194}51955196/**5197* Sets the designated column in either the current row or the insert5198* row of this <code>CachedRowSetImpl</code> object with the given5199* <code>Date</code> object.5200*5201* This method updates a column value in either the current row or5202* the insert row of this rowset, but it does not update the5203* database. If the cursor is on a row in the rowset, the5204* method {@link #updateRow} must be called to update the database.5205* If the cursor is on the insert row, the method {@link #insertRow}5206* must be called, which will insert the new row into both this rowset5207* and the database. Both of these methods must be called before the5208* cursor moves to another row.5209*5210* @param columnName a <code>String</code> object that must match the5211* SQL name of a column in this rowset, ignoring case5212* @param x the new column value5213* @throws SQLException if (1) the given column name does not match the5214* name of a column in this rowset, (2) the cursor is not on5215* one of this rowset's rows or its insert row, (3) the type5216* of the designated column is not an SQL <code>DATE</code> or5217* <code>TIMESTAMP</code>, or (4) this rowset is5218* <code>ResultSet.CONCUR_READ_ONLY</code>5219*/5220public void updateDate(String columnName, java.sql.Date x) throws SQLException {5221updateDate(getColIdxByName(columnName), x);5222}52235224/**5225* Sets the designated column in either the current row or the insert5226* row of this <code>CachedRowSetImpl</code> object with the given5227* <code>Time</code> object.5228*5229* This method updates a column value in either the current row or5230* the insert row of this rowset, but it does not update the5231* database. If the cursor is on a row in the rowset, the5232* method {@link #updateRow} must be called to update the database.5233* If the cursor is on the insert row, the method {@link #insertRow}5234* must be called, which will insert the new row into both this rowset5235* and the database. Both of these methods must be called before the5236* cursor moves to another row.5237*5238* @param columnName a <code>String</code> object that must match the5239* SQL name of a column in this rowset, ignoring case5240* @param x the new column value5241* @throws SQLException if (1) the given column name does not match the5242* name of a column in this rowset, (2) the cursor is not on5243* one of this rowset's rows or its insert row, (3) the type5244* of the designated column is not an SQL <code>TIME</code> or5245* <code>TIMESTAMP</code>, or (4) this rowset is5246* <code>ResultSet.CONCUR_READ_ONLY</code>5247*/5248public void updateTime(String columnName, java.sql.Time x) throws SQLException {5249updateTime(getColIdxByName(columnName), x);5250}52515252/**5253* Sets the designated column in either the current row or the insert5254* row of this <code>CachedRowSetImpl</code> object with the given5255* <code>Timestamp</code> object.5256*5257* This method updates a column value in either the current row or5258* the insert row of this rowset, but it does not update the5259* database. If the cursor is on a row in the rowset, the5260* method {@link #updateRow} must be called to update the database.5261* If the cursor is on the insert row, the method {@link #insertRow}5262* must be called, which will insert the new row into both this rowset5263* and the database. Both of these methods must be called before the5264* cursor moves to another row.5265*5266* @param columnName a <code>String</code> object that must match the5267* SQL name of a column in this rowset, ignoring case5268* @param x the new column value5269* @throws SQLException if the given column index is out of bounds or5270* the cursor is not on one of this rowset's rows or its5271* insert row5272* @throws SQLException if (1) the given column name does not match the5273* name of a column in this rowset, (2) the cursor is not on5274* one of this rowset's rows or its insert row, (3) the type5275* of the designated column is not an SQL <code>DATE</code>,5276* <code>TIME</code>, or <code>TIMESTAMP</code>, or (4) this5277* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5278*/5279public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException {5280updateTimestamp(getColIdxByName(columnName), x);5281}52825283/**5284* Sets the designated column in either the current row or the insert5285* row of this <code>CachedRowSetImpl</code> object with the given5286* ASCII stream value.5287* <P>5288* This method updates a column value in either the current row or5289* the insert row of this rowset, but it does not update the5290* database. If the cursor is on a row in the rowset, the5291* method {@link #updateRow} must be called to update the database.5292* If the cursor is on the insert row, the method {@link #insertRow}5293* must be called, which will insert the new row into both this rowset5294* and the database. Both of these methods must be called before the5295* cursor moves to another row.5296*5297* @param columnName a <code>String</code> object that must match the5298* SQL name of a column in this rowset, ignoring case5299* @param x the new column value5300* @param length the number of one-byte ASCII characters in the stream5301*/5302public void updateAsciiStream(String columnName,5303java.io.InputStream x,5304int length) throws SQLException {5305updateAsciiStream(getColIdxByName(columnName), x, length);5306}53075308/**5309* Sets the designated column in either the current row or the insert5310* row of this <code>CachedRowSetImpl</code> object with the given5311* <code>java.io.InputStream</code> object.5312* <P>5313* This method updates a column value in either the current row or5314* the insert row of this rowset, but it does not update the5315* database. If the cursor is on a row in the rowset, the5316* method {@link #updateRow} must be called to update the database.5317* If the cursor is on the insert row, the method {@link #insertRow}5318* must be called, which will insert the new row into both this rowset5319* and the database. Both of these methods must be called before the5320* cursor moves to another row.5321*5322* @param columnName a <code>String</code> object that must match the5323* SQL name of a column in this rowset, ignoring case5324* @param x the new column value; must be a <code>java.io.InputStream</code>5325* containing <code>BINARY</code>, <code>VARBINARY</code>, or5326* <code>LONGVARBINARY</code> data5327* @param length the length of the stream in bytes5328* @throws SQLException if (1) the given column name does not match the5329* name of a column in this rowset, (2) the cursor is not on5330* one of this rowset's rows or its insert row, (3) the data5331* in the stream is not binary, or (4) this rowset is5332* <code>ResultSet.CONCUR_READ_ONLY</code>5333*/5334public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException {5335updateBinaryStream(getColIdxByName(columnName), x, length);5336}53375338/**5339* Sets the designated column in either the current row or the insert5340* row of this <code>CachedRowSetImpl</code> object with the given5341* <code>java.io.Reader</code> object.5342* <P>5343* This method updates a column value in either the current row or5344* the insert row of this rowset, but it does not update the5345* database. If the cursor is on a row in the rowset, the5346* method {@link #updateRow} must be called to update the database.5347* If the cursor is on the insert row, the method {@link #insertRow}5348* must be called, which will insert the new row into both this rowset5349* and the database. Both of these methods must be called before the5350* cursor moves to another row.5351*5352* @param columnName a <code>String</code> object that must match the5353* SQL name of a column in this rowset, ignoring case5354* @param reader the new column value; must be a5355* <code>java.io.Reader</code> containing <code>BINARY</code>,5356* <code>VARBINARY</code>, <code>LONGVARBINARY</code>, <code>CHAR</code>,5357* <code>VARCHAR</code>, or <code>LONGVARCHAR</code> data5358* @param length the length of the stream in characters5359* @throws SQLException if (1) the given column name does not match the5360* name of a column in this rowset, (2) the cursor is not on5361* one of this rowset's rows or its insert row, (3) the data5362* in the stream is not a binary or character type, or (4) this5363* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5364*/5365public void updateCharacterStream(String columnName,5366java.io.Reader reader,5367int length) throws SQLException {5368updateCharacterStream(getColIdxByName(columnName), reader, length);5369}53705371/**5372* Sets the designated column in either the current row or the insert5373* row of this <code>CachedRowSetImpl</code> object with the given5374* <code>Object</code> value. The <code>scale</code> parameter5375* indicates the number of digits to the right of the decimal point5376* and is ignored if the new column value is not a type that will be5377* mapped to an SQL <code>DECIMAL</code> or <code>NUMERIC</code> value.5378* <P>5379* This method updates a column value in either the current row or5380* the insert row of this rowset, but it does not update the5381* database. If the cursor is on a row in the rowset, the5382* method {@link #updateRow} must be called to update the database.5383* If the cursor is on the insert row, the method {@link #insertRow}5384* must be called, which will insert the new row into both this rowset5385* and the database. Both of these methods must be called before the5386* cursor moves to another row.5387*5388* @param columnName a <code>String</code> object that must match the5389* SQL name of a column in this rowset, ignoring case5390* @param x the new column value5391* @param scale the number of digits to the right of the decimal point (for5392* <code>DECIMAL</code> and <code>NUMERIC</code> types only)5393* @throws SQLException if (1) the given column name does not match the5394* name of a column in this rowset, (2) the cursor is not on5395* one of this rowset's rows or its insert row, or (3) this5396* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5397*/5398public void updateObject(String columnName, Object x, int scale) throws SQLException {5399updateObject(getColIdxByName(columnName), x, scale);5400}54015402/**5403* Sets the designated column in either the current row or the insert5404* row of this <code>CachedRowSetImpl</code> object with the given5405* <code>Object</code> value.5406* <P>5407* This method updates a column value in either the current row or5408* the insert row of this rowset, but it does not update the5409* database. If the cursor is on a row in the rowset, the5410* method {@link #updateRow} must be called to update the database.5411* If the cursor is on the insert row, the method {@link #insertRow}5412* must be called, which will insert the new row into both this rowset5413* and the database. Both of these methods must be called before the5414* cursor moves to another row.5415*5416* @param columnName a <code>String</code> object that must match the5417* SQL name of a column in this rowset, ignoring case5418* @param x the new column value5419* @throws SQLException if (1) the given column name does not match the5420* name of a column in this rowset, (2) the cursor is not on5421* one of this rowset's rows or its insert row, or (3) this5422* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5423*/5424public void updateObject(String columnName, Object x) throws SQLException {5425updateObject(getColIdxByName(columnName), x);5426}54275428/**5429* Inserts the contents of this <code>CachedRowSetImpl</code> object's insert5430* row into this rowset immediately following the current row.5431* If the current row is the5432* position after the last row or before the first row, the new row will5433* be inserted at the end of the rowset. This method also notifies5434* listeners registered with this rowset that the row has changed.5435* <P>5436* The cursor must be on the insert row when this method is called.5437*5438* @throws SQLException if (1) the cursor is not on the insert row,5439* (2) one or more of the non-nullable columns in the insert5440* row has not been given a value, or (3) this rowset is5441* <code>ResultSet.CONCUR_READ_ONLY</code>5442*/5443public void insertRow() throws SQLException {5444int pos;54455446if (onInsertRow == false ||5447insertRow.isCompleteRow(RowSetMD) == false) {5448throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.failedins").toString());5449}5450// Added the setting of parameters that are passed5451// to setXXX methods after an empty CRS Object is5452// created through RowSetMetaData object5453Object [] toInsert = getParams();54545455for(int i = 0;i < toInsert.length; i++) {5456insertRow.setColumnObject(i+1,toInsert[i]);5457}54585459Row insRow = new Row(RowSetMD.getColumnCount(),5460insertRow.getOrigRow());5461insRow.setInserted();5462/*5463* The new row is inserted into the RowSet5464* immediately following the current row.5465*5466* If we are afterlast then the rows are5467* inserted at the end.5468*/5469if (currentRow >= numRows || currentRow < 0) {5470pos = numRows;5471} else {5472pos = currentRow;5473}54745475rvh.add(pos, insRow);5476++numRows;5477// notify the listeners that the row changed.5478notifyRowChanged();5479}54805481/**5482* Marks the current row of this <code>CachedRowSetImpl</code> object as5483* updated and notifies listeners registered with this rowset that the5484* row has changed.5485* <P>5486* This method cannot be called when the cursor is on the insert row, and5487* it should be called before the cursor moves to another row. If it is5488* called after the cursor moves to another row, this method has no effect,5489* and the updates made before the cursor moved will be lost.5490*5491* @throws SQLException if the cursor is on the insert row or this5492* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>5493*/5494public void updateRow() throws SQLException {5495// make sure we aren't on the insert row5496if (onInsertRow == true) {5497throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.updateins").toString());5498}54995500((Row)getCurrentRow()).setUpdated();55015502// notify the listeners that the row changed.5503notifyRowChanged();5504}55055506/**5507* Deletes the current row from this <code>CachedRowSetImpl</code> object and5508* notifies listeners registered with this rowset that a row has changed.5509* This method cannot be called when the cursor is on the insert row.5510* <P>5511* This method marks the current row as deleted, but it does not delete5512* the row from the underlying data source. The method5513* <code>acceptChanges</code> must be called to delete the row in5514* the data source.5515*5516* @throws SQLException if (1) this method is called when the cursor5517* is on the insert row, before the first row, or after the5518* last row or (2) this rowset is5519* <code>ResultSet.CONCUR_READ_ONLY</code>5520*/5521public void deleteRow() throws SQLException {5522// make sure the cursor is on a valid row5523checkCursor();55245525((Row)getCurrentRow()).setDeleted();5526++numDeleted;55275528// notify the listeners that the row changed.5529notifyRowChanged();5530}55315532/**5533* Sets the current row with its original value and marks the row as5534* not updated, thus undoing any changes made to the row since the5535* last call to the methods <code>updateRow</code> or <code>deleteRow</code>.5536* This method should be called only when the cursor is on a row in5537* this rowset.5538*5539* @throws SQLException if the cursor is on the insert row, before the5540* first row, or after the last row5541*/5542public void refreshRow() throws SQLException {5543// make sure we are on a row5544checkCursor();55455546// don't want this to happen...5547if (onInsertRow == true) {5548throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());5549}55505551Row currentRow = (Row)getCurrentRow();5552// just undo any changes made to this row.5553currentRow.clearUpdated();55545555}55565557/**5558* Rolls back any updates made to the current row of this5559* <code>CachedRowSetImpl</code> object and notifies listeners that5560* a row has changed. To have an effect, this method5561* must be called after an <code>updateXXX</code> method has been5562* called and before the method <code>updateRow</code> has been called.5563* If no updates have been made or the method <code>updateRow</code>5564* has already been called, this method has no effect.5565*5566* @throws SQLException if the cursor is on the insert row, before the5567* first row, or after the last row5568*/5569public void cancelRowUpdates() throws SQLException {5570// make sure we are on a row5571checkCursor();55725573// don't want this to happen...5574if (onInsertRow == true) {5575throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcp").toString());5576}55775578Row currentRow = (Row)getCurrentRow();5579if (currentRow.getUpdated() == true) {5580currentRow.clearUpdated();5581notifyRowChanged();5582}5583}55845585/**5586* Moves the cursor for this <code>CachedRowSetImpl</code> object5587* to the insert row. The current row in the rowset is remembered5588* while the cursor is on the insert row.5589* <P>5590* The insert row is a special row associated with an updatable5591* rowset. It is essentially a buffer where a new row may5592* be constructed by calling the appropriate <code>updateXXX</code>5593* methods to assign a value to each column in the row. A complete5594* row must be constructed; that is, every column that is not nullable5595* must be assigned a value. In order for the new row to become part5596* of this rowset, the method <code>insertRow</code> must be called5597* before the cursor is moved back to the rowset.5598* <P>5599* Only certain methods may be invoked while the cursor is on the insert5600* row; many methods throw an exception if they are called while the5601* cursor is there. In addition to the <code>updateXXX</code>5602* and <code>insertRow</code> methods, only the <code>getXXX</code> methods5603* may be called when the cursor is on the insert row. A <code>getXXX</code>5604* method should be called on a column only after an <code>updateXXX</code>5605* method has been called on that column; otherwise, the value returned is5606* undetermined.5607*5608* @throws SQLException if this <code>CachedRowSetImpl</code> object is5609* <code>ResultSet.CONCUR_READ_ONLY</code>5610*/5611public void moveToInsertRow() throws SQLException {5612if (getConcurrency() == ResultSet.CONCUR_READ_ONLY) {5613throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins").toString());5614}5615if (insertRow == null) {5616if (RowSetMD == null)5617throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins1").toString());5618int numCols = RowSetMD.getColumnCount();5619if (numCols > 0) {5620insertRow = new InsertRow(numCols);5621} else {5622throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.movetoins2").toString());5623}5624}5625onInsertRow = true;5626// %%% setCurrentRow called in BaseRow56275628currentRow = cursorPos;5629cursorPos = -1;56305631insertRow.initInsertRow();5632}56335634/**5635* Moves the cursor for this <code>CachedRowSetImpl</code> object to5636* the current row. The current row is the row the cursor was on5637* when the method <code>moveToInsertRow</code> was called.5638* <P>5639* Calling this method has no effect unless it is called while the5640* cursor is on the insert row.5641*5642* @throws SQLException if an error occurs5643*/5644public void moveToCurrentRow() throws SQLException {5645if (onInsertRow == false) {5646return;5647} else {5648cursorPos = currentRow;5649onInsertRow = false;5650}5651}56525653/**5654* Returns <code>null</code>.5655*5656* @return <code>null</code>5657* @throws SQLException if an error occurs5658*/5659public Statement getStatement() throws SQLException {5660return null;5661}56625663/**5664* Retrieves the value of the designated column in this5665* <code>CachedRowSetImpl</code> object as an <code>Object</code> in5666* the Java programming language, using the given5667* <code>java.util.Map</code> object to custom map the value if5668* appropriate.5669*5670* @param columnIndex the first column is <code>1</code>, the second5671* is <code>2</code>, and so on; must be <code>1</code> or larger5672* and equal to or less than the number of columns in this rowset5673* @param map a <code>java.util.Map</code> object showing the mapping5674* from SQL type names to classes in the Java programming5675* language5676* @return an <code>Object</code> representing the SQL value5677* @throws SQLException if the given column index is out of bounds or5678* the cursor is not on one of this rowset's rows or its5679* insert row5680*/5681public Object getObject(int columnIndex,5682java.util.Map<String,Class<?>> map)5683throws SQLException5684{5685Object value;56865687// sanity check.5688checkIndex(columnIndex);5689// make sure the cursor is on a valid row5690checkCursor();56915692setLastValueNull(false);5693value = getCurrentRow().getColumnObject(columnIndex);56945695// check for SQL NULL5696if (value == null) {5697setLastValueNull(true);5698return null;5699}5700if (value instanceof Struct) {5701Struct s = (Struct)value;57025703// look up the class in the map5704Class<?> c = map.get(s.getSQLTypeName());5705if (c != null) {5706// create new instance of the class5707SQLData obj = null;5708try {5709obj = (SQLData) ReflectUtil.newInstance(c);5710} catch(Exception ex) {5711throw new SQLException("Unable to Instantiate: ", ex);5712}5713// get the attributes from the struct5714Object attribs[] = s.getAttributes(map);5715// create the SQLInput "stream"5716SQLInputImpl sqlInput = new SQLInputImpl(attribs, map);5717// read the values...5718obj.readSQL(sqlInput, s.getSQLTypeName());5719return (Object)obj;5720}5721}5722return value;5723}57245725/**5726* Retrieves the value of the designated column in this5727* <code>CachedRowSetImpl</code> object as a <code>Ref</code> object5728* in the Java programming language.5729*5730* @param columnIndex the first column is <code>1</code>, the second5731* is <code>2</code>, and so on; must be <code>1</code> or larger5732* and equal to or less than the number of columns in this rowset5733* @return a <code>Ref</code> object representing an SQL<code> REF</code> value5734* @throws SQLException if (1) the given column index is out of bounds,5735* (2) the cursor is not on one of this rowset's rows or its5736* insert row, or (3) the designated column does not store an5737* SQL <code>REF</code> value5738* @see #getRef(String)5739*/5740public Ref getRef(int columnIndex) throws SQLException {5741Ref value;57425743// sanity check.5744checkIndex(columnIndex);5745// make sure the cursor is on a valid row5746checkCursor();57475748if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.REF) {5749throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());5750}57515752setLastValueNull(false);5753value = (Ref)(getCurrentRow().getColumnObject(columnIndex));57545755// check for SQL NULL5756if (value == null) {5757setLastValueNull(true);5758return null;5759}57605761return value;5762}57635764/**5765* Retrieves the value of the designated column in this5766* <code>CachedRowSetImpl</code> object as a <code>Blob</code> object5767* in the Java programming language.5768*5769* @param columnIndex the first column is <code>1</code>, the second5770* is <code>2</code>, and so on; must be <code>1</code> or larger5771* and equal to or less than the number of columns in this rowset5772* @return a <code>Blob</code> object representing an SQL <code>BLOB</code> value5773* @throws SQLException if (1) the given column index is out of bounds,5774* (2) the cursor is not on one of this rowset's rows or its5775* insert row, or (3) the designated column does not store an5776* SQL <code>BLOB</code> value5777* @see #getBlob(String)5778*/5779public Blob getBlob(int columnIndex) throws SQLException {5780Blob value;57815782// sanity check.5783checkIndex(columnIndex);5784// make sure the cursor is on a valid row5785checkCursor();57865787if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.BLOB) {5788System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex)));5789throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());5790}57915792setLastValueNull(false);5793value = (Blob)(getCurrentRow().getColumnObject(columnIndex));57945795// check for SQL NULL5796if (value == null) {5797setLastValueNull(true);5798return null;5799}58005801return value;5802}58035804/**5805* Retrieves the value of the designated column in this5806* <code>CachedRowSetImpl</code> object as a <code>Clob</code> object5807* in the Java programming language.5808*5809* @param columnIndex the first column is <code>1</code>, the second5810* is <code>2</code>, and so on; must be <code>1</code> or larger5811* and equal to or less than the number of columns in this rowset5812* @return a <code>Clob</code> object representing an SQL <code>CLOB</code> value5813* @throws SQLException if (1) the given column index is out of bounds,5814* (2) the cursor is not on one of this rowset's rows or its5815* insert row, or (3) the designated column does not store an5816* SQL <code>CLOB</code> value5817* @see #getClob(String)5818*/5819public Clob getClob(int columnIndex) throws SQLException {5820Clob value;58215822// sanity check.5823checkIndex(columnIndex);5824// make sure the cursor is on a valid row5825checkCursor();58265827if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.CLOB) {5828System.out.println(MessageFormat.format(resBundle.handleGetObject("cachedrowsetimpl.type").toString(), RowSetMD.getColumnType(columnIndex)));5829throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());5830}58315832setLastValueNull(false);5833value = (Clob)(getCurrentRow().getColumnObject(columnIndex));58345835// check for SQL NULL5836if (value == null) {5837setLastValueNull(true);5838return null;5839}58405841return value;5842}58435844/**5845* Retrieves the value of the designated column in this5846* <code>CachedRowSetImpl</code> object as an <code>Array</code> object5847* in the Java programming language.5848*5849* @param columnIndex the first column is <code>1</code>, the second5850* is <code>2</code>, and so on; must be <code>1</code> or larger5851* and equal to or less than the number of columns in this rowset5852* @return an <code>Array</code> object representing an SQL5853* <code>ARRAY</code> value5854* @throws SQLException if (1) the given column index is out of bounds,5855* (2) the cursor is not on one of this rowset's rows or its5856* insert row, or (3) the designated column does not store an5857* SQL <code>ARRAY</code> value5858* @see #getArray(String)5859*/5860public Array getArray(int columnIndex) throws SQLException {5861java.sql.Array value;58625863// sanity check.5864checkIndex(columnIndex);5865// make sure the cursor is on a valid row5866checkCursor();58675868if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.ARRAY) {5869throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());5870}58715872setLastValueNull(false);5873value = (java.sql.Array)(getCurrentRow().getColumnObject(columnIndex));58745875// check for SQL NULL5876if (value == null) {5877setLastValueNull(true);5878return null;5879}58805881return value;5882}58835884/**5885* Retrieves the value of the designated column in this5886* <code>CachedRowSetImpl</code> object as an <code>Object</code> in5887* the Java programming language, using the given5888* <code>java.util.Map</code> object to custom map the value if5889* appropriate.5890*5891* @param columnName a <code>String</code> object that must match the5892* SQL name of a column in this rowset, ignoring case5893* @param map a <code>java.util.Map</code> object showing the mapping5894* from SQL type names to classes in the Java programming5895* language5896* @return an <code>Object</code> representing the SQL value5897* @throws SQLException if the given column name is not the name of5898* a column in this rowset or the cursor is not on one of5899* this rowset's rows or its insert row5900*/5901public Object getObject(String columnName,5902java.util.Map<String,Class<?>> map)5903throws SQLException {5904return getObject(getColIdxByName(columnName), map);5905}59065907/**5908* Retrieves the value of the designated column in this5909* <code>CachedRowSetImpl</code> object as a <code>Ref</code> object5910* in the Java programming language.5911*5912* @param colName a <code>String</code> object that must match the5913* SQL name of a column in this rowset, ignoring case5914* @return a <code>Ref</code> object representing an SQL<code> REF</code> value5915* @throws SQLException if (1) the given column name is not the name of5916* a column in this rowset, (2) the cursor is not on one of5917* this rowset's rows or its insert row, or (3) the column value5918* is not an SQL <code>REF</code> value5919* @see #getRef(int)5920*/5921public Ref getRef(String colName) throws SQLException {5922return getRef(getColIdxByName(colName));5923}59245925/**5926* Retrieves the value of the designated column in this5927* <code>CachedRowSetImpl</code> object as a <code>Blob</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>Blob</code> object representing an SQL <code>BLOB</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 designated5936* column does not store an SQL <code>BLOB</code> value5937* @see #getBlob(int)5938*/5939public Blob getBlob(String colName) throws SQLException {5940return getBlob(getColIdxByName(colName));5941}59425943/**5944* Retrieves the value of the designated column in this5945* <code>CachedRowSetImpl</code> object as a <code>Clob</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>Clob</code> object representing an SQL5951* <code>CLOB</code> value5952* @throws SQLException if (1) the given column name is not the name of5953* a column in this rowset, (2) the cursor is not on one of5954* this rowset's rows or its insert row, or (3) the designated5955* column does not store an SQL <code>CLOB</code> value5956* @see #getClob(int)5957*/5958public Clob getClob(String colName) throws SQLException {5959return getClob(getColIdxByName(colName));5960}59615962/**5963* Retrieves the value of the designated column in this5964* <code>CachedRowSetImpl</code> object as an <code>Array</code> object5965* in the Java programming langugage.5966*5967* @param colName a <code>String</code> object that must match the5968* SQL name of a column in this rowset, ignoring case5969* @return an <code>Array</code> object representing an SQL5970* <code>ARRAY</code> value5971* @throws SQLException if (1) the given column name is not the name of5972* a column in this rowset, (2) the cursor is not on one of5973* this rowset's rows or its insert row, or (3) the designated5974* column does not store an SQL <code>ARRAY</code> value5975* @see #getArray(int)5976*/5977public Array getArray(String colName) throws SQLException {5978return getArray(getColIdxByName(colName));5979}59805981/**5982* Retrieves the value of the designated column in the current row5983* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Date</code>5984* object, using the given <code>Calendar</code> object to construct an5985* appropriate millisecond value for the date.5986*5987* @param columnIndex the first column is <code>1</code>, the second5988* is <code>2</code>, and so on; must be <code>1</code> or larger5989* and equal to or less than the number of columns in the rowset5990* @param cal the <code>java.util.Calendar</code> object to use in5991* constructing the date5992* @return the column value; if the value is SQL <code>NULL</code>,5993* the result is <code>null</code>5994* @throws SQLException if (1) the given column name is not the name of5995* a column in this rowset, (2) the cursor is not on one of5996* this rowset's rows or its insert row, or (3) the designated5997* column does not store an SQL <code>DATE</code> or5998* <code>TIMESTAMP</code> value5999*/6000public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException {6001Object value;60026003// sanity check.6004checkIndex(columnIndex);6005// make sure the cursor is on a valid row6006checkCursor();60076008setLastValueNull(false);6009value = getCurrentRow().getColumnObject(columnIndex);60106011// check for SQL NULL6012if (value == null) {6013setLastValueNull(true);6014return null;6015}60166017value = convertTemporal(value,6018RowSetMD.getColumnType(columnIndex),6019java.sql.Types.DATE);60206021// create a default calendar6022Calendar defaultCal = Calendar.getInstance();6023// set this Calendar to the time we have6024defaultCal.setTime((java.util.Date)value);60256026/*6027* Now we can pull the pieces of the date out6028* of the default calendar and put them into6029* the user provided calendar6030*/6031cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR));6032cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH));6033cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH));60346035/*6036* This looks a little odd but it is correct -6037* Calendar.getTime() returns a Date...6038*/6039return new java.sql.Date(cal.getTime().getTime());6040}60416042/**6043* Retrieves the value of the designated column in the current row6044* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Date</code>6045* object, using the given <code>Calendar</code> object to construct an6046* appropriate millisecond value for the date.6047*6048* @param columnName a <code>String</code> object that must match the6049* SQL name of a column in this rowset, ignoring case6050* @param cal the <code>java.util.Calendar</code> object to use in6051* constructing the date6052* @return the column value; if the value is SQL <code>NULL</code>,6053* the result is <code>null</code>6054* @throws SQLException if (1) the given column name is not the name of6055* a column in this rowset, (2) the cursor is not on one of6056* this rowset's rows or its insert row, or (3) the designated6057* column does not store an SQL <code>DATE</code> or6058* <code>TIMESTAMP</code> value6059*/6060public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException {6061return getDate(getColIdxByName(columnName), cal);6062}60636064/**6065* Retrieves the value of the designated column in the current row6066* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Time</code>6067* object, using the given <code>Calendar</code> object to construct an6068* appropriate millisecond value for the date.6069*6070* @param columnIndex the first column is <code>1</code>, the second6071* is <code>2</code>, and so on; must be <code>1</code> or larger6072* and equal to or less than the number of columns in the rowset6073* @param cal the <code>java.util.Calendar</code> object to use in6074* constructing the date6075* @return the column value; if the value is SQL <code>NULL</code>,6076* the result is <code>null</code>6077* @throws SQLException if (1) the given column name is not the name of6078* a column in this rowset, (2) the cursor is not on one of6079* this rowset's rows or its insert row, or (3) the designated6080* column does not store an SQL <code>TIME</code> or6081* <code>TIMESTAMP</code> value6082*/6083public java.sql.Time getTime(int columnIndex, Calendar cal) throws SQLException {6084Object value;60856086// sanity check.6087checkIndex(columnIndex);6088// make sure the cursor is on a valid row6089checkCursor();60906091setLastValueNull(false);6092value = getCurrentRow().getColumnObject(columnIndex);60936094// check for SQL NULL6095if (value == null) {6096setLastValueNull(true);6097return null;6098}60996100value = convertTemporal(value,6101RowSetMD.getColumnType(columnIndex),6102java.sql.Types.TIME);61036104// create a default calendar6105Calendar defaultCal = Calendar.getInstance();6106// set the time in the default calendar6107defaultCal.setTime((java.util.Date)value);61086109/*6110* Now we can pull the pieces of the date out6111* of the default calendar and put them into6112* the user provided calendar6113*/6114cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY));6115cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE));6116cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND));61176118return new java.sql.Time(cal.getTime().getTime());6119}61206121/**6122* Retrieves the value of the designated column in the current row6123* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Time</code>6124* object, using the given <code>Calendar</code> object to construct an6125* appropriate millisecond value for the date.6126*6127* @param columnName a <code>String</code> object that must match the6128* SQL name of a column in this rowset, ignoring case6129* @param cal the <code>java.util.Calendar</code> object to use in6130* constructing the date6131* @return the column value; if the value is SQL <code>NULL</code>,6132* the result is <code>null</code>6133* @throws SQLException if (1) the given column name is not the name of6134* a column in this rowset, (2) the cursor is not on one of6135* this rowset's rows or its insert row, or (3) the designated6136* column does not store an SQL <code>TIME</code> or6137* <code>TIMESTAMP</code> value6138*/6139public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException {6140return getTime(getColIdxByName(columnName), cal);6141}61426143/**6144* Retrieves the value of the designated column in the current row6145* of this <code>CachedRowSetImpl</code> object as a <code>java.sql.Timestamp</code>6146* object, using the given <code>Calendar</code> object to construct an6147* appropriate millisecond value for the date.6148*6149* @param columnIndex the first column is <code>1</code>, the second6150* is <code>2</code>, and so on; must be <code>1</code> or larger6151* and equal to or less than the number of columns in the rowset6152* @param cal the <code>java.util.Calendar</code> object to use in6153* constructing the date6154* @return the column value; if the value is SQL <code>NULL</code>,6155* the result is <code>null</code>6156* @throws SQLException if (1) the given column name is not the name of6157* a column in this rowset, (2) the cursor is not on one of6158* this rowset's rows or its insert row, or (3) the designated6159* column does not store an SQL <code>TIME</code> or6160* <code>TIMESTAMP</code> value6161*/6162public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {6163Object value;61646165// sanity check.6166checkIndex(columnIndex);6167// make sure the cursor is on a valid row6168checkCursor();61696170setLastValueNull(false);6171value = getCurrentRow().getColumnObject(columnIndex);61726173// check for SQL NULL6174if (value == null) {6175setLastValueNull(true);6176return null;6177}61786179value = convertTemporal(value,6180RowSetMD.getColumnType(columnIndex),6181java.sql.Types.TIMESTAMP);61826183// create a default calendar6184Calendar defaultCal = Calendar.getInstance();6185// set the time in the default calendar6186defaultCal.setTime((java.util.Date)value);61876188/*6189* Now we can pull the pieces of the date out6190* of the default calendar and put them into6191* the user provided calendar6192*/6193cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR));6194cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH));6195cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH));6196cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY));6197cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE));6198cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND));61996200return new java.sql.Timestamp(cal.getTime().getTime());6201}62026203/**6204* Retrieves the value of the designated column in the current row6205* of this <code>CachedRowSetImpl</code> object as a6206* <code>java.sql.Timestamp</code> object, using the given6207* <code>Calendar</code> object to construct an appropriate6208* millisecond value for the date.6209*6210* @param columnName a <code>String</code> object that must match the6211* SQL name of a column in this rowset, ignoring case6212* @param cal the <code>java.util.Calendar</code> object to use in6213* constructing the date6214* @return the column value; if the value is SQL <code>NULL</code>,6215* the result is <code>null</code>6216* @throws SQLException if (1) the given column name is not the name of6217* a column in this rowset, (2) the cursor is not on one of6218* this rowset's rows or its insert row, or (3) the designated6219* column does not store an SQL <code>DATE</code>,6220* <code>TIME</code>, or <code>TIMESTAMP</code> value6221*/6222public java.sql.Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {6223return getTimestamp(getColIdxByName(columnName), cal);6224}62256226/*6227* RowSetInternal Interface6228*/62296230/**6231* Retrieves the <code>Connection</code> object passed to this6232* <code>CachedRowSetImpl</code> object. This connection may be6233* used to populate this rowset with data or to write data back6234* to its underlying data source.6235*6236* @return the <code>Connection</code> object passed to this rowset;6237* may be <code>null</code> if there is no connection6238* @throws SQLException if an error occurs6239*/6240public Connection getConnection() throws SQLException{6241return conn;6242}62436244/**6245* Sets the metadata for this <code>CachedRowSetImpl</code> object6246* with the given <code>RowSetMetaData</code> object.6247*6248* @param md a <code>RowSetMetaData</code> object instance containing6249* metadata about the columsn in the rowset6250* @throws SQLException if invalid meta data is supplied to the6251* rowset6252*/6253public void setMetaData(RowSetMetaData md) throws SQLException {6254RowSetMD =(RowSetMetaDataImpl) md;6255}62566257/**6258* Returns a result set containing the original value of the rowset. The6259* original value is the state of the <code>CachedRowSetImpl</code> after the6260* last population or synchronization (whichever occurred most recently) with6261* the data source.6262* <p>6263* The cursor is positioned before the first row in the result set.6264* Only rows contained in the result set returned by <code>getOriginal()</code>6265* are said to have an original value.6266*6267* @return the original result set of the rowset6268* @throws SQLException if an error occurs produce the6269* <code>ResultSet</code> object6270*/6271public ResultSet getOriginal() throws SQLException {6272CachedRowSetImpl crs = new CachedRowSetImpl();6273crs.RowSetMD = RowSetMD;6274crs.numRows = numRows;6275crs.cursorPos = 0;62766277// make sure we don't get someone playing with these6278// %%% is this now necessary ???6279//crs.setReader(null);6280//crs.setWriter(null);6281int colCount = RowSetMD.getColumnCount();6282Row orig;62836284for (Iterator<?> i = rvh.iterator(); i.hasNext();) {6285orig = new Row(colCount, ((Row)i.next()).getOrigRow());6286crs.rvh.add(orig);6287}6288return (ResultSet)crs;6289}62906291/**6292* Returns a result set containing the original value of the current6293* row only.6294* The original value is the state of the <code>CachedRowSetImpl</code> after6295* the last population or synchronization (whichever occurred most recently)6296* with the data source.6297*6298* @return the original result set of the row6299* @throws SQLException if there is no current row6300* @see #setOriginalRow6301*/6302public ResultSet getOriginalRow() throws SQLException {6303CachedRowSetImpl crs = new CachedRowSetImpl();6304crs.RowSetMD = RowSetMD;6305crs.numRows = 1;6306crs.cursorPos = 0;6307crs.setTypeMap(this.getTypeMap());63086309// make sure we don't get someone playing with these6310// %%% is this now necessary ???6311//crs.setReader(null);6312//crs.setWriter(null);63136314Row orig = new Row(RowSetMD.getColumnCount(),6315getCurrentRow().getOrigRow());63166317crs.rvh.add(orig);63186319return (ResultSet)crs;63206321}63226323/**6324* Marks the current row in this rowset as being an original row.6325*6326* @throws SQLException if there is no current row6327* @see #getOriginalRow6328*/6329public void setOriginalRow() throws SQLException {6330if (onInsertRow == true) {6331throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());6332}63336334Row row = (Row)getCurrentRow();6335makeRowOriginal(row);63366337// this can happen if deleted rows are being shown6338if (row.getDeleted() == true) {6339removeCurrentRow();6340}6341}63426343/**6344* Makes the given row of this rowset the original row by clearing any6345* settings that mark the row as having been inserted, deleted, or updated.6346* This method is called internally by the methods6347* <code>setOriginalRow</code>6348* and <code>setOriginal</code>.6349*6350* @param row the row to be made the original row6351*/6352private void makeRowOriginal(Row row) {6353if (row.getInserted() == true) {6354row.clearInserted();6355}63566357if (row.getUpdated() == true) {6358row.moveCurrentToOrig();6359}6360}63616362/**6363* Marks all rows in this rowset as being original rows. Any updates6364* made to the rows become the original values for the rowset.6365* Calls to the method <code>setOriginal</code> connot be reversed.6366*6367* @throws SQLException if an error occurs6368*/6369public void setOriginal() throws SQLException {6370for (Iterator<?> i = rvh.iterator(); i.hasNext();) {6371Row row = (Row)i.next();6372makeRowOriginal(row);6373// remove deleted rows from the collection.6374if (row.getDeleted() == true) {6375i.remove();6376--numRows;6377}6378}6379numDeleted = 0;63806381// notify any listeners that the rowset has changed6382notifyRowSetChanged();6383}63846385/**6386* Returns an identifier for the object (table) that was used to create this6387* rowset.6388*6389* @return a <code>String</code> object that identifies the table from6390* which this <code>CachedRowSetImpl</code> object was derived6391* @throws SQLException if an error occurs6392*/6393public String getTableName() throws SQLException {6394return tableName;6395}63966397/**6398* Sets the identifier for the table from which this rowset was derived6399* to the given table name.6400*6401* @param tabName a <code>String</code> object that identifies the6402* table from which this <code>CachedRowSetImpl</code> object6403* was derived6404* @throws SQLException if an error occurs6405*/6406public void setTableName(String tabName) throws SQLException {6407if (tabName == null)6408throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.tablename").toString());6409else6410tableName = tabName;6411}64126413/**6414* Returns the columns that make a key to uniquely identify a6415* row in this <code>CachedRowSetImpl</code> object.6416*6417* @return an array of column numbers that constitutes a primary6418* key for this rowset. This array should be empty6419* if no column is representitive of a primary key6420* @throws SQLException if the rowset is empty or no columns6421* are designated as primary keys6422* @see #setKeyColumns6423*/6424public int[] getKeyColumns() throws SQLException {6425int[]keyColumns = this.keyCols;6426return (keyColumns == null) ? null : Arrays.copyOf(keyColumns, keyColumns.length);6427}642864296430/**6431* Sets this <code>CachedRowSetImpl</code> object's6432* <code>keyCols</code> field with the given array of column6433* numbers, which forms a key for uniquely identifying a row6434* in this rowset.6435*6436* @param keys an array of <code>int</code> indicating the6437* columns that form a primary key for this6438* <code>CachedRowSetImpl</code> object; every6439* element in the array must be greater than6440* <code>0</code> and less than or equal to the number6441* of columns in this rowset6442* @throws SQLException if any of the numbers in the6443* given array is not valid for this rowset6444* @see #getKeyColumns6445*/6446public void setKeyColumns(int [] keys) throws SQLException {6447int numCols = 0;6448if (RowSetMD != null) {6449numCols = RowSetMD.getColumnCount();6450if (keys.length > numCols)6451throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.keycols").toString());6452}6453keyCols = new int[keys.length];6454for (int i = 0; i < keys.length; i++) {6455if (RowSetMD != null && (keys[i] <= 0 ||6456keys[i] > numCols)) {6457throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString() +6458keys[i]);6459}6460keyCols[i] = keys[i];6461}6462}64636464/**6465* Sets the designated column in either the current row or the insert6466* row of this <code>CachedRowSetImpl</code> object with the given6467* <code>Ref</code> value.6468*6469* This method updates a column value in either the current row or6470* the insert row of this rowset, but it does not update the6471* database. If the cursor is on a row in the rowset, the6472* method {@link #updateRow} must be called to update the database.6473* If the cursor is on the insert row, the method {@link #insertRow}6474* must be called, which will insert the new row into both this rowset6475* and the database. Both of these methods must be called before the6476* cursor moves to another row.6477*6478* @param columnIndex the first column is <code>1</code>, the second6479* is <code>2</code>, and so on; must be <code>1</code> or larger6480* and equal to or less than the number of columns in this rowset6481* @param ref the new column <code>java.sql.Ref</code> value6482* @throws SQLException if (1) the given column index is out of bounds,6483* (2) the cursor is not on one of this rowset's rows or its6484* insert row, or (3) this rowset is6485* <code>ResultSet.CONCUR_READ_ONLY</code>6486*/6487public void updateRef(int columnIndex, java.sql.Ref ref) throws SQLException {6488// sanity check.6489checkIndex(columnIndex);6490// make sure the cursor is on a valid row6491checkCursor();64926493// SerialClob will help in getting the byte array and storing it.6494// We need to be checking DatabaseMetaData.locatorsUpdatorCopy()6495// or through RowSetMetaData.locatorsUpdatorCopy()6496getCurrentRow().setColumnObject(columnIndex, new SerialRef(ref));6497}64986499/**6500* Sets the designated column in either the current row or the insert6501* row of this <code>CachedRowSetImpl</code> object with the given6502* <code>double</code> value.6503*6504* This method updates a column value in either the current row or6505* the insert row of this rowset, but it does not update the6506* database. If the cursor is on a row in the rowset, the6507* method {@link #updateRow} must be called to update the database.6508* If the cursor is on the insert row, the method {@link #insertRow}6509* must be called, which will insert the new row into both this rowset6510* and the database. Both of these methods must be called before the6511* cursor moves to another row.6512*6513* @param columnName a <code>String</code> object that must match the6514* SQL name of a column in this rowset, ignoring case6515* @param ref the new column <code>java.sql.Ref</code> value6516* @throws SQLException if (1) the given column name does not match the6517* name of a column in this rowset, (2) the cursor is not on6518* one of this rowset's rows or its insert row, or (3) this6519* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>6520*/6521public void updateRef(String columnName, java.sql.Ref ref) throws SQLException {6522updateRef(getColIdxByName(columnName), ref);6523}65246525/**6526* Sets the designated column in either the current row or the insert6527* row of this <code>CachedRowSetImpl</code> object with the given6528* <code>double</code> value.6529*6530* This method updates a column value in either the current row or6531* the insert row of this rowset, but it does not update the6532* database. If the cursor is on a row in the rowset, the6533* method {@link #updateRow} must be called to update the database.6534* If the cursor is on the insert row, the method {@link #insertRow}6535* must be called, which will insert the new row into both this rowset6536* and the database. Both of these methods must be called before the6537* cursor moves to another row.6538*6539* @param columnIndex the first column is <code>1</code>, the second6540* is <code>2</code>, and so on; must be <code>1</code> or larger6541* and equal to or less than the number of columns in this rowset6542* @param c the new column <code>Clob</code> value6543* @throws SQLException if (1) the given column index is out of bounds,6544* (2) the cursor is not on one of this rowset's rows or its6545* insert row, or (3) this rowset is6546* <code>ResultSet.CONCUR_READ_ONLY</code>6547*/6548public void updateClob(int columnIndex, Clob c) throws SQLException {6549// sanity check.6550checkIndex(columnIndex);6551// make sure the cursor is on a valid row6552checkCursor();65536554// SerialClob will help in getting the byte array and storing it.6555// We need to be checking DatabaseMetaData.locatorsUpdatorCopy()6556// or through RowSetMetaData.locatorsUpdatorCopy()65576558if(dbmslocatorsUpdateCopy){6559getCurrentRow().setColumnObject(columnIndex, new SerialClob(c));6560}6561else{6562throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString());6563}6564}65656566/**6567* Sets the designated column in either the current row or the insert6568* row of this <code>CachedRowSetImpl</code> object with the given6569* <code>double</code> value.6570*6571* This method updates a column value in either the current row or6572* the insert row of this rowset, but it does not update the6573* database. If the cursor is on a row in the rowset, the6574* method {@link #updateRow} must be called to update the database.6575* If the cursor is on the insert row, the method {@link #insertRow}6576* must be called, which will insert the new row into both this rowset6577* and the database. Both of these methods must be called before the6578* cursor moves to another row.6579*6580* @param columnName a <code>String</code> object that must match the6581* SQL name of a column in this rowset, ignoring case6582* @param c the new column <code>Clob</code> value6583* @throws SQLException if (1) the given column name does not match the6584* name of a column in this rowset, (2) the cursor is not on6585* one of this rowset's rows or its insert row, or (3) this6586* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>6587*/6588public void updateClob(String columnName, Clob c) throws SQLException {6589updateClob(getColIdxByName(columnName), c);6590}65916592/**6593* Sets the designated column in either the current row or the insert6594* row of this <code>CachedRowSetImpl</code> object with the given6595* <code>java.sql.Blob</code> value.6596*6597* This method updates a column value in either the current row or6598* the insert row of this rowset, but it does not update the6599* database. If the cursor is on a row in the rowset, the6600* method {@link #updateRow} must be called to update the database.6601* If the cursor is on the insert row, the method {@link #insertRow}6602* must be called, which will insert the new row into both this rowset6603* and the database. Both of these methods must be called before the6604* cursor moves to another row.6605*6606* @param columnIndex the first column is <code>1</code>, the second6607* is <code>2</code>, and so on; must be <code>1</code> or larger6608* and equal to or less than the number of columns in this rowset6609* @param b the new column <code>Blob</code> value6610* @throws SQLException if (1) the given column index is out of bounds,6611* (2) the cursor is not on one of this rowset's rows or its6612* insert row, or (3) this rowset is6613* <code>ResultSet.CONCUR_READ_ONLY</code>6614*/6615public void updateBlob(int columnIndex, Blob b) throws SQLException {6616// sanity check.6617checkIndex(columnIndex);6618// make sure the cursor is on a valid row6619checkCursor();66206621// SerialBlob will help in getting the byte array and storing it.6622// We need to be checking DatabaseMetaData.locatorsUpdatorCopy()6623// or through RowSetMetaData.locatorsUpdatorCopy()66246625if(dbmslocatorsUpdateCopy){6626getCurrentRow().setColumnObject(columnIndex, new SerialBlob(b));6627}6628else{6629throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.opnotsupp").toString());6630}6631}66326633/**6634* Sets the designated column in either the current row or the insert6635* row of this <code>CachedRowSetImpl</code> object with the given6636* <code>java.sql.Blob </code> value.6637*6638* This method updates a column value in either the current row or6639* the insert row of this rowset, but it does not update the6640* database. If the cursor is on a row in the rowset, the6641* method {@link #updateRow} must be called to update the database.6642* If the cursor is on the insert row, the method {@link #insertRow}6643* must be called, which will insert the new row into both this rowset6644* and the database. Both of these methods must be called before the6645* cursor moves to another row.6646*6647* @param columnName a <code>String</code> object that must match the6648* SQL name of a column in this rowset, ignoring case6649* @param b the new column <code>Blob</code> value6650* @throws SQLException if (1) the given column name does not match the6651* name of a column in this rowset, (2) the cursor is not on6652* one of this rowset's rows or its insert row, or (3) this6653* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>6654*/6655public void updateBlob(String columnName, Blob b) throws SQLException {6656updateBlob(getColIdxByName(columnName), b);6657}66586659/**6660* Sets the designated column in either the current row or the insert6661* row of this <code>CachedRowSetImpl</code> object with the given6662* <code>java.sql.Array</code> values.6663*6664* This method updates a column value in either the current row or6665* the insert row of this rowset, but it does not update the6666* database. If the cursor is on a row in the rowset, the6667* method {@link #updateRow} must be called to update the database.6668* If the cursor is on the insert row, the method {@link #insertRow}6669* must be called, which will insert the new row into both this rowset6670* and the database. Both of these methods must be called before the6671* cursor moves to another row.6672*6673* @param columnIndex the first column is <code>1</code>, the second6674* is <code>2</code>, and so on; must be <code>1</code> or larger6675* and equal to or less than the number of columns in this rowset6676* @param a the new column <code>Array</code> value6677* @throws SQLException if (1) the given column index is out of bounds,6678* (2) the cursor is not on one of this rowset's rows or its6679* insert row, or (3) this rowset is6680* <code>ResultSet.CONCUR_READ_ONLY</code>6681*/6682public void updateArray(int columnIndex, Array a) throws SQLException {6683// sanity check.6684checkIndex(columnIndex);6685// make sure the cursor is on a valid row6686checkCursor();66876688// SerialArray will help in getting the byte array and storing it.6689// We need to be checking DatabaseMetaData.locatorsUpdatorCopy()6690// or through RowSetMetaData.locatorsUpdatorCopy()6691getCurrentRow().setColumnObject(columnIndex, new SerialArray(a));6692}66936694/**6695* Sets the designated column in either the current row or the insert6696* row of this <code>CachedRowSetImpl</code> object with the given6697* <code>java.sql.Array</code> value.6698*6699* This method updates a column value in either the current row or6700* the insert row of this rowset, but it does not update the6701* database. If the cursor is on a row in the rowset, the6702* method {@link #updateRow} must be called to update the database.6703* If the cursor is on the insert row, the method {@link #insertRow}6704* must be called, which will insert the new row into both this rowset6705* and the database. Both of these methods must be called before the6706* cursor moves to another row.6707*6708* @param columnName a <code>String</code> object that must match the6709* SQL name of a column in this rowset, ignoring case6710* @param a the new column <code>Array</code> value6711* @throws SQLException if (1) the given column name does not match the6712* name of a column in this rowset, (2) the cursor is not on6713* one of this rowset's rows or its insert row, or (3) this6714* rowset is <code>ResultSet.CONCUR_READ_ONLY</code>6715*/6716public void updateArray(String columnName, Array a) throws SQLException {6717updateArray(getColIdxByName(columnName), a);6718}671967206721/**6722* Retrieves the value of the designated column in this6723* <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object6724* in the Java programming language.6725*6726* @return a java.net.URL object containing the resource reference described by6727* the URL6728* @throws SQLException if (1) the given column index is out of bounds,6729* (2) the cursor is not on one of this rowset's rows or its6730* insert row, or (3) the designated column does not store an6731* SQL <code>DATALINK</code> value.6732* @see #getURL(String)6733*/6734public java.net.URL getURL(int columnIndex) throws SQLException {6735//throw new SQLException("Operation not supported");67366737java.net.URL value;67386739// sanity check.6740checkIndex(columnIndex);6741// make sure the cursor is on a valid row6742checkCursor();67436744if (RowSetMD.getColumnType(columnIndex) != java.sql.Types.DATALINK) {6745throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.dtypemismt").toString());6746}67476748setLastValueNull(false);6749value = (java.net.URL)(getCurrentRow().getColumnObject(columnIndex));67506751// check for SQL NULL6752if (value == null) {6753setLastValueNull(true);6754return null;6755}67566757return value;6758}67596760/**6761* Retrieves the value of the designated column in this6762* <code>CachedRowSetImpl</code> object as a <code>java.net.URL</code> object6763* in the Java programming language.6764*6765* @return a java.net.URL object containing the resource reference described by6766* the URL6767* @throws SQLException if (1) the given column name not the name of a column6768* in this rowset, or6769* (2) the cursor is not on one of this rowset's rows or its6770* insert row, or (3) the designated column does not store an6771* SQL <code>DATALINK</code> value.6772* @see #getURL(int)6773*/6774public java.net.URL getURL(String columnName) throws SQLException {6775return getURL(getColIdxByName(columnName));67766777}67786779/**6780* The first warning reported by calls on this <code>CachedRowSetImpl</code>6781* object is returned. Subsequent <code>CachedRowSetImpl</code> warnings will6782* be chained to this <code>SQLWarning</code>. All <code>RowSetWarnings</code>6783* warnings are generated in the disconnected environment and remain a6784* seperate warning chain to that provided by the <code>getWarnings</code>6785* method.6786*6787* <P>The warning chain is automatically cleared each time a new6788* row is read.6789*6790* <P><B>Note:</B> This warning chain only covers warnings caused6791* by <code>CachedRowSet</code> (and their child interface)6792* methods. All <code>SQLWarnings</code> can be obtained using the6793* <code>getWarnings</code> method which tracks warnings generated6794* by the underlying JDBC driver.6795* @return the first SQLWarning or null6796*6797*/6798public RowSetWarning getRowSetWarnings() {6799try {6800notifyCursorMoved();6801} catch (SQLException e) {} // mask exception6802return rowsetWarning;6803}680468056806/**6807* The function tries to isolate the tablename when only setCommand6808* is set and not setTablename is called provided there is only one table6809* name in the query else just leaves the setting of table name as such.6810* If setTablename is set later it will over ride this table name6811* value so retrieved.6812*6813* @return the tablename if only one table in query else return ""6814*/6815private String buildTableName(String command) throws SQLException {68166817// If we have a query from one table,6818// we set the table name implicitly6819// else user has to explicitly set the table name.68206821int indexFrom, indexComma;6822String strTablename ="";6823command = command.trim();68246825// Query can be a select, insert or update68266827if(command.toLowerCase().startsWith("select")) {6828// look for "from" keyword, after that look for a6829// comma after from. If comma is there don't set6830// table name else isolate table name.68316832indexFrom = command.toLowerCase().indexOf("from");6833indexComma = command.indexOf(",", indexFrom);68346835if(indexComma == -1) {6836// implies only one table6837strTablename = (command.substring(indexFrom+"from".length(),command.length())).trim();68386839String tabName = strTablename;68406841int idxWhere = tabName.toLowerCase().indexOf("where");68426843/**6844* Adding the addtional check for conditions following the table name.6845* If a condition is found truncate it.6846**/68476848if(idxWhere != -1)6849{6850tabName = tabName.substring(0,idxWhere).trim();6851}68526853strTablename = tabName;68546855} else {6856//strTablename="";6857}68586859} else if(command.toLowerCase().startsWith("insert")) {6860//strTablename="";6861} else if(command.toLowerCase().startsWith("update")) {6862//strTablename="";6863}6864return strTablename;6865}68666867/**6868* Commits all changes performed by the <code>acceptChanges()</code>6869* methods6870*6871* @see java.sql.Connection#commit6872*/6873public void commit() throws SQLException {6874conn.commit();6875}68766877/**6878* Rolls back all changes performed by the <code>acceptChanges()</code>6879* methods6880*6881* @see java.sql.Connection#rollback6882*/6883public void rollback() throws SQLException {6884conn.rollback();6885}68866887/**6888* Rolls back all changes performed by the <code>acceptChanges()</code>6889* to the last <code>Savepoint</code> transaction marker.6890*6891* @see java.sql.Connection#rollback(Savepoint)6892*/6893public void rollback(Savepoint s) throws SQLException {6894conn.rollback(s);6895}68966897/**6898* Unsets the designated parameter to the given int array.6899* This was set using <code>setMatchColumn</code>6900* as the column which will form the basis of the join.6901* <P>6902* The parameter value unset by this method should be same6903* as was set.6904*6905* @param columnIdxes the index into this rowset6906* object's internal representation of parameter values6907* @throws SQLException if an error occurs or the6908* parameter index is out of bounds or if the columnIdx is6909* not the same as set using <code>setMatchColumn(int [])</code>6910*/6911public void unsetMatchColumn(int[] columnIdxes) throws SQLException {69126913int i_val;6914for( int j= 0 ;j < columnIdxes.length; j++) {6915i_val = (Integer.parseInt(iMatchColumns.get(j).toString()));6916if(columnIdxes[j] != i_val) {6917throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString());6918}6919}69206921for( int i = 0;i < columnIdxes.length ;i++) {6922iMatchColumns.set(i, -1);6923}6924}69256926/**6927* Unsets the designated parameter to the given String array.6928* This was set using <code>setMatchColumn</code>6929* as the column which will form the basis of the join.6930* <P>6931* The parameter value unset by this method should be same6932* as was set.6933*6934* @param columnIdxes the index into this rowset6935* object's internal representation of parameter values6936* @throws SQLException if an error occurs or the6937* parameter index is out of bounds or if the columnName is6938* not the same as set using <code>setMatchColumn(String [])</code>6939*/6940public void unsetMatchColumn(String[] columnIdxes) throws SQLException {69416942for(int j = 0 ;j < columnIdxes.length; j++) {6943if( !columnIdxes[j].equals(strMatchColumns.get(j)) ){6944throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols").toString());6945}6946}69476948for(int i = 0 ; i < columnIdxes.length; i++) {6949strMatchColumns.set(i,null);6950}6951}69526953/**6954* Retrieves the column name as <code>String</code> array6955* that was set using <code>setMatchColumn(String [])</code>6956* for this rowset.6957*6958* @return a <code>String</code> array object that contains the column names6959* for the rowset which has this the match columns6960*6961* @throws SQLException if an error occurs or column name is not set6962*/6963public String[] getMatchColumnNames() throws SQLException {69646965String []str_temp = new String[strMatchColumns.size()];69666967if( strMatchColumns.get(0) == null) {6968throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString());6969}69706971strMatchColumns.copyInto(str_temp);6972return str_temp;6973}69746975/**6976* Retrieves the column id as <code>int</code> array that was set using6977* <code>setMatchColumn(int [])</code> for this rowset.6978*6979* @return a <code>int</code> array object that contains the column ids6980* for the rowset which has this as the match columns.6981*6982* @throws SQLException if an error occurs or column index is not set6983*/6984public int[] getMatchColumnIndexes() throws SQLException {69856986Integer []int_temp = new Integer[iMatchColumns.size()];6987int [] i_temp = new int[iMatchColumns.size()];6988int i_val;69896990i_val = iMatchColumns.get(0);69916992if( i_val == -1 ) {6993throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.setmatchcols").toString());6994}699569966997iMatchColumns.copyInto(int_temp);69986999for(int i = 0; i < int_temp.length; i++) {7000i_temp[i] = (int_temp[i]).intValue();7001}70027003return i_temp;7004}70057006/**7007* Sets the designated parameter to the given int array.7008* This forms the basis of the join for the7009* <code>JoinRowSet</code> as the column which will form the basis of the7010* join.7011* <P>7012* The parameter value set by this method is stored internally and7013* will be supplied as the appropriate parameter in this rowset's7014* command when the method <code>getMatchColumnIndexes</code> is called.7015*7016* @param columnIdxes the indexes into this rowset7017* object's internal representation of parameter values; the7018* first parameter is 0, the second is 1, and so on; must be7019* <code>0</code> or greater7020* @throws SQLException if an error occurs or the7021* parameter index is out of bounds7022*/7023public void setMatchColumn(int[] columnIdxes) throws SQLException {70247025for(int j = 0 ; j < columnIdxes.length; j++) {7026if( columnIdxes[j] < 0 ) {7027throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString());7028}7029}7030for(int i = 0 ;i < columnIdxes.length; i++) {7031iMatchColumns.add(i,columnIdxes[i]);7032}7033}70347035/**7036* Sets the designated parameter to the given String array.7037* This forms the basis of the join for the7038* <code>JoinRowSet</code> as the column which will form the basis of the7039* join.7040* <P>7041* The parameter value set by this method is stored internally and7042* will be supplied as the appropriate parameter in this rowset's7043* command when the method <code>getMatchColumn</code> is called.7044*7045* @param columnNames the name of the column into this rowset7046* object's internal representation of parameter values7047* @throws SQLException if an error occurs or the7048* parameter index is out of bounds7049*/7050public void setMatchColumn(String[] columnNames) throws SQLException {70517052for(int j = 0; j < columnNames.length; j++) {7053if( columnNames[j] == null || columnNames[j].equals("")) {7054throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());7055}7056}7057for( int i = 0; i < columnNames.length; i++) {7058strMatchColumns.add(i,columnNames[i]);7059}7060}706170627063/**7064* Sets the designated parameter to the given <code>int</code>7065* object. This forms the basis of the join for the7066* <code>JoinRowSet</code> as the column which will form the basis of the7067* join.7068* <P>7069* The parameter value set by this method is stored internally and7070* will be supplied as the appropriate parameter in this rowset's7071* command when the method <code>getMatchColumn</code> is called.7072*7073* @param columnIdx the index into this rowset7074* object's internal representation of parameter values; the7075* first parameter is 0, the second is 1, and so on; must be7076* <code>0</code> or greater7077* @throws SQLException if an error occurs or the7078* parameter index is out of bounds7079*/7080public void setMatchColumn(int columnIdx) throws SQLException {7081// validate, if col is ok to be set7082if(columnIdx < 0) {7083throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols1").toString());7084} else {7085// set iMatchColumn7086iMatchColumns.set(0, columnIdx);7087//strMatchColumn = null;7088}7089}70907091/**7092* Sets the designated parameter to the given <code>String</code>7093* object. This forms the basis of the join for the7094* <code>JoinRowSet</code> as the column which will form the basis of the7095* join.7096* <P>7097* The parameter value set by this method is stored internally and7098* will be supplied as the appropriate parameter in this rowset's7099* command when the method <code>getMatchColumn</code> is called.7100*7101* @param columnName the name of the column into this rowset7102* object's internal representation of parameter values7103* @throws SQLException if an error occurs or the7104* parameter index is out of bounds7105*/7106public void setMatchColumn(String columnName) throws SQLException {7107// validate, if col is ok to be set7108if(columnName == null || (columnName= columnName.trim()).equals("") ) {7109throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.matchcols2").toString());7110} else {7111// set strMatchColumn7112strMatchColumns.set(0, columnName);7113//iMatchColumn = -1;7114}7115}71167117/**7118* Unsets the designated parameter to the given <code>int</code>7119* object. This was set using <code>setMatchColumn</code>7120* as the column which will form the basis of the join.7121* <P>7122* The parameter value unset by this method should be same7123* as was set.7124*7125* @param columnIdx the index into this rowset7126* object's internal representation of parameter values7127* @throws SQLException if an error occurs or the7128* parameter index is out of bounds or if the columnIdx is7129* not the same as set using <code>setMatchColumn(int)</code>7130*/7131public void unsetMatchColumn(int columnIdx) throws SQLException {7132// check if we are unsetting the SAME column7133if(! iMatchColumns.get(0).equals(Integer.valueOf(columnIdx) ) ) {7134throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString());7135} else if(strMatchColumns.get(0) != null) {7136throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch1").toString());7137} else {7138// that is, we are unsetting it.7139iMatchColumns.set(0, -1);7140}7141}71427143/**7144* Unsets the designated parameter to the given <code>String</code>7145* object. This was set using <code>setMatchColumn</code>7146* as the column which will form the basis of the join.7147* <P>7148* The parameter value unset by this method should be same7149* as was set.7150*7151* @param columnName the index into this rowset7152* object's internal representation of parameter values7153* @throws SQLException if an error occurs or the7154* parameter index is out of bounds or if the columnName is7155* not the same as set using <code>setMatchColumn(String)</code>7156*/7157public void unsetMatchColumn(String columnName) throws SQLException {7158// check if we are unsetting the same column7159columnName = columnName.trim();71607161if(!((strMatchColumns.get(0)).equals(columnName))) {7162throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch").toString());7163} else if(iMatchColumns.get(0) > 0) {7164throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.unsetmatch2").toString());7165} else {7166strMatchColumns.set(0, null); // that is, we are unsetting it.7167}7168}71697170/**7171* Notifies registered listeners that a RowSet object in the given RowSetEvent7172* object has populated a number of additional rows. The <code>numRows</code> parameter7173* ensures that this event will only be fired every <code>numRow</code>.7174* <p>7175* The source of the event can be retrieved with the method event.getSource.7176*7177* @param event a <code>RowSetEvent</code> object that contains the7178* <code>RowSet</code> object that is the source of the events7179* @param numRows when populating, the number of rows interval on which the7180* <code>CachedRowSet</code> populated should fire; the default value7181* is zero; cannot be less than <code>fetchSize</code> or zero7182*/7183public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException {71847185if( numRows < 0 || numRows < getFetchSize()) {7186throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.numrows").toString());7187}71887189if(size() % numRows == 0) {7190RowSetEvent event_temp = new RowSetEvent(this);7191event = event_temp;7192notifyRowSetChanged();7193}7194}71957196/**7197* Populates this <code>CachedRowSet</code> object with data from7198* the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code>7199* method, an additional parameter is provided to allow starting position within7200* the <code>ResultSet</code> from where to populate the CachedRowSet7201* instance.7202*7203* This method is an alternative to the method <code>execute</code>7204* for filling the rowset with data. The method <code>populate</code>7205* does not require that the properties needed by the method7206* <code>execute</code>, such as the <code>command</code> property,7207* be set. This is true because the method <code>populate</code>7208* is given the <code>ResultSet</code> object from7209* which to get data and thus does not need to use the properties7210* required for setting up a connection and executing this7211* <code>CachedRowSetImpl</code> object's command.7212* <P>7213* After populating this rowset with data, the method7214* <code>populate</code> sets the rowset's metadata and7215* then sends a <code>RowSetChangedEvent</code> object7216* to all registered listeners prior to returning.7217*7218* @param data the <code>ResultSet</code> object containing the data7219* to be read into this <code>CachedRowSetImpl</code> object7220* @param start the integer specifing the position in the7221* <code>ResultSet</code> object to popultate the7222* <code>CachedRowSetImpl</code> object.7223* @throws SQLException if an error occurs; or the max row setting is7224* violated while populating the RowSet.Also id the start position7225* is negative.7226* @see #execute7227*/7228public void populate(ResultSet data, int start) throws SQLException{72297230int rowsFetched;7231Row currentRow;7232int numCols;7233int i;7234Map<String, Class<?>> map = getTypeMap();7235Object obj;7236int mRows;72377238cursorPos = 0;7239if(populatecallcount == 0){7240if(start < 0){7241throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.startpos").toString());7242}7243if(getMaxRows() == 0){7244data.absolute(start);7245while(data.next()){7246totalRows++;7247}7248totalRows++;7249}7250startPos = start;7251}7252populatecallcount = populatecallcount +1;7253resultSet = data;7254if((endPos - startPos) >= getMaxRows() && (getMaxRows() > 0)){7255endPos = prevEndPos;7256pagenotend = false;7257return;7258}72597260if((maxRowsreached != getMaxRows() || maxRowsreached != totalRows) && pagenotend) {7261startPrev = start - getPageSize();7262}72637264if( pageSize == 0){7265prevEndPos = endPos;7266endPos = start + getMaxRows() ;7267}7268else{7269prevEndPos = endPos;7270endPos = start + getPageSize();7271}727272737274if (start == 1){7275resultSet.beforeFirst();7276}7277else {7278resultSet.absolute(start -1);7279}7280if( pageSize == 0) {7281rvh = new Vector<Object>(getMaxRows());72827283}7284else{7285rvh = new Vector<Object>(getPageSize());7286}72877288if (data == null) {7289throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.populate").toString());7290}72917292// get the meta data for this ResultSet7293RSMD = data.getMetaData();72947295// set up the metadata7296RowSetMD = new RowSetMetaDataImpl();7297initMetaData(RowSetMD, RSMD);72987299// release the meta-data so that aren't tempted to use it.7300RSMD = null;7301numCols = RowSetMD.getColumnCount();7302mRows = this.getMaxRows();7303rowsFetched = 0;7304currentRow = null;73057306if(!data.next() && mRows == 0){7307endPos = prevEndPos;7308pagenotend = false;7309return;7310}73117312data.previous();73137314while ( data.next()) {73157316currentRow = new Row(numCols);7317if(pageSize == 0){7318if ( rowsFetched >= mRows && mRows > 0) {7319rowsetWarning.setNextException(new SQLException("Populating rows "7320+ "setting has exceeded max row setting"));7321break;7322}7323}7324else {7325if ( (rowsFetched >= pageSize) ||( maxRowsreached >= mRows && mRows > 0)) {7326rowsetWarning.setNextException(new SQLException("Populating rows "7327+ "setting has exceeded max row setting"));7328break;7329}7330}73317332for ( i = 1; i <= numCols; i++) {7333/*7334* check if the user has set a map. If no map7335* is set then use plain getObject. This lets7336* us work with drivers that do not support7337* getObject with a map in fairly sensible way7338*/7339if (map == null) {7340obj = data.getObject(i);7341} else {7342obj = data.getObject(i, map);7343}7344/*7345* the following block checks for the various7346* types that we have to serialize in order to7347* store - right now only structs have been tested7348*/7349if (obj instanceof Struct) {7350obj = new SerialStruct((Struct)obj, map);7351} else if (obj instanceof SQLData) {7352obj = new SerialStruct((SQLData)obj, map);7353} else if (obj instanceof Blob) {7354obj = new SerialBlob((Blob)obj);7355} else if (obj instanceof Clob) {7356obj = new SerialClob((Clob)obj);7357} else if (obj instanceof java.sql.Array) {7358obj = new SerialArray((java.sql.Array)obj, map);7359}73607361currentRow.initColumnObject(i, obj);7362}7363rowsFetched++;7364maxRowsreached++;7365rvh.add(currentRow);7366}7367numRows = rowsFetched ;7368// Also rowsFetched should be equal to rvh.size()7369// notify any listeners that the rowset has changed7370notifyRowSetChanged();73717372}73737374/**7375* The nextPage gets the next page, that is a <code>CachedRowSetImpl</code> object7376* containing the number of rows specified by page size.7377* @return boolean value true indicating whether there are more pages to come and7378* false indicating that this is the last page.7379* @throws SQLException if an error occurs or this called before calling populate.7380*/7381public boolean nextPage() throws SQLException {73827383if (populatecallcount == 0){7384throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString());7385}7386// Fix for 65541867387onFirstPage = false;7388if(callWithCon){7389crsReader.setStartPosition(endPos);7390crsReader.readData((RowSetInternal)this);7391resultSet = null;7392}7393else {7394populate(resultSet,endPos);7395}7396return pagenotend;7397}73987399/**7400* This is the setter function for setting the size of the page, which specifies7401* how many rows have to be retrived at a time.7402*7403* @param size which is the page size7404* @throws SQLException if size is less than zero or greater than max rows.7405*/7406public void setPageSize (int size) throws SQLException {7407if (size < 0) {7408throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize").toString());7409}7410if (size > getMaxRows() && getMaxRows() != 0) {7411throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.pagesize1").toString());7412}7413pageSize = size;7414}74157416/**7417* This is the getter function for the size of the page.7418*7419* @return an integer that is the page size.7420*/7421public int getPageSize() {7422return pageSize;7423}742474257426/**7427* Retrieves the data present in the page prior to the page from where it is7428* called.7429* @return boolean value true if it retrieves the previous page, flase if it7430* is on the first page.7431* @throws SQLException if it is called before populate is called or ResultSet7432* is of type <code>ResultSet.TYPE_FORWARD_ONLY</code> or if an error7433* occurs.7434*/7435public boolean previousPage() throws SQLException {7436int pS;7437int mR;7438int rem;74397440pS = getPageSize();7441mR = maxRowsreached;74427443if (populatecallcount == 0){7444throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.nextpage").toString());7445}74467447if( !callWithCon){7448if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY){7449throw new SQLException (resBundle.handleGetObject("cachedrowsetimpl.fwdonly").toString());7450}7451}74527453pagenotend = true;74547455if(startPrev < startPos ){7456onFirstPage = true;7457return false;7458}74597460if(onFirstPage){7461return false;7462}74637464rem = mR % pS;74657466if(rem == 0){7467maxRowsreached -= (2 * pS);7468if(callWithCon){7469crsReader.setStartPosition(startPrev);7470crsReader.readData((RowSetInternal)this);7471resultSet = null;7472}7473else {7474populate(resultSet,startPrev);7475}7476return true;7477}7478else7479{7480maxRowsreached -= (pS + rem);7481if(callWithCon){7482crsReader.setStartPosition(startPrev);7483crsReader.readData((RowSetInternal)this);7484resultSet = null;7485}7486else {7487populate(resultSet,startPrev);7488}7489return true;7490}7491}74927493/**7494* Goes to the page number passed as the parameter7495* @param page , the page loaded on a call to this function7496* @return true if the page exists false otherwise7497* @throws SQLException if an error occurs7498*/7499/*7500public boolean absolutePage(int page) throws SQLException{75017502boolean isAbs = true, retVal = true;7503int counter;75047505if( page <= 0 ){7506throw new SQLException("Absolute positoin is invalid");7507}7508counter = 0;75097510firstPage();7511counter++;7512while((counter < page) && isAbs) {7513isAbs = nextPage();7514counter ++;7515}75167517if( !isAbs && counter < page){7518retVal = false;7519}7520else if(counter == page){7521retVal = true;7522}75237524return retVal;7525}7526*/752775287529/**7530* Goes to the page number passed as the parameter from the current page.7531* The parameter can take postive or negative value accordingly.7532* @param page , the page loaded on a call to this function7533* @return true if the page exists false otherwise7534* @throws SQLException if an error occurs7535*/7536/*7537public boolean relativePage(int page) throws SQLException {75387539boolean isRel = true,retVal = true;7540int counter;75417542if(page > 0){7543counter = 0;7544while((counter < page) && isRel){7545isRel = nextPage();7546counter++;7547}75487549if(!isRel && counter < page){7550retVal = false;7551}7552else if( counter == page){7553retVal = true;7554}7555return retVal;7556}7557else {7558counter = page;7559isRel = true;7560while((counter < 0) && isRel){7561isRel = previousPage();7562counter++;7563}75647565if( !isRel && counter < 0){7566retVal = false;7567}7568else if(counter == 0){7569retVal = true;7570}7571return retVal;7572}7573}7574*/75757576/**7577* Retrieves the first page of data as specified by the page size.7578* @return boolean value true if present on first page, false otherwise7579* @throws SQLException if it called before populate or ResultSet is of7580* type <code>ResultSet.TYPE_FORWARD_ONLY</code> or an error occurs7581*/7582/*7583public boolean firstPage() throws SQLException {7584if (populatecallcount == 0){7585throw new SQLException("Populate the data before calling ");7586}7587if( !callWithCon){7588if(resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY) {7589throw new SQLException("Result of type forward only");7590}7591}7592endPos = 0;7593maxRowsreached = 0;7594pagenotend = true;7595if(callWithCon){7596crsReader.setStartPosition(startPos);7597crsReader.readData((RowSetInternal)this);7598resultSet = null;7599}7600else {7601populate(resultSet,startPos);7602}7603onFirstPage = true;7604return onFirstPage;7605}7606*/76077608/**7609* Retrives the last page of data as specified by the page size.7610* @return boolean value tur if present on the last page, false otherwise7611* @throws SQLException if called before populate or if an error occurs.7612*/7613/*7614public boolean lastPage() throws SQLException{7615int pS;7616int mR;7617int quo;7618int rem;76197620pS = getPageSize();7621mR = getMaxRows();76227623if(pS == 0){7624onLastPage = true;7625return onLastPage;7626}76277628if(getMaxRows() == 0){7629mR = totalRows;7630}76317632if (populatecallcount == 0){7633throw new SQLException("Populate the data before calling ");7634}76357636onFirstPage = false;76377638if((mR % pS) == 0){7639quo = mR / pS;7640int start = startPos + (pS * (quo - 1));7641maxRowsreached = mR - pS;7642if(callWithCon){7643crsReader.setStartPosition(start);7644crsReader.readData((RowSetInternal)this);7645resultSet = null;7646}7647else {7648populate(resultSet,start);7649}7650onLastPage = true;7651return onLastPage;7652}7653else {7654quo = mR /pS;7655rem = mR % pS;7656int start = startPos + (pS * quo);7657maxRowsreached = mR - (rem);7658if(callWithCon){7659crsReader.setStartPosition(start);7660crsReader.readData((RowSetInternal)this);7661resultSet = null;7662}7663else {7664populate(resultSet,start);7665}7666onLastPage = true;7667return onLastPage;7668}7669}7670*/76717672/**7673* Sets the status for the row on which the cursor is positioned. The insertFlag is used7674* to mention the toggle status for this row7675* @param insertFlag if it is true - marks this row as inserted7676* if it is false - marks it as not a newly inserted row7677* @throws SQLException if an error occurs while doing this operation7678*/7679public void setRowInserted(boolean insertFlag) throws SQLException {76807681checkCursor();76827683if(onInsertRow == true)7684throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidop").toString());76857686if( insertFlag ) {7687((Row)getCurrentRow()).setInserted();7688} else {7689((Row)getCurrentRow()).clearInserted();7690}7691}76927693/**7694* Retrieves the value of the designated <code>SQL XML</code> parameter as a7695* <code>SQLXML</code> object in the Java programming language.7696* @param columnIndex the first column is 1, the second is 2, ...7697* @return a SQLXML object that maps an SQL XML value7698* @throws SQLException if a database access error occurs7699* @since 6.07700*/7701public SQLXML getSQLXML(int columnIndex) throws SQLException {7702throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7703}77047705/**7706* Retrieves the value of the designated <code>SQL XML</code> parameter as a7707* <code>SQLXML</code> object in the Java programming language.7708* @param colName the name of the column from which to retrieve the value7709* @return a SQLXML object that maps an SQL XML value7710* @throws SQLException if a database access error occurs7711*/7712public SQLXML getSQLXML(String colName) throws SQLException {7713throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7714}77157716/**7717* Retrieves the value of the designated column in the current row of this7718* <code>ResultSet</code> object as a java.sql.RowId object in the Java7719* programming language.7720*7721* @param columnIndex the first column is 1, the second 2, ...7722* @return the column value if the value is a SQL <code>NULL</code> the7723* value returned is <code>null</code>7724* @throws SQLException if a database access error occurs7725* @since 6.07726*/7727public RowId getRowId(int columnIndex) throws SQLException {7728throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7729}77307731/**7732* Retrieves the value of the designated column in the current row of this7733* <code>ResultSet</code> object as a java.sql.RowId object in the Java7734* programming language.7735*7736* @param columnName the name of the column7737* @return the column value if the value is a SQL <code>NULL</code> the7738* value returned is <code>null</code>7739* @throws SQLException if a database access error occurs7740* @since 6.07741*/7742public RowId getRowId(String columnName) throws SQLException {7743throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7744}77457746/**7747* Updates the designated column with a <code>RowId</code> value. The updater7748* methods are used to update column values in the current row or the insert7749* row. The updater methods do not update the underlying database; instead7750* the <code>updateRow<code> or <code>insertRow</code> methods are called7751* to update the database.7752*7753* @param columnIndex the first column is 1, the second 2, ...7754* @param x the column value7755* @throws SQLException if a database access occurs7756* @since 6.07757*/7758public void updateRowId(int columnIndex, RowId x) throws SQLException {7759throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7760}77617762/**7763* Updates the designated column with a <code>RowId</code> value. The updater7764* methods are used to update column values in the current row or the insert7765* row. The updater methods do not update the underlying database; instead7766* the <code>updateRow<code> or <code>insertRow</code> methods are called7767* to update the database.7768*7769* @param columnName the name of the column7770* @param x the column value7771* @throws SQLException if a database access occurs7772* @since 6.07773*/7774public void updateRowId(String columnName, RowId x) throws SQLException {7775throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7776}77777778/**7779* Retrieves the holdability of this ResultSet object7780* @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or ResultSet.CLOSE_CURSORS_AT_COMMIT7781* @throws SQLException if a database error occurs7782* @since 6.07783*/7784public int getHoldability() throws SQLException {7785throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7786}77877788/**7789* Retrieves whether this ResultSet object has been closed. A ResultSet is closed if the7790* method close has been called on it, or if it is automatically closed.7791* @return true if this ResultSet object is closed; false if it is still open7792* @throws SQLException if a database access error occurs7793* @since 6.07794*/7795public boolean isClosed() throws SQLException {7796throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7797}77987799/**7800* This method is used for updating columns that support National Character sets.7801* It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns.7802* @param columnIndex the first column is 1, the second 2, ...7803* @param nString the value for the column to be updated7804* @throws SQLException if a database access error occurs7805* @since 6.07806*/7807public void updateNString(int columnIndex, String nString) throws SQLException {7808throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7809}78107811/**7812* This method is used for updating columns that support National Character sets.7813* It can be used for updating NCHAR,NVARCHAR and LONGNVARCHAR columns.7814* @param columnName name of the Column7815* @param nString the value for the column to be updated7816* @throws SQLException if a database access error occurs7817* @since 6.07818*/7819public void updateNString(String columnName, String nString) throws SQLException {7820throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7821}782278237824/*o7825* This method is used for updating SQL <code>NCLOB</code> type that maps7826* to <code>java.sql.Types.NCLOB</code>7827* @param columnIndex the first column is 1, the second 2, ...7828* @param nClob the value for the column to be updated7829* @throws SQLException if a database access error occurs7830* @since 6.07831*/7832public void updateNClob(int columnIndex, NClob nClob) throws SQLException {7833throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7834}78357836/**7837* This method is used for updating SQL <code>NCLOB</code> type that maps7838* to <code>java.sql.Types.NCLOB</code>7839* @param columnName name of the column7840* @param nClob the value for the column to be updated7841* @throws SQLException if a database access error occurs7842* @since 6.07843*/7844public void updateNClob(String columnName, NClob nClob) throws SQLException {7845throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7846}78477848/**7849* Retrieves the value of the designated column in the current row7850* of this <code>ResultSet</code> object as a <code>NClob</code> object7851* in the Java programming language.7852*7853* @param i the first column is 1, the second is 2, ...7854* @return a <code>NClob</code> object representing the SQL7855* <code>NCLOB</code> value in the specified column7856* @exception SQLException if a database access error occurs7857* @since 6.07858*/7859public NClob getNClob(int i) throws SQLException {7860throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7861}786278637864/**7865* Retrieves the value of the designated column in the current row7866* of this <code>ResultSet</code> object as a <code>NClob</code> object7867* in the Java programming language.7868*7869* @param colName the name of the column from which to retrieve the value7870* @return a <code>NClob</code> object representing the SQL <code>NCLOB</code>7871* value in the specified column7872* @exception SQLException if a database access error occurs7873* @since 6.07874*/7875public NClob getNClob(String colName) throws SQLException {7876throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7877}78787879public <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException {7880return null;7881}78827883public boolean isWrapperFor(Class<?> interfaces) throws SQLException {7884return false;7885}788678877888/**7889* Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an7890* SQL <code>XML</code> value when it sends it to the database.7891* @param parameterIndex index of the first parameter is 1, the second is 2, ...7892* @param xmlObject a <code>SQLXML</code> object that maps an SQL <code>XML</code> value7893* @throws SQLException if a database access error occurs7894* @since 1.67895*/7896public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {7897throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7898}78997900/**7901* Sets the designated parameter to the given <code>java.sql.SQLXML</code> object. The driver converts this to an7902* <code>SQL XML</code> value when it sends it to the database.7903* @param parameterName the name of the parameter7904* @param xmlObject a <code>SQLXML</code> object that maps an <code>SQL XML</code> value7905* @throws SQLException if a database access error occurs7906* @since 1.67907*/7908public void setSQLXML(String parameterName, SQLXML xmlObject) throws SQLException {7909throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7910}791179127913/**7914* Sets the designated parameter to the given <code>java.sql.RowId</code> object. The7915* driver converts this to a SQL <code>ROWID</code> value when it sends it7916* to the database7917*7918* @param parameterIndex the first parameter is 1, the second is 2, ...7919* @param x the parameter value7920* @throws SQLException if a database access error occurs7921*7922* @since 1.67923*/7924public void setRowId(int parameterIndex, RowId x) throws SQLException {7925throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7926}792779287929/**7930* Sets the designated parameter to the given <code>java.sql.RowId</code> object. The7931* driver converts this to a SQL <code>ROWID</code> when it sends it to the7932* database.7933*7934* @param parameterName the name of the parameter7935* @param x the parameter value7936* @throws SQLException if a database access error occurs7937* @since 1.67938*/7939public void setRowId(String parameterName, RowId x) throws SQLException {7940throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7941}794279437944/**7945* Sets the designated parameter to a <code>Reader</code> object. The7946* <code>Reader</code> reads the data till end-of-file is reached. The7947* driver does the necessary conversion from Java character format to7948* the national character set in the database.79497950* <P><B>Note:</B> This stream object can either be a standard7951* Java stream object or your own subclass that implements the7952* standard interface.7953* <P><B>Note:</B> Consult your JDBC driver documentation to determine if7954* it might be more efficient to use a version of7955* <code>setNCharacterStream</code> which takes a length parameter.7956*7957* @param parameterIndex of the first parameter is 1, the second is 2, ...7958* @param value the parameter value7959* @throws SQLException if the driver does not support national7960* character sets; if the driver can detect that a data conversion7961* error could occur ; if a database access error occurs; or7962* this method is called on a closed <code>PreparedStatement</code>7963* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method7964* @since 1.67965*/7966public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {7967throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());7968}796979707971/**7972* Sets the designated parameter to a <code>java.sql.NClob</code> object. The object7973* implements the <code>java.sql.NClob</code> interface. This <code>NClob</code>7974* object maps to a SQL <code>NCLOB</code>.7975* @param parameterName the name of the column to be set7976* @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; or if a database access error occurs7980* @since 1.67981*/7982public void setNClob(String parameterName, NClob value) throws SQLException {7983throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());7984}798579867987/**7988* Retrieves the value of the designated column in the current row7989* of this <code>ResultSet</code> object as a7990* <code>java.io.Reader</code> object.7991* It is intended for use when7992* accessing <code>NCHAR</code>,<code>NVARCHAR</code>7993* and <code>LONGNVARCHAR</code> columns.7994*7995* @return a <code>java.io.Reader</code> object that contains the column7996* value; if the value is SQL <code>NULL</code>, the value returned is7997* <code>null</code> in the Java programming language.7998* @param columnIndex the first column is 1, the second is 2, ...7999* @exception SQLException if a database access error occurs8000* @since 1.68001*/8002public java.io.Reader getNCharacterStream(int columnIndex) throws SQLException {8003throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8004}800580068007/**8008* Retrieves the value of the designated column in the current row8009* of this <code>ResultSet</code> object as a8010* <code>java.io.Reader</code> object.8011* It is intended for use when8012* accessing <code>NCHAR</code>,<code>NVARCHAR</code>8013* and <code>LONGNVARCHAR</code> columns.8014*8015* @param columnName the name of the column8016* @return a <code>java.io.Reader</code> object that contains the column8017* value; if the value is SQL <code>NULL</code>, the value returned is8018* <code>null</code> in the Java programming language8019* @exception SQLException if a database access error occurs8020* @since 1.68021*/8022public java.io.Reader getNCharacterStream(String columnName) throws SQLException {8023throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8024}802580268027/**8028* Updates the designated column with a <code>java.sql.SQLXML</code> value.8029* The updater8030* methods are used to update column values in the current row or the insert8031* row. The updater methods do not update the underlying database; instead8032* the <code>updateRow</code> or <code>insertRow</code> methods are called8033* to update the database.8034* @param columnIndex the first column is 1, the second 2, ...8035* @param xmlObject the value for the column to be updated8036* @throws SQLException if a database access error occurs8037* @since 1.68038*/8039public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {8040throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8041}80428043/**8044* Updates the designated column with a <code>java.sql.SQLXML</code> value.8045* The updater8046* methods are used to update column values in the current row or the insert8047* row. The updater methods do not update the underlying database; instead8048* the <code>updateRow</code> or <code>insertRow</code> methods are called8049* to update the database.8050*8051* @param columnName the name of the column8052* @param xmlObject the column value8053* @throws SQLException if a database access occurs8054* @since 1.68055*/8056public void updateSQLXML(String columnName, SQLXML xmlObject) throws SQLException {8057throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8058}80598060/**8061* Retrieves the value of the designated column in the current row8062* of this <code>ResultSet</code> object as8063* a <code>String</code> in the Java programming language.8064* It is intended for use when8065* accessing <code>NCHAR</code>,<code>NVARCHAR</code>8066* and <code>LONGNVARCHAR</code> columns.8067*8068* @param columnIndex the first column is 1, the second is 2, ...8069* @return the column value; if the value is SQL <code>NULL</code>, the8070* value returned is <code>null</code>8071* @exception SQLException if a database access error occurs8072* @since 1.68073*/8074public String getNString(int columnIndex) 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 columnName the SQL name of the column8087* @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(String columnName) throws SQLException {8093throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8094}80958096/**8097* Updates the designated column with a character stream value, which will8098* have the specified number of bytes. The driver does the necessary conversion8099* from Java character format to the national character set in the database.8100* It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns.8101* The updater methods are used to update column values in the current row or8102* the insert row. The updater methods do not update the underlying database;8103* instead the updateRow or insertRow methods are called to update the database.8104*8105* @param columnIndex - the first column is 1, the second is 2, ...8106* @param x - the new column value8107* @param length - the length of the stream8108* @exception SQLException if a database access error occurs8109* @since 1.68110*/8111public void updateNCharacterStream(int columnIndex,8112java.io.Reader x,8113long length)8114throws SQLException {8115throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8116}81178118/**8119* Updates the designated column with a character stream value, which will8120* have the specified number of bytes. The driver does the necessary conversion8121* from Java character format to the national character set in the database.8122* It is intended for use when updating NCHAR,NVARCHAR and LONGNVARCHAR columns.8123* The updater methods are used to update column values in the current row or8124* the insert row. The updater methods do not update the underlying database;8125* instead the updateRow or insertRow methods are called to update the database.8126*8127* @param columnName - name of the Column8128* @param x - the new column value8129* @param length - the length of the stream8130* @exception SQLException if a database access error occurs8131* @since 1.68132*/8133public void updateNCharacterStream(String columnName,8134java.io.Reader x,8135long length)8136throws SQLException {8137throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.opnotysupp").toString());8138}81398140/**8141* Updates the designated column with a character stream value. The8142* driver does the necessary conversion from Java character format to8143* the national character set in the database.8144* It is intended for use when8145* updating <code>NCHAR</code>,<code>NVARCHAR</code>8146* and <code>LONGNVARCHAR</code> columns.8147*8148* The updater methods are used to update column values in the8149* current row or the insert row. The updater methods do not8150* update the underlying database; instead the <code>updateRow</code> or8151* <code>insertRow</code> methods are called to update the database.8152*8153* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8154* it might be more efficient to use a version of8155* <code>updateNCharacterStream</code> which takes a length parameter.8156*8157* @param columnIndex the first column is 1, the second is 2, ...8158* @param x the new column value8159* @exception SQLException if a database access error occurs,8160* the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set8161* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8162* this method8163* @since 1.68164*/8165public void updateNCharacterStream(int columnIndex,8166java.io.Reader x) throws SQLException {8167throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8168}81698170/**8171* Updates the designated column with a character stream value. The8172* driver does the necessary conversion from Java character format to8173* the national character set in the database.8174* It is intended for use when8175* updating <code>NCHAR</code>,<code>NVARCHAR</code>8176* and <code>LONGNVARCHAR</code> columns.8177*8178* The updater methods are used to update column values in the8179* current row or the insert row. The updater methods do not8180* update the underlying database; instead the <code>updateRow</code> or8181* <code>insertRow</code> methods are called to update the database.8182*8183* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8184* it might be more efficient to use a version of8185* <code>updateNCharacterStream</code> which takes a length parameter.8186*8187* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8188bel is the name of the column8189* @param reader the <code>java.io.Reader</code> object containing8190* the new column value8191* @exception SQLException if a database access error occurs,8192* the result set concurrency is <code>CONCUR_READ_ONLY</code> or this method is called on a closed result set8193* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8194* this method8195* @since 1.68196*/8197public void updateNCharacterStream(String columnLabel,8198java.io.Reader reader) throws SQLException {8199throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8200}82018202//////////////////////////82038204/**8205* Updates the designated column using the given input stream, which8206* will have the specified number of bytes.8207* When a very large ASCII value is input to a <code>LONGVARCHAR</code>8208* parameter, it may be more practical to send it via a8209* <code>java.io.InputStream</code>. Data will be read from the stream8210* as needed until end-of-file is reached. The JDBC driver will8211* do any necessary conversion from ASCII to the database char format.8212*8213* <P><B>Note:</B> This stream object can either be a standard8214* Java stream object or your own subclass that implements the8215* standard interface.8216* <p>8217* The updater methods are used to update column values in the8218* current row or the insert row. The updater methods do not8219* update the underlying database; instead the <code>updateRow</code> or8220* <code>insertRow</code> methods are called to update the database.8221*8222* @param columnIndex the first column is 1, the second is 2, ...8223* @param inputStream An object that contains the data to set the parameter8224* value to.8225* @param length the number of bytes in the parameter data.8226* @exception SQLException if a database access error occurs,8227* the result set concurrency is <code>CONCUR_READ_ONLY</code>8228* or this method is called on a closed result set8229* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8230* this method8231* @since 1.68232*/8233public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException{8234throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8235}82368237/**8238* Updates the designated column using the given input stream, which8239* will have the specified number of bytes.8240* When a very large ASCII value is input to a <code>LONGVARCHAR</code>8241* parameter, it may be more practical to send it via a8242* <code>java.io.InputStream</code>. Data will be read from the stream8243* as needed until end-of-file is reached. The JDBC driver will8244* do any necessary conversion from ASCII to the database char format.8245*8246* <P><B>Note:</B> This stream object can either be a standard8247* Java stream object or your own subclass that implements the8248* standard interface.8249* <p>8250* The updater methods are used to update column values in the8251* current row or the insert row. The updater methods do not8252* update the underlying database; instead the <code>updateRow</code> or8253* <code>insertRow</code> methods are called to update the database.8254*8255* @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 column8256* @param inputStream An object that contains the data to set the parameter8257* value to.8258* @param length the number of bytes in the parameter data.8259* @exception SQLException if a database access error occurs,8260* the result set concurrency is <code>CONCUR_READ_ONLY</code>8261* or this method is called on a closed result set8262* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8263* this method8264* @since 1.68265*/8266public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {8267throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8268}82698270/**8271* Updates the designated column using the given input stream.8272* When a very large ASCII value is input to a <code>LONGVARCHAR</code>8273* parameter, it may be more practical to send it via a8274* <code>java.io.InputStream</code>. Data will be read from the stream8275* as needed until end-of-file is reached. The JDBC driver will8276* do any necessary conversion from ASCII to the database char format.8277*8278* <P><B>Note:</B> This stream object can either be a standard8279* Java stream object or your own subclass that implements the8280* standard interface.8281*8282* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8283* it might be more efficient to use a version of8284* <code>updateBlob</code> which takes a length parameter.8285* <p>8286* The updater methods are used to update column values in the8287* current row or the insert row. The updater methods do not8288* update the underlying database; instead the <code>updateRow</code> or8289* <code>insertRow</code> methods are called to update the database.8290*8291* @param columnIndex the first column is 1, the second is 2, ...8292* @param inputStream An object that contains the data to set the parameter8293* value to.8294* @exception SQLException if a database access error occurs,8295* the result set concurrency is <code>CONCUR_READ_ONLY</code>8296* or this method is called on a closed result set8297* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8298* this method8299* @since 1.68300*/8301public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {8302throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8303}83048305/**8306* Updates the designated column using the given input stream.8307* When a very large ASCII value is input to a <code>LONGVARCHAR</code>8308* parameter, it may be more practical to send it via a8309* <code>java.io.InputStream</code>. Data will be read from the stream8310* as needed until end-of-file is reached. The JDBC driver will8311* do any necessary conversion from ASCII to the database char format.8312*8313* <P><B>Note:</B> This stream object can either be a standard8314* Java stream object or your own subclass that implements the8315* standard interface.8316* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8317* it might be more efficient to use a version of8318* <code>updateBlob</code> which takes a length parameter.8319* <p>8320* The updater methods are used to update column values in the8321* current row or the insert row. The updater methods do not8322* update the underlying database; instead the <code>updateRow</code> or8323* <code>insertRow</code> methods are called to update the database.8324*8325* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8326bel is the name of the column8327* @param inputStream An object that contains the data to set the parameter8328* value to.8329* @exception SQLException if a database access error occurs,8330* the result set concurrency is <code>CONCUR_READ_ONLY</code>8331* or this method is called on a closed result set8332* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8333* this method8334* @since 1.68335*/8336public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {8337throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8338}83398340/**8341* Updates the designated column using the given <code>Reader</code>8342* object, which is the given number of characters long.8343* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8344* parameter, it may be more practical to send it via a8345* <code>java.io.Reader</code> object. The data will be read from the stream8346* as needed until end-of-file is reached. The JDBC driver will8347* do any necessary conversion from UNICODE to the database char format.8348*8349* <P><B>Note:</B> This stream object can either be a standard8350* Java stream object or your own subclass that implements the8351* standard interface.8352* <p>8353* The updater methods are used to update column values in the8354* current row or the insert row. The updater methods do not8355* update the underlying database; instead the <code>updateRow</code> or8356* <code>insertRow</code> methods are called to update the database.8357*8358* @param columnIndex the first column is 1, the second is 2, ...8359* @param reader An object that contains the data to set the parameter value to.8360* @param length the number of characters in the parameter data.8361* @exception SQLException if a database access error occurs,8362* the result set concurrency is <code>CONCUR_READ_ONLY</code>8363* or this method is called on a closed result set8364* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8365* this method8366* @since 1.68367*/8368public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {8369throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8370}83718372/**8373* Updates the designated column using the given <code>Reader</code>8374* object, which is the given number of characters long.8375* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8376* parameter, it may be more practical to send it via a8377* <code>java.io.Reader</code> object. The data will be read from the stream8378* as needed until end-of-file is reached. The JDBC driver will8379* do any necessary conversion from UNICODE to the database char format.8380*8381* <P><B>Note:</B> This stream object can either be a standard8382* Java stream object or your own subclass that implements the8383* standard interface.8384* <p>8385* The updater methods are used to update column values in the8386* current row or the insert row. The updater methods do not8387* update the underlying database; instead the <code>updateRow</code> or8388* <code>insertRow</code> methods are called to update the database.8389*8390* @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 column8391* @param reader An object that contains the data to set the parameter value to.8392* @param length the number of characters in the parameter data.8393* @exception SQLException if a database access error occurs,8394* the result set concurrency is <code>CONCUR_READ_ONLY</code>8395* or this method is called on a closed result set8396* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8397* this method8398* @since 1.68399*/8400public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {8401throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8402}84038404/**8405* Updates the designated column using the given <code>Reader</code>8406* object.8407* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8408* parameter, it may be more practical to send it via a8409* <code>java.io.Reader</code> object. The data will be read from the stream8410* as needed until end-of-file is reached. The JDBC driver will8411* do any necessary conversion from UNICODE to the database char format.8412*8413* <P><B>Note:</B> This stream object can either be a standard8414* Java stream object or your own subclass that implements the8415* standard interface.8416* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8417* it might be more efficient to use a version of8418* <code>updateClob</code> which takes a length parameter.8419* <p>8420* The updater methods are used to update column values in the8421* current row or the insert row. The updater methods do not8422* update the underlying database; instead the <code>updateRow</code> or8423* <code>insertRow</code> methods are called to update the database.8424*8425* @param columnIndex the first column is 1, the second is 2, ...8426* @param reader An object that contains the data to set the parameter value to.8427* @exception SQLException if a database access error occurs,8428* the result set concurrency is <code>CONCUR_READ_ONLY</code>8429* or this method is called on a closed result set8430* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8431* this method8432* @since 1.68433*/8434public void updateClob(int columnIndex, Reader reader) throws SQLException {8435throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8436}84378438/**8439* Updates the designated column using the given <code>Reader</code>8440* object.8441* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8442* parameter, it may be more practical to send it via a8443* <code>java.io.Reader</code> object. The data will be read from the stream8444* as needed until end-of-file is reached. The JDBC driver will8445* do any necessary conversion from UNICODE to the database char format.8446*8447* <P><B>Note:</B> This stream object can either be a standard8448* Java stream object or your own subclass that implements the8449* standard interface.8450* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8451* it might be more efficient to use a version of8452* <code>updateClob</code> which takes a length parameter.8453* <p>8454* The updater methods are used to update column values in the8455* current row or the insert row. The updater methods do not8456* update the underlying database; instead the <code>updateRow</code> or8457* <code>insertRow</code> methods are called to update the database.8458*8459* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8460bel is the name of the column8461* @param reader An object that contains the data to set the parameter value to.8462* @exception SQLException if a database access error occurs,8463* the result set concurrency is <code>CONCUR_READ_ONLY</code>8464* or this method is called on a closed result set8465* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8466* this method8467* @since 1.68468*/8469public void updateClob(String columnLabel, Reader reader) throws SQLException {8470throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8471}84728473/**8474* Updates the designated column using the given <code>Reader</code>8475* object, which is the given number of characters long.8476* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8477* parameter, it may be more practical to send it via a8478* <code>java.io.Reader</code> object. The data will be read from the stream8479* as needed until end-of-file is reached. The JDBC driver will8480* do any necessary conversion from UNICODE to the database char format.8481*8482* <P><B>Note:</B> This stream object can either be a standard8483* Java stream object or your own subclass that implements the8484* standard interface.8485* <p>8486* The updater methods are used to update column values in the8487* current row or the insert row. The updater methods do not8488* update the underlying database; instead the <code>updateRow</code> or8489* <code>insertRow</code> methods are called to update the database.8490*8491* @param columnIndex the first column is 1, the second 2, ...8492* @param reader An object that contains the data to set the parameter value to.8493* @param length the number of characters in the parameter data.8494* @throws SQLException if the driver does not support national8495* character sets; if the driver can detect that a data conversion8496* error could occur; this method is called on a closed result set,8497* if a database access error occurs or8498* the result set concurrency is <code>CONCUR_READ_ONLY</code>8499* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8500* this method8501* @since 1.68502*/8503public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {8504throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8505}85068507/**8508* Updates the designated column using the given <code>Reader</code>8509* object, which is the given number of characters long.8510* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8511* parameter, it may be more practical to send it via a8512* <code>java.io.Reader</code> object. The data will be read from the stream8513* as needed until end-of-file is reached. The JDBC driver will8514* do any necessary conversion from UNICODE to the database char format.8515*8516* <P><B>Note:</B> This stream object can either be a standard8517* Java stream object or your own subclass that implements the8518* standard interface.8519* <p>8520* The updater methods are used to update column values in the8521* current row or the insert row. The updater methods do not8522* update the underlying database; instead the <code>updateRow</code> or8523* <code>insertRow</code> methods are called to update the database.8524*8525* @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 column8526* @param reader An object that contains the data to set the parameter value to.8527* @param length the number of characters in the parameter data.8528* @throws SQLException if the driver does not support national8529* character sets; if the driver can detect that a data conversion8530* error could occur; this method is called on a closed result set;8531* if a database access error occurs or8532* the result set concurrency is <code>CONCUR_READ_ONLY</code>8533* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8534* this method8535* @since 1.68536*/8537public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {8538throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8539}85408541/**8542* Updates the designated column using the given <code>Reader</code>8543* object.8544* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8545* parameter, it may be more practical to send it via a8546* <code>java.io.Reader</code> object. The data will be read from the stream8547* as needed until end-of-file is reached. The JDBC driver will8548* do any necessary conversion from UNICODE to the database char format.8549*8550* <P><B>Note:</B> This stream object can either be a standard8551* Java stream object or your own subclass that implements the8552* standard interface.8553* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8554* it might be more efficient to use a version of8555* <code>updateNClob</code> which takes a length parameter.8556* <p>8557* The updater methods are used to update column values in the8558* current row or the insert row. The updater methods do not8559* update the underlying database; instead the <code>updateRow</code> or8560* <code>insertRow</code> methods are called to update the database.8561*8562* @param columnIndex the first column is 1, the second 2, ...8563* @param reader An object that contains the data to set the parameter value to.8564* @throws SQLException if the driver does not support national8565* character sets; if the driver can detect that a data conversion8566* error could occur; this method is called on a closed result set,8567* if a database access error occurs or8568* the result set concurrency is <code>CONCUR_READ_ONLY</code>8569* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8570* this method8571* @since 1.68572*/8573public void updateNClob(int columnIndex, Reader reader) throws SQLException {8574throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8575}85768577/**8578* Updates the designated column using the given <code>Reader</code>8579* object.8580* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>8581* parameter, it may be more practical to send it via a8582* <code>java.io.Reader</code> object. The data will be read from the stream8583* as needed until end-of-file is reached. The JDBC driver will8584* do any necessary conversion from UNICODE to the database char format.8585*8586* <P><B>Note:</B> This stream object can either be a standard8587* Java stream object or your own subclass that implements the8588* standard interface.8589* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8590* it might be more efficient to use a version of8591* <code>updateNClob</code> which takes a length parameter.8592* <p>8593* The updater methods are used to update column values in the8594* current row or the insert row. The updater methods do not8595* update the underlying database; instead the <code>updateRow</code> or8596* <code>insertRow</code> methods are called to update the database.8597*8598* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8599bel is the name of the column8600* @param reader An object that contains the data to set the parameter value to.8601* @throws SQLException if the driver does not support national8602* character sets; if the driver can detect that a data conversion8603* error could occur; this method is called on a closed result set;8604* if a database access error occurs or8605* the result set concurrency is <code>CONCUR_READ_ONLY</code>8606* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8607* this method8608* @since 1.68609*/8610public void updateNClob(String columnLabel, Reader reader) throws SQLException {8611throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8612}86138614/**8615* Updates the designated column with an ascii stream value, which will have8616* the specified number of bytes.8617* The updater methods are used to update column values in the8618* current row or the insert row. The updater methods do not8619* update the underlying database; instead the <code>updateRow</code> or8620* <code>insertRow</code> methods are called to update the database.8621*8622* @param columnIndex the first column is 1, the second is 2, ...8623* @param x the new column value8624* @param length the length of the stream8625* @exception SQLException if a database access error occurs,8626* the result set concurrency is <code>CONCUR_READ_ONLY</code>8627* or this method is called on a closed result set8628* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8629* this method8630* @since 1.68631*/8632public void updateAsciiStream(int columnIndex,8633java.io.InputStream x,8634long length) throws SQLException {86358636}86378638/**8639* Updates the designated column with a binary stream value, which will have8640* the specified number of bytes.8641* The updater methods are used to update column values in the8642* current row or the insert row. The updater methods do not8643* update the underlying database; instead the <code>updateRow</code> or8644* <code>insertRow</code> methods are called to update the database.8645*8646* @param columnIndex the first column is 1, the second is 2, ...8647* @param x the new column value8648* @param length the length of the stream8649* @exception SQLException if a database access error occurs,8650* the result set concurrency is <code>CONCUR_READ_ONLY</code>8651* or this method is called on a closed result set8652* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8653* this method8654* @since 1.68655*/8656public void updateBinaryStream(int columnIndex,8657java.io.InputStream x,8658long length) throws SQLException {8659}86608661/**8662* Updates the designated column with a character stream value, which will have8663* the specified number of bytes.8664* The updater methods are used to update column values in the8665* current row or the insert row. The updater methods do not8666* update the underlying database; instead the <code>updateRow</code> or8667* <code>insertRow</code> methods are called to update the database.8668*8669* @param columnIndex the first column is 1, the second is 2, ...8670* @param x the new column value8671* @param length the length of the stream8672* @exception SQLException if a database access error occurs,8673* the result set concurrency is <code>CONCUR_READ_ONLY</code>8674* or this method is called on a closed result set8675* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8676* this method8677* @since 1.68678*/8679public void updateCharacterStream(int columnIndex,8680java.io.Reader x,8681long length) throws SQLException {8682throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8683}86848685/**8686* Updates the designated column with a character stream value, which will have8687* the specified number of bytes.8688* The updater methods are used to update column values in the8689* current row or the insert row. The updater methods do not8690* update the underlying database; instead the <code>updateRow</code> or8691* <code>insertRow</code> methods are called to update the database.8692*8693* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8694bel is the name of the column8695* @param reader the <code>java.io.Reader</code> object containing8696* the new column value8697* @param length the length of the stream8698* @exception SQLException if a database access error occurs,8699* the result set concurrency is <code>CONCUR_READ_ONLY</code>8700* or this method is called on a closed result set8701* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8702* this method8703* @since 1.68704*/8705public void updateCharacterStream(String columnLabel,8706java.io.Reader reader,8707long length) throws SQLException {8708throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8709}8710/**8711* Updates the designated column with an ascii stream value, which will have8712* the specified number of bytes..8713* The updater methods are used to update column values in the8714* current row or the insert row. The updater methods do not8715* update the underlying database; instead the <code>updateRow</code> or8716* <code>insertRow</code> methods are called to update the database.8717*8718* @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 column8719* @param x the new column value8720* @param length the length of the stream8721* @exception SQLException if a database access error occurs,8722* the result set concurrency is <code>CONCUR_READ_ONLY</code>8723* or this method is called on a closed result set8724* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8725* this method8726* @since 1.68727*/8728public void updateAsciiStream(String columnLabel,8729java.io.InputStream x,8730long length) throws SQLException {8731}87328733/**8734* Updates the designated column with a binary stream value, which will have8735* the specified number of bytes.8736* The updater methods are used to update column values in the8737* current row or the insert row. The updater methods do not8738* update the underlying database; instead the <code>updateRow</code> or8739* <code>insertRow</code> methods are called to update the database.8740*8741* @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 column8742* @param x the new column value8743* @param length the length of the stream8744* @exception SQLException if a database access error occurs,8745* the result set concurrency is <code>CONCUR_READ_ONLY</code>8746* or this method is called on a closed result set8747* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8748* this method8749* @since 1.68750*/8751public void updateBinaryStream(String columnLabel,8752java.io.InputStream x,8753long length) throws SQLException {8754}87558756/**8757* Updates the designated column with a binary stream value.8758* The updater methods are used to update column values in the8759* current row or the insert row. The updater methods do not8760* update the underlying database; instead the <code>updateRow</code> or8761* <code>insertRow</code> methods are called to update the database.8762*8763* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8764* it might be more efficient to use a version of8765* <code>updateBinaryStream</code> which takes a length parameter.8766*8767* @param columnIndex the first column is 1, the second is 2, ...8768* @param x the new column value8769* @exception SQLException if a database access error occurs,8770* the result set concurrency is <code>CONCUR_READ_ONLY</code>8771* or this method is called on a closed result set8772* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8773* this method8774* @since 1.68775*/8776public void updateBinaryStream(int columnIndex,8777java.io.InputStream x) throws SQLException {8778throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8779}878087818782/**8783* Updates the designated column with a binary stream value.8784* The updater methods are used to update column values in the8785* current row or the insert row. The updater methods do not8786* update the underlying database; instead the <code>updateRow</code> or8787* <code>insertRow</code> methods are called to update the database.8788*8789* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8790* it might be more efficient to use a version of8791* <code>updateBinaryStream</code> which takes a length parameter.8792*8793* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8794bel is the name of the column8795* @param x the new column value8796* @exception SQLException if a database access error occurs,8797* the result set concurrency is <code>CONCUR_READ_ONLY</code>8798* or this method is called on a closed result set8799* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8800* this method8801* @since 1.68802*/8803public void updateBinaryStream(String columnLabel,8804java.io.InputStream x) throws SQLException {8805throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8806}88078808/**8809* Updates the designated column with a character stream value.8810* The updater methods are used to update column values in the8811* current row or the insert row. The updater methods do not8812* update the underlying database; instead the <code>updateRow</code> or8813* <code>insertRow</code> methods are called to update the database.8814*8815* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8816* it might be more efficient to use a version of8817* <code>updateCharacterStream</code> which takes a length parameter.8818*8819* @param columnIndex the first column is 1, the second is 2, ...8820* @param x the new column value8821* @exception SQLException if a database access error occurs,8822* the result set concurrency is <code>CONCUR_READ_ONLY</code>8823* or this method is called on a closed result set8824* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8825* this method8826* @since 1.68827*/8828public void updateCharacterStream(int columnIndex,8829java.io.Reader x) throws SQLException {8830throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8831}88328833/**8834* Updates the designated column with a character stream value.8835* The updater methods are used to update column values in the8836* current row or the insert row. The updater methods do not8837* update the underlying database; instead the <code>updateRow</code> or8838* <code>insertRow</code> methods are called to update the database.8839*8840* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8841* it might be more efficient to use a version of8842* <code>updateCharacterStream</code> which takes a length parameter.8843*8844* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8845bel is the name of the column8846* @param reader the <code>java.io.Reader</code> object containing8847* the new column value8848* @exception SQLException if a database access error occurs,8849* the result set concurrency is <code>CONCUR_READ_ONLY</code>8850* or this method is called on a closed result set8851* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8852* this method8853* @since 1.68854*/8855public void updateCharacterStream(String columnLabel,8856java.io.Reader reader) throws SQLException {8857throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8858}88598860/**8861* Updates the designated column with an ascii stream value.8862* The updater methods are used to update column values in the8863* current row or the insert row. The updater methods do not8864* update the underlying database; instead the <code>updateRow</code> or8865* <code>insertRow</code> methods are called to update the database.8866*8867* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8868* it might be more efficient to use a version of8869* <code>updateAsciiStream</code> which takes a length parameter.8870*8871* @param columnIndex the first column is 1, the second is 2, ...8872* @param x the new column value8873* @exception SQLException if a database access error occurs,8874* the result set concurrency is <code>CONCUR_READ_ONLY</code>8875* or this method is called on a closed result set8876* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8877* this method8878* @since 1.68879*/8880public void updateAsciiStream(int columnIndex,8881java.io.InputStream x) throws SQLException {8882throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8883}88848885/**8886* Updates the designated column with an ascii stream value.8887* The updater methods are used to update column values in the8888* current row or the insert row. The updater methods do not8889* update the underlying database; instead the <code>updateRow</code> or8890* <code>insertRow</code> methods are called to update the database.8891*8892* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8893* it might be more efficient to use a version of8894* <code>updateAsciiStream</code> which takes a length parameter.8895*8896* @param columnLabel the label for the column specified with the SQL AS clause. If the SQL AS clause was not specified, then the la8897bel is the name of the column8898* @param x the new column value8899* @exception SQLException if a database access error occurs,8900* the result set concurrency is <code>CONCUR_READ_ONLY</code>8901* or this method is called on a closed result set8902* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8903* this method8904* @since 1.68905*/8906public void updateAsciiStream(String columnLabel,8907java.io.InputStream x) throws SQLException {89088909}89108911/**8912* Sets the designated parameter to the given <code>java.net.URL</code> value.8913* The driver converts this to an SQL <code>DATALINK</code> value8914* when it sends it to the database.8915*8916* @param parameterIndex the first parameter is 1, the second is 2, ...8917* @param x the <code>java.net.URL</code> object to be set8918* @exception SQLException if a database access error occurs or8919* this method is called on a closed <code>PreparedStatement</code>8920* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method8921* @since 1.48922*/8923public void setURL(int parameterIndex, java.net.URL x) throws SQLException{8924throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8925}89268927/**8928* Sets the designated parameter to a <code>Reader</code> object.8929* This method differs from the <code>setCharacterStream (int, Reader)</code> method8930* because it informs the driver that the parameter value should be sent to8931* the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the8932* driver may have to do extra work to determine whether the parameter8933* data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>8934* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8935* it might be more efficient to use a version of8936* <code>setNClob</code> which takes a length parameter.8937*8938* @param parameterIndex index of the first parameter is 1, the second is 2, ...8939* @param reader An object that contains the data to set the parameter value to.8940* @throws SQLException if parameterIndex does not correspond to a parameter8941* marker in the SQL statement;8942* if the driver does not support national character sets;8943* if the driver can detect that a data conversion8944* error could occur; if a database access error occurs or8945* this method is called on a closed <code>PreparedStatement</code>8946* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method8947*8948* @since 1.68949*/8950public void setNClob(int parameterIndex, Reader reader)8951throws SQLException{8952throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8953}89548955/**8956* Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number8957* of characters specified by length otherwise a <code>SQLException</code> will be8958* generated when the <code>CallableStatement</code> is executed.8959* This method differs from the <code>setCharacterStream (int, Reader, int)</code> method8960* because it informs the driver that the parameter value should be sent to8961* the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the8962* driver may have to do extra work to determine whether the parameter8963* data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>8964*8965* @param parameterName the name of the parameter to be set8966* @param reader An object that contains the data to set the parameter value to.8967* @param length the number of characters in the parameter data.8968* @throws SQLException if parameterIndex does not correspond to a parameter8969* marker in the SQL statement; if the length specified is less than zero;8970* if the driver does not support national8971* character sets; if the driver can detect that a data conversion8972* error could occur; if a database access error occurs or8973* this method is called on a closed <code>CallableStatement</code>8974* @exception SQLFeatureNotSupportedException if the JDBC driver does not support8975* this method8976* @since 1.68977*/8978public void setNClob(String parameterName, Reader reader, long length)8979throws SQLException{8980throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());8981}898289838984/**8985* Sets the designated parameter to a <code>Reader</code> object.8986* This method differs from the <code>setCharacterStream (int, Reader)</code> method8987* because it informs the driver that the parameter value should be sent to8988* the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the8989* driver may have to do extra work to determine whether the parameter8990* data should be send to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>8991* <P><B>Note:</B> Consult your JDBC driver documentation to determine if8992* it might be more efficient to use a version of8993* <code>setNClob</code> which takes a length parameter.8994*8995* @param parameterName the name of the parameter8996* @param reader An object that contains the data to set the parameter value to.8997* @throws SQLException if the driver does not support national character sets;8998* if the driver can detect that a data conversion8999* error could occur; if a database access error occurs or9000* this method is called on a closed <code>CallableStatement</code>9001* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9002*9003* @since 1.69004*/9005public void setNClob(String parameterName, Reader reader)9006throws SQLException{9007throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9008}900990109011/**9012* Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number9013* of characters specified by length otherwise a <code>SQLException</code> will be9014* generated when the <code>PreparedStatement</code> is executed.9015* This method differs from the <code>setCharacterStream (int, Reader, int)</code> method9016* because it informs the driver that the parameter value should be sent to9017* the server as a <code>NCLOB</code>. When the <code>setCharacterStream</code> method is used, the9018* driver may have to do extra work to determine whether the parameter9019* data should be sent to the server as a <code>LONGNVARCHAR</code> or a <code>NCLOB</code>9020* @param parameterIndex index of the first parameter is 1, the second is 2, ...9021* @param reader An object that contains the data to set the parameter value to.9022* @param length the number of characters in the parameter data.9023* @throws SQLException if parameterIndex does not correspond to a parameter9024* marker in the SQL statement; if the length specified is less than zero;9025* if the driver does not support national character sets;9026* if the driver can detect that a data conversion9027* error could occur; if a database access error occurs or9028* this method is called on a closed <code>PreparedStatement</code>9029* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9030*9031* @since 1.69032*/9033public void setNClob(int parameterIndex, Reader reader, long length)9034throws SQLException{9035throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9036}903790389039/**9040* Sets the designated parameter to a <code>java.sql.NClob</code> object. The driver converts this to9041a9042* SQL <code>NCLOB</code> value when it sends it to the database.9043* @param parameterIndex of the first parameter is 1, the second is 2, ...9044* @param value the parameter value9045* @throws SQLException if the driver does not support national9046* character sets; if the driver can detect that a data conversion9047* error could occur ; or if a database access error occurs9048* @since 1.69049*/9050public void setNClob(int parameterIndex, NClob value) throws SQLException{9051throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9052}905390549055/**9056* Sets the designated parameter to the given <code>String</code> object.9057* The driver converts this to a SQL <code>NCHAR</code> or9058* <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value9059* (depending on the argument's9060* size relative to the driver's limits on <code>NVARCHAR</code> values)9061* when it sends it to the database.9062*9063* @param parameterIndex of the first parameter is 1, the second is 2, ...9064* @param value the parameter value9065* @throws SQLException if the driver does not support national9066* character sets; if the driver can detect that a data conversion9067* error could occur ; or if a database access error occurs9068* @since 1.69069*/9070public void setNString(int parameterIndex, String value) throws SQLException{9071throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9072}907390749075/**9076* Sets the designated parameter to the given <code>String</code> object.9077* The driver converts this to a SQL <code>NCHAR</code> or9078* <code>NVARCHAR</code> or <code>LONGNVARCHAR</code>9079* @param parameterName the name of the column to be set9080* @param value the parameter value9081* @throws SQLException if the driver does not support national9082* character sets; if the driver can detect that a data conversion9083* error could occur; or if a database access error occurs9084* @since 1.69085*/9086public void setNString(String parameterName, String value)9087throws SQLException{9088throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9089}909090919092/**9093* Sets the designated parameter to a <code>Reader</code> object. The9094* <code>Reader</code> reads the data till end-of-file is reached. The9095* driver does the necessary conversion from Java character format to9096* the national character set in the database.9097* @param parameterIndex of the first parameter is 1, the second is 2, ...9098* @param value the parameter value9099* @param length the number of characters in the parameter data.9100* @throws SQLException if the driver does not support national9101* character sets; if the driver can detect that a data conversion9102* error could occur ; or if a database access error occurs9103* @since 1.69104*/9105public void setNCharacterStream(int parameterIndex, Reader value, long length) throws 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 parameterName the name of the column to be set9116* @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(String parameterName, Reader value, long length)9124throws SQLException{9125throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9126}91279128/**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.91339134* <P><B>Note:</B> This stream object can either be a standard9135* Java stream object or your own subclass that implements the9136* standard interface.9137* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9138* it might be more efficient to use a version of9139* <code>setNCharacterStream</code> which takes a length parameter.9140*9141* @param parameterName the name of the parameter9142* @param value the parameter value9143* @throws SQLException if the driver does not support national9144* character sets; if the driver can detect that a data conversion9145* error could occur ; if a database access error occurs; or9146* this method is called on a closed <code>CallableStatement</code>9147* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9148* @since 1.69149*/9150public void setNCharacterStream(String parameterName, Reader value) throws SQLException{9151throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9152}91539154/**9155* Sets the designated parameter to the given <code>java.sql.Timestamp</code> value,9156* using the given <code>Calendar</code> object. The driver uses9157* the <code>Calendar</code> object to construct an SQL <code>TIMESTAMP</code> value,9158* which the driver then sends to the database. With a9159* a <code>Calendar</code> object, the driver can calculate the timestamp9160* taking into account a custom timezone. If no9161* <code>Calendar</code> object is specified, the driver uses the default9162* timezone, which is that of the virtual machine running the application.9163*9164* @param parameterName the name of the parameter9165* @param x the parameter value9166* @param cal the <code>Calendar</code> object the driver will use9167* to construct the timestamp9168* @exception SQLException if a database access error occurs or9169* this method is called on a closed <code>CallableStatement</code>9170* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9171* this method9172* @see #getTimestamp9173* @since 1.49174*/9175public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)9176throws SQLException{9177throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9178}91799180/**9181* Sets the designated parameter to a <code>Reader</code> object. The <code>reader</code> must contain the number9182* of characters specified by length otherwise a <code>SQLException</code> will be9183* generated when the <code>CallableStatement</code> is executed.9184* This method differs from the <code>setCharacterStream (int, Reader, int)</code> method9185* because it informs the driver that the parameter value should be sent to9186* the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the9187* driver may have to do extra work to determine whether the parameter9188* data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>9189* @param parameterName the name of the parameter to be set9190* @param reader An object that contains the data to set the parameter value to.9191* @param length the number of characters in the parameter data.9192* @throws SQLException if parameterIndex does not correspond to a parameter9193* marker in the SQL statement; if the length specified is less than zero;9194* a database access error occurs or9195* this method is called on a closed <code>CallableStatement</code>9196* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9197* this method9198*9199* @since 1.69200*/9201public void setClob(String parameterName, Reader reader, long length)9202throws SQLException{9203throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9204}920592069207/**9208* Sets the designated parameter to the given <code>java.sql.Clob</code> object.9209* The driver converts this to an SQL <code>CLOB</code> value when it9210* sends it to the database.9211*9212* @param parameterName the name of the parameter9213* @param x a <code>Clob</code> object that maps an SQL <code>CLOB</code> value9214* @exception SQLException if a database access error occurs or9215* this method is called on a closed <code>CallableStatement</code>9216* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9217* this method9218* @since 1.69219*/9220public void setClob (String parameterName, Clob x) throws SQLException{9221throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9222}922392249225/**9226* Sets the designated parameter to a <code>Reader</code> object.9227* This method differs from the <code>setCharacterStream (int, Reader)</code> method9228* because it informs the driver that the parameter value should be sent to9229* the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the9230* driver may have to do extra work to determine whether the parameter9231* data should be send to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>9232*9233* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9234* it might be more efficient to use a version of9235* <code>setClob</code> which takes a length parameter.9236*9237* @param parameterName the name of the parameter9238* @param reader An object that contains the data to set the parameter value to.9239* @throws SQLException if a database access error occurs or this method is called on9240* a closed <code>CallableStatement</code>9241*9242* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9243* @since 1.69244*/9245public void setClob(String parameterName, Reader reader)9246throws SQLException{9247throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9248}924992509251/**9252* Sets the designated parameter to the given <code>java.sql.Date</code> value9253* using the default time zone of the virtual machine that is running9254* the application.9255* The driver converts this9256* to an SQL <code>DATE</code> value when it sends it to the database.9257*9258* @param parameterName the name of the parameter9259* @param x the parameter value9260* @exception SQLException if a database access error occurs or9261* this method is called on a closed <code>CallableStatement</code>9262* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9263* this method9264* @see #getDate9265* @since 1.49266*/9267public void setDate(String parameterName, java.sql.Date x)9268throws SQLException{9269throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9270}927192729273/**9274* Sets the designated parameter to the given <code>java.sql.Date</code> value,9275* using the given <code>Calendar</code> object. The driver uses9276* the <code>Calendar</code> object to construct an SQL <code>DATE</code> value,9277* which the driver then sends to the database. With a9278* a <code>Calendar</code> object, the driver can calculate the date9279* taking into account a custom timezone. If no9280* <code>Calendar</code> object is specified, the driver uses the default9281* timezone, which is that of the virtual machine running the application.9282*9283* @param parameterName the name of the parameter9284* @param x the parameter value9285* @param cal the <code>Calendar</code> object the driver will use9286* to construct the date9287* @exception SQLException if a database access error occurs or9288* this method is called on a closed <code>CallableStatement</code>9289* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9290* this method9291* @see #getDate9292* @since 1.49293*/9294public void setDate(String parameterName, java.sql.Date x, Calendar cal)9295throws SQLException{9296throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9297}929892999300/**9301* Sets the designated parameter to the given <code>java.sql.Time</code> value.9302* The driver converts this9303* to an SQL <code>TIME</code> value when it sends it to the database.9304*9305* @param parameterName the name of the parameter9306* @param x the parameter value9307* @exception SQLException if a database access error occurs or9308* this method is called on a closed <code>CallableStatement</code>9309* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9310* this method9311* @see #getTime9312* @since 1.49313*/9314public void setTime(String parameterName, java.sql.Time x)9315throws SQLException{9316throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9317}931893199320/**9321* Sets the designated parameter to the given <code>java.sql.Time</code> value,9322* using the given <code>Calendar</code> object. The driver uses9323* the <code>Calendar</code> object to construct an SQL <code>TIME</code> value,9324* which the driver then sends to the database. With a9325* a <code>Calendar</code> object, the driver can calculate the time9326* taking into account a custom timezone. If no9327* <code>Calendar</code> object is specified, the driver uses the default9328* timezone, which is that of the virtual machine running the application.9329*9330* @param parameterName the name of the parameter9331* @param x the parameter value9332* @param cal the <code>Calendar</code> object the driver will use9333* to construct the time9334* @exception SQLException if a database access error occurs or9335* this method is called on a closed <code>CallableStatement</code>9336* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9337* this method9338* @see #getTime9339* @since 1.49340*/9341public void setTime(String parameterName, java.sql.Time x, Calendar cal)9342throws SQLException{9343throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9344}93459346/**9347* Sets the designated parameter to a <code>Reader</code> object.9348* This method differs from the <code>setCharacterStream (int, Reader)</code> method9349* because it informs the driver that the parameter value should be sent to9350* the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the9351* driver may have to do extra work to determine whether the parameter9352* data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>9353*9354* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9355* it might be more efficient to use a version of9356* <code>setClob</code> which takes a length parameter.9357*9358* @param parameterIndex index of the first parameter is 1, the second is 2, ...9359* @param reader An object that contains the data to set the parameter value to.9360* @throws SQLException if a database access error occurs, this method is called on9361* a closed <code>PreparedStatement</code>or if parameterIndex does not correspond to a parameter9362* marker in the SQL statement9363*9364* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9365* @since 1.69366*/9367public void setClob(int parameterIndex, Reader reader)9368throws SQLException{9369throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9370}93719372/**9373* Sets the designated parameter to a <code>Reader</code> object. The reader must contain the number9374* of characters specified by length otherwise a <code>SQLException</code> will be9375* generated when the <code>PreparedStatement</code> is executed.9376*This method differs from the <code>setCharacterStream (int, Reader, int)</code> method9377* because it informs the driver that the parameter value should be sent to9378* the server as a <code>CLOB</code>. When the <code>setCharacterStream</code> method is used, the9379* driver may have to do extra work to determine whether the parameter9380* data should be sent to the server as a <code>LONGVARCHAR</code> or a <code>CLOB</code>9381* @param parameterIndex index of the first parameter is 1, the second is 2, ...9382* @param reader An object that contains the data to set the parameter value to.9383* @param length the number of characters in the parameter data.9384* @throws SQLException if a database access error occurs, this method is called on9385* a closed <code>PreparedStatement</code>, if parameterIndex does not correspond to a parameter9386* marker in the SQL statement, or if the length specified is less than zero.9387*9388* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9389* @since 1.69390*/9391public void setClob(int parameterIndex, Reader reader, long length)9392throws SQLException{9393throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9394}939593969397/**9398* Sets the designated parameter to a <code>InputStream</code> object. The inputstream must contain the number9399* of characters specified by length otherwise a <code>SQLException</code> will be9400* generated when the <code>PreparedStatement</code> is executed.9401* This method differs from the <code>setBinaryStream (int, InputStream, int)</code>9402* method because it informs the driver that the parameter value should be9403* sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used,9404* the driver may have to do extra work to determine whether the parameter9405* data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>9406* @param parameterIndex index of the first parameter is 1,9407* the second is 2, ...9408* @param inputStream An object that contains the data to set the parameter9409* value to.9410* @param length the number of bytes in the parameter data.9411* @throws SQLException if a database access error occurs,9412* this method is called on a closed <code>PreparedStatement</code>,9413* if parameterIndex does not correspond9414* to a parameter marker in the SQL statement, if the length specified9415* is less than zero or if the number of bytes in the inputstream does not match9416* the specified length.9417* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9418*9419* @since 1.69420*/9421public void setBlob(int parameterIndex, InputStream inputStream, long length)9422throws SQLException{9423throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9424}942594269427/**9428* Sets the designated parameter to a <code>InputStream</code> object.9429* This method differs from the <code>setBinaryStream (int, InputStream)</code>9430* method because it informs the driver that the parameter value should be9431* sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used,9432* the driver may have to do extra work to determine whether the parameter9433* data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>9434*9435* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9436* it might be more efficient to use a version of9437* <code>setBlob</code> which takes a length parameter.9438*9439* @param parameterIndex index of the first parameter is 1,9440* the second is 2, ...9441* @param inputStream An object that contains the data to set the parameter9442* value to.9443* @throws SQLException if a database access error occurs,9444* this method is called on a closed <code>PreparedStatement</code> or9445* if parameterIndex does not correspond9446* to a parameter marker in the SQL statement,9447* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9448*9449* @since 1.69450*/9451public void setBlob(int parameterIndex, InputStream inputStream)9452throws SQLException{9453throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9454}945594569457/**9458* Sets the designated parameter to a <code>InputStream</code> object. The <code>inputstream</code> must contain the number9459* of characters specified by length, otherwise a <code>SQLException</code> will be9460* generated when the <code>CallableStatement</code> is executed.9461* This method differs from the <code>setBinaryStream (int, InputStream, int)</code>9462* method because it informs the driver that the parameter value should be9463* sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used,9464* the driver may have to do extra work to determine whether the parameter9465* data should be sent to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>9466*9467* @param parameterName the name of the parameter to be set9468* the second is 2, ...9469*9470* @param inputStream An object that contains the data to set the parameter9471* value to.9472* @param length the number of bytes in the parameter data.9473* @throws SQLException if parameterIndex does not correspond9474* to a parameter marker in the SQL statement, or if the length specified9475* is less than zero; if the number of bytes in the inputstream does not match9476* the specified length; if a database access error occurs or9477* this method is called on a closed <code>CallableStatement</code>9478* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9479* this method9480*9481* @since 1.69482*/9483public void setBlob(String parameterName, InputStream inputStream, long length)9484throws SQLException{9485throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9486}948794889489/**9490* Sets the designated parameter to the given <code>java.sql.Blob</code> object.9491* The driver converts this to an SQL <code>BLOB</code> value when it9492* sends it to the database.9493*9494* @param parameterName the name of the parameter9495* @param x a <code>Blob</code> object that maps an SQL <code>BLOB</code> value9496* @exception SQLException if a database access error occurs or9497* this method is called on a closed <code>CallableStatement</code>9498* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9499* this method9500* @since 1.69501*/9502public void setBlob (String parameterName, Blob x) throws SQLException{9503throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9504}950595069507/**9508* Sets the designated parameter to a <code>InputStream</code> object.9509* This method differs from the <code>setBinaryStream (int, InputStream)</code>9510* method because it informs the driver that the parameter value should be9511* sent to the server as a <code>BLOB</code>. When the <code>setBinaryStream</code> method is used,9512* the driver may have to do extra work to determine whether the parameter9513* data should be send to the server as a <code>LONGVARBINARY</code> or a <code>BLOB</code>9514*9515* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9516* it might be more efficient to use a version of9517* <code>setBlob</code> which takes a length parameter.9518*9519* @param parameterName the name of the parameter9520* @param inputStream An object that contains the data to set the parameter9521* value to.9522* @throws SQLException if a database access error occurs or9523* this method is called on a closed <code>CallableStatement</code>9524* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9525*9526* @since 1.69527*/9528public void setBlob(String parameterName, InputStream inputStream)9529throws SQLException{9530throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9531}95329533/**9534* Sets the value of the designated parameter with the given object. The second9535* argument must be an object type; for integral values, the9536* <code>java.lang</code> equivalent objects should be used.9537*9538* <p>The given Java object will be converted to the given targetSqlType9539* before being sent to the database.9540*9541* If the object has a custom mapping (is of a class implementing the9542* interface <code>SQLData</code>),9543* the JDBC driver should call the method <code>SQLData.writeSQL</code> to write it9544* to the SQL data stream.9545* If, on the other hand, the object is of a class implementing9546* <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>,9547* <code>Struct</code>, <code>java.net.URL</code>,9548* or <code>Array</code>, the driver should pass it to the database as a9549* value of the corresponding SQL type.9550* <P>9551* Note that this method may be used to pass datatabase-9552* specific abstract data types.9553*9554* @param parameterName the name of the parameter9555* @param x the object containing the input parameter value9556* @param targetSqlType the SQL type (as defined in java.sql.Types) to be9557* sent to the database. The scale argument may further qualify this type.9558* @param scale for java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types,9559* this is the number of digits after the decimal point. For all other9560* types, this value will be ignored.9561* @exception SQLException if a database access error occurs or9562* this method is called on a closed <code>CallableStatement</code>9563* @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is9564* a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,9565* <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,9566* <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,9567* <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>9568* or <code>STRUCT</code> data type and the JDBC driver does not support9569* this data type9570* @see Types9571* @see #getObject9572* @since 1.49573*/9574public void setObject(String parameterName, Object x, int targetSqlType, int scale)9575throws SQLException{9576throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9577}9578957995809581/**9582* Sets the value of the designated parameter with the given object.9583* This method is like the method <code>setObject</code>9584* above, except that it assumes a scale of zero.9585*9586* @param parameterName the name of the parameter9587* @param x the object containing the input parameter value9588* @param targetSqlType the SQL type (as defined in java.sql.Types) to be9589* sent to the database9590* @exception SQLException if a database access error occurs or9591* this method is called on a closed <code>CallableStatement</code>9592* @exception SQLFeatureNotSupportedException if <code>targetSqlType</code> is9593* a <code>ARRAY</code>, <code>BLOB</code>, <code>CLOB</code>,9594* <code>DATALINK</code>, <code>JAVA_OBJECT</code>, <code>NCHAR</code>,9595* <code>NCLOB</code>, <code>NVARCHAR</code>, <code>LONGNVARCHAR</code>,9596* <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>9597* or <code>STRUCT</code> data type and the JDBC driver does not support9598* this data type9599* @see #getObject9600* @since 1.49601*/9602public void setObject(String parameterName, Object x, int targetSqlType)9603throws SQLException{9604throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9605}960696079608/**9609* Sets the value of the designated parameter with the given object.9610* The second parameter must be of type <code>Object</code>; therefore, the9611* <code>java.lang</code> equivalent objects should be used for built-in types.9612*9613* <p>The JDBC specification specifies a standard mapping from9614* Java <code>Object</code> types to SQL types. The given argument9615* will be converted to the corresponding SQL type before being9616* sent to the database.9617*9618* <p>Note that this method may be used to pass datatabase-9619* specific abstract data types, by using a driver-specific Java9620* type.9621*9622* If the object is of a class implementing the interface <code>SQLData</code>,9623* the JDBC driver should call the method <code>SQLData.writeSQL</code>9624* to write it to the SQL data stream.9625* If, on the other hand, the object is of a class implementing9626* <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, <code>NClob</code>,9627* <code>Struct</code>, <code>java.net.URL</code>,9628* or <code>Array</code>, the driver should pass it to the database as a9629* value of the corresponding SQL type.9630* <P>9631* This method throws an exception if there is an ambiguity, for example, if the9632* object is of a class implementing more than one of the interfaces named above.9633*9634* @param parameterName the name of the parameter9635* @param x the object containing the input parameter value9636* @exception SQLException if a database access error occurs,9637* this method is called on a closed <code>CallableStatement</code> or if the given9638* <code>Object</code> parameter is ambiguous9639* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9640* this method9641* @see #getObject9642* @since 1.49643*/9644public void setObject(String parameterName, Object x) throws SQLException{9645throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9646}96479648/**9649* Sets the designated parameter to the given input stream, which will have9650* the specified number of bytes.9651* When a very large ASCII value is input to a <code>LONGVARCHAR</code>9652* parameter, it may be more practical to send it via a9653* <code>java.io.InputStream</code>. Data will be read from the stream9654* as needed until end-of-file is reached. The JDBC driver will9655* do any necessary conversion from ASCII to the database char format.9656*9657* <P><B>Note:</B> This stream object can either be a standard9658* Java stream object or your own subclass that implements the9659* standard interface.9660*9661* @param parameterName the name of the parameter9662* @param x the Java input stream that contains the ASCII parameter value9663* @param length the number of bytes in the stream9664* @exception SQLException if a database access error occurs or9665* this method is called on a closed <code>CallableStatement</code>9666* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9667* this method9668* @since 1.49669*/9670public void setAsciiStream(String parameterName, java.io.InputStream x, int length)9671throws SQLException{9672throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9673}967496759676/**9677* Sets the designated parameter to the given input stream, which will have9678* the specified number of bytes.9679* When a very large binary value is input to a <code>LONGVARBINARY</code>9680* parameter, it may be more practical to send it via a9681* <code>java.io.InputStream</code> object. The data will be read from the stream9682* as needed until end-of-file is reached.9683*9684* <P><B>Note:</B> This stream object can either be a standard9685* Java stream object or your own subclass that implements the9686* standard interface.9687*9688* @param parameterName the name of the parameter9689* @param x the java input stream which contains the binary parameter value9690* @param length the number of bytes in the stream9691* @exception SQLException if a database access error occurs or9692* this method is called on a closed <code>CallableStatement</code>9693* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9694* this method9695* @since 1.49696*/9697public void setBinaryStream(String parameterName, java.io.InputStream x,9698int length) throws SQLException{9699throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9700}970197029703/**9704* Sets the designated parameter to the given <code>Reader</code>9705* object, which is the given number of characters long.9706* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>9707* parameter, it may be more practical to send it via a9708* <code>java.io.Reader</code> object. The data will be read from the stream9709* as needed until end-of-file is reached. The JDBC driver will9710* do any necessary conversion from UNICODE to the database char format.9711*9712* <P><B>Note:</B> This stream object can either be a standard9713* Java stream object or your own subclass that implements the9714* standard interface.9715*9716* @param parameterName the name of the parameter9717* @param reader the <code>java.io.Reader</code> object that9718* contains the UNICODE data used as the designated parameter9719* @param length the number of characters in the stream9720* @exception SQLException if a database access error occurs or9721* this method is called on a closed <code>CallableStatement</code>9722* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9723* this method9724* @since 1.49725*/9726public void setCharacterStream(String parameterName,9727java.io.Reader reader,9728int length) throws SQLException{9729throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9730}973197329733/**9734* Sets the designated parameter to the given input stream.9735* When a very large ASCII value is input to a <code>LONGVARCHAR</code>9736* parameter, it may be more practical to send it via a9737* <code>java.io.InputStream</code>. Data will be read from the stream9738* as needed until end-of-file is reached. The JDBC driver will9739* do any necessary conversion from ASCII to the database char format.9740*9741* <P><B>Note:</B> This stream object can either be a standard9742* Java stream object or your own subclass that implements the9743* standard interface.9744* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9745* it might be more efficient to use a version of9746* <code>setAsciiStream</code> which takes a length parameter.9747*9748* @param parameterName the name of the parameter9749* @param x the Java input stream that contains the ASCII parameter value9750* @exception SQLException if a database access error occurs or9751* this method is called on a closed <code>CallableStatement</code>9752* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9753* @since 1.69754*/9755public void setAsciiStream(String parameterName, java.io.InputStream x)9756throws SQLException{9757throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9758}975997609761/**9762* Sets the designated parameter to the given input stream.9763* When a very large binary value is input to a <code>LONGVARBINARY</code>9764* parameter, it may be more practical to send it via a9765* <code>java.io.InputStream</code> object. The data will be read from the9766* stream as needed until end-of-file is reached.9767*9768* <P><B>Note:</B> This stream object can either be a standard9769* Java stream object or your own subclass that implements the9770* standard interface.9771* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9772* it might be more efficient to use a version of9773* <code>setBinaryStream</code> which takes a length parameter.9774*9775* @param parameterName the name of the parameter9776* @param x the java input stream which contains the binary parameter value9777* @exception SQLException if a database access error occurs or9778* this method is called on a closed <code>CallableStatement</code>9779* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9780* @since 1.69781*/9782public void setBinaryStream(String parameterName, java.io.InputStream x)9783throws SQLException{9784throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9785}9786978797889789/**9790* Sets the designated parameter to the given <code>Reader</code>9791* object.9792* When a very large UNICODE value is input to a <code>LONGVARCHAR</code>9793* parameter, it may be more practical to send it via a9794* <code>java.io.Reader</code> object. The data will be read from the stream9795* as needed until end-of-file is reached. The JDBC driver will9796* do any necessary conversion from UNICODE to the database char format.9797*9798* <P><B>Note:</B> This stream object can either be a standard9799* Java stream object or your own subclass that implements the9800* standard interface.9801* <P><B>Note:</B> Consult your JDBC driver documentation to determine if9802* it might be more efficient to use a version of9803* <code>setCharacterStream</code> which takes a length parameter.9804*9805* @param parameterName the name of the parameter9806* @param reader the <code>java.io.Reader</code> object that contains the9807* Unicode data9808* @exception SQLException if a database access error occurs or9809* this method is called on a closed <code>CallableStatement</code>9810* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this method9811* @since 1.69812*/9813public void setCharacterStream(String parameterName,9814java.io.Reader reader) throws SQLException{9815throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9816}98179818/**9819* Sets the designated parameter to the given9820* <code>java.math.BigDecimal</code> value.9821* The driver converts this to an SQL <code>NUMERIC</code> value when9822* it sends it to the database.9823*9824* @param parameterName the name of the parameter9825* @param x the parameter value9826* @exception SQLException if a database access error occurs or9827* this method is called on a closed <code>CallableStatement</code>9828* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9829* this method9830* @see #getBigDecimal9831* @since 1.49832*/9833public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{9834throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9835}9836983798389839/**9840* Sets the designated parameter to the given Java <code>String</code> value.9841* The driver converts this9842* to an SQL <code>VARCHAR</code> or <code>LONGVARCHAR</code> value9843* (depending on the argument's9844* size relative to the driver's limits on <code>VARCHAR</code> values)9845* when it sends it to the database.9846*9847* @param parameterName the name of the parameter9848* @param x the parameter value9849* @exception SQLException if a database access error occurs or9850* this method is called on a closed <code>CallableStatement</code>9851* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9852* this method9853* @see #getString9854* @since 1.49855*/9856public void setString(String parameterName, String x) throws SQLException{9857throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9858}9859986098619862/**9863* Sets the designated parameter to the given Java array of bytes.9864* The driver converts this to an SQL <code>VARBINARY</code> or9865* <code>LONGVARBINARY</code> (depending on the argument's size relative9866* to the driver's limits on <code>VARBINARY</code> values) when it sends9867* it to the database.9868*9869* @param parameterName the name of the parameter9870* @param x the parameter value9871* @exception SQLException if a database access error occurs or9872* this method is called on a closed <code>CallableStatement</code>9873* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9874* this method9875* @see #getBytes9876* @since 1.49877*/9878public void setBytes(String parameterName, byte x[]) throws SQLException{9879throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9880}9881988298839884/**9885* Sets the designated parameter to the given <code>java.sql.Timestamp</code> value.9886* The driver9887* converts this to an SQL <code>TIMESTAMP</code> value when it sends it to the9888* database.9889*9890* @param parameterName the name of the parameter9891* @param x the parameter value9892* @exception SQLException if a database access error occurs or9893* this method is called on a closed <code>CallableStatement</code>9894* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9895* this method9896* @see #getTimestamp9897* @since 1.49898*/9899public void setTimestamp(String parameterName, java.sql.Timestamp x)9900throws SQLException{9901throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9902}99039904/**9905* Sets the designated parameter to SQL <code>NULL</code>.9906*9907* <P><B>Note:</B> You must specify the parameter's SQL type.9908*9909* @param parameterName the name of the parameter9910* @param sqlType the SQL type code defined in <code>java.sql.Types</code>9911* @exception SQLException if a database access error occurs or9912* this method is called on a closed <code>CallableStatement</code>9913* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9914* this method9915* @since 1.49916*/9917public void setNull(String parameterName, int sqlType) throws SQLException {9918throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9919}992099219922/**9923* Sets the designated parameter to SQL <code>NULL</code>.9924* This version of the method <code>setNull</code> should9925* be used for user-defined types and REF type parameters. Examples9926* of user-defined types include: STRUCT, DISTINCT, JAVA_OBJECT, and9927* named array types.9928*9929* <P><B>Note:</B> To be portable, applications must give the9930* SQL type code and the fully-qualified SQL type name when specifying9931* a NULL user-defined or REF parameter. In the case of a user-defined type9932* the name is the type name of the parameter itself. For a REF9933* parameter, the name is the type name of the referenced type. If9934* a JDBC driver does not need the type code or type name information,9935* it may ignore it.9936*9937* Although it is intended for user-defined and Ref parameters,9938* this method may be used to set a null parameter of any JDBC type.9939* If the parameter does not have a user-defined or REF type, the given9940* typeName is ignored.9941*9942*9943* @param parameterName the name of the parameter9944* @param sqlType a value from <code>java.sql.Types</code>9945* @param typeName the fully-qualified name of an SQL user-defined type;9946* ignored if the parameter is not a user-defined type or9947* SQL <code>REF</code> value9948* @exception SQLException if a database access error occurs or9949* this method is called on a closed <code>CallableStatement</code>9950* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9951* this method9952* @since 1.49953*/9954public void setNull (String parameterName, int sqlType, String typeName)9955throws SQLException{9956throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9957}9958995999609961/**9962* Sets the designated parameter to the given Java <code>boolean</code> value.9963* The driver converts this9964* to an SQL <code>BIT</code> or <code>BOOLEAN</code> value when it sends it to the database.9965*9966* @param parameterName the name of the parameter9967* @param x the parameter value9968* @exception SQLException if a database access error occurs or9969* this method is called on a closed <code>CallableStatement</code>9970* @see #getBoolean9971* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9972* this method9973* @since 1.49974*/9975public void setBoolean(String parameterName, boolean x) throws SQLException{9976throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9977}9978997999809981/**9982* Sets the designated parameter to the given Java <code>byte</code> value.9983* The driver converts this9984* to an SQL <code>TINYINT</code> value when it sends it to the database.9985*9986* @param parameterName the name of the parameter9987* @param x the parameter value9988* @exception SQLException if a database access error occurs or9989* this method is called on a closed <code>CallableStatement</code>9990* @exception SQLFeatureNotSupportedException if the JDBC driver does not support9991* this method9992* @see #getByte9993* @since 1.49994*/9995public void setByte(String parameterName, byte x) throws SQLException{9996throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());9997}999899991000010001/**10002* Sets the designated parameter to the given Java <code>short</code> value.10003* The driver converts this10004* to an SQL <code>SMALLINT</code> value when it sends it to the database.10005*10006* @param parameterName the name of the parameter10007* @param x the parameter value10008* @exception SQLException if a database access error occurs or10009* this method is called on a closed <code>CallableStatement</code>10010* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10011* this method10012* @see #getShort10013* @since 1.410014*/10015public void setShort(String parameterName, short x) throws SQLException{10016throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10017}100181001910020/**10021* Sets the designated parameter to the given Java <code>int</code> value.10022* The driver converts this10023* to an SQL <code>INTEGER</code> value when it sends it to the database.10024*10025* @param parameterName the name of the parameter10026* @param x the parameter value10027* @exception SQLException if a database access error occurs or10028* this method is called on a closed <code>CallableStatement</code>10029* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10030* this method10031* @see #getInt10032* @since 1.410033*/10034public void setInt(String parameterName, int x) throws SQLException{10035throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10036}100371003810039/**10040* Sets the designated parameter to the given Java <code>long</code> value.10041* The driver converts this10042* to an SQL <code>BIGINT</code> value when it sends it to the database.10043*10044* @param parameterName the name of the parameter10045* @param x the parameter value10046* @exception SQLException if a database access error occurs or10047* this method is called on a closed <code>CallableStatement</code>10048* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10049* this method10050* @see #getLong10051* @since 1.410052*/10053public void setLong(String parameterName, long x) throws SQLException{10054throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10055}100561005710058/**10059* Sets the designated parameter to the given Java <code>float</code> value.10060* The driver converts this10061* to an SQL <code>FLOAT</code> value when it sends it to the database.10062*10063* @param parameterName the name of the parameter10064* @param x the parameter value10065* @exception SQLException if a database access error occurs or10066* this method is called on a closed <code>CallableStatement</code>10067* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10068* this method10069* @see #getFloat10070* @since 1.410071*/10072public void setFloat(String parameterName, float x) throws SQLException{10073throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10074}100751007610077/**10078* Sets the designated parameter to the given Java <code>double</code> value.10079* The driver converts this10080* to an SQL <code>DOUBLE</code> value when it sends it to the database.10081*10082* @param parameterName the name of the parameter10083* @param x the parameter value10084* @exception SQLException if a database access error occurs or10085* this method is called on a closed <code>CallableStatement</code>10086* @exception SQLFeatureNotSupportedException if the JDBC driver does not support10087* this method10088* @see #getDouble10089* @since 1.410090*/10091public void setDouble(String parameterName, double x) throws SQLException{10092throw new SQLFeatureNotSupportedException(resBundle.handleGetObject("cachedrowsetimpl.featnotsupp").toString());10093}1009410095/**10096* This method re populates the resBundle10097* during the deserialization process10098*10099*/10100private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {10101// Default state initialization happens here10102ois.defaultReadObject();10103// Initialization of transient Res Bundle happens here .10104try {10105resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();10106} catch(IOException ioe) {10107throw new RuntimeException(ioe);10108}1010910110}1011110112//------------------------- JDBC 4.1 -----------------------------------10113public <T> T getObject(int columnIndex, Class<T> type) throws SQLException {10114throw new SQLFeatureNotSupportedException("Not supported yet.");10115}1011610117public <T> T getObject(String columnLabel, Class<T> type) throws SQLException {10118throw new SQLFeatureNotSupportedException("Not supported yet.");10119}1012010121static final long serialVersionUID =1884577171200622428L;10122}101231012410125