History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/rowset/JoinRowSetImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/rowset/JoinRowSetImpl.java+4353−0
@@ -0,0 +1,4353 @@
1+/*
2+ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package com.sun.rowset;
27+
28+import java.sql.*;
29+import javax.sql.*;
30+import javax.naming.*;
31+import java.io.*;
32+import java.math.*;
33+import java.util.*;
34+
35+import javax.sql.rowset.*;
36+import javax.sql.rowset.spi.SyncProvider;
37+import javax.sql.rowset.spi.SyncProviderException;
38+
39+/**
40+ * The standard implementation of the <code>JoinRowSet</code>
41+ * interface providing an SQL <code>JOIN</code> between <code>RowSet</code>
42+ * objects.
43+ * <P>
44+ * The implementation provides an ANSI-style <code>JOIN</code> providing an
45+ * inner join between two tables. Any unmatched rows in either table of the
46+ * join are discarded.
47+ * <p>
48+ * Typically, a <code>JoinRowSet</code> implementation is leveraged by
49+ * <code>RowSet</code> instances that are in a disconnected environment and
50+ * thus do not have the luxury of an open connection to the data source to
51+ * establish logical relationships between themselves. In other words, it is
52+ * largely <code>CachedRowSet</code> objects and implementations derived from
53+ * the <code>CachedRowSet</code> interface that will use the <code>JoinRowSetImpl</code>
54+ * implementation.
55+ *
56+ * @author Amit Handa, Jonathan Bruce
57+ */
58+public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet {
59+ /**
60+ * A <code>Vector</code> object that contains the <code>RowSet</code> objects
61+ * that have been added to this <code>JoinRowSet</code> object.
62+ */
63+ private Vector<CachedRowSetImpl> vecRowSetsInJOIN;
64+
65+ /**
66+ * The <code>CachedRowSet</code> object that encapsulates this
67+ * <code>JoinRowSet</code> object.
68+ * When <code>RowSet</code> objects are added to this <code>JoinRowSet</code>
69+ * object, they are also added to <i>crsInternal</i> to form the same kind of
70+ * SQL <code>JOIN</code>. As a result, methods for making updates to this
71+ * <code>JoinRowSet</code> object can use <i>crsInternal</i> methods in their
72+ * implementations.
73+ */
74+ private CachedRowSetImpl crsInternal;
75+
76+ /**
77+ * A <code>Vector</code> object containing the types of join that have been set
78+ * for this <code>JoinRowSet</code> object.
79+ * The last join type set forms the basis of succeeding joins.
80+ */
81+ private Vector<Integer> vecJoinType;
82+
83+ /**
84+ * A <code>Vector</code> object containing the names of all the tables entering
85+ * the join.
86+ */
87+ private Vector<String> vecTableNames;
88+
89+ /**
90+ * An <code>int</code> that indicates the column index of the match column.
91+ */
92+ private int iMatchKey;
93+
94+ /**
95+ * A <code>String</code> object that stores the name of the match column.
96+ */
97+ private String strMatchKey ;
98+
99+ /**
100+ * An array of <code>boolean</code> values indicating the types of joins supported
101+ * by this <code>JoinRowSet</code> implementation.
102+ */
103+ boolean[] supportedJOINs;
104+
105+ /**
106+ * The <code>WebRowSet</code> object that encapsulates this <code>JoinRowSet</code>
107+ * object. This <code>WebRowSet</code> object allows this <code>JoinRowSet</code>
108+ * object to leverage the properties and methods of a <code>WebRowSet</code>
109+ * object.
110+ */
111+ private WebRowSet wrs;
112+
113+
114+ /**
115+ * Constructor for <code>JoinRowSetImpl</code> class. Configures various internal data
116+ * structures to provide mechanisms required for <code>JoinRowSet</code> interface
117+ * implementation.
118+ *
119+ * @throws SQLException if an error occurs in instantiating an instance of
120+ * <code>JoinRowSetImpl</code>
121+ */
122+ public JoinRowSetImpl() throws SQLException {
123+
124+ vecRowSetsInJOIN = new Vector<CachedRowSetImpl>();
125+ crsInternal = new CachedRowSetImpl();
126+ vecJoinType = new Vector<Integer>();
127+ vecTableNames = new Vector<String>();
128+ iMatchKey = -1;
129+ strMatchKey = null;
130+ supportedJOINs =
131+ new boolean[] {false, true, false, false, false};
132+ try {
133+ resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
134+ } catch(IOException ioe) {
135+ throw new RuntimeException(ioe);
136+ }
137+
138+ }
139+
140+ /**
141+ * Adds the given <code>RowSet</code> object to this
142+ * <code>JoinRowSet</code> object. If this
143+ * rowset is the first to be added to the <code>JoinRowSet</code>
144+ * object, it forms the basis for the <code>JOIN</code>
145+ * relationships to be formed.
146+ * <p>
147+ * This method should be used when the given <code>RowSet</code> object
148+ * already has a match column set.
149+ *
150+ * @param rowset the <code>RowSet</code> object that implements the
151+ * <code>Joinable</code> interface and is to be added
152+ * to this <code>JoinRowSet</code> object
153+ * @throws SQLException if an empty <code>RowSet</code> is added to the to the
154+ * <code>JoinRowSet</code>; if a match column is not set; or if an
155+ * additional <code>RowSet</code> violates the active <code>JOIN</code>
156+ * @see CachedRowSet#setMatchColumn
157+ */
158+ public void addRowSet(Joinable rowset) throws SQLException {
159+ boolean boolColId, boolColName;
160+
161+ boolColId = false;
162+ boolColName = false;
163+ CachedRowSetImpl cRowset;
164+
165+ if(!(rowset instanceof RowSet)) {
166+ throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notinstance").toString());
167+ }
168+
169+ if(rowset instanceof JdbcRowSetImpl ) {
170+ cRowset = new CachedRowSetImpl();
171+ cRowset.populate((RowSet)rowset);
172+ if(cRowset.size() == 0){
173+ throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.emptyrowset").toString());
174+ }
175+
176+
177+ try {
178+ int matchColumnCount = 0;
179+ for(int i=0; i< rowset.getMatchColumnIndexes().length; i++) {
180+ if(rowset.getMatchColumnIndexes()[i] != -1)
181+ ++ matchColumnCount;
182+ else
183+ break;
184+ }
185+ int[] pCol = new int[matchColumnCount];
186+ for(int i=0; i<matchColumnCount; i++)
187+ pCol[i] = rowset.getMatchColumnIndexes()[i];
188+ cRowset.setMatchColumn(pCol);
189+ } catch(SQLException sqle) {
190+
191+ }
192+
193+ } else {
194+ cRowset = (CachedRowSetImpl)rowset;
195+ if(cRowset.size() == 0){
196+ throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.emptyrowset").toString());
197+ }
198+ }
199+
200+ // Either column id or column name will be set
201+ // If both not set throw exception.
202+
203+ try {
204+ iMatchKey = (cRowset.getMatchColumnIndexes())[0];
205+ } catch(SQLException sqle) {
206+ //if not set catch the exception but do nothing now.
207+ boolColId = true;
208+ }
209+
210+ try {
211+ strMatchKey = (cRowset.getMatchColumnNames())[0];
212+ } catch(SQLException sqle) {
213+ //if not set catch the exception but do nothing now.
214+ boolColName = true;
215+ }
216+
217+ if(boolColId && boolColName) {
218+ // neither setter methods have been used to set
219+ throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.matchnotset").toString());
220+ } else {
221+ //if(boolColId || boolColName)
222+ // either of the setter methods have been set.
223+ if(boolColId){
224+ //
225+ ArrayList<Integer> indices = new ArrayList<>();
226+ for(int i=0;i<cRowset.getMatchColumnNames().length;i++) {
227+ if( (strMatchKey = (cRowset.getMatchColumnNames())[i]) != null) {
228+ iMatchKey = cRowset.findColumn(strMatchKey);
229+ indices.add(iMatchKey);
230+ }
231+ else
232+ break;
233+ }
234+ int[] indexes = new int[indices.size()];
235+ for(int i=0; i<indices.size();i++)
236+ indexes[i] = ((Integer)indices.get(i)).intValue();
237+ cRowset.setMatchColumn(indexes);
238+ // Set the match column here because join will be
239+ // based on columnId,
240+ // (nested for loop in initJOIN() checks for equality
241+ // based on columnIndex)
242+ } else {
243+ //do nothing, iMatchKey is set.
244+ }
245+ // Now both iMatchKey and strMatchKey have been set pointing
246+ // to the same column
247+ }
248+
249+ // Till first rowset setJoinType may not be set because
250+ // default type is JoinRowSet.INNER_JOIN which should
251+ // be set and for subsequent additions of rowset, if not set
252+ // keep on adding join type as JoinRowSet.INNER_JOIN
253+ // to vecJoinType.
254+
255+ initJOIN(cRowset);
256+ }
257+
258+ /**
259+ * Adds the given <code>RowSet</code> object to the <code>JOIN</code> relation
260+ * and sets the designated column as the match column.
261+ * If the given <code>RowSet</code>
262+ * object is the first to be added to this <code>JoinRowSet</code>
263+ * object, it forms the basis of the <code>JOIN</code> relationship to be formed
264+ * when other <code>RowSet</code> objects are added .
265+ * <P>
266+ * This method should be used when the given <code>RowSet</code> object
267+ * does not already have a match column set.
268+ *
269+ * @param rowset a <code>RowSet</code> object to be added to
270+ * the <code>JOIN</code> relation; must implement the <code>Joinable</code>
271+ * interface
272+ * @param columnIdx an <code>int</code> giving the index of the column to be set as
273+ * the match column
274+ * @throws SQLException if (1) an empty <code>RowSet</code> object is added to this
275+ * <code>JoinRowSet</code> object, (2) a match column has not been set,
276+ * or (3) the <code>RowSet</code> object being added violates the active
277+ * <code>JOIN</code>
278+ * @see CachedRowSet#unsetMatchColumn
279+ */
280+ public void addRowSet(RowSet rowset, int columnIdx) throws SQLException {
281+ //passing the rowset as well as the columnIdx to form the joinrowset.
282+
283+ ((CachedRowSetImpl)rowset).setMatchColumn(columnIdx);
284+
285+ addRowSet((Joinable)rowset);
286+ }
287+
288+ /**
289+ * Adds the given <code>RowSet</code> object to the <code>JOIN</code> relationship
290+ * and sets the designated column as the match column. If the given
291+ * <code>RowSet</code>
292+ * object is the first to be added to this <code>JoinRowSet</code>
293+ * object, it forms the basis of the <code>JOIN</code> relationship to be formed
294+ * when other <code>RowSet</code> objects are added .
295+ * <P>
296+ * This method should be used when the given <code>RowSet</code> object
297+ * does not already have a match column set.
298+ *
299+ * @param rowset a <code>RowSet</code> object to be added to
300+ * the <code>JOIN</code> relation
301+ * @param columnName a <code>String</code> object giving the name of the column
302+ * to be set as the match column; must implement the <code>Joinable</code>
303+ * interface
304+ * @throws SQLException if (1) an empty <code>RowSet</code> object is added to this
305+ * <code>JoinRowSet</code> object, (2) a match column has not been set,
306+ * or (3) the <code>RowSet</code> object being added violates the active
307+ * <code>JOIN</code>
308+ */
309+ public void addRowSet(RowSet rowset, String columnName) throws SQLException {
310+ //passing the rowset as well as the columnIdx to form the joinrowset.
311+ ((CachedRowSetImpl)rowset).setMatchColumn(columnName);
312+ addRowSet((Joinable)rowset);
313+ }
314+
315+ /**
316+ * Adds the given <code>RowSet</code> objects to the <code>JOIN</code> relationship
317+ * and sets the designated columns as the match columns. If the first
318+ * <code>RowSet</code> object in the array of <code>RowSet</code> objects
319+ * is the first to be added to this <code>JoinRowSet</code>
320+ * object, it forms the basis of the <code>JOIN</code> relationship to be formed
321+ * when other <code>RowSet</code> objects are added.
322+ * <P>
323+ * The first <code>int</code>
324+ * in <i>columnIdx</i> is used to set the match column for the first
325+ * <code>RowSet</code> object in <i>rowset</i>, the second <code>int</code>
326+ * in <i>columnIdx</i> is used to set the match column for the second
327+ * <code>RowSet</code> object in <i>rowset</i>, and so on.
328+ * <P>
329+ * This method should be used when the given <code>RowSet</code> objects
330+ * do not already have match columns set.
331+ *
332+ * @param rowset an array of <code>RowSet</code> objects to be added to
333+ * the <code>JOIN</code> relation; each <code>RowSet</code> object must
334+ * implement the <code>Joinable</code> interface
335+ * @param columnIdx an array of <code>int</code> values designating the columns
336+ * to be set as the
337+ * match columns for the <code>RowSet</code> objects in <i>rowset</i>
338+ * @throws SQLException if the number of <code>RowSet</code> objects in
339+ * <i>rowset</i> is not equal to the number of <code>int</code> values
340+ * in <i>columnIdx</i>
341+ */
342+ public void addRowSet(RowSet[] rowset,
343+ int[] columnIdx) throws SQLException {
344+ //validate if length of rowset array is same as length of int array.
345+ if(rowset.length != columnIdx.length) {
346+ throw new SQLException
347+ (resBundle.handleGetObject("joinrowsetimpl.numnotequal").toString());
348+ } else {
349+ for(int i=0; i< rowset.length; i++) {
350+ ((CachedRowSetImpl)rowset[i]).setMatchColumn(columnIdx[i]);
351+ addRowSet((Joinable)rowset[i]);
352+ } //end for
353+ } //end if
354+
355+ }
356+
357+
358+ /**
359+ * Adds the given <code>RowSet</code> objects to the <code>JOIN</code> relationship
360+ * and sets the designated columns as the match columns. If the first
361+ * <code>RowSet</code> object in the array of <code>RowSet</code> objects
362+ * is the first to be added to this <code>JoinRowSet</code>
363+ * object, it forms the basis of the <code>JOIN</code> relationship to be formed
364+ * when other <code>RowSet</code> objects are added.
365+ * <P>
366+ * The first <code>String</code> object
367+ * in <i>columnName</i> is used to set the match column for the first
368+ * <code>RowSet</code> object in <i>rowset</i>, the second <code>String</code>
369+ * object in <i>columnName</i> is used to set the match column for the second
370+ * <code>RowSet</code> object in <i>rowset</i>, and so on.
371+ * <P>
372+ * This method should be used when the given <code>RowSet</code> objects
373+ * do not already have match columns set.
374+ *
375+ * @param rowset an array of <code>RowSet</code> objects to be added to
376+ * the <code>JOIN</code> relation; each <code>RowSet</code> object must
377+ * implement the <code>Joinable</code> interface
378+ * @param columnName an array of <code>String</code> objects designating the columns
379+ * to be set as the
380+ * match columns for the <code>RowSet</code> objects in <i>rowset</i>
381+ * @throws SQLException if the number of <code>RowSet</code> objects in
382+ * <i>rowset</i> is not equal to the number of <code>String</code> objects
383+ * in <i>columnName</i>, an empty <code>JdbcRowSet</code> is added to the
384+ * <code>JoinRowSet</code>, if a match column is not set,
385+ * or one or the <code>RowSet</code> objects in <i>rowset</i> violates the
386+ * active <code>JOIN</code>
387+ */
388+ public void addRowSet(RowSet[] rowset,
389+ String[] columnName) throws SQLException {
390+ //validate if length of rowset array is same as length of int array.
391+
392+ if(rowset.length != columnName.length) {
393+ throw new SQLException
394+ (resBundle.handleGetObject("joinrowsetimpl.numnotequal").toString());
395+ } else {
396+ for(int i=0; i< rowset.length; i++) {
397+ ((CachedRowSetImpl)rowset[i]).setMatchColumn(columnName[i]);
398+ addRowSet((Joinable)rowset[i]);
399+ } //end for
400+ } //end if
401+
402+ }
403+
404+ /**
405+ * Returns a Collection of the <code>RowSet</code> object instances
406+ * currently residing with the instance of the <code>JoinRowSet</code>
407+ * object instance. This should return the 'n' number of RowSet contained
408+ * within the JOIN and maintain any updates that have occoured while in
409+ * this union.
410+ *
411+ * @return A <code>Collection</code> of the added <code>RowSet</code>
412+ * object instances
413+ * @throws SQLException if an error occours generating a collection
414+ * of the originating RowSets contained within the JOIN.
415+ */
416+ public Collection getRowSets() throws SQLException {
417+ return vecRowSetsInJOIN;
418+ }
419+
420+ /**
421+ * Returns a string array of the RowSet names currently residing
422+ * with the <code>JoinRowSet</code> object instance.
423+ *
424+ * @return a string array of the RowSet names
425+ * @throws SQLException if an error occours retrieving the RowSet names
426+ * @see CachedRowSet#setTableName
427+ */
428+ public String[] getRowSetNames() throws SQLException {
429+ Object [] arr = vecTableNames.toArray();
430+ String []strArr = new String[arr.length];
431+
432+ for( int i = 0;i < arr.length; i++) {
433+ strArr[i] = arr[i].toString();
434+ }
435+
436+ return strArr;
437+ }
438+
439+ /**
440+ * Creates a separate <code>CachedRowSet</code> object that contains the data
441+ * in this <code>JoinRowSet</code> object.
442+ * <P>
443+ * If any updates or modifications have been applied to this <code>JoinRowSet</code>
444+ * object, the <code>CachedRowSet</code> object returned by this method will
445+ * not be able to persist
446+ * the changes back to the originating rows and tables in the
447+ * data source because the data may be from different tables. The
448+ * <code>CachedRowSet</code> instance returned should not
449+ * contain modification data, such as whether a row has been updated or what the
450+ * original values are. Also, the <code>CachedRowSet</code> object should clear
451+ * its properties pertaining to
452+ * its originating SQL statement. An application should reset the
453+ * SQL statement using the <code>RowSet.setCommand</code> method.
454+ * <p>
455+ * To persist changes back to the data source, the <code>JoinRowSet</code> object
456+ * calls the method <code>acceptChanges</code>. Implementations
457+ * can leverage the internal data and update tracking in their
458+ * implementations to interact with the <code>SyncProvider</code> to persist any
459+ * changes.
460+ *
461+ * @return a <code>CachedRowSet</code> object containing the contents of this
462+ * <code>JoinRowSet</code> object
463+ * @throws SQLException if an error occurs assembling the <code>CachedRowSet</code>
464+ * object
465+ * @see javax.sql.RowSet
466+ * @see javax.sql.rowset.CachedRowSet
467+ * @see javax.sql.rowset.spi.SyncProvider
468+ */
469+ public CachedRowSet toCachedRowSet() throws SQLException {
470+ return crsInternal;
471+ }
472+
473+ /**
474+ * Returns <code>true</code> if this <code>JoinRowSet</code> object supports
475+ * an SQL <code>CROSS_JOIN</code> and <code>false</code> if it does not.
476+ *
477+ * @return <code>true</code> if the CROSS_JOIN is supported; <code>false</code>
478+ * otherwise
479+ */
480+ public boolean supportsCrossJoin() {
481+ return supportedJOINs[JoinRowSet.CROSS_JOIN];
482+ }
483+
484+ /**
485+ * Returns <code>true</code> if this <code>JoinRowSet</code> object supports
486+ * an SQL <code>INNER_JOIN</code> and <code>false</code> if it does not.
487+ *
488+ * @return true is the INNER_JOIN is supported; false otherwise
489+ */
490+ public boolean supportsInnerJoin() {
491+ return supportedJOINs[JoinRowSet.INNER_JOIN];
492+ }
493+
494+ /**
495+ * Returns <code>true</code> if this <code>JoinRowSet</code> object supports
496+ * an SQL <code>LEFT_OUTER_JOIN</code> and <code>false</code> if it does not.
497+ *
498+ * @return true is the LEFT_OUTER_JOIN is supported; false otherwise
499+ */
500+ public boolean supportsLeftOuterJoin() {
501+ return supportedJOINs[JoinRowSet.LEFT_OUTER_JOIN];
502+ }
503+
504+ /**
505+ * Returns <code>true</code> if this <code>JoinRowSet</code> object supports
506+ * an SQL <code>RIGHT_OUTER_JOIN</code> and <code>false</code> if it does not.
507+ *
508+ * @return true is the RIGHT_OUTER_JOIN is supported; false otherwise
509+ */
510+ public boolean supportsRightOuterJoin() {
511+ return supportedJOINs[JoinRowSet.RIGHT_OUTER_JOIN];
512+ }
513+
514+ /**
515+ * Returns <code>true</code> if this <code>JoinRowSet</code> object supports
516+ * an SQL <code>FULL_JOIN</code> and <code>false</code> if it does not.
517+ *
518+ * @return true is the FULL_JOIN is supported; false otherwise
519+ */
520+ public boolean supportsFullJoin() {
521+ return supportedJOINs[JoinRowSet.FULL_JOIN];
522+
523+ }
524+
525+ /**
526+ * Sets the type of SQL <code>JOIN</code> that this <code>JoinRowSet</code>
527+ * object will use. This method
528+ * allows an application to adjust the type of <code>JOIN</code> imposed
529+ * on tables contained within this <code>JoinRowSet</code> object and to do it
530+ * on the fly. The last <code>JOIN</code> type set determines the type of
531+ * <code>JOIN</code> to be performed.
532+ * <P>
533+ * Implementations should throw an <code>SQLException</code> if they do
534+ * not support the given <code>JOIN</code> type.
535+ *
536+ * @param type one of the standard <code>JoinRowSet</code> constants
537+ * indicating the type of <code>JOIN</code>. Must be one of the
538+ * following:
539+ * <code>JoinRowSet.CROSS_JOIN</code>
540+ * <code>JoinRowSet.INNER_JOIN</code>
541+ * <code>JoinRowSet.LEFT_OUTER_JOIN</code>
542+ * <code>JoinRowSet.RIGHT_OUTER_JOIN</code>, or
543+ * <code>JoinRowSet.FULL_JOIN</code>
544+ * @throws SQLException if an unsupported <code>JOIN</code> type is set
545+ */
546+ public void setJoinType(int type) throws SQLException {
547+ // The join which governs the join of two rowsets is the last
548+ // join set, using setJoinType
549+
550+ if (type >= JoinRowSet.CROSS_JOIN && type <= JoinRowSet.FULL_JOIN) {
551+ if (type != JoinRowSet.INNER_JOIN) {
552+ // This 'if' will be removed after all joins are implemented.
553+ throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString());
554+ } else {
555+ Integer Intgr = Integer.valueOf(JoinRowSet.INNER_JOIN);
556+ vecJoinType.add(Intgr);
557+ }
558+ } else {
559+ throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notdefined").toString());
560+ } //end if
561+ }
562+
563+
564+ /**
565+ * This checks for a match column for
566+ * whether it exists or not.
567+ *
568+ * @param <code>CachedRowSet</code> object whose match column needs to be checked.
569+ * @throws SQLException if MatchColumn is not set.
570+ */
571+ private boolean checkforMatchColumn(Joinable rs) throws SQLException {
572+ int[] i = rs.getMatchColumnIndexes();
573+ if (i.length <= 0) {
574+ return false;
575+ }
576+ return true;
577+ }
578+
579+ /**
580+ * Internal initialization of <code>JoinRowSet</code>.
581+ */
582+ private void initJOIN(CachedRowSet rowset) throws SQLException {
583+ try {
584+
585+ CachedRowSetImpl cRowset = (CachedRowSetImpl)rowset;
586+ // Create a new CachedRowSet object local to this function.
587+ CachedRowSetImpl crsTemp = new CachedRowSetImpl();
588+ RowSetMetaDataImpl rsmd = new RowSetMetaDataImpl();
589+
590+ /* The following 'if block' seems to be always going true.
591+ commenting this out for present
592+
593+ if (!supportedJOINs[1]) {
594+ throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.notsupported").toString());
595+ }
596+
597+ */
598+
599+ if (vecRowSetsInJOIN.isEmpty() ) {
600+
601+ // implies first cRowset to be added to the Join
602+ // simply add this as a CachedRowSet.
603+ // Also add it to the class variable of type vector
604+ // do not need to check "type" of Join but it should be set.
605+ crsInternal = (CachedRowSetImpl)rowset.createCopy();
606+ crsInternal.setMetaData((RowSetMetaDataImpl)cRowset.getMetaData());
607+ // metadata will also set the MatchColumn.
608+
609+ vecRowSetsInJOIN.add(cRowset);
610+
611+ } else {
612+ // At this point we are ready to add another rowset to 'this' object
613+ // Check the size of vecJoinType and vecRowSetsInJoin
614+
615+ // If nothing is being set, internally call setJoinType()
616+ // to set to JoinRowSet.INNER_JOIN.
617+
618+ // For two rowsets one (valid) entry should be there in vecJoinType
619+ // For three rowsets two (valid) entries should be there in vecJoinType
620+
621+ // Maintain vecRowSetsInJoin = vecJoinType + 1
622+
623+
624+ if( (vecRowSetsInJOIN.size() - vecJoinType.size() ) == 2 ) {
625+ // we are going to add next rowset and setJoinType has not been set
626+ // recently, so set it to setJoinType() to JoinRowSet.INNER_JOIN.
627+ // the default join type
628+
629+ setJoinType(JoinRowSet.INNER_JOIN);
630+ } else if( (vecRowSetsInJOIN.size() - vecJoinType.size() ) == 1 ) {
631+ // do nothing setjoinType() has been set by programmer
632+ }
633+
634+ // Add the table names to the class variable of type vector.
635+ vecTableNames.add(crsInternal.getTableName());
636+ vecTableNames.add(cRowset.getTableName());
637+ // Now we have two rowsets crsInternal and cRowset which need
638+ // to be INNER JOIN'ED to form a new rowset
639+ // Compare table1.MatchColumn1.value1 == { table2.MatchColumn2.value1
640+ // ... upto table2.MatchColumn2.valueN }
641+ // ...
642+ // Compare table1.MatchColumn1.valueM == { table2.MatchColumn2.value1
643+ // ... upto table2.MatchColumn2.valueN }
644+ //
645+ // Assuming first rowset has M rows and second N rows.
646+
647+ int rowCount2 = cRowset.size();
648+ int rowCount1 = crsInternal.size();
649+
650+ // total columns in the new CachedRowSet will be sum of both -1
651+ // (common column)
652+ int matchColumnCount = 0;
653+ for(int i=0; i< crsInternal.getMatchColumnIndexes().length; i++) {
654+ if(crsInternal.getMatchColumnIndexes()[i] != -1)
655+ ++ matchColumnCount;
656+ else
657+ break;
658+ }
659+
660+ rsmd.setColumnCount
661+ (crsInternal.getMetaData().getColumnCount() +
662+ cRowset.getMetaData().getColumnCount() - matchColumnCount);
663+
664+ crsTemp.setMetaData(rsmd);
665+ crsInternal.beforeFirst();
666+ cRowset.beforeFirst();
667+ for (int i = 1 ; i <= rowCount1 ; i++) {
668+ if(crsInternal.isAfterLast() ) {
669+ break;
670+ }
671+ if(crsInternal.next()) {
672+ cRowset.beforeFirst();
673+ for(int j = 1 ; j <= rowCount2 ; j++) {
674+ if( cRowset.isAfterLast()) {
675+ break;
676+ }
677+ if(cRowset.next()) {
678+ boolean match = true;
679+ for(int k=0; k<matchColumnCount; k++) {
680+ if (!crsInternal.getObject( crsInternal.getMatchColumnIndexes()[k]).equals
681+ (cRowset.getObject(cRowset.getMatchColumnIndexes()[k]))) {
682+ match = false;
683+ break;
684+ }
685+ }
686+ if (match) {
687+
688+ int p;
689+ int colc = 0; // reset this variable everytime you loop
690+ // re create a JoinRowSet in crsTemp object
691+ crsTemp.moveToInsertRow();
692+
693+ // create a new rowset crsTemp with data from first rowset
694+ for( p=1;
695+ p<=crsInternal.getMetaData().getColumnCount();p++) {
696+
697+ match = false;
698+ for(int k=0; k<matchColumnCount; k++) {
699+ if (p == crsInternal.getMatchColumnIndexes()[k] ) {
700+ match = true;
701+ break;
702+ }
703+ }
704+ if ( !match ) {
705+
706+ crsTemp.updateObject(++colc, crsInternal.getObject(p));
707+ // column type also needs to be passed.
708+
709+ rsmd.setColumnName
710+ (colc, crsInternal.getMetaData().getColumnName(p));
711+ rsmd.setTableName(colc, crsInternal.getTableName());
712+
713+ rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p));
714+ rsmd.setAutoIncrement(p, crsInternal.getMetaData().isAutoIncrement(p));
715+ rsmd.setCaseSensitive(p, crsInternal.getMetaData().isCaseSensitive(p));
716+ rsmd.setCatalogName(p, crsInternal.getMetaData().getCatalogName(p));
717+ rsmd.setColumnDisplaySize(p, crsInternal.getMetaData().getColumnDisplaySize(p));
718+ rsmd.setColumnLabel(p, crsInternal.getMetaData().getColumnLabel(p));
719+ rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p));
720+ rsmd.setColumnTypeName(p, crsInternal.getMetaData().getColumnTypeName(p));
721+ rsmd.setCurrency(p,crsInternal.getMetaData().isCurrency(p) );
722+ rsmd.setNullable(p, crsInternal.getMetaData().isNullable(p));
723+ rsmd.setPrecision(p, crsInternal.getMetaData().getPrecision(p));
724+ rsmd.setScale(p, crsInternal.getMetaData().getScale(p));
725+ rsmd.setSchemaName(p, crsInternal.getMetaData().getSchemaName(p));
726+ rsmd.setSearchable(p, crsInternal.getMetaData().isSearchable(p));
727+ rsmd.setSigned(p, crsInternal.getMetaData().isSigned(p));
728+
729+ } else {
730+ // will happen only once, for that merged column pass
731+ // the types as OBJECT, if types not equal
732+
733+ crsTemp.updateObject(++colc, crsInternal.getObject(p));
734+
735+ rsmd.setColumnName(colc, crsInternal.getMetaData().getColumnName(p));
736+ rsmd.setTableName
737+ (colc, crsInternal.getTableName()+
738+ "#"+
739+ cRowset.getTableName());
740+
741+
742+ rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p));
743+ rsmd.setAutoIncrement(p, crsInternal.getMetaData().isAutoIncrement(p));
744+ rsmd.setCaseSensitive(p, crsInternal.getMetaData().isCaseSensitive(p));
745+ rsmd.setCatalogName(p, crsInternal.getMetaData().getCatalogName(p));
746+ rsmd.setColumnDisplaySize(p, crsInternal.getMetaData().getColumnDisplaySize(p));
747+ rsmd.setColumnLabel(p, crsInternal.getMetaData().getColumnLabel(p));
748+ rsmd.setColumnType(p, crsInternal.getMetaData().getColumnType(p));
749+ rsmd.setColumnTypeName(p, crsInternal.getMetaData().getColumnTypeName(p));
750+ rsmd.setCurrency(p,crsInternal.getMetaData().isCurrency(p) );
751+ rsmd.setNullable(p, crsInternal.getMetaData().isNullable(p));
752+ rsmd.setPrecision(p, crsInternal.getMetaData().getPrecision(p));
753+ rsmd.setScale(p, crsInternal.getMetaData().getScale(p));
754+ rsmd.setSchemaName(p, crsInternal.getMetaData().getSchemaName(p));
755+ rsmd.setSearchable(p, crsInternal.getMetaData().isSearchable(p));
756+ rsmd.setSigned(p, crsInternal.getMetaData().isSigned(p));
757+
758+ //don't do ++colc in the above statement
759+ } //end if
760+ } //end for
761+
762+
763+ // append the rowset crsTemp, with data from second rowset
764+ for(int q=1;
765+ q<= cRowset.getMetaData().getColumnCount();q++) {
766+
767+ match = false;
768+ for(int k=0; k<matchColumnCount; k++) {
769+ if (q == cRowset.getMatchColumnIndexes()[k] ) {
770+ match = true;
771+ break;
772+ }
773+ }
774+ if ( !match ) {
775+
776+ crsTemp.updateObject(++colc, cRowset.getObject(q));
777+
778+ rsmd.setColumnName
779+ (colc, cRowset.getMetaData().getColumnName(q));
780+ rsmd.setTableName(colc, cRowset.getTableName());
781+
782+ /**
783+ * This will happen for a special case scenario. The value of 'p'
784+ * will always be one more than the number of columns in the first
785+ * rowset in the join. So, for a value of 'q' which is the number of
786+ * columns in the second rowset that participates in the join.
787+ * So decrement value of 'p' by 1 else `p+q-1` will be out of range.
788+ **/
789+
790+ //if((p+q-1) > ((crsInternal.getMetaData().getColumnCount()) +
791+ // (cRowset.getMetaData().getColumnCount()) - 1)) {
792+ // --p;
793+ //}
794+ rsmd.setColumnType(p+q-1, cRowset.getMetaData().getColumnType(q));
795+ rsmd.setAutoIncrement(p+q-1, cRowset.getMetaData().isAutoIncrement(q));
796+ rsmd.setCaseSensitive(p+q-1, cRowset.getMetaData().isCaseSensitive(q));
797+ rsmd.setCatalogName(p+q-1, cRowset.getMetaData().getCatalogName(q));
798+ rsmd.setColumnDisplaySize(p+q-1, cRowset.getMetaData().getColumnDisplaySize(q));
799+ rsmd.setColumnLabel(p+q-1, cRowset.getMetaData().getColumnLabel(q));
800+ rsmd.setColumnType(p+q-1, cRowset.getMetaData().getColumnType(q));
801+ rsmd.setColumnTypeName(p+q-1, cRowset.getMetaData().getColumnTypeName(q));
802+ rsmd.setCurrency(p+q-1,cRowset.getMetaData().isCurrency(q) );
803+ rsmd.setNullable(p+q-1, cRowset.getMetaData().isNullable(q));
804+ rsmd.setPrecision(p+q-1, cRowset.getMetaData().getPrecision(q));
805+ rsmd.setScale(p+q-1, cRowset.getMetaData().getScale(q));
806+ rsmd.setSchemaName(p+q-1, cRowset.getMetaData().getSchemaName(q));
807+ rsmd.setSearchable(p+q-1, cRowset.getMetaData().isSearchable(q));
808+ rsmd.setSigned(p+q-1, cRowset.getMetaData().isSigned(q));
809+ }
810+ else {
811+ --p;
812+ }
813+ }
814+ crsTemp.insertRow();
815+ crsTemp.moveToCurrentRow();
816+
817+ } else {
818+ // since not equa12
819+ // so do nothing
820+ } //end if
821+ // bool1 = cRowset.next();
822+ }
823+
824+ } // end inner for
825+ //bool2 = crsInternal.next();
826+ }
827+
828+ } //end outer for
829+ crsTemp.setMetaData(rsmd);
830+ crsTemp.setOriginal();
831+
832+ // Now the join is done.
833+ // Make crsInternal = crsTemp, to be ready for next merge, if at all.
834+
835+ int[] pCol = new int[matchColumnCount];
836+ for(int i=0; i<matchColumnCount; i++)
837+ pCol[i] = crsInternal.getMatchColumnIndexes()[i];
838+
839+ crsInternal = (CachedRowSetImpl)crsTemp.createCopy();
840+
841+ // Because we add the first rowset as crsInternal to the
842+ // merged rowset, so pCol will point to the Match column.
843+ // until reset, am not sure we should set this or not(?)
844+ // if this is not set next inner join won't happen
845+ // if we explicitly do not set a set MatchColumn of
846+ // the new crsInternal.
847+
848+ crsInternal.setMatchColumn(pCol);
849+ // Add the merged rowset to the class variable of type vector.
850+ crsInternal.setMetaData(rsmd);
851+ vecRowSetsInJOIN.add(cRowset);
852+ } //end if
853+ } catch(SQLException sqle) {
854+ // %%% Exception should not dump here:
855+ sqle.printStackTrace();
856+ throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.initerror").toString() + sqle);
857+ } catch (Exception e) {
858+ e.printStackTrace();
859+ throw new SQLException(resBundle.handleGetObject("joinrowsetimpl.genericerr").toString() + e);
860+ }
861+ }
862+
863+ /**
864+ * Return a SQL-like description of the <code>WHERE</code> clause being used
865+ * in a <code>JoinRowSet</code> object instance. An implementation can describe
866+ * the <code>WHERE</code> clause of the SQL <code>JOIN</code> by supplying a <code>SQL</code>
867+ * strings description of <code>JOIN</code> or provide a textual description to assist
868+ * applications using a <code>JoinRowSet</code>.
869+ *
870+ * @return whereClause a textual or SQL descripition of the logical
871+ * <code>WHERE</code> cluase used in the <code>JoinRowSet</code> instance
872+ * @throws SQLException if an error occurs in generating a representation
873+ * of the <code>WHERE</code> clause.
874+ */
875+ public String getWhereClause() throws SQLException {
876+
877+ String strWhereClause = "Select ";
878+ String whereClause;
879+ String tabName= "";
880+ String strTabName = "";
881+ int sz,cols;
882+ int j;
883+ CachedRowSetImpl crs;
884+
885+ // get all the column(s) names from each rowset.
886+ // append them with their tablenames i.e. tableName.columnName
887+ // Select tableName1.columnName1,..., tableNameX.columnNameY
888+ // from tableName1,...tableNameX where
889+ // tableName1.(rowset1.getMatchColumnName()) ==
890+ // tableName2.(rowset2.getMatchColumnName()) + "and" +
891+ // tableNameX.(rowsetX.getMatchColumnName()) ==
892+ // tableNameZ.(rowsetZ.getMatchColumnName()));
893+
894+ sz = vecRowSetsInJOIN.size();
895+ for(int i=0;i<sz; i++) {
896+ crs = (CachedRowSetImpl)vecRowSetsInJOIN.get(i);
897+ cols = crs.getMetaData().getColumnCount();
898+ tabName = tabName.concat(crs.getTableName());
899+ strTabName = strTabName.concat(tabName+", ");
900+ j = 1;
901+ while(j<cols) {
902+
903+ strWhereClause = strWhereClause.concat
904+ (tabName+"."+crs.getMetaData().getColumnName(j++));
905+ strWhereClause = strWhereClause.concat(", ");
906+ } //end while
907+ } //end for
908+
909+
910+ // now remove the last ","
911+ strWhereClause = strWhereClause.substring
912+ (0, strWhereClause.lastIndexOf(","));
913+
914+ // Add from clause
915+ strWhereClause = strWhereClause.concat(" from ");
916+
917+ // Add the table names.
918+ strWhereClause = strWhereClause.concat(strTabName);
919+
920+ //Remove the last ","
921+ strWhereClause = strWhereClause.substring
922+ (0, strWhereClause.lastIndexOf(","));
923+
924+ // Add the where clause
925+ strWhereClause = strWhereClause.concat(" where ");
926+
927+ // Get the match columns
928+ // rowset1.getMatchColumnName() == rowset2.getMatchColumnName()
929+ for(int i=0;i<sz; i++) {
930+ strWhereClause = strWhereClause.concat(
931+ ((CachedRowSetImpl)vecRowSetsInJOIN.get(i)).getMatchColumnNames()[0]);
932+ if(i%2!=0) {
933+ strWhereClause = strWhereClause.concat("=");
934+ } else {
935+ strWhereClause = strWhereClause.concat(" and");
936+ }
937+ strWhereClause = strWhereClause.concat(" ");
938+ }
939+
940+ return strWhereClause;
941+ }
942+
943+
944+ /**
945+ * Moves the cursor down one row from its current position and
946+ * returns <code>true</code> if the new cursor position is a
947+ * valid row.
948+ * The cursor for a new <code>ResultSet</code> object is initially
949+ * positioned before the first row. The first call to the method
950+ * <code>next</code> moves the cursor to the first row, making it
951+ * the current row; the second call makes the second row the
952+ * current row, and so on.
953+ *
954+ * <P>If an input stream from the previous row is open, it is
955+ * implicitly closed. The <code>ResultSet</code> object's warning
956+ * chain is cleared when a new row is read.
957+ *
958+ * @return <code>true</code> if the new current row is valid;
959+ * <code>false</code> if there are no more rows
960+ * @throws SQLException if an error occurs or
961+ * the cursor is not positioned in the rowset, before
962+ * the first row, or after the last row
963+ */
964+ public boolean next() throws SQLException {
965+ return crsInternal.next();
966+ }
967+
968+
969+ /**
970+ * Releases the current contents of this rowset, discarding outstanding
971+ * updates. The rowset contains no rows after the method
972+ * <code>release</code> is called. This method sends a
973+ * <code>RowSetChangedEvent</code> object to all registered listeners prior
974+ * to returning.
975+ *
976+ * @throws SQLException if an error occurs
977+ */
978+ public void close() throws SQLException {
979+ crsInternal.close();
980+ }
981+
982+
983+ /**
984+ * Reports whether the last column read was SQL <code>NULL</code>.
985+ * Note that you must first call the method <code>getXXX</code>
986+ * on a column to try to read its value and then call the method
987+ * <code>wasNull</code> to determine whether the value was
988+ * SQL <code>NULL</code>.
989+ *
990+ * @return <code>true</code> if the value in the last column read
991+ * was SQL <code>NULL</code>; <code>false</code> otherwise
992+ * @throws SQLException if an error occurs
993+ */
994+ public boolean wasNull() throws SQLException {
995+ return crsInternal.wasNull();
996+ }
997+
998+ /**
999+ * Retrieves the value of the designated column in the current row
1000+ * of this <code>JoinRowSetImpl</code> object as a
1001+ * <code>String</code> object.
1002+ *
1003+ * @param columnIndex the first column is <code>1</code>, the second
1004+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1005+ * and equal to or less than the number of columns in the rowset
1006+ * @return the column value; if the value is SQL <code>NULL</code>, the
1007+ * result is <code>null</code>
1008+ * @throws SQLException if the given column index is out of bounds or
1009+ * the cursor is not on a valid row
1010+ */
1011+ public String getString(int columnIndex) throws SQLException {
1012+ return crsInternal.getString(columnIndex);
1013+ }
1014+
1015+ /**
1016+ * Retrieves the value of the designated column in the current row
1017+ * of this <code>JoinRowSetImpl</code> object as a
1018+ * <code>boolean</code> value.
1019+ *
1020+ * @param columnIndex the first column is <code>1</code>, the second
1021+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1022+ * and equal to or less than the number of columns in the rowset
1023+ * @return the column value; if the value is SQL <code>NULL</code>, the
1024+ * result is <code>false</code>
1025+ * @throws SQLException if the given column index is out of bounds,
1026+ * the cursor is not on a valid row, or this method fails
1027+ */
1028+ public boolean getBoolean(int columnIndex) throws SQLException {
1029+ return crsInternal.getBoolean(columnIndex);
1030+ }
1031+
1032+ /**
1033+ * Retrieves the value of the designated column in the current row
1034+ * of this <code>JoinRowSetImpl</code> object as a
1035+ * <code>byte</code> value.
1036+ *
1037+ * @param columnIndex the first column is <code>1</code>, the second
1038+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1039+ * and equal to or less than the number of columns in the rowset
1040+ * @return the column value; if the value is SQL <code>NULL</code>, the
1041+ * result is <code>0</code>
1042+ * @throws SQLException if the given column index is out of bounds,
1043+ * the cursor is not on a valid row, or this method fails
1044+ */
1045+ public byte getByte(int columnIndex) throws SQLException {
1046+ return crsInternal.getByte(columnIndex);
1047+ }
1048+
1049+ /**
1050+ * Retrieves the value of the designated column in the current row
1051+ * of this <code>JoinRowSetImpl</code> object as a
1052+ * <code>short</code> value.
1053+ *
1054+ * @param columnIndex the first column is <code>1</code>, the second
1055+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1056+ * and equal to or less than the number of columns in the rowset
1057+ * @return the column value; if the value is SQL <code>NULL</code>, the
1058+ * result is <code>0</code>
1059+ * @throws SQLException if the given column index is out of bounds,
1060+ * the cursor is not on a valid row, or this method fails
1061+ */
1062+ public short getShort(int columnIndex) throws SQLException {
1063+ return crsInternal.getShort(columnIndex);
1064+ }
1065+
1066+ /**
1067+ * Retrieves the value of the designated column in the current row
1068+ * of this <code>JoinRowSetImpl</code> object as a
1069+ * <code>short</code> value.
1070+ *
1071+ * @param columnIndex the first column is <code>1</code>, the second
1072+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1073+ * and equal to or less than the number of columns in the rowset
1074+ * @return the column value; if the value is SQL <code>NULL</code>, the
1075+ * result is <code>0</code>
1076+ * @throws SQLException if the given column index is out of bounds,
1077+ * the cursor is not on a valid row, or this method fails
1078+ */
1079+ public int getInt(int columnIndex) throws SQLException {
1080+ return crsInternal.getInt(columnIndex);
1081+ }
1082+
1083+ /**
1084+ * Retrieves the value of the designated column in the current row
1085+ * of this <code>JoinRowSetImpl</code> object as a
1086+ * <code>long</code> value.
1087+ *
1088+ * @param columnIndex the first column is <code>1</code>, the second
1089+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1090+ * and equal to or less than the number of columns in the rowset
1091+ * @return the column value; if the value is SQL <code>NULL</code>, the
1092+ * result is <code>0</code>
1093+ * @throws SQLException if the given column index is out of bounds,
1094+ * the cursor is not on a valid row, or this method fails
1095+ */
1096+ public long getLong(int columnIndex) throws SQLException {
1097+ return crsInternal.getLong(columnIndex);
1098+ }
1099+
1100+ /**
1101+ * Retrieves the value of the designated column in the current row
1102+ * of this <code>JoinRowSetImpl</code> object as a
1103+ * <code>float</code> value.
1104+ *
1105+ * @param columnIndex the first column is <code>1</code>, the second
1106+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1107+ * and equal to or less than the number of columns in the rowset
1108+ * @return the column value; if the value is SQL <code>NULL</code>, the
1109+ * result is <code>0</code>
1110+ * @throws SQLException if the given column index is out of bounds,
1111+ * the cursor is not on a valid row, or this method fails
1112+ */
1113+ public float getFloat(int columnIndex) throws SQLException {
1114+ return crsInternal.getFloat(columnIndex);
1115+ }
1116+
1117+ /**
1118+ * Retrieves the value of the designated column in the current row
1119+ * of this <code>JoinRowSetImpl</code> object as a
1120+ * <code>double</code> value.
1121+ *
1122+ * @param columnIndex the first column is <code>1</code>, the second
1123+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1124+ * and equal to or less than the number of columns in the rowset
1125+ * @return the column value; if the value is SQL <code>NULL</code>, the
1126+ * result is <code>0</code>
1127+ * @throws SQLException if the given column index is out of bounds,
1128+ * the cursor is not on a valid row, or this method fails
1129+ */
1130+ public double getDouble(int columnIndex) throws SQLException {
1131+ return crsInternal.getDouble(columnIndex);
1132+ }
1133+
1134+ /**
1135+ * Retrieves the value of the designated column in the current row
1136+ * of this <code>JoinRowSetImpl</code> object as a
1137+ * <code>java.math.BigDecimal</code> object.
1138+ * <P>
1139+ * This method is deprecated; use the version of <code>getBigDecimal</code>
1140+ * that does not take a scale parameter and returns a value with full
1141+ * precision.
1142+ *
1143+ * @param columnIndex the first column is <code>1</code>, the second
1144+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1145+ * and equal to or less than the number of columns in the rowset
1146+ * @param scale the number of digits to the right of the decimal point in the
1147+ * value returned
1148+ * @return the column value with the specified number of digits to the right
1149+ * of the decimal point; if the value is SQL <code>NULL</code>, the
1150+ * result is <code>null</code>
1151+ * @throws SQLException if the given column index is out of bounds,
1152+ * the cursor is not on a valid row, or this method fails
1153+ * @deprecated
1154+ */
1155+ public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
1156+ return crsInternal.getBigDecimal(columnIndex);
1157+ }
1158+
1159+ /**
1160+ * Retrieves the value of the designated column in the current row
1161+ * of this <code>JoinRowSetImpl</code> object as a
1162+ * <code>byte array</code> value.
1163+ *
1164+ * @param columnIndex the first column is <code>1</code>, the second
1165+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1166+ * and equal to or less than the number of columns in the rowset
1167+ * @return the column value; if the value is SQL <code>NULL</code>, the
1168+ * result is <code>null</code>
1169+ * @throws SQLException if the given column index is out of bounds,
1170+ * the cursor is not on a valid row, or the the value to be
1171+ * retrieved is not binary
1172+ */
1173+ public byte[] getBytes(int columnIndex) throws SQLException {
1174+ return crsInternal.getBytes(columnIndex);
1175+ }
1176+
1177+ /**
1178+ * Retrieves the value of the designated column in the current row
1179+ * of this <code>JoinRowSetImpl</code> object as a
1180+ * <code>java.sql.Date</code> object.
1181+ *
1182+ * @param columnIndex the first column is <code>1</code>, the second
1183+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1184+ * and equal to or less than the number of columns in the rowset
1185+ * @return the column value; if the value is SQL <code>NULL</code>, the
1186+ * result is <code>null</code>
1187+ * @throws SQLException if the given column index is out of bounds,
1188+ * the cursor is not on a valid row, or this method fails
1189+ */
1190+ public java.sql.Date getDate(int columnIndex) throws SQLException {
1191+ return crsInternal.getDate(columnIndex);
1192+ }
1193+
1194+ /**
1195+ * Retrieves the value of the designated column in the current row
1196+ * of this <code>JoinRowSetImpl</code> object as a
1197+ * <code>java.sql.Time</code> object.
1198+ *
1199+ * @param columnIndex the first column is <code>1</code>, the second
1200+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1201+ * and equal to or less than the number of columns in the rowset
1202+ * @return the column value; if the value is SQL <code>NULL</code>, the
1203+ * result is <code>null</code>
1204+ * @throws SQLException if the given column index is out of bounds,
1205+ * the cursor is not on a valid row, or this method fails
1206+ */
1207+ public java.sql.Time getTime(int columnIndex) throws SQLException {
1208+ return crsInternal.getTime(columnIndex);
1209+ }
1210+
1211+ /**
1212+ * Retrieves the value of the designated column in the current row
1213+ * of this <code>JoinRowSetImpl</code> object as a
1214+ * <code>java.sql.Timestamp</code> object.
1215+ *
1216+ * @param columnIndex the first column is <code>1</code>, the second
1217+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1218+ * and equal to or less than the number of columns in the rowset
1219+ * @return the column value; if the value is SQL <code>NULL</code>, the
1220+ * result is <code>null</code>
1221+ * @throws SQLException if the given column index is out of bounds,
1222+ * the cursor is not on a valid row, or this method fails
1223+ */
1224+ public java.sql.Timestamp getTimestamp(int columnIndex) throws SQLException {
1225+ return crsInternal.getTimestamp(columnIndex);
1226+ }
1227+
1228+ /**
1229+ * Retrieves the value of the designated column in the current row
1230+ * of this <code>JoinRowSetImpl</code> object as a
1231+ * <code>java.sql.Timestamp</code> object.
1232+ *
1233+ * @param columnIndex the first column is <code>1</code>, the second
1234+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1235+ * and equal to or less than the number of columns in the rowset
1236+ * @return the column value; if the value is SQL <code>NULL</code>, the
1237+ * result is <code>null</code>
1238+ * @throws SQLException if the given column index is out of bounds,
1239+ * the cursor is not on a valid row, or this method fails
1240+ */
1241+ public java.io.InputStream getAsciiStream(int columnIndex) throws SQLException {
1242+ return crsInternal.getAsciiStream(columnIndex);
1243+ }
1244+
1245+ /**
1246+ * A column value can be retrieved as a stream of Unicode characters
1247+ * and then read in chunks from the stream. This method is particularly
1248+ * suitable for retrieving large LONGVARCHAR values. The JDBC driver will
1249+ * do any necessary conversion from the database format into Unicode.
1250+ *
1251+ * <P><B>Note:</B> All the data in the returned stream must be
1252+ * read prior to getting the value of any other column. The next
1253+ * call to a get method implicitly closes the stream. . Also, a
1254+ * stream may return 0 for available() whether there is data
1255+ * available or not.
1256+ *
1257+ * @param columnIndex the first column is <code>1</code>, the second
1258+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1259+ * and equal to or less than the number of columns in this rowset
1260+ * @return a Java input stream that delivers the database column value
1261+ * as a stream of two byte Unicode characters. If the value is SQL NULL
1262+ * then the result is null.
1263+ * @throws SQLException if an error occurs
1264+ * @deprecated
1265+ */
1266+ public java.io.InputStream getUnicodeStream(int columnIndex) throws SQLException {
1267+ return crsInternal.getUnicodeStream(columnIndex);
1268+ }
1269+
1270+ /**
1271+ * A column value can be retrieved as a stream of uninterpreted bytes
1272+ * and then read in chunks from the stream. This method is particularly
1273+ * suitable for retrieving large LONGVARBINARY values.
1274+ *
1275+ * <P><B>Note:</B> All the data in the returned stream must be
1276+ * read prior to getting the value of any other column. The next
1277+ * call to a get method implicitly closes the stream. Also, a
1278+ * stream may return 0 for available() whether there is data
1279+ * available or not.
1280+ *
1281+ * @param columnIndex the first column is <code>1</code>, the second
1282+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1283+ * and equal to or less than the number of columns in the rowset
1284+ * @return a Java input stream that delivers the database column value
1285+ * as a stream of uninterpreted bytes. If the value is SQL NULL
1286+ * then the result is null.
1287+ * @throws SQLException if an error occurs
1288+ */
1289+ public java.io.InputStream getBinaryStream(int columnIndex) throws SQLException {
1290+ return crsInternal.getBinaryStream(columnIndex);
1291+ }
1292+
1293+ // ColumnName methods
1294+
1295+ /**
1296+ * Retrieves the value stored in the designated column
1297+ * of the current row as a <code>String</code> object.
1298+ *
1299+ * @param columnName a <code>String</code> object giving the SQL name of
1300+ * a column in this <code>JoinRowSetImpl</code> object
1301+ * @return the column value; if the value is SQL <code>NULL</code>,
1302+ * the result is <code>null</code>
1303+ * @throws SQLException if the given column name does not match one of
1304+ * this rowset's column names or the cursor is not on one of
1305+ * this rowset's rows or its insert row
1306+ */
1307+ public String getString(String columnName) throws SQLException {
1308+ return crsInternal.getString(columnName);
1309+ }
1310+
1311+ /**
1312+ * Retrieves the value stored in the designated column
1313+ * of the current row as a <code>boolean</code> value.
1314+ *
1315+ * @param columnName a <code>String</code> object giving the SQL name of
1316+ * a column in this <code>JoinRowSetImpl</code> object
1317+ * @return the column value; if the value is SQL <code>NULL</code>,
1318+ * the result is <code>false</code>
1319+ * @throws SQLException if the given column name does not match one of
1320+ * this rowset's column names or the cursor is not on one of
1321+ * this rowset's rows or its insert row
1322+ */
1323+ public boolean getBoolean(String columnName) throws SQLException {
1324+ return crsInternal.getBoolean(columnName);
1325+ }
1326+
1327+ /**
1328+ * Retrieves the value stored in the designated column
1329+ * of the current row as a <code>byte</code> value.
1330+ *
1331+ * @param columnName a <code>String</code> object giving the SQL name of
1332+ * a column in this <code>JoinRowSetImpl</code> object
1333+ * @return the column value; if the value is SQL <code>NULL</code>,
1334+ * the result is <code>0</code>
1335+ * @throws SQLException if the given column name does not match one of
1336+ * this rowset's column names or the cursor is not on one of
1337+ * this rowset's rows or its insert row
1338+ */
1339+ public byte getByte(String columnName) throws SQLException {
1340+ return crsInternal.getByte(columnName);
1341+ }
1342+
1343+ /**
1344+ * Retrieves the value stored in the designated column
1345+ * of the current row as a <code>short</code> value.
1346+ *
1347+ * @param columnName a <code>String</code> object giving the SQL name of
1348+ * a column in this <code>JoinRowSetImpl</code> object
1349+ * @return the column value; if the value is SQL <code>NULL</code>,
1350+ * the result is <code>0</code>
1351+ * @throws SQLException if the given column name does not match one of
1352+ * this rowset's column names or the cursor is not on one of
1353+ * this rowset's rows or its insert row
1354+ */
1355+ public short getShort(String columnName) throws SQLException {
1356+ return crsInternal.getShort(columnName);
1357+ }
1358+
1359+ /**
1360+ * Retrieves the value stored in the designated column
1361+ * of the current row as an <code>int</code> value.
1362+ *
1363+ * @param columnName a <code>String</code> object giving the SQL name of
1364+ * a column in this <code>JoinRowSetImpl</code> object
1365+ * @return the column value; if the value is SQL <code>NULL</code>,
1366+ * the result is <code>0</code>
1367+ * @throws SQLException if the given column name does not match one of
1368+ * this rowset's column names or the cursor is not on one of
1369+ * this rowset's rows or its insert row
1370+ */
1371+ public int getInt(String columnName) throws SQLException {
1372+ return crsInternal.getInt(columnName);
1373+ }
1374+
1375+ /**
1376+ * Retrieves the value stored in the designated column
1377+ * of the current row as a <code>long</code> value.
1378+ *
1379+ * @param columnName a <code>String</code> object giving the SQL name of
1380+ * a column in this <code>JoinRowSetImpl</code> object
1381+ * @return the column value; if the value is SQL <code>NULL</code>,
1382+ * the result is <code>0</code>
1383+ * @throws SQLException if the given column name does not match one of
1384+ * this rowset's column names or the cursor is not on one of
1385+ * this rowset's rows or its insert row
1386+ */
1387+ public long getLong(String columnName) throws SQLException {
1388+ return crsInternal.getLong(columnName);
1389+ }
1390+
1391+ /**
1392+ * Retrieves the value stored in the designated column
1393+ * of the current row as a <code>float</code> value.
1394+ *
1395+ * @param columnName a <code>String</code> object giving the SQL name of
1396+ * a column in this <code>JoinRowSetImpl</code> object
1397+ * @return the column value; if the value is SQL <code>NULL</code>,
1398+ * the result is <code>0</code>
1399+ * @throws SQLException if the given column name does not match one of
1400+ * this rowset's column names or the cursor is not on one of
1401+ * this rowset's rows or its insert row
1402+ */
1403+ public float getFloat(String columnName) throws SQLException {
1404+ return crsInternal.getFloat(columnName);
1405+ }
1406+
1407+ /**
1408+ * Retrieves the value stored in the designated column
1409+ * of the current row as a <code>double</code> value.
1410+ *
1411+ * @param columnName a <code>String</code> object giving the SQL name of
1412+ * a column in this <code>JoinRowSetImpl</code> object
1413+ * @return the column value; if the value is SQL <code>NULL</code>,
1414+ * the result is <code>0</code>
1415+ * @throws SQLException if the given column name does not match one of
1416+ * this rowset's column names or the cursor is not on one of
1417+ * this rowset's rows or its insert row
1418+ */
1419+ public double getDouble(String columnName) throws SQLException {
1420+ return crsInternal.getDouble(columnName);
1421+ }
1422+
1423+ /**
1424+ * Retrieves the value stored in the designated column
1425+ * of the current row as a <code>java.math.BigDecimal</code> object.
1426+ *
1427+ * @param columnName a <code>String</code> object giving the SQL name of
1428+ * a column in this <code>JoinRowSetImpl</code> object
1429+ * @param scale the number of digits to the right of the decimal point
1430+ * @return the column value; if the value is SQL <code>NULL</code>,
1431+ * the result is <code>null</code>
1432+ * @throws SQLException if the given column name does not match one of
1433+ * this rowset's column names or the cursor is not on one of
1434+ * this rowset's rows or its insert row
1435+ * @deprecated use the method <code>getBigDecimal(String columnName)</code>
1436+ * instead
1437+ */
1438+ public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
1439+ return crsInternal.getBigDecimal(columnName);
1440+ }
1441+
1442+ /**
1443+ * Retrieves the value stored in the designated column
1444+ * of the current row as a byte array.
1445+ * The bytes represent the raw values returned by the driver.
1446+ *
1447+ * @param columnName a <code>String</code> object giving the SQL name of
1448+ * a column in this <code>JoinRowSetImpl</code> object
1449+ * @return the column value; if the value is SQL <code>NULL</code>,
1450+ * the result is <code>null</code>
1451+ * @throws SQLException if the given column name does not match one of
1452+ * this rowset's column names or the cursor is not on one of
1453+ * this rowset's rows or its insert row
1454+ */
1455+ public byte[] getBytes(String columnName) throws SQLException {
1456+ return crsInternal.getBytes(columnName);
1457+ }
1458+
1459+ /**
1460+ * Retrieves the value stored in the designated column
1461+ * of the current row as a <code>java.sql.Date</code> object.
1462+ *
1463+ * @param columnName a <code>String</code> object giving the SQL name of
1464+ * a column in this <code>JoinRowSetImpl</code> object
1465+ * @return the column value; if the value is SQL <code>NULL</code>,
1466+ * the result is <code>null</code>
1467+ * @throws SQLException if the given column name does not match one of
1468+ * this rowset's column names or the cursor is not on one of
1469+ * this rowset's rows or its insert row
1470+ */
1471+ public java.sql.Date getDate(String columnName) throws SQLException {
1472+ return crsInternal.getDate(columnName);
1473+ }
1474+
1475+ /**
1476+ * Retrieves the value stored in the designated column
1477+ * of the current row as a <code>java.sql.Time</code> object.
1478+ *
1479+ * @param columnName a <code>String</code> object giving the SQL name of
1480+ * a column in this <code>JoinRowSetImpl</code> object
1481+ * @return the column value; if the value is SQL <code>NULL</code>,
1482+ * the result is <code>null</code>
1483+ * @throws SQLException if the given column name does not match one of
1484+ * this rowset's column names or the cursor is not on one of
1485+ * this rowset's rows or its insert row
1486+ */
1487+ public java.sql.Time getTime(String columnName) throws SQLException {
1488+ return crsInternal.getTime(columnName);
1489+ }
1490+
1491+ /**
1492+ * Retrieves the value stored in the designated column
1493+ * of the current row as a <code>java.sql.Timestamp</code> object.
1494+ *
1495+ * @param columnName a <code>String</code> object giving the SQL name of
1496+ * a column in this <code>JoinRowSetImpl</code> object
1497+ * @return the column value; if the value is SQL <code>NULL</code>,
1498+ * the result is <code>null</code>
1499+ * @throws SQLException if the given column name does not match one of
1500+ * this rowset's column names or the cursor is not on one of
1501+ * this rowset's rows or its insert row
1502+ */
1503+ public java.sql.Timestamp getTimestamp(String columnName) throws SQLException {
1504+ return crsInternal.getTimestamp(columnName);
1505+ }
1506+
1507+ /**
1508+ * This method is not supported, and it will throw an
1509+ * <code>UnsupportedOperationException</code> if it is called.
1510+ * <P>
1511+ * A column value can be retrieved as a stream of ASCII characters
1512+ * and then read in chunks from the stream. This method is particularly
1513+ * suitable for retrieving large LONGVARCHAR values. The JDBC driver will
1514+ * do any necessary conversion from the database format into ASCII format.
1515+ *
1516+ * <P><B>Note:</B> All the data in the returned stream must
1517+ * be read prior to getting the value of any other column. The
1518+ * next call to a <code>getXXX</code> method implicitly closes the stream.
1519+ *
1520+ * @param columnName a <code>String</code> object giving the SQL name of
1521+ * a column in this <code>JoinRowSetImpl</code> object
1522+ * @return a Java input stream that delivers the database column value
1523+ * as a stream of one-byte ASCII characters. If the value is SQL
1524+ * <code>NULL</code>, the result is <code>null</code>.
1525+ * @throws UnsupportedOperationException if this method is called
1526+ */
1527+ public java.io.InputStream getAsciiStream(String columnName) throws SQLException {
1528+ return crsInternal.getAsciiStream(columnName);
1529+ }
1530+
1531+ /**
1532+ * Retrieves the value stored in the designated column
1533+ * of the current row as a <code>java.io.InputStream</code> object.
1534+ * A column value can be retrieved as a stream of Unicode characters
1535+ * and then read in chunks from the stream. This method is particularly
1536+ * suitable for retrieving large <code>LONGVARCHAR</code> values.
1537+ * The JDBC driver will do any necessary conversion from the database
1538+ * format into Unicode.
1539+ *
1540+ * <P><B>Note:</B> All the data in the returned stream must
1541+ * be read prior to getting the value of any other column. The
1542+ * next call to a <code>getXXX</code> method implicitly closes the stream.
1543+ *
1544+ * @param columnName a <code>String</code> object giving the SQL name of
1545+ * a column in this <code>JoinRowSetImpl</code> object
1546+ * @return a Java input stream that delivers the database column value
1547+ * as a stream of two-byte Unicode characters. If the value is
1548+ * SQL <code>NULL</code>, the result is <code>null</code>.
1549+ * @throws SQLException if the given column name does not match one of
1550+ * this rowset's column names or the cursor is not on one of
1551+ * this rowset's rows or its insert row
1552+ * @deprecated use the method <code>getCharacterStream</code> instead
1553+ */
1554+ public java.io.InputStream getUnicodeStream(String columnName) throws SQLException {
1555+ return crsInternal.getUnicodeStream(columnName);
1556+ }
1557+
1558+ /**
1559+ * Retrieves the value stored in the designated column
1560+ * of the current row as a <code>java.io.InputStream</code> object.
1561+ * A column value can be retrieved as a stream of uninterpreted bytes
1562+ * and then read in chunks from the stream. This method is particularly
1563+ * suitable for retrieving large <code>LONGVARBINARY</code> values.
1564+ *
1565+ * <P><B>Note:</B> All the data in the returned stream must
1566+ * be read prior to getting the value of any other column. The
1567+ * next call to a get method implicitly closes the stream.
1568+ *
1569+ * @param columnName a <code>String</code> object giving the SQL name of
1570+ * a column in this <code>JoinRowSetImpl</code> object
1571+ * @return a Java input stream that delivers the database column value
1572+ * as a stream of uninterpreted bytes. If the value is SQL
1573+ * <code>NULL</code>, the result is <code>null</code>.
1574+ * @throws SQLException if the given column name does not match one of
1575+ * this rowset's column names or the cursor is not on one of
1576+ * this rowset's rows or its insert row
1577+ */
1578+ public java.io.InputStream getBinaryStream(String columnName) throws SQLException {
1579+ return crsInternal.getBinaryStream(columnName);
1580+ }
1581+
1582+ /* The first warning reported by calls on this <code>JoinRowSetImpl</code>
1583+ * object is returned. Subsequent <code>JoinRowSetImpl</code> warnings will
1584+ * be chained to this <code>SQLWarning</code>.
1585+ *
1586+ * <P>The warning chain is automatically cleared each time a new
1587+ * row is read.
1588+ *
1589+ * <P><B>Note:</B> This warning chain only covers warnings caused
1590+ * by <code>ResultSet</code> methods. Any warning caused by statement
1591+ * methods (such as reading OUT parameters) will be chained on the
1592+ * <code>Statement</code> object.
1593+ *
1594+ * @return the first SQLWarning or null
1595+ * @throws UnsupportedOperationException if this method is called
1596+ */
1597+ public SQLWarning getWarnings() {
1598+ return crsInternal.getWarnings();
1599+ }
1600+
1601+ /**
1602+ * Throws an <code>UnsupportedOperationException</code> if called.
1603+ * <P>
1604+ * After a call to this method, the <code>getWarnings</code> method
1605+ * returns <code>null</code> until a new warning is reported for this
1606+ * <code>JoinRowSetImpl</code> object.
1607+ *
1608+ * @throws UnsupportedOperationException if this method is called
1609+ */
1610+ public void clearWarnings() {
1611+ crsInternal.clearWarnings();
1612+ }
1613+
1614+ /**
1615+ * Retrieves the name of the SQL cursor used by this
1616+ * <code>JoinRowSetImpl</code> object.
1617+ *
1618+ * <P>In SQL, a result table is retrieved through a cursor that is
1619+ * named. The current row of a result can be updated or deleted
1620+ * using a positioned update/delete statement that references the
1621+ * cursor name. To insure that the cursor has the proper isolation
1622+ * level to support an update operation, the cursor's <code>SELECT</code>
1623+ * statement should be of the form 'select for update'. If the 'for update'
1624+ * clause is omitted, positioned updates may fail.
1625+ *
1626+ * <P>JDBC supports this SQL feature by providing the name of the
1627+ * SQL cursor used by a <code>ResultSet</code> object. The current row
1628+ * of a result set is also the current row of this SQL cursor.
1629+ *
1630+ * <P><B>Note:</B> If positioned updates are not supported, an
1631+ * <code>SQLException</code> is thrown.
1632+ *
1633+ * @return the SQL cursor name for this <code>JoinRowSetImpl</code> object's
1634+ * cursor
1635+ * @throws SQLException if an error occurs
1636+ */
1637+ public String getCursorName() throws SQLException {
1638+ return crsInternal.getCursorName();
1639+ }
1640+
1641+ /**
1642+ * Retrieves the <code>ResultSetMetaData</code> object that contains
1643+ * information about this <code>CachedRowsSet</code> object. The
1644+ * information includes the number of columns, the data type for each
1645+ * column, and other properties for each column.
1646+ *
1647+ * @return the <code>ResultSetMetaData</code> object that describes this
1648+ * <code>JoinRowSetImpl</code> object's columns
1649+ * @throws SQLException if an error occurs
1650+ */
1651+ public ResultSetMetaData getMetaData() throws SQLException {
1652+ return crsInternal.getMetaData();
1653+ }
1654+
1655+ /**
1656+ * Retrieves the value of the designated column in the current row
1657+ * of this <code>JoinRowSetImpl</code> object as an
1658+ * <code>Object</code> value.
1659+ * <P>
1660+ * The type of the <code>Object</code> will be the default
1661+ * Java object type corresponding to the column's SQL type,
1662+ * following the mapping for built-in types specified in the JDBC
1663+ * specification.
1664+ * <P>
1665+ * This method may also be used to read datatabase-specific
1666+ * abstract data types.
1667+ * <P>
1668+ * This implementation of the method <code>getObject</code> extends its
1669+ * behavior so that it gets the attributes of an SQL structured type as
1670+ * as an array of <code>Object</code> values. This method also custom
1671+ * maps SQL user-defined types to classes in the Java programming language.
1672+ * When the specified column contains
1673+ * a structured or distinct value, the behavior of this method is as
1674+ * if it were a call to the method <code>getObject(columnIndex,
1675+ * this.getStatement().getConnection().getTypeMap())</code>.
1676+ *
1677+ * @param columnIndex the first column is <code>1</code>, the second
1678+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1679+ * and equal to or less than the number of columns in the rowset
1680+ * @return a <code>java.lang.Object</code> holding the column value;
1681+ * if the value is SQL <code>NULL</code>, the result is <code>null</code>
1682+ * @throws SQLException if the given column index is out of bounds,
1683+ * the cursor is not on a valid row, or there is a problem getting
1684+ * the <code>Class</code> object for a custom mapping
1685+ * @since 1.2
1686+ */
1687+ public Object getObject(int columnIndex) throws SQLException {
1688+ return crsInternal.getObject(columnIndex);
1689+ }
1690+
1691+ /**
1692+ * Retrieves the value of the designated column in the current row
1693+ * of this <code>JoinRowSetImpl</code> object as an
1694+ * <code>Object</code> value.
1695+ * <P>
1696+ * The type of the <code>Object</code> will be the default
1697+ * Java object type corresponding to the column's SQL type,
1698+ * following the mapping for built-in types specified in the JDBC
1699+ * specification.
1700+ * <P>
1701+ * This method may also be used to read datatabase-specific
1702+ * abstract data types.
1703+ * <P>
1704+ * This implementation of the method <code>getObject</code> extends its
1705+ * behavior so that it gets the attributes of an SQL structured type as
1706+ * as an array of <code>Object</code> values. This method also custom
1707+ * maps SQL user-defined types to classes
1708+ * in the Java programming language. When the specified column contains
1709+ * a structured or distinct value, the behavior of this method is as
1710+ * if it were a call to the method <code>getObject(columnIndex,
1711+ * this.getStatement().getConnection().getTypeMap())</code>.
1712+ *
1713+ * @param columnIndex the first column is <code>1</code>, the second
1714+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1715+ * and equal to or less than the number of columns in the rowset
1716+ * @param map a <code>java.util.Map</code> object showing the mapping
1717+ * from SQL type names to classes in the Java programming
1718+ * language
1719+ * @return a <code>java.lang.Object</code> holding the column value;
1720+ * if the value is SQL <code>NULL</code>, the result is
1721+ * <code>null</code>
1722+ * @throws SQLException if (1) the given column name does not match
1723+ * one of this rowset's column names, (2) the cursor is not
1724+ * on a valid row, or (3) there is a problem getting
1725+ * the <code>Class</code> object for a custom mapping
1726+ */
1727+ public Object getObject(int columnIndex,
1728+ java.util.Map<String,Class<?>> map)
1729+ throws SQLException {
1730+ return crsInternal.getObject(columnIndex, map);
1731+ }
1732+
1733+ /**
1734+ * Retrieves the value of the designated column in the current row
1735+ * of this <code>JoinRowSetImpl</code> object as an
1736+ * <code>Object</code> value.
1737+ * <P>
1738+ * The type of the <code>Object</code> will be the default
1739+ * Java object type corresponding to the column's SQL type,
1740+ * following the mapping for built-in types specified in the JDBC
1741+ * specification.
1742+ * <P>
1743+ * This method may also be used to read datatabase-specific
1744+ * abstract data types.
1745+ * <P>
1746+ * This implementation of the method <code>getObject</code> extends its
1747+ * behavior so that it gets the attributes of an SQL structured type as
1748+ * as an array of <code>Object</code> values. This method also custom
1749+ * maps SQL user-defined types to classes
1750+ * in the Java programming language. When the specified column contains
1751+ * a structured or distinct value, the behavior of this method is as
1752+ * if it were a call to the method <code>getObject(columnIndex,
1753+ * this.getStatement().getConnection().getTypeMap())</code>.
1754+ *
1755+ * @param columnName a <code>String</code> object that must match the
1756+ * SQL name of a column in this rowset, ignoring case
1757+ * @return a <code>java.lang.Object</code> holding the column value;
1758+ * if the value is SQL <code>NULL</code>, the result is
1759+ * <code>null</code>
1760+ * @throws SQLException if (1) the given column name does not match
1761+ * one of this rowset's column names, (2) the cursor is not
1762+ * on a valid row, or (3) there is a problem getting
1763+ * the <code>Class</code> object for a custom mapping
1764+ */
1765+ public Object getObject(String columnName) throws SQLException {
1766+ return crsInternal.getObject(columnName);
1767+ }
1768+
1769+ /**
1770+ * Retrieves the value of the designated column in this
1771+ * <code>JoinRowSetImpl</code> object as an <code>Object</code> in
1772+ * the Java programming lanugage, using the given
1773+ * <code>java.util.Map</code> object to custom map the value if
1774+ * appropriate.
1775+ *
1776+ * @param columnName a <code>String</code> object that must match the
1777+ * SQL name of a column in this rowset, ignoring case
1778+ * @param map a <code>java.util.Map</code> object showing the mapping
1779+ * from SQL type names to classes in the Java programming
1780+ * language
1781+ * @return an <code>Object</code> representing the SQL value
1782+ * @throws SQLException if the given column index is out of bounds or
1783+ * the cursor is not on one of this rowset's rows or its
1784+ * insert row
1785+ */
1786+ public Object getObject(String columnName,
1787+ java.util.Map<String,Class<?>> map)
1788+ throws SQLException {
1789+ return crsInternal.getObject(columnName, map);
1790+ }
1791+
1792+ /**
1793+ * Retrieves the value stored in the designated column
1794+ * of the current row as a <code>java.io.Reader</code> object.
1795+ *
1796+ * <P><B>Note:</B> All the data in the returned stream must
1797+ * be read prior to getting the value of any other column. The
1798+ * next call to a <code>getXXX</code> method implicitly closes the stream.
1799+ *
1800+ * @param columnIndex the first column is <code>1</code>, the second
1801+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1802+ * and equal to or less than the number of columns in the rowset
1803+ * @return a Java character stream that delivers the database column value
1804+ * as a <code>java.io.Reader</code> object. If the value is
1805+ * SQL <code>NULL</code>, the result is <code>null</code>.
1806+ * @throws SQLException if the given column index is out of bounds,
1807+ * the cursor is not on a valid row, or there is a type mismatch
1808+ */
1809+ public java.io.Reader getCharacterStream(int columnIndex) throws SQLException {
1810+ return crsInternal.getCharacterStream(columnIndex);
1811+ }
1812+
1813+ /**
1814+ * Retrieves the value stored in the designated column
1815+ * of the current row as a <code>java.io.Reader</code> object.
1816+ *
1817+ * <P><B>Note:</B> All the data in the returned stream must
1818+ * be read prior to getting the value of any other column. The
1819+ * next call to a <code>getXXX</code> method implicitly closes the stream.
1820+ *
1821+ * @param columnName a <code>String</code> object giving the SQL name of
1822+ * a column in this <code>JoinRowSetImpl</code> object
1823+ * @return a Java input stream that delivers the database column value
1824+ * as a stream of two-byte Unicode characters. If the value is
1825+ * SQL <code>NULL</code>, the result is <code>null</code>.
1826+ * @throws SQLException if the given column index is out of bounds,
1827+ * the cursor is not on a valid row, or there is a type mismatch
1828+ */
1829+ public java.io.Reader getCharacterStream(String columnName) throws SQLException {
1830+ return crsInternal.getCharacterStream(columnName);
1831+ }
1832+
1833+ /**
1834+ * Retrieves the value of the designated column in the current row
1835+ * of this <code>JoinRowSetImpl</code> object as a
1836+ * <code>java.math.BigDecimal</code> object.
1837+ *
1838+ * @param columnIndex the first column is <code>1</code>, the second
1839+ * is <code>2</code>, and so on; must be <code>1</code> or larger
1840+ * and equal to or less than the number of columns in the rowset
1841+ * @return a <code>java.math.BigDecimal</code> value with full precision;
1842+ * if the value is SQL <code>NULL</code>, the result is <code>null</code>
1843+ * @throws SQLException if the given column index is out of bounds,
1844+ * the cursor is not on a valid row, or this method fails
1845+ */
1846+ public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
1847+ return crsInternal.getBigDecimal(columnIndex);
1848+ }
1849+
1850+ /**
1851+ * Retrieves the value of the designated column in the current row
1852+ * of this <code>JoinRowSetImpl</code> object as a
1853+ * <code>java.math.BigDecimal</code> object.
1854+ *
1855+ * @param columnName a <code>String</code> object that must match the
1856+ * SQL name of a column in this rowset, ignoring case
1857+ * @return a <code>java.math.BigDecimal</code> value with full precision;
1858+ * if the value is SQL <code>NULL</code>, the result is <code>null</code>
1859+ * @throws SQLException if the given column index is out of bounds,
1860+ * the cursor is not on a valid row, or this method fails
1861+ */
1862+ public BigDecimal getBigDecimal(String columnName) throws SQLException {
1863+ return crsInternal.getBigDecimal(columnName);
1864+ }
1865+
1866+ /**
1867+ * Returns the number of rows in this <code>JoinRowSetImpl</code> object.
1868+ *
1869+ * @return number of rows in the rowset
1870+ */
1871+ public int size() {
1872+ return crsInternal.size();
1873+ }
1874+
1875+ /**
1876+ * Indicates whether the cursor is before the first row in this
1877+ * <code>JoinRowSetImpl</code> object.
1878+ *
1879+ * @return <code>true</code> if the cursor is before the first row;
1880+ * <code>false</code> otherwise or if the rowset contains no rows
1881+ * @throws SQLException if an error occurs
1882+ */
1883+ public boolean isBeforeFirst() throws SQLException {
1884+ return crsInternal.isBeforeFirst();
1885+ }
1886+
1887+ /**
1888+ * Indicates whether the cursor is after the last row in this
1889+ * <code>JoinRowSetImpl</code> object.
1890+ *
1891+ * @return <code>true</code> if the cursor is after the last row;
1892+ * <code>false</code> otherwise or if the rowset contains no rows
1893+ * @throws SQLException if an error occurs
1894+ */
1895+ public boolean isAfterLast() throws SQLException {
1896+ return crsInternal.isAfterLast();
1897+ }
1898+
1899+ /**
1900+ * Indicates whether the cursor is on the first row in this
1901+ * <code>JoinRowSetImpl</code> object.
1902+ *
1903+ * @return <code>true</code> if the cursor is on the first row;
1904+ * <code>false</code> otherwise or if the rowset contains no rows
1905+ * @throws SQLException if an error occurs
1906+ */
1907+ public boolean isFirst() throws SQLException {
1908+ return crsInternal.isFirst();
1909+ }
1910+
1911+ /**
1912+ * Indicates whether the cursor is on the last row in this
1913+ * <code>JoinRowSetImpl</code> object.
1914+ * <P>
1915+ * Note: Calling the method <code>isLast</code> may be expensive
1916+ * because the JDBC driver might need to fetch ahead one row in order
1917+ * to determine whether the current row is the last row in this rowset.
1918+ *
1919+ * @return <code>true</code> if the cursor is on the last row;
1920+ * <code>false</code> otherwise or if this rowset contains no rows
1921+ * @throws SQLException if an error occurs
1922+ */
1923+ public boolean isLast() throws SQLException {
1924+ return crsInternal.isLast();
1925+ }
1926+
1927+ /**
1928+ * Moves this <code>JoinRowSetImpl</code> object's cursor to the front of
1929+ * the rowset, just before the first row. This method has no effect if
1930+ * this rowset contains no rows.
1931+ *
1932+ * @throws SQLException if an error occurs or the type of this rowset
1933+ * is <code>ResultSet.TYPE_FORWARD_ONLY</code>
1934+ */
1935+ public void beforeFirst() throws SQLException {
1936+ crsInternal.beforeFirst();
1937+ }
1938+
1939+ /**
1940+ * Moves this <code>JoinRowSetImpl</code> object's cursor to the end of
1941+ * the rowset, just after the last row. This method has no effect if
1942+ * this rowset contains no rows.
1943+ *
1944+ * @throws SQLException if an error occurs
1945+ */
1946+ public void afterLast() throws SQLException {
1947+ crsInternal.afterLast();
1948+ }
1949+
1950+ /**
1951+ * Moves this <code>JoinRowSetImpl</code> object's cursor to the first row
1952+ * and returns <code>true</code> if the operation was successful. This
1953+ * method also notifies registered listeners that the cursor has moved.
1954+ *
1955+ * @return <code>true</code> if the cursor is on a valid row;
1956+ * <code>false</code> otherwise or if there are no rows in this
1957+ * <code>JoinRowSetImpl</code> object
1958+ * @throws SQLException if the type of this rowset
1959+ * is <code>ResultSet.TYPE_FORWARD_ONLY</code>
1960+ */
1961+ public boolean first() throws SQLException {
1962+ return crsInternal.first();
1963+ }
1964+
1965+
1966+ /**
1967+ * Moves this <code>JoinRowSetImpl</code> object's cursor to the last row
1968+ * and returns <code>true</code> if the operation was successful. This
1969+ * method also notifies registered listeners that the cursor has moved.
1970+ *
1971+ * @return <code>true</code> if the cursor is on a valid row;
1972+ * <code>false</code> otherwise or if there are no rows in this
1973+ * <code>JoinRowSetImpl</code> object
1974+ * @throws SQLException if the type of this rowset
1975+ * is <code>ResultSet.TYPE_FORWARD_ONLY</code>
1976+ */
1977+ public boolean last() throws SQLException {
1978+ return crsInternal.last();
1979+ }
1980+
1981+ /**
1982+ * Returns the number of the current row in this <code>JoinRowSetImpl</code>
1983+ * object. The first row is number 1, the second number 2, and so on.
1984+ *
1985+ * @return the number of the current row; <code>0</code> if there is no
1986+ * current row
1987+ * @throws SQLException if an error occurs
1988+ */
1989+ public int getRow() throws SQLException {
1990+ return crsInternal.getRow();
1991+ }
1992+
1993+ /**
1994+ * Moves this <code>JoinRowSetImpl</code> object's cursor to the row number
1995+ * specified.
1996+ *
1997+ * <p>If the number is positive, the cursor moves to an absolute row with
1998+ * respect to the beginning of the rowset. The first row is row 1, the second
1999+ * is row 2, and so on. For example, the following command, in which
2000+ * <code>crs</code> is a <code>JoinRowSetImpl</code> object, moves the cursor
2001+ * to the fourth row, starting from the beginning of the rowset.
2002+ * <PRE><code>
2003+ *
2004+ * crs.absolute(4);
2005+ *
2006+ * </code> </PRE>
2007+ * <P>
2008+ * If the number is negative, the cursor moves to an absolute row position
2009+ * with respect to the end of the rowset. For example, calling
2010+ * <code>absolute(-1)</code> positions the cursor on the last row,
2011+ * <code>absolute(-2)</code> moves it on the next-to-last row, and so on.
2012+ * If the <code>JoinRowSetImpl</code> object <code>crs</code> has five rows,
2013+ * the following command moves the cursor to the fourth-to-last row, which
2014+ * in the case of a rowset with five rows, is also the second row, counting
2015+ * from the beginning.
2016+ * <PRE><code>
2017+ *
2018+ * crs.absolute(-4);
2019+ *
2020+ * </code> </PRE>
2021+ *
2022+ * If the number specified is larger than the number of rows, the cursor
2023+ * will move to the position after the last row. If the number specified
2024+ * would move the cursor one or more rows before the first row, the cursor
2025+ * moves to the position before the first row.
2026+ * <P>
2027+ * Note: Calling <code>absolute(1)</code> is the same as calling the
2028+ * method <code>first()</code>. Calling <code>absolute(-1)</code> is the
2029+ * same as calling <code>last()</code>.
2030+ *
2031+ * @param row a positive number to indicate the row, starting row numbering from
2032+ * the first row, which is <code>1</code>; a negative number to indicate
2033+ * the row, starting row numbering from the last row, which is
2034+ * <code>-1</code>; must not be <code>0</code>
2035+ * @return <code>true</code> if the cursor is on the rowset; <code>false</code>
2036+ * otherwise
2037+ * @throws SQLException if the given cursor position is <code>0</code> or the
2038+ * type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code>
2039+ */
2040+ public boolean absolute(int row) throws SQLException {
2041+ return crsInternal.absolute(row);
2042+ }
2043+
2044+ /**
2045+ * Moves the cursor the specified number of rows from the current
2046+ * position, with a positive number moving it forward and a
2047+ * negative number moving it backward.
2048+ * <P>
2049+ * If the number is positive, the cursor moves the specified number of
2050+ * rows toward the end of the rowset, starting at the current row.
2051+ * For example, the following command, in which
2052+ * <code>crs</code> is a <code>JoinRowSetImpl</code> object with 100 rows,
2053+ * moves the cursor forward four rows from the current row. If the
2054+ * current row is 50, the cursor would move to row 54.
2055+ * <PRE><code>
2056+ *
2057+ * crs.relative(4);
2058+ *
2059+ * </code> </PRE>
2060+ * <P>
2061+ * If the number is negative, the cursor moves back toward the beginning
2062+ * the specified number of rows, starting at the current row.
2063+ * For example, calling the method
2064+ * <code>absolute(-1)</code> positions the cursor on the last row,
2065+ * <code>absolute(-2)</code> moves it on the next-to-last row, and so on.
2066+ * If the <code>JoinRowSetImpl</code> object <code>crs</code> has five rows,
2067+ * the following command moves the cursor to the fourth-to-last row, which
2068+ * in the case of a rowset with five rows, is also the second row
2069+ * from the beginning.
2070+ * <PRE><code>
2071+ *
2072+ * crs.absolute(-4);
2073+ *
2074+ * </code> </PRE>
2075+ *
2076+ * If the number specified is larger than the number of rows, the cursor
2077+ * will move to the position after the last row. If the number specified
2078+ * would move the cursor one or more rows before the first row, the cursor
2079+ * moves to the position before the first row. In both cases, this method
2080+ * throws an <code>SQLException</code>.
2081+ * <P>
2082+ * Note: Calling <code>absolute(1)</code> is the same as calling the
2083+ * method <code>first()</code>. Calling <code>absolute(-1)</code> is the
2084+ * same as calling <code>last()</code>. Calling <code>relative(0)</code>
2085+ * is valid, but it does not change the cursor position.
2086+ *
2087+ * @param rows an <code>int</code> indicating the number of rows to move
2088+ * the cursor, starting at the current row; a positive number
2089+ * moves the cursor forward; a negative number moves the cursor
2090+ * backward; must not move the cursor past the valid
2091+ * rows
2092+ * @return <code>true</code> if the cursor is on a row in this
2093+ * <code>JoinRowSetImpl</code> object; <code>false</code>
2094+ * otherwise
2095+ * @throws SQLException if there are no rows in this rowset, the cursor is
2096+ * positioned either before the first row or after the last row, or
2097+ * the rowset is type <code>ResultSet.TYPE_FORWARD_ONLY</code>
2098+ */
2099+ public boolean relative(int rows) throws SQLException {
2100+ return crsInternal.relative(rows);
2101+ }
2102+
2103+ /**
2104+ * Moves this <code>JoinRowSetImpl</code> object's cursor to the
2105+ * previous row and returns <code>true</code> if the cursor is on
2106+ * a valid row or <code>false</code> if it is not.
2107+ * This method also notifies all listeners registered with this
2108+ * <code>JoinRowSetImpl</code> object that its cursor has moved.
2109+ * <P>
2110+ * Note: calling the method <code>previous()</code> is not the same
2111+ * as calling the method <code>relative(-1)</code>. This is true
2112+ * because it is possible to call <code>previous()</code> from the insert
2113+ * row, from after the last row, or from the current row, whereas
2114+ * <code>relative</code> may only be called from the current row.
2115+ * <P>
2116+ * The method <code>previous</code> may used in a <code>while</code>
2117+ * loop to iterate through a rowset starting after the last row
2118+ * and moving toward the beginning. The loop ends when <code>previous</code>
2119+ * returns <code>false</code>, meaning that there are no more rows.
2120+ * For example, the following code fragment retrieves all the data in
2121+ * the <code>JoinRowSetImpl</code> object <code>crs</code>, which has
2122+ * three columns. Note that the cursor must initially be positioned
2123+ * after the last row so that the first call to the method
2124+ * <code>previous</code> places the cursor on the last line.
2125+ * <PRE> <code>
2126+ *
2127+ * crs.afterLast();
2128+ * while (previous()) {
2129+ * String name = crs.getString(1);
2130+ * int age = crs.getInt(2);
2131+ * short ssn = crs.getShort(3);
2132+ * System.out.println(name + " " + age + " " + ssn);
2133+ * }
2134+ *
2135+ * </code> </PRE>
2136+ * This method throws an <code>SQLException</code> if the cursor is not
2137+ * on a row in the rowset, before the first row, or after the last row.
2138+ *
2139+ * @return <code>true</code> if the cursor is on a valid row;
2140+ * <code>false</code> if it is before the first row or after the
2141+ * last row
2142+ * @throws SQLException if the cursor is not on a valid position or the
2143+ * type of this rowset is <code>ResultSet.TYPE_FORWARD_ONLY</code>
2144+ */
2145+ public boolean previous() throws SQLException {
2146+ return crsInternal.previous();
2147+ }
2148+
2149+ /**
2150+ * Returns the index of the column whose name is <i>columnName</i>.
2151+ *
2152+ * @param columnName a <code>String</code> object giving the name of the
2153+ * column for which the index will be returned; the name must
2154+ * match the SQL name of a column in this <code>JoinRowSet</code>
2155+ * object, ignoring case
2156+ * @throws SQLException if the given column name does not match one of the
2157+ * column names for this <code>JoinRowSet</code> object
2158+ */
2159+ public int findColumn(String columnName) throws SQLException {
2160+ return crsInternal.findColumn(columnName);
2161+ }
2162+
2163+ /**
2164+ * Indicates whether the current row of this <code>JoinRowSetImpl</code>
2165+ * object has been updated. The value returned
2166+ * depends on whether this rowset can detect updates: <code>false</code>
2167+ * will always be returned if it does not detect updates.
2168+ *
2169+ * @return <code>true</code> if the row has been visibly updated
2170+ * by the owner or another and updates are detected;
2171+ * <code>false</code> otherwise
2172+ * @throws SQLException if the cursor is on the insert row or not
2173+ * on a valid row
2174+ *
2175+ * @see DatabaseMetaData#updatesAreDetected
2176+ */
2177+ public boolean rowUpdated() throws SQLException {
2178+ return crsInternal.rowUpdated();
2179+ }
2180+
2181+ /**
2182+ * Indicates whether the designated column of the current row of
2183+ * this <code>JoinRowSetImpl</code> object has been updated. The
2184+ * value returned depends on whether this rowset can detcted updates:
2185+ * <code>false</code> will always be returned if it does not detect updates.
2186+ *
2187+ * @return <code>true</code> if the column updated
2188+ * <code>false</code> otherwse
2189+ * @throws SQLException if the cursor is on the insert row or not
2190+ * on a valid row
2191+ * @see DatabaseMetaData#updatesAreDetected
2192+ */
2193+ public boolean columnUpdated(int indexColumn) throws SQLException {
2194+ return crsInternal.columnUpdated(indexColumn);
2195+ }
2196+
2197+ /**
2198+ * Indicates whether the current row has been inserted. The value returned
2199+ * depends on whether or not the rowset can detect visible inserts.
2200+ *
2201+ * @return <code>true</code> if a row has been inserted and inserts are detected;
2202+ * <code>false</code> otherwise
2203+ * @throws SQLException if the cursor is on the insert row or not
2204+ * not on a valid row
2205+ *
2206+ * @see DatabaseMetaData#insertsAreDetected
2207+ */
2208+ public boolean rowInserted() throws SQLException {
2209+ return crsInternal.rowInserted();
2210+ }
2211+
2212+ /**
2213+ * Indicates whether the current row has been deleted. A deleted row
2214+ * may leave a visible "hole" in a rowset. This method can be used to
2215+ * detect such holes if the rowset can detect deletions. This method
2216+ * will always return <code>false</code> if this rowset cannot detect
2217+ * deletions.
2218+ *
2219+ * @return <code>true</code> if (1)the current row is blank, indicating that
2220+ * the row has been deleted, and (2)deletions are detected;
2221+ * <code>false</code> otherwise
2222+ * @throws SQLException if the cursor is on a valid row in this rowset
2223+ * @see DatabaseMetaData#deletesAreDetected
2224+ */
2225+ public boolean rowDeleted() throws SQLException {
2226+ return crsInternal.rowDeleted();
2227+ }
2228+
2229+ /**
2230+ * Sets the designated nullable column in the current row or the
2231+ * insert row of this <code>JoinRowSetImpl</code> object with
2232+ * <code>null</code> value.
2233+ * <P>
2234+ * This method updates a column value in the current row or the insert
2235+ * row of this rowset; however, another method must be called to complete
2236+ * the update process. If the cursor is on a row in the rowset, the
2237+ * method {@link #updateRow} must be called to mark the row as updated
2238+ * and to notify listeners that the row has changed.
2239+ * If the cursor is on the insert row, the method {@link #insertRow}
2240+ * must be called to insert the new row into this rowset and to notify
2241+ * listeners that a row has changed.
2242+ * <P>
2243+ * In order to propagate updates in this rowset to the underlying
2244+ * data source, an application must call the method acceptChanges
2245+ * after it calls either <code>updateRow</code> or <code>insertRow</code>.
2246+ *
2247+ * @param columnIndex the first column is <code>1</code>, the second
2248+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2249+ * and equal to or less than the number of columns in this rowset
2250+ * @throws SQLException if (1) the given column index is out of bounds,
2251+ * (2) the cursor is not on one of this rowset's rows or its
2252+ * insert row, or (3) this rowset is
2253+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2254+ */
2255+ public void updateNull(int columnIndex) throws SQLException {
2256+ crsInternal.updateNull(columnIndex);
2257+ }
2258+
2259+ /**
2260+ * Sets the designated column in either the current row or the insert
2261+ * row of this <code>JoinRowSetImpl</code> object with the given
2262+ * <code>boolean</code> value.
2263+ * <P>
2264+ * This method updates a column value in the current row or the insert
2265+ * row of this rowset, but it does not update the database.
2266+ * If the cursor is on a row in the rowset, the
2267+ * method {@link #updateRow} must be called to update the database.
2268+ * If the cursor is on the insert row, the method {@link #insertRow}
2269+ * must be called, which will insert the new row into both this rowset
2270+ * and the database. Both of these methods must be called before the
2271+ * cursor moves to another row.
2272+ *
2273+ * @param columnIndex the first column is <code>1</code>, the second
2274+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2275+ * and equal to or less than the number of columns in this rowset
2276+ * @param x the new column value
2277+ * @throws SQLException if (1) the given column index is out of bounds,
2278+ * (2) the cursor is not on one of this rowset's rows or its
2279+ * insert row, or (3) this rowset is
2280+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2281+ */
2282+ public void updateBoolean(int columnIndex, boolean x) throws SQLException {
2283+ crsInternal.updateBoolean(columnIndex, x);
2284+ }
2285+
2286+ /**
2287+ * Sets the designated column in either the current row or the insert
2288+ * row of this <code>JoinRowSetImpl</code> object with the given
2289+ * <code>byte</code> value.
2290+ * <P>
2291+ * This method updates a column value in the current row or the insert
2292+ * row of this rowset, but it does not update the database.
2293+ * If the cursor is on a row in the rowset, the
2294+ * method {@link #updateRow} must be called to update the database.
2295+ * If the cursor is on the insert row, the method {@link #insertRow}
2296+ * must be called, which will insert the new row into both this rowset
2297+ * and the database. Both of these methods must be called before the
2298+ * cursor moves to another row.
2299+ *
2300+ * @param columnIndex the first column is <code>1</code>, the second
2301+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2302+ * and equal to or less than the number of columns in this rowset
2303+ * @param x the new column value
2304+ * @throws SQLException if (1) the given column index is out of bounds,
2305+ * (2) the cursor is not on one of this rowset's rows or its
2306+ * insert row, or (3) this rowset is
2307+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2308+ */
2309+ public void updateByte(int columnIndex, byte x) throws SQLException {
2310+ crsInternal.updateByte(columnIndex, x);
2311+ }
2312+
2313+ /**
2314+ * Sets the designated column in either the current row or the insert
2315+ * row of this <code>JoinRowSetImpl</code> object with the given
2316+ * <code>short</code> value.
2317+ * <P>
2318+ * This method updates a column value in the current row or the insert
2319+ * row of this rowset, but it does not update the database.
2320+ * If the cursor is on a row in the rowset, the
2321+ * method {@link #updateRow} must be called to update the database.
2322+ * If the cursor is on the insert row, the method {@link #insertRow}
2323+ * must be called, which will insert the new row into both this rowset
2324+ * and the database. Both of these methods must be called before the
2325+ * cursor moves to another row.
2326+ *
2327+ * @param columnIndex the first column is <code>1</code>, the second
2328+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2329+ * and equal to or less than the number of columns in this rowset
2330+ * @param x the new column value
2331+ * @throws SQLException if (1) the given column index is out of bounds,
2332+ * (2) the cursor is not on one of this rowset's rows or its
2333+ * insert row, or (3) this rowset is
2334+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2335+ */
2336+ public void updateShort(int columnIndex, short x) throws SQLException {
2337+ crsInternal.updateShort(columnIndex, x);
2338+ }
2339+
2340+ /**
2341+ * Sets the designated column in either the current row or the insert
2342+ * row of this <code>JoinRowSetImpl</code> object with the given
2343+ * <code>int</code> value.
2344+ * <P>
2345+ * This method updates a column value in the current row or the insert
2346+ * row of this rowset, but it does not update the database.
2347+ * If the cursor is on a row in the rowset, the
2348+ * method {@link #updateRow} must be called to update the database.
2349+ * If the cursor is on the insert row, the method {@link #insertRow}
2350+ * must be called, which will insert the new row into both this rowset
2351+ * and the database. Both of these methods must be called before the
2352+ * cursor moves to another row.
2353+ *
2354+ * @param columnIndex the first column is <code>1</code>, the second
2355+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2356+ * and equal to or less than the number of columns in this rowset
2357+ * @param x the new column value
2358+ * @throws SQLException if (1) the given column index is out of bounds,
2359+ * (2) the cursor is not on one of this rowset's rows or its
2360+ * insert row, or (3) this rowset is
2361+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2362+ */
2363+ public void updateInt(int columnIndex, int x) throws SQLException {
2364+ crsInternal.updateInt(columnIndex, x);
2365+ }
2366+
2367+ /**
2368+ * Sets the designated column in either the current row or the insert
2369+ * row of this <code>JoinRowSetImpl</code> object with the given
2370+ * <code>long</code> value.
2371+ * <P>
2372+ * This method updates a column value in the current row or the insert
2373+ * row of this rowset, but it does not update the database.
2374+ * If the cursor is on a row in the rowset, the
2375+ * method {@link #updateRow} must be called to update the database.
2376+ * If the cursor is on the insert row, the method {@link #insertRow}
2377+ * must be called, which will insert the new row into both this rowset
2378+ * and the database. Both of these methods must be called before the
2379+ * cursor moves to another row.
2380+ *
2381+ * @param columnIndex the first column is <code>1</code>, the second
2382+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2383+ * and equal to or less than the number of columns in this rowset
2384+ * @param x the new column value
2385+ * @throws SQLException if (1) the given column index is out of bounds,
2386+ * (2) the cursor is not on one of this rowset's rows or its
2387+ * insert row, or (3) this rowset is
2388+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2389+ */
2390+ public void updateLong(int columnIndex, long x) throws SQLException {
2391+ crsInternal.updateLong(columnIndex, x);
2392+ }
2393+
2394+ /**
2395+ * Sets the designated column in either the current row or the insert
2396+ * row of this <code>JoinRowSetImpl</code> object with the given
2397+ * <code>float</code> value.
2398+ * <P>
2399+ * This method updates a column value in the current row or the insert
2400+ * row of this rowset, but it does not update the database.
2401+ * If the cursor is on a row in the rowset, the
2402+ * method {@link #updateRow} must be called to update the database.
2403+ * If the cursor is on the insert row, the method {@link #insertRow}
2404+ * must be called, which will insert the new row into both this rowset
2405+ * and the database. Both of these methods must be called before the
2406+ * cursor moves to another row.
2407+ *
2408+ * @param columnIndex the first column is <code>1</code>, the second
2409+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2410+ * and equal to or less than the number of columns in this rowset
2411+ * @param x the new column value
2412+ * @throws SQLException if (1) the given column index is out of bounds,
2413+ * (2) the cursor is not on one of this rowset's rows or its
2414+ * insert row, or (3) this rowset is
2415+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2416+ */
2417+ public void updateFloat(int columnIndex, float x) throws SQLException {
2418+ crsInternal.updateFloat(columnIndex, x);
2419+ }
2420+
2421+ /**
2422+ * Sets the designated column in either the current row or the insert
2423+ * row of this <code>JoinRowSetImpl</code> object with the given
2424+ * <code>double</code> value.
2425+ *
2426+ * This method updates a column value in either the current row or
2427+ * the insert row of this rowset, but it does not update the
2428+ * database. If the cursor is on a row in the rowset, the
2429+ * method {@link #updateRow} must be called to update the database.
2430+ * If the cursor is on the insert row, the method {@link #insertRow}
2431+ * must be called, which will insert the new row into both this rowset
2432+ * and the database. Both of these methods must be called before the
2433+ * cursor moves to another row.
2434+ *
2435+ * @param columnIndex the first column is <code>1</code>, the second
2436+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2437+ * and equal to or less than the number of columns in this rowset
2438+ * @param x the new column value
2439+ * @throws SQLException if (1) the given column index is out of bounds,
2440+ * (2) the cursor is not on one of this rowset's rows or its
2441+ * insert row, or (3) this rowset is
2442+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2443+ */
2444+ public void updateDouble(int columnIndex, double x) throws SQLException {
2445+ crsInternal.updateDouble(columnIndex, x);
2446+ }
2447+
2448+ /**
2449+ * Sets the designated column in either the current row or the insert
2450+ * row of this <code>JoinRowSetImpl</code> object with the given
2451+ * <code>java.math.BigDecimal</code> object.
2452+ * <P>
2453+ * This method updates a column value in the current row or the insert
2454+ * row of this rowset, but it does not update the database.
2455+ * If the cursor is on a row in the rowset, the
2456+ * method {@link #updateRow} must be called to update the database.
2457+ * If the cursor is on the insert row, the method {@link #insertRow}
2458+ * must be called, which will insert the new row into both this rowset
2459+ * and the database. Both of these methods must be called before the
2460+ * cursor moves to another row.
2461+ *
2462+ * @param columnIndex the first column is <code>1</code>, the second
2463+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2464+ * and equal to or less than the number of columns in this rowset
2465+ * @param x the new column value
2466+ * @throws SQLException if (1) the given column index is out of bounds,
2467+ * (2) the cursor is not on one of this rowset's rows or its
2468+ * insert row, or (3) this rowset is
2469+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2470+ */
2471+ public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
2472+ crsInternal.updateBigDecimal(columnIndex, x);
2473+ }
2474+
2475+ /**
2476+ * Sets the designated column in either the current row or the insert
2477+ * row of this <code>JoinRowSetImpl</code> object with the given
2478+ * <code>String</code> object.
2479+ * <P>
2480+ * This method updates a column value in either the current row or
2481+ * the insert row of this rowset, but it does not update the
2482+ * database. If the cursor is on a row in the rowset, the
2483+ * method {@link #updateRow} must be called to mark the row as updated.
2484+ * If the cursor is on the insert row, the method {@link #insertRow}
2485+ * must be called to insert the new row into this rowset and mark it
2486+ * as inserted. Both of these methods must be called before the
2487+ * cursor moves to another row.
2488+ * <P>
2489+ * The method <code>acceptChanges</code> must be called if the
2490+ * updated values are to be written back to the underlying database.
2491+ *
2492+ * @param columnIndex the first column is <code>1</code>, the second
2493+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2494+ * and equal to or less than the number of columns in this rowset
2495+ * @param x the new column value
2496+ * @throws SQLException if (1) the given column index is out of bounds,
2497+ * (2) the cursor is not on one of this rowset's rows or its
2498+ * insert row, or (3) this rowset is
2499+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2500+ */
2501+ public void updateString(int columnIndex, String x) throws SQLException {
2502+ crsInternal.updateString(columnIndex, x);
2503+ }
2504+
2505+ /**
2506+ * Sets the designated column in either the current row or the insert
2507+ * row of this <code>JoinRowSetImpl</code> object with the given
2508+ * <code>byte</code> array.
2509+ *
2510+ * This method updates a column value in either the current row or
2511+ * the insert row of this rowset, but it does not update the
2512+ * database. If the cursor is on a row in the rowset, the
2513+ * method {@link #updateRow} must be called to update the database.
2514+ * If the cursor is on the insert row, the method {@link #insertRow}
2515+ * must be called, which will insert the new row into both this rowset
2516+ * and the database. Both of these methods must be called before the
2517+ * cursor moves to another row.
2518+ *
2519+ * @param columnIndex the first column is <code>1</code>, the second
2520+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2521+ * and equal to or less than the number of columns in this rowset
2522+ * @param x the new column value
2523+ * @throws SQLException if (1) the given column index is out of bounds,
2524+ * (2) the cursor is not on one of this rowset's rows or its
2525+ * insert row, or (3) this rowset is
2526+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2527+ */
2528+ public void updateBytes(int columnIndex, byte x[]) throws SQLException {
2529+ crsInternal.updateBytes(columnIndex, x);
2530+ }
2531+
2532+ /**
2533+ * Sets the designated column in either the current row or the insert
2534+ * row of this <code>JoinRowSetImpl</code> object with the given
2535+ * <code>Date</code> object.
2536+ *
2537+ * This method updates a column value in either the current row or
2538+ * the insert row of this rowset, but it does not update the
2539+ * database. If the cursor is on a row in the rowset, the
2540+ * method {@link #updateRow} must be called to update the database.
2541+ * If the cursor is on the insert row, the method {@link #insertRow}
2542+ * must be called, which will insert the new row into both this rowset
2543+ * and the database. Both of these methods must be called before the
2544+ * cursor moves to another row.
2545+ *
2546+ * @param columnIndex the first column is <code>1</code>, the second
2547+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2548+ * and equal to or less than the number of columns in this rowset
2549+ * @param x the new column value
2550+ * @throws SQLException if (1) the given column index is out of bounds,
2551+ * (2) the cursor is not on one of this rowset's rows or its
2552+ * insert row, (3) the type of the designated column is not
2553+ * an SQL <code>DATE</code> or <code>TIMESTAMP</code>, or
2554+ * (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2555+ */
2556+ public void updateDate(int columnIndex, java.sql.Date x) throws SQLException {
2557+ crsInternal.updateDate(columnIndex, x);
2558+ }
2559+
2560+ /**
2561+ * Sets the designated column in either the current row or the insert
2562+ * row of this <code>JoinRowSetImpl</code> object with the given
2563+ * <code>Time</code> object.
2564+ *
2565+ * This method updates a column value in either the current row or
2566+ * the insert row of this rowset, but it does not update the
2567+ * database. If the cursor is on a row in the rowset, the
2568+ * method {@link #updateRow} must be called to update the database.
2569+ * If the cursor is on the insert row, the method {@link #insertRow}
2570+ * must be called, which will insert the new row into both this rowset
2571+ * and the database. Both of these methods must be called before the
2572+ * cursor moves to another row.
2573+ *
2574+ * @param columnIndex the first column is <code>1</code>, the second
2575+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2576+ * and equal to or less than the number of columns in this rowset
2577+ * @param x the new column value
2578+ * @throws SQLException if (1) the given column index is out of bounds,
2579+ * (2) the cursor is not on one of this rowset's rows or its
2580+ * insert row, (3) the type of the designated column is not
2581+ * an SQL <code>TIME</code> or <code>TIMESTAMP</code>, or
2582+ * (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2583+ */
2584+ public void updateTime(int columnIndex, java.sql.Time x) throws SQLException {
2585+ crsInternal.updateTime(columnIndex, x);
2586+ }
2587+
2588+ /**
2589+ * Sets the designated column in either the current row or the insert
2590+ * row of this <code>JoinRowSetImpl</code> object with the given
2591+ * <code>Timestamp</code> object.
2592+ *
2593+ * This method updates a column value in either the current row or
2594+ * the insert row of this rowset, but it does not update the
2595+ * database. If the cursor is on a row in the rowset, the
2596+ * method {@link #updateRow} must be called to update the database.
2597+ * If the cursor is on the insert row, the method {@link #insertRow}
2598+ * must be called, which will insert the new row into both this rowset
2599+ * and the database. Both of these methods must be called before the
2600+ * cursor moves to another row.
2601+ *
2602+ * @param columnIndex the first column is <code>1</code>, the second
2603+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2604+ * and equal to or less than the number of columns in this rowset
2605+ * @param x the new column value
2606+ * @throws SQLException if (1) the given column index is out of bounds,
2607+ * (2) the cursor is not on one of this rowset's rows or its
2608+ * insert row, (3) the type of the designated column is not
2609+ * an SQL <code>DATE</code>, <code>TIME</code>, or
2610+ * <code>TIMESTAMP</code>, or (4) this rowset is
2611+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2612+ */
2613+ public void updateTimestamp(int columnIndex, java.sql.Timestamp x) throws SQLException {
2614+ crsInternal.updateTimestamp(columnIndex, x);
2615+ }
2616+
2617+ /*
2618+ * Sets the designated column in either the current row or the insert
2619+ * row of this <code>JoinRowSetImpl</code> object with the given
2620+ * ASCII stream value.
2621+ * <P>
2622+ * This method updates a column value in either the current row or
2623+ * the insert row of this rowset, but it does not update the
2624+ * database. If the cursor is on a row in the rowset, the
2625+ * method {@link #updateRow} must be called to update the database.
2626+ * If the cursor is on the insert row, the method {@link #insertRow}
2627+ * must be called, which will insert the new row into both this rowset
2628+ * and the database. Both of these methods must be called before the
2629+ * cursor moves to another row.
2630+ *
2631+ * @param columnIndex the first column is <code>1</code>, the second
2632+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2633+ * and equal to or less than the number of columns in this rowset
2634+ * @param x the new column value
2635+ * @param length the number of one-byte ASCII characters in the stream
2636+ * @throws UnsupportedOperationException if this method is invoked
2637+ */
2638+ public void updateAsciiStream(int columnIndex, java.io.InputStream x, int length) throws SQLException {
2639+ crsInternal.updateAsciiStream(columnIndex, x, length);
2640+ }
2641+
2642+ /**
2643+ * Sets the designated column in either the current row or the insert
2644+ * row of this <code>JoinRowSetImpl</code> object with the given
2645+ * <code>java.io.InputStream</code> object.
2646+ * <P>
2647+ * This method updates a column value in either the current row or
2648+ * the insert row of this rowset, but it does not update the
2649+ * database. If the cursor is on a row in the rowset, the
2650+ * method {@link #updateRow} must be called to update the database.
2651+ * If the cursor is on the insert row, the method {@link #insertRow}
2652+ * must be called, which will insert the new row into both this rowset
2653+ * and the database. Both of these methods must be called before the
2654+ * cursor moves to another row.
2655+ *
2656+ * @param columnIndex the first column is <code>1</code>, the second
2657+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2658+ * and equal to or less than the number of columns in this rowset
2659+ * @param x the new column value; must be a <code>java.io.InputStream</code>
2660+ * containing <code>BINARY</code>, <code>VARBINARY</code>, or
2661+ * <code>LONGVARBINARY</code> data
2662+ * @param length the length of the stream in bytes
2663+ * @throws SQLException if (1) the given column index is out of bounds,
2664+ * (2) the cursor is not on one of this rowset's rows or its
2665+ * insert row, (3) the data in the stream is not binary, or
2666+ * (4) this rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2667+ */
2668+ public void updateBinaryStream(int columnIndex, java.io.InputStream x, int length) throws SQLException {
2669+ crsInternal.updateBinaryStream(columnIndex, x, length);
2670+ }
2671+
2672+ /**
2673+ * Sets the designated column in either the current row or the insert
2674+ * row of this <code>JoinRowSetImpl</code> object with the given
2675+ * <code>java.io.Reader</code> object.
2676+ * <P>
2677+ * This method updates a column value in either the current row or
2678+ * the insert row of this rowset, but it does not update the
2679+ * database. If the cursor is on a row in the rowset, the
2680+ * method {@link #updateRow} must be called to update the database.
2681+ * If the cursor is on the insert row, the method {@link #insertRow}
2682+ * must be called, which will insert the new row into both this rowset
2683+ * and the database. Both of these methods must be called before the
2684+ * cursor moves to another row.
2685+ *
2686+ * @param columnIndex the first column is <code>1</code>, the second
2687+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2688+ * and equal to or less than the number of columns in this rowset
2689+ * @param x the new column value; must be a <code>java.io.Reader</code>
2690+ * containing <code>BINARY</code>, <code>VARBINARY</code>,
2691+ * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
2692+ * or <code>LONGVARCHAR</code> data
2693+ * @param length the length of the stream in characters
2694+ * @throws SQLException if (1) the given column index is out of bounds,
2695+ * (2) the cursor is not on one of this rowset's rows or its
2696+ * insert row, (3) the data in the stream is not a binary or
2697+ * character type, or (4) this rowset is
2698+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2699+ */
2700+ public void updateCharacterStream(int columnIndex, java.io.Reader x, int length) throws SQLException {
2701+ crsInternal.updateCharacterStream(columnIndex, x, length);
2702+ }
2703+
2704+ /**
2705+ * Sets the designated column in either the current row or the insert
2706+ * row of this <code>JoinRowSetImpl</code> object with the given
2707+ * <code>Object</code> value. The <code>scale</code> parameter indicates
2708+ * the number of digits to the right of the decimal point and is ignored
2709+ * if the new column value is not a type that will be mapped to an SQL
2710+ * <code>DECIMAL</code> or <code>NUMERIC</code> value.
2711+ * <P>
2712+ * This method updates a column value in either the current row or
2713+ * the insert row of this rowset, but it does not update the
2714+ * database. If the cursor is on a row in the rowset, the
2715+ * method {@link #updateRow} must be called to update the database.
2716+ * If the cursor is on the insert row, the method {@link #insertRow}
2717+ * must be called, which will insert the new row into both this rowset
2718+ * and the database. Both of these methods must be called before the
2719+ * cursor moves to another row.
2720+ *
2721+ * @param columnIndex the first column is <code>1</code>, the second
2722+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2723+ * and equal to or less than the number of columns in this rowset
2724+ * @param x the new column value
2725+ * @param scale the number of digits to the right of the decimal point (for
2726+ * <code>DECIMAL</code> and <code>NUMERIC</code> types only)
2727+ * @throws SQLException if (1) the given column index is out of bounds,
2728+ * (2) the cursor is not on one of this rowset's rows or its
2729+ * insert row, or (3) this rowset is
2730+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2731+ */
2732+ public void updateObject(int columnIndex, Object x, int scale) throws SQLException {
2733+ crsInternal.updateObject(columnIndex, x, scale);
2734+ }
2735+
2736+ /**
2737+ * Sets the designated column in either the current row or the insert
2738+ * row of this <code>JoinRowSetImpl</code> object with the given
2739+ * <code>Object</code> value.
2740+ * <P>
2741+ * This method updates a column value in either the current row or
2742+ * the insert row of this rowset, but it does not update the
2743+ * database. If the cursor is on a row in the rowset, the
2744+ * method {@link #updateRow} must be called to update the database.
2745+ * If the cursor is on the insert row, the method {@link #insertRow}
2746+ * must be called, which will insert the new row into both this rowset
2747+ * and the database. Both of these methods must be called before the
2748+ * cursor moves to another row.
2749+ *
2750+ * @param columnIndex the first column is <code>1</code>, the second
2751+ * is <code>2</code>, and so on; must be <code>1</code> or larger
2752+ * and equal to or less than the number of columns in this rowset
2753+ * @param x the new column value
2754+ * @throws SQLException if (1) the given column index is out of bounds,
2755+ * (2) the cursor is not on one of this rowset's rows or its
2756+ * insert row, or (3) this rowset is
2757+ * <code>ResultSet.CONCUR_READ_ONLY</code>
2758+ */
2759+ public void updateObject(int columnIndex, Object x) throws SQLException {
2760+ crsInternal.updateObject(columnIndex, x);
2761+ }
2762+
2763+ // columnName updates
2764+
2765+ /**
2766+ * Sets the designated nullable column in the current row or the
2767+ * insert row of this <code>JoinRowSetImpl</code> object with
2768+ * <code>null</code> value.
2769+ * <P>
2770+ * This method updates a column value in the current row or the insert
2771+ * row of this rowset, but it does not update the database.
2772+ * If the cursor is on a row in the rowset, the
2773+ * method {@link #updateRow} must be called to update the database.
2774+ * If the cursor is on the insert row, the method {@link #insertRow}
2775+ * must be called, which will insert the new row into both this rowset
2776+ * and the database.
2777+ *
2778+ * @param columnName a <code>String</code> object that must match the
2779+ * SQL name of a column in this rowset, ignoring case
2780+ * @throws SQLException if (1) the given column name does not match the
2781+ * name of a column in this rowset, (2) the cursor is not on
2782+ * one of this rowset's rows or its insert row, or (3) this
2783+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2784+ */
2785+ public void updateNull(String columnName) throws SQLException {
2786+ crsInternal.updateNull(columnName);
2787+ }
2788+
2789+ /**
2790+ * Sets the designated column in either the current row or the insert
2791+ * row of this <code>JoinRowSetImpl</code> object with the given
2792+ * <code>boolean</code> value.
2793+ * <P>
2794+ * This method updates a column value in the current row or the insert
2795+ * row of this rowset, but it does not update the database.
2796+ * If the cursor is on a row in the rowset, the
2797+ * method {@link #updateRow} must be called to update the database.
2798+ * If the cursor is on the insert row, the method {@link #insertRow}
2799+ * must be called, which will insert the new row into both this rowset
2800+ * and the database. Both of these methods must be called before the
2801+ * cursor moves to another row.
2802+ *
2803+ * @param columnName a <code>String</code> object that must match the
2804+ * SQL name of a column in this rowset, ignoring case
2805+ * @param x the new column value
2806+ * @throws SQLException if (1) the given column name does not match the
2807+ * name of a column in this rowset, (2) the cursor is not on
2808+ * one of this rowset's rows or its insert row, or (3) this
2809+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2810+ */
2811+ public void updateBoolean(String columnName, boolean x) throws SQLException {
2812+ crsInternal.updateBoolean(columnName, x);
2813+ }
2814+
2815+ /**
2816+ * Sets the designated column in either the current row or the insert
2817+ * row of this <code>JoinRowSetImpl</code> object with the given
2818+ * <code>byte</code> value.
2819+ * <P>
2820+ * This method updates a column value in the current row or the insert
2821+ * row of this rowset, but it does not update the database.
2822+ * If the cursor is on a row in the rowset, the
2823+ * method {@link #updateRow} must be called to update the database.
2824+ * If the cursor is on the insert row, the method {@link #insertRow}
2825+ * must be called, which will insert the new row into both this rowset
2826+ * and the database. Both of these methods must be called before the
2827+ * cursor moves to another row.
2828+ *
2829+ * @param columnName a <code>String</code> object that must match the
2830+ * SQL name of a column in this rowset, ignoring case
2831+ * @param x the new column value
2832+ * @throws SQLException if (1) the given column name does not match the
2833+ * name of a column in this rowset, (2) the cursor is not on
2834+ * one of this rowset's rows or its insert row, or (3) this
2835+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2836+ */
2837+ public void updateByte(String columnName, byte x) throws SQLException {
2838+ crsInternal.updateByte(columnName, x);
2839+ }
2840+
2841+ /**
2842+ * Sets the designated column in either the current row or the insert
2843+ * row of this <code>JoinRowSetImpl</code> object with the given
2844+ * <code>short</code> value.
2845+ * <P>
2846+ * This method updates a column value in the current row or the insert
2847+ * row of this rowset, but it does not update the database.
2848+ * If the cursor is on a row in the rowset, the
2849+ * method {@link #updateRow} must be called to update the database.
2850+ * If the cursor is on the insert row, the method {@link #insertRow}
2851+ * must be called, which will insert the new row into both this rowset
2852+ * and the database. Both of these methods must be called before the
2853+ * cursor moves to another row.
2854+ *
2855+ * @param columnName a <code>String</code> object that must match the
2856+ * SQL name of a column in this rowset, ignoring case
2857+ * @param x the new column value
2858+ * @throws SQLException if (1) the given column name does not match the
2859+ * name of a column in this rowset, (2) the cursor is not on
2860+ * one of this rowset's rows or its insert row, or (3) this
2861+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2862+ */
2863+ public void updateShort(String columnName, short x) throws SQLException {
2864+ crsInternal.updateShort(columnName, x);
2865+ }
2866+
2867+ /**
2868+ * Sets the designated column in either the current row or the insert
2869+ * row of this <code>JoinRowSetImpl</code> object with the given
2870+ * <code>int</code> value.
2871+ * <P>
2872+ * This method updates a column value in the current row or the insert
2873+ * row of this rowset, but it does not update the database.
2874+ * If the cursor is on a row in the rowset, the
2875+ * method {@link #updateRow} must be called to update the database.
2876+ * If the cursor is on the insert row, the method {@link #insertRow}
2877+ * must be called, which will insert the new row into both this rowset
2878+ * and the database. Both of these methods must be called before the
2879+ * cursor moves to another row.
2880+ *
2881+ * @param columnName a <code>String</code> object that must match the
2882+ * SQL name of a column in this rowset, ignoring case
2883+ * @param x the new column value
2884+ * @throws SQLException if (1) the given column name does not match the
2885+ * name of a column in this rowset, (2) the cursor is not on
2886+ * one of this rowset's rows or its insert row, or (3) this
2887+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2888+ */
2889+ public void updateInt(String columnName, int x) throws SQLException {
2890+ crsInternal.updateInt(columnName, x);
2891+ }
2892+
2893+ /**
2894+ * Sets the designated column in either the current row or the insert
2895+ * row of this <code>JoinRowSetImpl</code> object with the given
2896+ * <code>long</code> value.
2897+ * <P>
2898+ * This method updates a column value in the current row or the insert
2899+ * row of this rowset, but it does not update the database.
2900+ * If the cursor is on a row in the rowset, the
2901+ * method {@link #updateRow} must be called to update the database.
2902+ * If the cursor is on the insert row, the method {@link #insertRow}
2903+ * must be called, which will insert the new row into both this rowset
2904+ * and the database. Both of these methods must be called before the
2905+ * cursor moves to another row.
2906+ *
2907+ * @param columnName a <code>String</code> object that must match the
2908+ * SQL name of a column in this rowset, ignoring case
2909+ * @param x the new column value
2910+ * @throws SQLException if (1) the given column name does not match the
2911+ * name of a column in this rowset, (2) the cursor is not on
2912+ * one of this rowset's rows or its insert row, or (3) this
2913+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2914+ */
2915+ public void updateLong(String columnName, long x) throws SQLException {
2916+ crsInternal.updateLong(columnName, x);
2917+ }
2918+
2919+ /**
2920+ * Sets the designated column in either the current row or the insert
2921+ * row of this <code>JoinRowSetImpl</code> object with the given
2922+ * <code>float</code> value.
2923+ * <P>
2924+ * This method updates a column value in the current row or the insert
2925+ * row of this rowset, but it does not update the database.
2926+ * If the cursor is on a row in the rowset, the
2927+ * method {@link #updateRow} must be called to update the database.
2928+ * If the cursor is on the insert row, the method {@link #insertRow}
2929+ * must be called, which will insert the new row into both this rowset
2930+ * and the database. Both of these methods must be called before the
2931+ * cursor moves to another row.
2932+ *
2933+ * @param columnName a <code>String</code> object that must match the
2934+ * SQL name of a column in this rowset, ignoring case
2935+ * @param x the new column value
2936+ * @throws SQLException if (1) the given column name does not match the
2937+ * name of a column in this rowset, (2) the cursor is not on
2938+ * one of this rowset's rows or its insert row, or (3) this
2939+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2940+ */
2941+ public void updateFloat(String columnName, float x) throws SQLException {
2942+ crsInternal.updateFloat(columnName, x);
2943+ }
2944+
2945+ /**
2946+ * Sets the designated column in either the current row or the insert
2947+ * row of this <code>JoinRowSetImpl</code> object with the given
2948+ * <code>double</code> value.
2949+ *
2950+ * This method updates a column value in either the current row or
2951+ * the insert row of this rowset, but it does not update the
2952+ * database. If the cursor is on a row in the rowset, the
2953+ * method {@link #updateRow} must be called to update the database.
2954+ * If the cursor is on the insert row, the method {@link #insertRow}
2955+ * must be called, which will insert the new row into both this rowset
2956+ * and the database. Both of these methods must be called before the
2957+ * cursor moves to another row.
2958+ *
2959+ * @param columnName a <code>String</code> object that must match the
2960+ * SQL name of a column in this rowset, ignoring case
2961+ * @param x the new column value
2962+ * @throws SQLException if (1) the given column name does not match the
2963+ * name of a column in this rowset, (2) the cursor is not on
2964+ * one of this rowset's rows or its insert row, or (3) this
2965+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2966+ */
2967+ public void updateDouble(String columnName, double x) throws SQLException {
2968+ crsInternal.updateDouble(columnName, x);
2969+ }
2970+
2971+ /**
2972+ * Sets the designated column in either the current row or the insert
2973+ * row of this <code>JoinRowSetImpl</code> object with the given
2974+ * <code>java.math.BigDecimal</code> object.
2975+ * <P>
2976+ * This method updates a column value in the current row or the insert
2977+ * row of this rowset, but it does not update the database.
2978+ * If the cursor is on a row in the rowset, the
2979+ * method {@link #updateRow} must be called to update the database.
2980+ * If the cursor is on the insert row, the method {@link #insertRow}
2981+ * must be called, which will insert the new row into both this rowset
2982+ * and the database. Both of these methods must be called before the
2983+ * cursor moves to another row.
2984+ *
2985+ * @param columnName a <code>String</code> object that must match the
2986+ * SQL name of a column in this rowset, ignoring case
2987+ * @param x the new column value
2988+ * @throws SQLException if (1) the given column name does not match the
2989+ * name of a column in this rowset, (2) the cursor is not on
2990+ * one of this rowset's rows or its insert row, or (3) this
2991+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
2992+ */
2993+ public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
2994+ crsInternal.updateBigDecimal(columnName, x);
2995+ }
2996+
2997+ /**
2998+ * Sets the designated column in either the current row or the insert
2999+ * row of this <code>JoinRowSetImpl</code> object with the given
3000+ * <code>String</code> object.
3001+ *
3002+ * This method updates a column value in either the current row or
3003+ * the insert row of this rowset, but it does not update the
3004+ * database. If the cursor is on a row in the rowset, the
3005+ * method {@link #updateRow} must be called to update the database.
3006+ * If the cursor is on the insert row, the method {@link #insertRow}
3007+ * must be called, which will insert the new row into both this rowset
3008+ * and the database. Both of these methods must be called before the
3009+ * cursor moves to another row.
3010+ *
3011+ * @param columnName a <code>String</code> object that must match the
3012+ * SQL name of a column in this rowset, ignoring case
3013+ * @param x the new column value
3014+ * @throws SQLException if (1) the given column name does not match the
3015+ * name of a column in this rowset, (2) the cursor is not on
3016+ * one of this rowset's rows or its insert row, or (3) this
3017+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
3018+ */
3019+ public void updateString(String columnName, String x) throws SQLException {
3020+ crsInternal.updateString(columnName, x);
3021+ }
3022+
3023+ /**
3024+ * Sets the designated column in either the current row or the insert
3025+ * row of this <code>JoinRowSetImpl</code> object with the given
3026+ * <code>byte</code> array.
3027+ *
3028+ * This method updates a column value in either the current row or
3029+ * the insert row of this rowset, but it does not update the
3030+ * database. If the cursor is on a row in the rowset, the
3031+ * method {@link #updateRow} must be called to update the database.
3032+ * If the cursor is on the insert row, the method {@link #insertRow}
3033+ * must be called, which will insert the new row into both this rowset
3034+ * and the database. Both of these methods must be called before the
3035+ * cursor moves to another row.
3036+ *
3037+ * @param columnName a <code>String</code> object that must match the
3038+ * SQL name of a column in this rowset, ignoring case
3039+ * @param x the new column value
3040+ * @throws SQLException if (1) the given column name does not match the
3041+ * name of a column in this rowset, (2) the cursor is not on
3042+ * one of this rowset's rows or its insert row, or (3) this
3043+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
3044+ */
3045+ public void updateBytes(String columnName, byte x[]) throws SQLException {
3046+ crsInternal.updateBytes(columnName, x);
3047+ }
3048+
3049+ /**
3050+ * Sets the designated column in either the current row or the insert
3051+ * row of this <code>JoinRowSetImpl</code> object with the given
3052+ * <code>Date</code> object.
3053+ *
3054+ * This method updates a column value in either the current row or
3055+ * the insert row of this rowset, but it does not update the
3056+ * database. If the cursor is on a row in the rowset, the
3057+ * method {@link #updateRow} must be called to update the database.
3058+ * If the cursor is on the insert row, the method {@link #insertRow}
3059+ * must be called, which will insert the new row into both this rowset
3060+ * and the database. Both of these methods must be called before the
3061+ * cursor moves to another row.
3062+ *
3063+ * @param columnName a <code>String</code> object that must match the
3064+ * SQL name of a column in this rowset, ignoring case
3065+ * @param x the new column value
3066+ * @throws SQLException if (1) the given column name does not match the
3067+ * name of a column in this rowset, (2) the cursor is not on
3068+ * one of this rowset's rows or its insert row, (3) the type
3069+ * of the designated column is not an SQL <code>DATE</code> or
3070+ * <code>TIMESTAMP</code>, or (4) this rowset is
3071+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3072+ */
3073+ public void updateDate(String columnName, java.sql.Date x) throws SQLException {
3074+ crsInternal.updateDate(columnName, x);
3075+ }
3076+
3077+ /**
3078+ * Sets the designated column in either the current row or the insert
3079+ * row of this <code>JoinRowSetImpl</code> object with the given
3080+ * <code>Time</code> object.
3081+ *
3082+ * This method updates a column value in either the current row or
3083+ * the insert row of this rowset, but it does not update the
3084+ * database. If the cursor is on a row in the rowset, the
3085+ * method {@link #updateRow} must be called to update the database.
3086+ * If the cursor is on the insert row, the method {@link #insertRow}
3087+ * must be called, which will insert the new row into both this rowset
3088+ * and the database. Both of these methods must be called before the
3089+ * cursor moves to another row.
3090+ *
3091+ * @param columnName a <code>String</code> object that must match the
3092+ * SQL name of a column in this rowset, ignoring case
3093+ * @param x the new column value
3094+ * @throws SQLException if (1) the given column name does not match the
3095+ * name of a column in this rowset, (2) the cursor is not on
3096+ * one of this rowset's rows or its insert row, (3) the type
3097+ * of the designated column is not an SQL <code>TIME</code> or
3098+ * <code>TIMESTAMP</code>, or (4) this rowset is
3099+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3100+ */
3101+ public void updateTime(String columnName, java.sql.Time x) throws SQLException {
3102+ crsInternal.updateTime(columnName, x);
3103+ }
3104+
3105+ /**
3106+ * Sets the designated column in either the current row or the insert
3107+ * row of this <code>JoinRowSetImpl</code> object with the given
3108+ * <code>Timestamp</code> object.
3109+ *
3110+ * This method updates a column value in either the current row or
3111+ * the insert row of this rowset, but it does not update the
3112+ * database. If the cursor is on a row in the rowset, the
3113+ * method {@link #updateRow} must be called to update the database.
3114+ * If the cursor is on the insert row, the method {@link #insertRow}
3115+ * must be called, which will insert the new row into both this rowset
3116+ * and the database. Both of these methods must be called before the
3117+ * cursor moves to another row.
3118+ *
3119+ * @param columnName a <code>String</code> object that must match the
3120+ * SQL name of a column in this rowset, ignoring case
3121+ * @param x the new column value
3122+ * @throws SQLException if the given column index is out of bounds or
3123+ * the cursor is not on one of this rowset's rows or its
3124+ * insert row
3125+ * @throws SQLException if (1) the given column name does not match the
3126+ * name of a column in this rowset, (2) the cursor is not on
3127+ * one of this rowset's rows or its insert row, (3) the type
3128+ * of the designated column is not an SQL <code>DATE</code>,
3129+ * <code>TIME</code>, or <code>TIMESTAMP</code>, or (4) this
3130+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
3131+ */
3132+ public void updateTimestamp(String columnName, java.sql.Timestamp x) throws SQLException {
3133+ crsInternal.updateTimestamp(columnName, x);
3134+ }
3135+
3136+ /**
3137+ * Unsupported; throws an <code>UnsupportedOperationException</code>
3138+ * if called.
3139+ * <P>
3140+ * Sets the designated column in either the current row or the insert
3141+ * row of this <code>JoinRowSetImpl</code> object with the given
3142+ * ASCII stream value.
3143+ * <P>
3144+ * This method updates a column value in either the current row or
3145+ * the insert row of this rowset, but it does not update the
3146+ * database. If the cursor is on a row in the rowset, the
3147+ * method {@link #updateRow} must be called to update the database.
3148+ * If the cursor is on the insert row, the method {@link #insertRow}
3149+ * must be called, which will insert the new row into both this rowset
3150+ * and the database. Both of these methods must be called before the
3151+ * cursor moves to another row.
3152+ *
3153+ * @param columnName a <code>String</code> object that must match the
3154+ * SQL name of a column in this rowset, ignoring case
3155+ * @param x the new column value
3156+ * @param length the number of one-byte ASCII characters in the stream
3157+ * @throws UnsupportedOperationException if this method is invoked
3158+ */
3159+ public void updateAsciiStream(String columnName, java.io.InputStream x, int length) throws SQLException {
3160+ crsInternal.updateAsciiStream(columnName, x, length);
3161+ }
3162+
3163+ /**
3164+ * Sets the designated column in either the current row or the insert
3165+ * row of this <code>JoinRowSetImpl</code> object with the given
3166+ * <code>java.io.InputStream</code> object.
3167+ * <P>
3168+ * This method updates a column value in either the current row or
3169+ * the insert row of this rowset, but it does not update the
3170+ * database. If the cursor is on a row in the rowset, the
3171+ * method {@link #updateRow} must be called to update the database.
3172+ * If the cursor is on the insert row, the method {@link #insertRow}
3173+ * must be called, which will insert the new row into both this rowset
3174+ * and the database. Both of these methods must be called before the
3175+ * cursor moves to another row.
3176+ *
3177+ * @param columnName a <code>String</code> object that must match the
3178+ * SQL name of a column in this rowset, ignoring case
3179+ * @param x the new column value; must be a <code>java.io.InputStream</code>
3180+ * containing <code>BINARY</code>, <code>VARBINARY</code>, or
3181+ * <code>LONGVARBINARY</code> data
3182+ * @param length the length of the stream in bytes
3183+ * @throws SQLException if (1) the given column name does not match the
3184+ * name of a column in this rowset, (2) the cursor is not on
3185+ * one of this rowset's rows or its insert row, (3) the data
3186+ * in the stream is not binary, or (4) this rowset is
3187+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3188+ */
3189+ public void updateBinaryStream(String columnName, java.io.InputStream x, int length) throws SQLException {
3190+ crsInternal.updateBinaryStream(columnName, x, length);
3191+ }
3192+
3193+ /**
3194+ * Sets the designated column in either the current row or the insert
3195+ * row of this <code>JoinRowSetImpl</code> object with the given
3196+ * <code>java.io.Reader</code> object.
3197+ * <P>
3198+ * This method updates a column value in either the current row or
3199+ * the insert row of this rowset, but it does not update the
3200+ * database. If the cursor is on a row in the rowset, the
3201+ * method {@link #updateRow} must be called to update the database.
3202+ * If the cursor is on the insert row, the method {@link #insertRow}
3203+ * must be called, which will insert the new row into both this rowset
3204+ * and the database. Both of these methods must be called before the
3205+ * cursor moves to another row.
3206+ *
3207+ * @param columnName a <code>String</code> object that must match the
3208+ * SQL name of a column in this rowset, ignoring case
3209+ * @param x the new column value; must be a <code>java.io.Reader</code>
3210+ * containing <code>BINARY</code>, <code>VARBINARY</code>,
3211+ * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
3212+ * or <code>LONGVARCHAR</code> data
3213+ * @param length the length of the stream in characters
3214+ * @throws SQLException if (1) the given column name does not match the
3215+ * name of a column in this rowset, (2) the cursor is not on
3216+ * one of this rowset's rows or its insert row, (3) the data
3217+ * in the stream is not a binary or character type, or (4) this
3218+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
3219+ */
3220+ public void updateCharacterStream(String columnName, java.io.Reader x, int length) throws SQLException {
3221+ crsInternal.updateCharacterStream(columnName, x, length);
3222+ }
3223+
3224+ /**
3225+ * Sets the designated column in either the current row or the insert
3226+ * row of this <code>JoinRowSetImpl</code> object with the given
3227+ * <code>Object</code> value. The <code>scale</code> parameter
3228+ * indicates the number of digits to the right of the decimal point
3229+ * and is ignored if the new column value is not a type that will be
3230+ * mapped to an SQL <code>DECIMAL</code> or <code>NUMERIC</code> value.
3231+ * <P>
3232+ * This method updates a column value in either the current row or
3233+ * the insert row of this rowset, but it does not update the
3234+ * database. If the cursor is on a row in the rowset, the
3235+ * method {@link #updateRow} must be called to update the database.
3236+ * If the cursor is on the insert row, the method {@link #insertRow}
3237+ * must be called, which will insert the new row into both this rowset
3238+ * and the database. Both of these methods must be called before the
3239+ * cursor moves to another row.
3240+ *
3241+ * @param columnName a <code>String</code> object that must match the
3242+ * SQL name of a column in this rowset, ignoring case
3243+ * @param x the new column value
3244+ * @param scale the number of digits to the right of the decimal point (for
3245+ * <code>DECIMAL</code> and <code>NUMERIC</code> types only)
3246+ * @throws SQLException if the given column index is out of bounds or
3247+ * the cursor is not on one of this rowset's rows or its
3248+ * insert row
3249+ * @throws SQLException if (1) the given column name does not match the
3250+ * name of a column in this rowset, (2) the cursor is not on
3251+ * one of this rowset's rows or its insert row, or (3) this
3252+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
3253+ */
3254+ public void updateObject(String columnName, Object x, int scale) throws SQLException {
3255+ crsInternal.updateObject(columnName, x, scale);
3256+ }
3257+
3258+ /**
3259+ * Sets the designated column in either the current row or the insert
3260+ * row of this <code>JoinRowSetImpl</code> object with the given
3261+ * <code>Object</code> value.
3262+ * <P>
3263+ * This method updates a column value in either the current row or
3264+ * the insert row of this rowset, but it does not update the
3265+ * database. If the cursor is on a row in the rowset, the
3266+ * method {@link #updateRow} must be called to update the database.
3267+ * If the cursor is on the insert row, the method {@link #insertRow}
3268+ * must be called, which will insert the new row into both this rowset
3269+ * and the database. Both of these methods must be called before the
3270+ * cursor moves to another row.
3271+ *
3272+ * @param columnName a <code>String</code> object that must match the
3273+ * SQL name of a column in this rowset, ignoring case
3274+ * @param x the new column value
3275+ * @throws SQLException if (1) the given column name does not match the
3276+ * name of a column in this rowset, (2) the cursor is not on
3277+ * one of this rowset's rows or its insert row, or (3) this
3278+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
3279+ */
3280+ public void updateObject(String columnName, Object x) throws SQLException {
3281+ crsInternal.updateObject(columnName, x);
3282+ }
3283+
3284+ /**
3285+ * Inserts the contents of this <code>JoinRowSetImpl</code> object's insert
3286+ * row into this rowset immediately following the current row.
3287+ * If the current row is the
3288+ * position after the last row or before the first row, the new row will
3289+ * be inserted at the end of the rowset. This method also notifies
3290+ * listeners registered with this rowset that the row has changed.
3291+ * <P>
3292+ * The cursor must be on the insert row when this method is called.
3293+ *
3294+ * @throws SQLException if (1) the cursor is not on the insert row,
3295+ * (2) one or more of the non-nullable columns in the insert
3296+ * row has not been given a value, or (3) this rowset is
3297+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3298+ */
3299+ public void insertRow() throws SQLException {
3300+ crsInternal.insertRow();
3301+ }
3302+
3303+ /**
3304+ * Marks the current row of this <code>JoinRowSetImpl</code> object as
3305+ * updated and notifies listeners registered with this rowset that the
3306+ * row has changed.
3307+ * <P>
3308+ * This method cannot be called when the cursor is on the insert row, and
3309+ * it should be called before the cursor moves to another row. If it is
3310+ * called after the cursor moves to another row, this method has no effect,
3311+ * and the updates made before the cursor moved will be lost.
3312+ *
3313+ * @throws SQLException if the cursor is on the insert row or this
3314+ * rowset is <code>ResultSet.CONCUR_READ_ONLY</code>
3315+ */
3316+ public void updateRow() throws SQLException {
3317+ crsInternal.updateRow();
3318+ }
3319+
3320+ /**
3321+ * Deletes the current row from this <code>JoinRowSetImpl</code> object and
3322+ * notifies listeners registered with this rowset that a row has changed.
3323+ * This method cannot be called when the cursor is on the insert row.
3324+ * <P>
3325+ * This method marks the current row as deleted, but it does not delete
3326+ * the row from the underlying data source. The method
3327+ * <code>acceptChanges</code> must be called to delete the row in
3328+ * the data source.
3329+ *
3330+ * @throws SQLException if (1) this method is called when the cursor
3331+ * is on the insert row, before the first row, or after the
3332+ * last row or (2) this rowset is
3333+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3334+ */
3335+ public void deleteRow() throws SQLException {
3336+ crsInternal.deleteRow();
3337+ }
3338+
3339+ /**
3340+ * Sets the current row with its original value and marks the row as
3341+ * not updated, thus undoing any changes made to the row since the
3342+ * last call to the methods <code>updateRow</code> or <code>deleteRow</code>.
3343+ * This method should be called only when the cursor is on a row in
3344+ * this rowset.
3345+ *
3346+ * @throws SQLException if the cursor is on the insert row, before the
3347+ * first row, or after the last row
3348+ */
3349+ public void refreshRow() throws SQLException {
3350+ crsInternal.refreshRow();
3351+ }
3352+
3353+ /**
3354+ * Rolls back any updates made to the current row of this
3355+ * <code>JoinRowSetImpl</code> object and notifies listeners that
3356+ * a row has changed. To have an effect, this method
3357+ * must be called after an <code>updateXXX</code> method has been
3358+ * called and before the method <code>updateRow</code> has been called.
3359+ * If no updates have been made or the method <code>updateRow</code>
3360+ * has already been called, this method has no effect.
3361+ * <P>
3362+ * After <code>updateRow</code> is called it is the
3363+ * <code>cancelRowUpdates</code> has no affect on the newly
3364+ * inserted values. The method <code>cancelRowInsert</code> can
3365+ * be used to remove any rows inserted into the RowSet.
3366+ *
3367+ * @throws SQLException if the cursor is on the insert row, before the
3368+ * first row, or after the last row
3369+ */
3370+ public void cancelRowUpdates() throws SQLException {
3371+ crsInternal.cancelRowUpdates();
3372+ }
3373+
3374+ /**
3375+ * Moves the cursor for this <code>JoinRowSetImpl</code> object
3376+ * to the insert row. The current row in the rowset is remembered
3377+ * while the cursor is on the insert row.
3378+ * <P>
3379+ * The insert row is a special row associated with an updatable
3380+ * rowset. It is essentially a buffer where a new row may
3381+ * be constructed by calling the appropriate <code>updateXXX</code>
3382+ * methods to assign a value to each column in the row. A complete
3383+ * row must be constructed; that is, every column that is not nullable
3384+ * must be assigned a value. In order for the new row to become part
3385+ * of this rowset, the method <code>insertRow</code> must be called
3386+ * before the cursor is moved back to the rowset.
3387+ * <P>
3388+ * Only certain methods may be invoked while the cursor is on the insert
3389+ * row; many methods throw an exception if they are called while the
3390+ * cursor is there. In addition to the <code>updateXXX</code>
3391+ * and <code>insertRow</code> methods, only the <code>getXXX</code> methods
3392+ * may be called when the cursor is on the insert row. A <code>getXXX</code>
3393+ * method should be called on a column only after an <code>updateXXX</code>
3394+ * method has been called on that column; otherwise, the value returned is
3395+ * undetermined.
3396+ *
3397+ * @throws SQLException if this <code>JoinRowSetImpl</code> object is
3398+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3399+ */
3400+ public void moveToInsertRow() throws SQLException {
3401+ crsInternal.moveToInsertRow();
3402+ }
3403+
3404+ /**
3405+ * Moves the cursor for this <code>JoinRowSetImpl</code> object to
3406+ * the current row. The current row is the row the cursor was on
3407+ * when the method <code>moveToInsertRow</code> was called.
3408+ * <P>
3409+ * Calling this method has no effect unless it is called while the
3410+ * cursor is on the insert row.
3411+ *
3412+ * @throws SQLException if an error occurs
3413+ */
3414+ public void moveToCurrentRow() throws SQLException {
3415+ crsInternal.moveToCurrentRow();
3416+ }
3417+
3418+ /**
3419+ * Returns <code>null</code>.
3420+ *
3421+ * @return <code>null</code>
3422+ * @throws SQLException if an error occurs
3423+ */
3424+ public Statement getStatement() throws SQLException {
3425+ return crsInternal.getStatement();
3426+ }
3427+
3428+ /**
3429+ * Retrieves the value of the designated column in this
3430+ * <code>JoinRowSetImpl</code> object as a <code>Ref</code> object
3431+ * in the Java programming lanugage.
3432+ *
3433+ * @param columnIndex the first column is <code>1</code>, the second
3434+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3435+ * and equal to or less than the number of columns in this rowset
3436+ * @return a <code>Ref</code> object representing an SQL<code> REF</code> value
3437+ * @throws SQLException if (1) the given column index is out of bounds,
3438+ * (2) the cursor is not on one of this rowset's rows or its
3439+ * insert row, or (3) the designated column does not store an
3440+ * SQL <code>REF</code> value
3441+ */
3442+ public Ref getRef(int columnIndex) throws SQLException {
3443+ return crsInternal.getRef(columnIndex);
3444+ }
3445+
3446+ /**
3447+ * Retrieves the value of the designated column in this
3448+ * <code>JoinRowSetImpl</code> object as a <code>Blob</code> object
3449+ * in the Java programming lanugage.
3450+ *
3451+ * @param columnIndex the first column is <code>1</code>, the second
3452+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3453+ * and equal to or less than the number of columns in this rowset
3454+ * @return a <code>Blob</code> object representing an SQL <code>BLOB</code> value
3455+ * @throws SQLException if (1) the given column index is out of bounds,
3456+ * (2) the cursor is not on one of this rowset's rows or its
3457+ * insert row, or (3) the designated column does not store an
3458+ * SQL <code>BLOB</code> value
3459+ */
3460+ public Blob getBlob(int columnIndex) throws SQLException {
3461+ return crsInternal.getBlob(columnIndex);
3462+ }
3463+
3464+ /**
3465+ * Retrieves the value of the designated column in this
3466+ * <code>JoinRowSetImpl</code> object as a <code>Clob</code> object
3467+ * in the Java programming lanugage.
3468+ *
3469+ * @param columnIndex the first column is <code>1</code>, the second
3470+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3471+ * and equal to or less than the number of columns in this rowset
3472+ * @return a <code>Clob</code> object representing an SQL <code>CLOB</code> value
3473+ * @throws SQLException if (1) the given column index is out of bounds,
3474+ * (2) the cursor is not on one of this rowset's rows or its
3475+ * insert row, or (3) the designated column does not store an
3476+ * SQL <code>CLOB</code> value
3477+ */
3478+ public Clob getClob(int columnIndex) throws SQLException {
3479+ return crsInternal.getClob(columnIndex);
3480+ }
3481+
3482+ /**
3483+ * Retrieves the value of the designated column in this
3484+ * <code>JoinRowSetImpl</code> object as an <code>Array</code> object
3485+ * in the Java programming lanugage.
3486+ *
3487+ * @param columnIndex the first column is <code>1</code>, the second
3488+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3489+ * and equal to or less than the number of columns in this rowset
3490+ * @return an <code>Array</code> object representing an SQL
3491+ * <code>ARRAY</code> value
3492+ * @throws SQLException if (1) the given column index is out of bounds,
3493+ * (2) the cursor is not on one of this rowset's rows or its
3494+ * insert row, or (3) the designated column does not store an
3495+ * SQL <code>ARRAY</code> value
3496+ */
3497+ public Array getArray(int columnIndex) throws SQLException {
3498+ return crsInternal.getArray(columnIndex);
3499+ }
3500+
3501+ // ColumnName
3502+
3503+ /**
3504+ * Retrieves the value of the designated column in this
3505+ * <code>JoinRowSetImpl</code> object as a <code>Ref</code> object
3506+ * in the Java programming lanugage.
3507+ *
3508+ * @param columnName a <code>String</code> object that must match the
3509+ * SQL name of a column in this rowset, ignoring case
3510+ * @return a <code>Ref</code> object representing an SQL<code> REF</code> value
3511+ * @throws SQLException if (1) the given column name is not the name
3512+ * of a column in this rowset, (2) the cursor is not on one of
3513+ * this rowset's rows or its insert row, or (3) the column value
3514+ * is not an SQL <code>REF</code> value
3515+ */
3516+ public Ref getRef(String columnName) throws SQLException {
3517+ return crsInternal.getRef(columnName);
3518+ }
3519+
3520+ /**
3521+ * Retrieves the value of the designated column in this
3522+ * <code>JoinRowSetImpl</code> object as a <code>Blob</code> object
3523+ * in the Java programming lanugage.
3524+ *
3525+ * @param columnName a <code>String</code> object that must match the
3526+ * SQL name of a column in this rowset, ignoring case
3527+ * @return a <code>Blob</code> object representing an SQL
3528+ * <code>BLOB</code> value
3529+ * @throws SQLException if (1) the given column name is not the name of
3530+ * a column in this rowset, (2) the cursor is not on one of
3531+ * this rowset's rows or its insert row, or (3) the designated
3532+ * column does not store an SQL <code>BLOB</code> value
3533+ */
3534+ public Blob getBlob(String columnName) throws SQLException {
3535+ return crsInternal.getBlob(columnName);
3536+ }
3537+
3538+ /**
3539+ * Retrieves the value of the designated column in this
3540+ * <code>JoinRowSetImpl</code> object as a <code>Clob</code> object
3541+ * in the Java programming lanugage.
3542+ *
3543+ * @param columnName a <code>String</code> object that must match the
3544+ * SQL name of a column in this rowset, ignoring case
3545+ * @return a <code>Clob</code> object representing an SQL
3546+ * <code>CLOB</code> value
3547+ * @throws SQLException if (1) the given column name is not the name of
3548+ * a column in this rowset, (2) the cursor is not on one of
3549+ * this rowset's rows or its insert row, or (3) the designated
3550+ * column does not store an SQL <code>CLOB</code> value
3551+ */
3552+ public Clob getClob(String columnName) throws SQLException {
3553+ return crsInternal.getClob(columnName);
3554+ }
3555+
3556+ /**
3557+ * Retrieves the value of the designated column in this
3558+ * <code>JoinRowSetImpl</code> object as an <code>Array</code> object
3559+ * in the Java programming lanugage.
3560+ *
3561+ * @param columnName a <code>String</code> object that must match the
3562+ * SQL name of a column in this rowset, ignoring case
3563+ * @return an <code>Array</code> object representing an SQL
3564+ * <code>ARRAY</code> value
3565+ * @throws SQLException if (1) the given column name is not the name of
3566+ * a column in this rowset, (2) the cursor is not on one of
3567+ * this rowset's rows or its insert row, or (3) the designated
3568+ * column does not store an SQL <code>ARRAY</code> value
3569+ */
3570+ public Array getArray(String columnName) throws SQLException {
3571+ return crsInternal.getArray(columnName);
3572+ }
3573+
3574+ /**
3575+ * Retrieves the value of the designated column in the current row
3576+ * of this <code>JoinRowSetImpl</code> object as a <code>java.sql.Date</code>
3577+ * object, using the given <code>Calendar</code> object to construct an
3578+ * appropriate millisecond value for the date.
3579+ *
3580+ * @param columnIndex the first column is <code>1</code>, the second
3581+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3582+ * and equal to or less than the number of columns in the rowset
3583+ * @param cal the <code>java.util.Calendar</code> object to use in
3584+ * constructing the date
3585+ * @return the column value; if the value is SQL <code>NULL</code>,
3586+ * the result is <code>null</code>
3587+ * @throws SQLException if (1) the given column name is not the name of
3588+ * a column in this rowset, (2) the cursor is not on one of
3589+ * this rowset's rows or its insert row, or (3) the designated
3590+ * column does not store an SQL <code>DATE</code> or
3591+ * <code>TIMESTAMP</code> value
3592+ */
3593+ public java.sql.Date getDate(int columnIndex, Calendar cal) throws SQLException {
3594+ return crsInternal.getDate(columnIndex, cal);
3595+ }
3596+
3597+ /**
3598+ * Retrieves the value of the designated column in the current row
3599+ * of this <code>JoinRowSetImpl</code> object as a <code>java.sql.Date</code>
3600+ * object, using the given <code>Calendar</code> object to construct an
3601+ * appropriate millisecond value for the date.
3602+ *
3603+ * @param columnName a <code>String</code> object that must match the
3604+ * SQL name of a column in this rowset, ignoring case
3605+ * @param cal the <code>java.util.Calendar</code> object to use in
3606+ * constructing the date
3607+ * @return the column value; if the value is SQL <code>NULL</code>,
3608+ * the result is <code>null</code>
3609+ * @throws SQLException if (1) the given column name is not the name of
3610+ * a column in this rowset, (2) the cursor is not on one of
3611+ * this rowset's rows or its insert row, or (3) the designated
3612+ * column does not store an SQL <code>DATE</code> or
3613+ * <code>TIMESTAMP</code> value
3614+ */
3615+ public java.sql.Date getDate(String columnName, Calendar cal) throws SQLException {
3616+ return crsInternal.getDate(columnName, cal);
3617+ }
3618+
3619+ /**
3620+ * Retrieves the value of the designated column in the current row
3621+ * of this <code>JoinRowSetImpl</code> object as a <code>java.sql.Time</code>
3622+ * object, using the given <code>Calendar</code> object to construct an
3623+ * appropriate millisecond value for the date.
3624+ *
3625+ * @param columnIndex the first column is <code>1</code>, the second
3626+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3627+ * and equal to or less than the number of columns in the rowset
3628+ * @param cal the <code>java.util.Calendar</code> object to use in
3629+ * constructing the date
3630+ * @return the column value; if the value is SQL <code>NULL</code>,
3631+ * the result is <code>null</code>
3632+ * @throws SQLException if (1) the given column name is not the name of
3633+ * a column in this rowset, (2) the cursor is not on one of
3634+ * this rowset's rows or its insert row, or (3) the designated
3635+ * column does not store an SQL <code>TIME</code> or
3636+ * <code>TIMESTAMP</code> value
3637+ */
3638+ public java.sql.Time getTime(int columnIndex, Calendar cal) throws SQLException {
3639+ return crsInternal.getTime(columnIndex, cal);
3640+ }
3641+
3642+ /**
3643+ * Retrieves the value of the designated column in the current row
3644+ * of this <code>JoinRowSetImpl</code> object as a <code>java.sql.Time</code>
3645+ * object, using the given <code>Calendar</code> object to construct an
3646+ * appropriate millisecond value for the date.
3647+ *
3648+ * @param columnName a <code>String</code> object that must match the
3649+ * SQL name of a column in this rowset, ignoring case
3650+ * @param cal the <code>java.util.Calendar</code> object to use in
3651+ * constructing the date
3652+ * @return the column value; if the value is SQL <code>NULL</code>,
3653+ * the result is <code>null</code>
3654+ * @throws SQLException if (1) the given column name is not the name of
3655+ * a column in this rowset, (2) the cursor is not on one of
3656+ * this rowset's rows or its insert row, or (3) the designated
3657+ * column does not store an SQL <code>TIME</code> or
3658+ * <code>TIMESTAMP</code> value
3659+ */
3660+ public java.sql.Time getTime(String columnName, Calendar cal) throws SQLException {
3661+ return crsInternal.getTime(columnName, cal);
3662+ }
3663+
3664+ /**
3665+ * Retrieves the value of the designated column in the current row
3666+ * of this <code>JoinRowSetImpl</code> object as a <code>java.sql.Timestamp</code>
3667+ * object, using the given <code>Calendar</code> object to construct an
3668+ * appropriate millisecond value for the date.
3669+ *
3670+ * @param columnIndex the first column is <code>1</code>, the second
3671+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3672+ * and equal to or less than the number of columns in the rowset
3673+ * @param cal the <code>java.util.Calendar</code> object to use in
3674+ * constructing the date
3675+ * @return the column value; if the value is SQL <code>NULL</code>,
3676+ * the result is <code>null</code>
3677+ * @throws SQLException if (1) the given column name is not the name of
3678+ * a column in this rowset, (2) the cursor is not on one of
3679+ * this rowset's rows or its insert row, or (3) the designated
3680+ * column does not store an SQL <code>TIME</code> or
3681+ * <code>TIMESTAMP</code> value
3682+ */
3683+ public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
3684+ return crsInternal.getTimestamp(columnIndex, cal);
3685+ }
3686+
3687+ /**
3688+ * Retrieves the value of the designated column in the current row
3689+ * of this <code>JoinRowSetImpl</code> object as a
3690+ * <code>java.sql.Timestamp</code> object, using the given
3691+ * <code>Calendar</code> object to construct an appropriate
3692+ * millisecond value for the date.
3693+ *
3694+ * @param columnName a <code>String</code> object that must match the
3695+ * SQL name of a column in this rowset, ignoring case
3696+ * @param cal the <code>java.util.Calendar</code> object to use in
3697+ * constructing the date
3698+ * @return the column value; if the value is SQL <code>NULL</code>,
3699+ * the result is <code>null</code>
3700+ * @throws SQLException if (1) the given column name is not the name of
3701+ * a column in this rowset, (2) the cursor is not on one of
3702+ * this rowset's rows or its insert row, or (3) the designated
3703+ * column does not store an SQL <code>DATE</code>,
3704+ * <code>TIME</code>, or <code>TIMESTAMP</code> value
3705+ */
3706+ public java.sql.Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
3707+ return crsInternal.getTimestamp(columnName, cal);
3708+ }
3709+
3710+ /**
3711+ * Sets the metadata for this <code>JoinRowSetImpl</code> object
3712+ * with the given <code>RowSetMetaData</code> object.
3713+ *
3714+ * @param md a <code>RowSetMetaData</code> object instance containing
3715+ * metadata about the columsn in the rowset
3716+ * @throws SQLException if invalid meta data is supplied to the
3717+ * rowset
3718+ */
3719+ public void setMetaData(RowSetMetaData md) throws SQLException {
3720+ crsInternal.setMetaData(md);
3721+ }
3722+
3723+ public ResultSet getOriginal() throws SQLException {
3724+ return crsInternal.getOriginal();
3725+ }
3726+
3727+ /**
3728+ * Returns a result set containing the original value of the rowset.
3729+ * The cursor is positioned before the first row in the result set.
3730+ * Only rows contained in the result set returned by getOriginal()
3731+ * are said to have an original value.
3732+ *
3733+ * @return the original result set of the rowset
3734+ * @throws SQLException if an error occurs produce the
3735+ * <code>ResultSet</code> object
3736+ */
3737+ public ResultSet getOriginalRow() throws SQLException {
3738+ return crsInternal.getOriginalRow();
3739+ }
3740+
3741+ /**
3742+ * Returns a result set containing the original value of the current
3743+ * row only.
3744+ *
3745+ * @throws SQLException if there is no current row
3746+ * @see #setOriginalRow
3747+ */
3748+ public void setOriginalRow() throws SQLException {
3749+ crsInternal.setOriginalRow();
3750+ }
3751+
3752+ /**
3753+ * Returns the columns that make a key to uniquely identify a
3754+ * row in this <code>JoinRowSetImpl</code> object.
3755+ *
3756+ * @return an array of column number that constites a primary
3757+ * key for this rowset. This array should be empty
3758+ * if no columns is representitive of a primary key
3759+ * @throws SQLException if the rowset is empty or no columns
3760+ * are designated as primary keys
3761+ * @see #setKeyColumns
3762+ */
3763+ public int[] getKeyColumns() throws SQLException {
3764+ return crsInternal.getKeyColumns();
3765+ }
3766+
3767+ /**
3768+ * Sets this <code>JoinRowSetImpl</code> object's
3769+ * <code>keyCols</code> field with the given array of column
3770+ * numbers, which forms a key for uniquely identifying a row
3771+ * in this rowset.
3772+ *
3773+ * @param cols an array of <code>int</code> indicating the
3774+ * columns that form a primary key for this
3775+ * <code>JoinRowSetImpl</code> object; every
3776+ * element in the array must be greater than
3777+ * <code>0</code> and less than or equal to the number
3778+ * of columns in this rowset
3779+ * @throws SQLException if any of the numbers in the
3780+ * given array is not valid for this rowset
3781+ * @see #getKeyColumns
3782+ */
3783+ public void setKeyColumns(int[] cols) throws SQLException {
3784+ crsInternal.setKeyColumns(cols);
3785+ }
3786+
3787+ /**
3788+ * Sets the designated column in either the current row or the insert
3789+ * row of this <code>JoinRowSetImpl</code> object with the given
3790+ * <code>Ref</code> value.
3791+ * <P>
3792+ * This method updates a column value in the current row or the insert
3793+ * row of this rowset, but it does not update the database.
3794+ * If the cursor is on a row in the rowset, the
3795+ * method {@link #updateRow} must be called to update the database.
3796+ * If the cursor is on the insert row, the method {@link #insertRow}
3797+ * must be called, which will insert the new row into both this rowset
3798+ * and the database. Either of these methods must be called before the
3799+ * cursor moves to another row.
3800+ *
3801+ * @param columnIndex the first column is <code>1</code>, the second
3802+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3803+ * and equal to or less than the number of columns in this rowset
3804+ * @param ref the <code>java.sql.Ref</code> object that will be set as
3805+ * the new column value
3806+ * @throws SQLException if (1) the given column index is out of bounds,
3807+ * (2) the cursor is not on one of this rowset's rows or its
3808+ * insert row, or (3) this rowset is
3809+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3810+ */
3811+ public void updateRef(int columnIndex, java.sql.Ref ref) throws SQLException {
3812+ crsInternal.updateRef(columnIndex, ref);
3813+ }
3814+
3815+ /**
3816+ * Sets the designated column in either the current row or the insert
3817+ * row of this <code>JoinRowSetImpl</code> object with the given
3818+ * <code>Ref</code> value.
3819+ * <P>
3820+ * This method updates a column value in the current row or the insert
3821+ * row of this rowset, but it does not update the database.
3822+ * If the cursor is on a row in the rowset, the
3823+ * method {@link #updateRow} must be called to update the database.
3824+ * If the cursor is on the insert row, the method {@link #insertRow}
3825+ * must be called, which will insert the new row into both this rowset
3826+ * and the database. Either of these methods must be called before the
3827+ * cursor moves to another row.
3828+ *
3829+ * @param columnName a <code>String</code> object giving the name of the column
3830+ * to be updated; must match one of the column names in this
3831+ * <code>JoinRowSetImpl</code> object
3832+ * @param ref the <code>java.sql.Ref</code> object that will be set as
3833+ * the new column value
3834+ * @throws SQLException if (1) the given column name is not valid,
3835+ * (2) the cursor is not on one of this rowset's rows or its
3836+ * insert row, or (3) this rowset is
3837+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3838+ */
3839+ public void updateRef(String columnName, java.sql.Ref ref) throws SQLException {
3840+ crsInternal.updateRef(columnName, ref);
3841+ }
3842+
3843+ /**
3844+ * Sets the designated column in either the current row or the insert
3845+ * row of this <code>JoinRowSetImpl</code> object with the given
3846+ * <code>Clob</code> object.
3847+ * <P>
3848+ * This method updates a column value in the current row or the insert
3849+ * row of this rowset, but it does not update the database.
3850+ * If the cursor is on a row in the rowset, the
3851+ * method {@link #updateRow} must be called to update the database.
3852+ * If the cursor is on the insert row, the method {@link #insertRow}
3853+ * must be called, which will insert the new row into both this rowset
3854+ * and the database. Either of these methods must be called before the
3855+ * cursor moves to another row.
3856+ *
3857+ * @param columnIndex the first column is <code>1</code>, the second
3858+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3859+ * and equal to or less than the number of columns in this rowset
3860+ * @param c the <code>java.sql.Clob</code> object that will be set as
3861+ * the new column value
3862+ * @throws SQLException if (1) the given column index is out of bounds,
3863+ * (2) the cursor is not on one of this rowset's rows or its
3864+ * insert row, or (3) this rowset is
3865+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3866+ */
3867+ public void updateClob(int columnIndex, Clob c) throws SQLException {
3868+ crsInternal.updateClob(columnIndex, c);
3869+ }
3870+
3871+ /**
3872+ * Sets the designated column in either the current row or the insert
3873+ * row of this <code>JoinRowSetImpl</code> object with the given
3874+ * <code>Clob</code> object.
3875+ * <P>
3876+ * This method updates a column value in the current row or the insert
3877+ * row of this rowset, but it does not update the database.
3878+ * If the cursor is on a row in the rowset, the
3879+ * method {@link #updateRow} must be called to update the database.
3880+ * If the cursor is on the insert row, the method {@link #insertRow}
3881+ * must be called, which will insert the new row into both this rowset
3882+ * and the database. Either of these methods must be called before the
3883+ * cursor moves to another row.
3884+ *
3885+ * @param columnName a <code>String</code> object giving the name of the column
3886+ * to be updated; must match one of the column names in this
3887+ * <code>JoinRowSetImpl</code> object
3888+ * @param c the <code>java.sql.Clob</code> object that will be set as
3889+ * the new column value
3890+ * @throws SQLException if (1) the given column name is not valid,
3891+ * (2) the cursor is not on one of this rowset's rows or its
3892+ * insert row, or (3) this rowset is
3893+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3894+ */
3895+ public void updateClob(String columnName, Clob c) throws SQLException {
3896+ crsInternal.updateClob(columnName, c);
3897+ }
3898+
3899+ /**
3900+ * Sets the designated column in either the current row or the insert
3901+ * row of this <code>JoinRowSetImpl</code> object with the given
3902+ * <code>Blob</code> value.
3903+ * <P>
3904+ * This method updates a column value in the current row or the insert
3905+ * row of this rowset, but it does not update the database.
3906+ * If the cursor is on a row in the rowset, the
3907+ * method {@link #updateRow} must be called to update the database.
3908+ * If the cursor is on the insert row, the method {@link #insertRow}
3909+ * must be called, which will insert the new row into both this rowset
3910+ * and the database. Either of these methods must be called before the
3911+ * cursor moves to another row.
3912+ *
3913+ * @param columnIndex the first column is <code>1</code>, the second
3914+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3915+ * and equal to or less than the number of columns in this rowset
3916+ * @param b the <code>java.sql.Blob</code> object that will be set as
3917+ * the new column value
3918+ * @throws SQLException if (1) the given column index is out of bounds,
3919+ * (2) the cursor is not on one of this rowset's rows or its
3920+ * insert row, or (3) this rowset is
3921+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3922+ */
3923+ public void updateBlob(int columnIndex, Blob b) throws SQLException {
3924+ crsInternal.updateBlob(columnIndex, b);
3925+ }
3926+
3927+ /**
3928+ * Sets the designated column in either the current row or the insert
3929+ * row of this <code>JoinRowSetImpl</code> object with the given
3930+ * <code>Blob</code> object.
3931+ * <P>
3932+ * This method updates a column value in the current row or the insert
3933+ * row of this rowset, but it does not update the database.
3934+ * If the cursor is on a row in the rowset, the
3935+ * method {@link #updateRow} must be called to update the database.
3936+ * If the cursor is on the insert row, the method {@link #insertRow}
3937+ * must be called, which will insert the new row into both this rowset
3938+ * and the database. Either of these methods must be called before the
3939+ * cursor moves to another row.
3940+ *
3941+ * @param columnName a <code>String</code> object giving the name of the column
3942+ * to be updated; must match one of the column names in this
3943+ * <code>JoinRowSetImpl</code> object
3944+ * @param b the <code>java.sql.Blob</code> object that will be set as
3945+ * the new column value
3946+ * @throws SQLException if (1) the given column name is not valid,
3947+ * (2) the cursor is not on one of this rowset's rows or its
3948+ * insert row, or (3) this rowset is
3949+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3950+ */
3951+ public void updateBlob(String columnName, Blob b) throws SQLException {
3952+ crsInternal.updateBlob(columnName, b);
3953+ }
3954+
3955+ /**
3956+ * Sets the designated column in either the current row or the insert
3957+ * row of this <code>JoinRowSetImpl</code> object with the given
3958+ * <code>Array</code> object.
3959+ * <P>
3960+ * This method updates a column value in the current row or the insert
3961+ * row of this rowset, but it does not update the database.
3962+ * If the cursor is on a row in the rowset, the
3963+ * method {@link #updateRow} must be called to update the database.
3964+ * If the cursor is on the insert row, the method {@link #insertRow}
3965+ * must be called, which will insert the new row into both this rowset
3966+ * and the database. Either of these methods must be called before the
3967+ * cursor moves to another row.
3968+ *
3969+ * @param columnIndex the first column is <code>1</code>, the second
3970+ * is <code>2</code>, and so on; must be <code>1</code> or larger
3971+ * and equal to or less than the number of columns in this rowset
3972+ * @param a the <code>java.sql.Array</code> object that will be set as
3973+ * the new column value
3974+ * @throws SQLException if (1) the given column index is out of bounds,
3975+ * (2) the cursor is not on one of this rowset's rows or its
3976+ * insert row, or (3) this rowset is
3977+ * <code>ResultSet.CONCUR_READ_ONLY</code>
3978+ */
3979+ public void updateArray(int columnIndex, Array a) throws SQLException {
3980+ crsInternal.updateArray(columnIndex, a);
3981+ }
3982+
3983+ /**
3984+ * Sets the designated column in either the current row or the insert
3985+ * row of this <code>JoinRowSetImpl</code> object with the given
3986+ * <code>Array</code> object.
3987+ * <P>
3988+ * This method updates a column value in the current row or the insert
3989+ * row of this rowset, but it does not update the database.
3990+ * If the cursor is on a row in the rowset, the
3991+ * method {@link #updateRow} must be called to update the database.
3992+ * If the cursor is on the insert row, the method {@link #insertRow}
3993+ * must be called, which will insert the new row into both this rowset
3994+ * and the database. Either of these methods must be called before the
3995+ * cursor moves to another row.
3996+ *
3997+ * @param columnName a <code>String</code> object giving the name of the column
3998+ * to be updated; must match one of the column names in this
3999+ * <code>JoinRowSetImpl</code> object
4000+ * @param a the <code>java.sql.Array</code> object that will be set as
4001+ * the new column value
4002+ * @throws SQLException if (1) the given column name is not valid,
4003+ * (2) the cursor is not on one of this rowset's rows or its
4004+ * insert row, or (3) this rowset is
4005+ * <code>ResultSet.CONCUR_READ_ONLY</code>
4006+ */
4007+ public void updateArray(String columnName, Array a) throws SQLException {
4008+ crsInternal.updateArray(columnName, a);
4009+ }
4010+
4011+ /**
4012+ * Populates this <code>JoinRowSetImpl</code> object with data.
4013+ * This form of the method uses the rowset's user, password, and url or
4014+ * data source name properties to create a database
4015+ * connection. If properties that are needed
4016+ * have not been set, this method will throw an exception.
4017+ * <P>
4018+ * Another form of this method uses an existing JDBC <code>Connection</code>
4019+ * object instead of creating a new one; therefore, it ignores the
4020+ * properties used for establishing a new connection.
4021+ * <P>
4022+ * The query specified by the command property is executed to create a
4023+ * <code>ResultSet</code> object from which to retrieve data.
4024+ * The current contents of the rowset are discarded, and the
4025+ * rowset's metadata is also (re)set. If there are outstanding updates,
4026+ * they are also ignored.
4027+ * <P>
4028+ * The method <code>execute</code> closes any database connections that it
4029+ * creates.
4030+ *
4031+ * @throws SQLException if an error occurs or the
4032+ * necessary properties have not been set
4033+ */
4034+ public void execute() throws SQLException {
4035+ crsInternal.execute();
4036+ }
4037+
4038+ /**
4039+ * Populates this <code>JoinRowSetImpl</code> object with data,
4040+ * using the given connection to produce the result set from
4041+ * which data will be read. A second form of this method,
4042+ * which takes no arguments, uses the values from this rowset's
4043+ * user, password, and either url or data source properties to
4044+ * create a new database connection. The form of <code>execute</code>
4045+ * that is given a connection ignores these properties.
4046+ *
4047+ * @param conn A standard JDBC <code>Connection</code> object with valid
4048+ * properties that the <code>JoinRowSet</code> implementation
4049+ * can pass to a synchronization provider to establish a
4050+ * connection to the datasource
4051+ * @throws SQLException if an invalid <code>Connection</code> is supplied
4052+ * or an error occurs in establishing the connection to the
4053+ * data soure
4054+ * @see java.sql.Connection
4055+ */
4056+ public void execute(Connection conn) throws SQLException {
4057+ crsInternal.execute(conn);
4058+ }
4059+
4060+ /**
4061+ * Provide interface coverage for getURL(int) in ResultSet->RowSet
4062+ */
4063+ public java.net.URL getURL(int columnIndex) throws SQLException {
4064+ return crsInternal.getURL(columnIndex);
4065+ }
4066+
4067+ /**
4068+ * Provide interface coverage for getURL(String) in ResultSet->RowSet
4069+ */
4070+ public java.net.URL getURL(String columnName) throws SQLException {
4071+ return crsInternal.getURL(columnName);
4072+ }
4073+
4074+ /**
4075+ * Creates a new <code>WebRowSet</code> object, populates it with the
4076+ * data in the given <code>ResultSet</code> object, and writes it
4077+ * to the given <code>java.io.Writer</code> object in XML format.
4078+ *
4079+ * @throws SQLException if an error occurs writing out the rowset
4080+ * contents to XML
4081+ */
4082+ public void writeXml(ResultSet rs, java.io.Writer writer)
4083+ throws SQLException {
4084+ wrs = new WebRowSetImpl();
4085+ wrs.populate(rs);
4086+ wrs.writeXml(writer);
4087+ }
4088+
4089+ /**
4090+ * Writes this <code>JoinRowSet</code> object to the given
4091+ * <code>java.io.Writer</code> object in XML format. In
4092+ * addition to the rowset's data, its properties and metadata
4093+ * are also included.
4094+ *
4095+ * @throws SQLException if an error occurs writing out the rowset
4096+ * contents to XML
4097+ */
4098+ public void writeXml(java.io.Writer writer) throws SQLException {
4099+ createWebRowSet().writeXml(writer);
4100+}
4101+
4102+ /**
4103+ * Reads this <code>JoinRowSet</code> object in its XML format.
4104+ *
4105+ * @throws SQLException if a database access error occurs
4106+ */
4107+ public void readXml(java.io.Reader reader) throws SQLException {
4108+ wrs = new WebRowSetImpl();
4109+ wrs.readXml(reader);
4110+ crsInternal = (CachedRowSetImpl)wrs;
4111+ }
4112+
4113+ // Stream based methods
4114+ /**
4115+ * Reads a stream based XML input to populate an <code>WebRowSet</code>
4116+ *
4117+ * @throws SQLException if a data source access occurs
4118+ * @throws IOException if a IO exception occurs
4119+ */
4120+ public void readXml(java.io.InputStream iStream) throws SQLException, IOException {
4121+ wrs = new WebRowSetImpl();
4122+ wrs.readXml(iStream);
4123+ crsInternal = (CachedRowSetImpl)wrs;
4124+ }
4125+
4126+ /**
4127+ * Creates an an output stream of the internal state and contents of a
4128+ * <code>WebRowSet</code> for XML proceessing
4129+ *
4130+ * @throws SQLException if a datasource access occurs
4131+ * @throws IOException if an IO exception occurs
4132+ */
4133+ public void writeXml(java.io.OutputStream oStream) throws SQLException, IOException {
4134+ createWebRowSet().writeXml(oStream);
4135+ }
4136+
4137+ /**
4138+ * Creates a new <code>WebRowSet</code> object, populates it with
4139+ * the contents of the <code>ResultSet</code> and creates an output
4140+ * streams the internal state and contents of the rowset for XML processing.
4141+ *
4142+ * @throws SQLException if a datasource access occurs
4143+ * @throws IOException if an IO exception occurs
4144+ */
4145+ public void writeXml(ResultSet rs, java.io.OutputStream oStream) throws SQLException, IOException {
4146+ wrs = new WebRowSetImpl();
4147+ wrs.populate(rs);
4148+ wrs.writeXml(oStream);
4149+ }
4150+
4151+ /**
4152+ * %%% Javadoc comments to be added here
4153+ */
4154+ private WebRowSet createWebRowSet() throws SQLException {
4155+ if(wrs != null) {
4156+ // check if it has already been initialized.
4157+ return wrs;
4158+ } else {
4159+ wrs = new WebRowSetImpl();
4160+ crsInternal.beforeFirst();
4161+ wrs.populate(crsInternal);
4162+ return wrs;
4163+ }
4164+ }
4165+
4166+ /**
4167+ * Returns the last set SQL <code>JOIN</code> type in this JoinRowSetImpl
4168+ * object
4169+ *
4170+ * @return joinType One of the standard JoinRowSet static field JOIN types
4171+ * @throws SQLException if an error occurs determining the current join type
4172+ */
4173+ public int getJoinType() throws SQLException {
4174+ if (vecJoinType == null) {
4175+ // Default JoinRowSet type
4176+ this.setJoinType(JoinRowSet.INNER_JOIN);
4177+ }
4178+ Integer i = (Integer)(vecJoinType.get(vecJoinType.size()-1));
4179+ return i.intValue();
4180+ }
4181+
4182+ /**
4183+ * The listener will be notified whenever an event occurs on this <code>JoinRowSet</code>
4184+ * object.
4185+ * <P>
4186+ * A listener might, for example, be a table or graph that needs to
4187+ * be updated in order to accurately reflect the current state of
4188+ * the <code>RowSet</code> object.
4189+ * <p>
4190+ * <b>Note</b>: if the <code>RowSetListener</code> object is
4191+ * <code>null</code>, this method silently discards the <code>null</code>
4192+ * value and does not add a null reference to the set of listeners.
4193+ * <p>
4194+ * <b>Note</b>: if the listener is already set, and the new <code>RowSetListerner</code>
4195+ * instance is added to the set of listeners already registered to receive
4196+ * event notifications from this <code>RowSet</code>.
4197+ *
4198+ * @param listener an object that has implemented the
4199+ * <code>javax.sql.RowSetListener</code> interface and wants to be notified
4200+ * of any events that occur on this <code>JoinRowSet</code> object; May be
4201+ * null.
4202+ * @see #removeRowSetListener
4203+ */
4204+ public void addRowSetListener(RowSetListener listener) {
4205+ crsInternal.addRowSetListener(listener);
4206+ }
4207+
4208+ /**
4209+ * Removes the designated object from this <code>JoinRowSet</code> object's list of listeners.
4210+ * If the given argument is not a registered listener, this method
4211+ * does nothing.
4212+ *
4213+ * <b>Note</b>: if the <code>RowSetListener</code> object is
4214+ * <code>null</code>, this method silently discards the <code>null</code>
4215+ * value.
4216+ *
4217+ * @param listener a <code>RowSetListener</code> object that is on the list
4218+ * of listeners for this <code>JoinRowSet</code> object
4219+ * @see #addRowSetListener
4220+ */
4221+ public void removeRowSetListener(RowSetListener listener) {
4222+ crsInternal.removeRowSetListener(listener);
4223+ }
4224+
4225+ /**
4226+ * Converts this <code>JoinRowSetImpl</code> object to a collection
4227+ * of tables. The sample implementation utilitizes the <code>TreeMap</code>
4228+ * collection type.
4229+ * This class guarantees that the map will be in ascending key order,
4230+ * sorted according to the natural order for the key's class.
4231+ *
4232+ * @return a <code>Collection</code> object consisting of tables,
4233+ * each of which is a copy of a row in this
4234+ * <code>JoinRowSetImpl</code> object
4235+ * @throws SQLException if an error occurs in generating the collection
4236+ * @see #toCollection(int)
4237+ * @see #toCollection(String)
4238+ * @see java.util.TreeMap
4239+ */
4240+ public Collection<?> toCollection() throws SQLException {
4241+ return crsInternal.toCollection();
4242+ }
4243+
4244+ /**
4245+ * Returns the specified column of this <code>JoinRowSetImpl</code> object
4246+ * as a <code>Collection</code> object. This method makes a copy of the
4247+ * column's data and utilitizes the <code>Vector</code> to establish the
4248+ * collection. The <code>Vector</code> class implements a growable array
4249+ * objects allowing the individual components to be accessed using an
4250+ * an integer index similar to that of an array.
4251+ *
4252+ * @return a <code>Collection</code> object that contains the value(s)
4253+ * stored in the specified column of this
4254+ * <code>JoinRowSetImpl</code>
4255+ * object
4256+ * @throws SQLException if an error occurs generated the collection; or
4257+ * an invalid column is provided.
4258+ * @see #toCollection()
4259+ * @see #toCollection(String)
4260+ * @see java.util.Vector
4261+ */
4262+ public Collection<?> toCollection(int column) throws SQLException {
4263+ return crsInternal.toCollection(column);
4264+ }
4265+
4266+ /**
4267+ * Returns the specified column of this <code>JoinRowSetImpl</code> object
4268+ * as a <code>Collection</code> object. This method makes a copy of the
4269+ * column's data and utilitizes the <code>Vector</code> to establish the
4270+ * collection. The <code>Vector</code> class implements a growable array
4271+ * objects allowing the individual components to be accessed using an
4272+ * an integer index similar to that of an array.
4273+ *
4274+ * @return a <code>Collection</code> object that contains the value(s)
4275+ * stored in the specified column of this
4276+ * <code>JoinRowSetImpl</code>
4277+ * object
4278+ * @throws SQLException if an error occurs generated the collection; or
4279+ * an invalid column is provided.
4280+ * @see #toCollection()
4281+ * @see #toCollection(int)
4282+ * @see java.util.Vector
4283+ */
4284+ public Collection<?> toCollection(String column) throws SQLException {
4285+ return crsInternal.toCollection(column);
4286+ }
4287+
4288+ /**
4289+ * Creates a <code>RowSet</code> object that is a copy of
4290+ * this <code>JoinRowSetImpl</code> object's table structure
4291+ * and the constraints only.
4292+ * There will be no data in the object being returned.
4293+ * Updates made on a copy are not visible to the original rowset.
4294+ * <P>
4295+ * This helps in getting the underlying XML schema which can
4296+ * be used as the basis for populating a <code>WebRowSet</code>.
4297+ *
4298+ * @return a new <code>CachedRowSet</code> object that is a copy
4299+ * of this <code>JoinRowSetImpl</code> object's schema and
4300+ * retains all the constraints on the original rowset but contains
4301+ * no data
4302+ * @throws SQLException if an error occurs in generating the copy
4303+ * of the <code>CachedRowSet</code> object
4304+ * @see #createShared
4305+ * @see #createCopy
4306+ * @see #createCopyNoConstraints
4307+ * @see javax.sql.RowSetEvent
4308+ * @see javax.sql.RowSetListener
4309+ */
4310+ public CachedRowSet createCopySchema() throws SQLException {
4311+ return crsInternal.createCopySchema();
4312+ }
4313+
4314+ /**
4315+ * {@inheritDoc}
4316+ */
4317+ public void setSyncProvider(String providerStr) throws SQLException {
4318+ crsInternal.setSyncProvider(providerStr);
4319+ }
4320+
4321+ /**
4322+ * {@inheritDoc}
4323+ */
4324+ public void acceptChanges() throws SyncProviderException {
4325+ crsInternal.acceptChanges();
4326+ }
4327+
4328+ /**
4329+ * {@inheritDoc}
4330+ */
4331+ public SyncProvider getSyncProvider() throws SQLException {
4332+ return crsInternal.getSyncProvider();
4333+ }
4334+
4335+ /**
4336+ * This method re populates the resBundle
4337+ * during the deserialization process
4338+ *
4339+ */
4340+ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
4341+ // Default state initialization happens here
4342+ ois.defaultReadObject();
4343+ // Initialization of transient Res Bundle happens here .
4344+ try {
4345+ resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
4346+ } catch(IOException ioe) {
4347+ throw new RuntimeException(ioe);
4348+ }
4349+
4350+ }
4351+
4352+ static final long serialVersionUID = -5590501621560008453L;
4353+}