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/javax/sql/rowset/CachedRowSet.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/sql/rowset/CachedRowSet.java+1625−0
@@ -0,0 +1,1625 @@
1+/*
2+ * Copyright (c) 2003, 2010, 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 javax.sql.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.spi.*;
36+
37+/**
38+ * The interface that all standard implementations of
39+ * <code>CachedRowSet</code> must implement.
40+ * <P>
41+ * The reference implementation of the <code>CachedRowSet</code> interface provided
42+ * by Oracle Corporation is a standard implementation. Developers may use this implementation
43+ * just as it is, they may extend it, or they may choose to write their own implementations
44+ * of this interface.
45+ * <P>
46+ * A <code>CachedRowSet</code> object is a container for rows of data
47+ * that caches its rows in memory, which makes it possible to operate without always being
48+ * connected to its data source. Further, it is a
49+ * JavaBeans<sup><font size=-2>TM</font></sup> component and is scrollable,
50+ * updatable, and serializable. A <code>CachedRowSet</code> object typically
51+ * contains rows from a result set, but it can also contain rows from any file
52+ * with a tabular format, such as a spread sheet. The reference implementation
53+ * supports getting data only from a <code>ResultSet</code> object, but
54+ * developers can extend the <code>SyncProvider</code> implementations to provide
55+ * access to other tabular data sources.
56+ * <P>
57+ * An application can modify the data in a <code>CachedRowSet</code> object, and
58+ * those modifications can then be propagated back to the source of the data.
59+ * <P>
60+ * A <code>CachedRowSet</code> object is a <i>disconnected</i> rowset, which means
61+ * that it makes use of a connection to its data source only briefly. It connects to its
62+ * data source while it is reading data to populate itself with rows and again
63+ * while it is propagating changes back to its underlying data source. The rest
64+ * of the time, a <code>CachedRowSet</code> object is disconnected, including
65+ * while its data is being modified. Being disconnected makes a <code>RowSet</code>
66+ * object much leaner and therefore much easier to pass to another component. For
67+ * example, a disconnected <code>RowSet</code> object can be serialized and passed
68+ * over the wire to a thin client such as a personal digital assistant (PDA).
69+ * <P>
70+ *
71+ * <h3>1.0 Creating a <code>CachedRowSet</code> Object</h3>
72+ * The following line of code uses the default constructor for
73+ * <code>CachedRowSet</code>
74+ * supplied in the reference implementation (RI) to create a default
75+ * <code>CachedRowSet</code> object.
76+ * <PRE>
77+ * CachedRowSetImpl crs = new CachedRowSetImpl();
78+ * </PRE>
79+ * This new <code>CachedRowSet</code> object will have its properties set to the
80+ * default properties of a <code>BaseRowSet</code> object, and, in addition, it will
81+ * have an <code>RIOptimisticProvider</code> object as its synchronization provider.
82+ * <code>RIOptimisticProvider</code>, one of two <code>SyncProvider</code>
83+ * implementations included in the RI, is the default provider that the
84+ * <code>SyncFactory</code> singleton will supply when no synchronization
85+ * provider is specified.
86+ * <P>
87+ * A <code>SyncProvider</code> object provides a <code>CachedRowSet</code> object
88+ * with a reader (a <code>RowSetReader</code> object) for reading data from a
89+ * data source to populate itself with data. A reader can be implemented to read
90+ * data from a <code>ResultSet</code> object or from a file with a tabular format.
91+ * A <code>SyncProvider</code> object also provides
92+ * a writer (a <code>RowSetWriter</code> object) for synchronizing any
93+ * modifications to the <code>CachedRowSet</code> object's data made while it was
94+ * disconnected with the data in the underlying data source.
95+ * <P>
96+ * A writer can be implemented to exercise various degrees of care in checking
97+ * for conflicts and in avoiding them.
98+ * (A conflict occurs when a value in the data source has been changed after
99+ * the rowset populated itself with that value.)
100+ * The <code>RIOptimisticProvider</code> implementation assumes there will be
101+ * few or no conflicts and therefore sets no locks. It updates the data source
102+ * with values from the <code>CachedRowSet</code> object only if there are no
103+ * conflicts.
104+ * Other writers can be implemented so that they always write modified data to
105+ * the data source, which can be accomplished either by not checking for conflicts
106+ * or, on the other end of the spectrum, by setting locks sufficient to prevent data
107+ * in the data source from being changed. Still other writer implementations can be
108+ * somewhere in between.
109+ * <P>
110+ * A <code>CachedRowSet</code> object may use any
111+ * <code>SyncProvider</code> implementation that has been registered
112+ * with the <code>SyncFactory</code> singleton. An application
113+ * can find out which <code>SyncProvider</code> implementations have been
114+ * registered by calling the following line of code.
115+ * <PRE>
116+ * java.util.Enumeration providers = SyncFactory.getRegisteredProviders();
117+ * </PRE>
118+ * <P>
119+ * There are two ways for a <code>CachedRowSet</code> object to specify which
120+ * <code>SyncProvider</code> object it will use.
121+ * <UL)
122+ * <LI>Supplying the name of the implementation to the constructor<BR>
123+ * The following line of code creates the <code>CachedRowSet</code>
124+ * object <i>crs2</i> that is initialized with default values except that its
125+ * <code>SyncProvider</code> object is the one specified.
126+ * <PRE>
127+ * CachedRowSetImpl crs2 = new CachedRowSetImpl(
128+ * "com.fred.providers.HighAvailabilityProvider");
129+ * </PRE>
130+ * <LI>Setting the <code>SyncProvider</code> using the <code>CachedRowSet</code>
131+ * method <code>setSyncProvider</code><BR>
132+ * The following line of code resets the <code>SyncProvider</code> object
133+ * for <i>crs</i>, the <code>CachedRowSet</code> object created with the
134+ * default constructor.
135+ * <PRE>
136+ * crs.setSyncProvider("com.fred.providers.HighAvailabilityProvider");
137+ * </PRE>
138+ * </UL)
139+ * See the comments for <code>SyncFactory</code> and <code>SyncProvider</code> for
140+ * more details.
141+ *
142+ * <P>
143+ * <h3>2.0 Retrieving Data from a <code>CachedRowSet</code> Object</h3>
144+ * Data is retrieved from a <code>CachedRowSet</code> object by using the
145+ * getter methods inherited from the <code>ResultSet</code>
146+ * interface. The following examples, in which <code>crs</code> is a
147+ * <code>CachedRowSet</code>
148+ * object, demonstrate how to iterate through the rows, retrieving the column
149+ * values in each row. The first example uses the version of the
150+ * getter methods that take a column number; the second example
151+ * uses the version that takes a column name. Column numbers are generally
152+ * used when the <code>RowSet</code> object's command
153+ * is of the form <code>SELECT * FROM TABLENAME</code>; column names are most
154+ * commonly used when the command specifies columns by name.
155+ * <PRE>
156+ * while (crs.next()) {
157+ * String name = crs.getString(1);
158+ * int id = crs.getInt(2);
159+ * Clob comment = crs.getClob(3);
160+ * short dept = crs.getShort(4);
161+ * System.out.println(name + " " + id + " " + comment + " " + dept);
162+ * }
163+ * </PRE>
164+ *
165+ * <PRE>
166+ * while (crs.next()) {
167+ * String name = crs.getString("NAME");
168+ * int id = crs.getInt("ID");
169+ * Clob comment = crs.getClob("COM");
170+ * short dept = crs.getShort("DEPT");
171+ * System.out.println(name + " " + id + " " + comment + " " + dept);
172+ * }
173+ * </PRE>
174+ * <h4>2.1 Retrieving <code>RowSetMetaData</code></h4>
175+ * An application can get information about the columns in a <code>CachedRowSet</code>
176+ * object by calling <code>ResultSetMetaData</code> and <code>RowSetMetaData</code>
177+ * methods on a <code>RowSetMetaData</code> object. The following code fragment,
178+ * in which <i>crs</i> is a <code>CachedRowSet</code> object, illustrates the process.
179+ * The first line creates a <code>RowSetMetaData</code> object with information
180+ * about the columns in <i>crs</i>. The method <code>getMetaData</code>,
181+ * inherited from the <code>ResultSet</code> interface, returns a
182+ * <code>ResultSetMetaData</code> object, which is cast to a
183+ * <code>RowSetMetaData</code> object before being assigned to the variable
184+ * <i>rsmd</i>. The second line finds out how many columns <i>jrs</i> has, and
185+ * the third line gets the JDBC type of values stored in the second column of
186+ * <code>jrs</code>.
187+ * <PRE>
188+ * RowSetMetaData rsmd = (RowSetMetaData)crs.getMetaData();
189+ * int count = rsmd.getColumnCount();
190+ * int type = rsmd.getColumnType(2);
191+ * </PRE>
192+ * The <code>RowSetMetaData</code> interface differs from the
193+ * <code>ResultSetMetaData</code> interface in two ways.
194+ * <UL>
195+ * <LI><i>It includes <code>setter</code> methods:</i> A <code>RowSet</code>
196+ * object uses these methods internally when it is populated with data from a
197+ * different <code>ResultSet</code> object.
198+ * <P>
199+ * <LI><i>It contains fewer <code>getter</code> methods:</i> Some
200+ * <code>ResultSetMetaData</code> methods to not apply to a <code>RowSet</code>
201+ * object. For example, methods retrieving whether a column value is writable
202+ * or read only do not apply because all of a <code>RowSet</code> object's
203+ * columns will be writable or read only, depending on whether the rowset is
204+ * updatable or not.
205+ * </UL>
206+ * NOTE: In order to return a <code>RowSetMetaData</code> object, implementations must
207+ * override the <code>getMetaData()</code> method defined in
208+ * <code>java.sql.ResultSet</code> and return a <code>RowSetMetaData</code> object.
209+ *
210+ * <h3>3.0 Updating a <code>CachedRowSet</code> Object</h3>
211+ * Updating a <code>CachedRowSet</code> object is similar to updating a
212+ * <code>ResultSet</code> object, but because the rowset is not connected to
213+ * its data source while it is being updated, it must take an additional step
214+ * to effect changes in its underlying data source. After calling the method
215+ * <code>updateRow</code> or <code>insertRow</code>, a
216+ * <code>CachedRowSet</code>
217+ * object must also call the method <code>acceptChanges</code> to have updates
218+ * written to the data source. The following example, in which the cursor is
219+ * on a row in the <code>CachedRowSet</code> object <i>crs</i>, shows
220+ * the code required to update two column values in the current row and also
221+ * update the <code>RowSet</code> object's underlying data source.
222+ * <PRE>
223+ * crs.updateShort(3, 58);
224+ * crs.updateInt(4, 150000);
225+ * crs.updateRow();
226+ * crs.acceptChanges();
227+ * </PRE>
228+ * <P>
229+ * The next example demonstrates moving to the insert row, building a new
230+ * row on the insert row, inserting it into the rowset, and then calling the
231+ * method <code>acceptChanges</code> to add the new row to the underlying data
232+ * source. Note that as with the getter methods, the updater methods may take
233+ * either a column index or a column name to designate the column being acted upon.
234+ * <PRE>
235+ * crs.moveToInsertRow();
236+ * crs.updateString("Name", "Shakespeare");
237+ * crs.updateInt("ID", 10098347);
238+ * crs.updateShort("Age", 58);
239+ * crs.updateInt("Sal", 150000);
240+ * crs.insertRow();
241+ * crs.moveToCurrentRow();
242+ * crs.acceptChanges();
243+ * </PRE>
244+ * <P>
245+ * NOTE: Where the <code>insertRow()</code> method inserts the contents of a
246+ * <code>CachedRowSet</code> object's insert row is implementation-defined.
247+ * The reference implementation for the <code>CachedRowSet</code> interface
248+ * inserts a new row immediately following the current row, but it could be
249+ * implemented to insert new rows in any number of other places.
250+ * <P>
251+ * Another thing to note about these examples is how they use the method
252+ * <code>acceptChanges</code>. It is this method that propagates changes in
253+ * a <code>CachedRowSet</code> object back to the underlying data source,
254+ * calling on the <code>RowSet</code> object's writer internally to write
255+ * changes to the data source. To do this, the writer has to incur the expense
256+ * of establishing a connection with that data source. The
257+ * preceding two code fragments call the method <code>acceptChanges</code>
258+ * immediately after calling <code>updateRow</code> or <code>insertRow</code>.
259+ * However, when there are multiple rows being changed, it is more efficient to call
260+ * <code>acceptChanges</code> after all calls to <code>updateRow</code>
261+ * and <code>insertRow</code> have been made. If <code>acceptChanges</code>
262+ * is called only once, only one connection needs to be established.
263+ * <P>
264+ * <h3>4.0 Updating the Underlying Data Source</h3>
265+ * When the method <code>acceptChanges</code> is executed, the
266+ * <code>CachedRowSet</code> object's writer, a <code>RowSetWriterImpl</code>
267+ * object, is called behind the scenes to write the changes made to the
268+ * rowset to the underlying data source. The writer is implemented to make a
269+ * connection to the data source and write updates to it.
270+ * <P>
271+ * A writer is made available through an implementation of the
272+ * <code>SyncProvider</code> interface, as discussed in section 1,
273+ * "Creating a <code>CachedRowSet</code> Object."
274+ * The default reference implementation provider, <code>RIOptimisticProvider</code>,
275+ * has its writer implemented to use an optimistic concurrency control
276+ * mechanism. That is, it maintains no locks in the underlying database while
277+ * the rowset is disconnected from the database and simply checks to see if there
278+ * are any conflicts before writing data to the data source. If there are any
279+ * conflicts, it does not write anything to the data source.
280+ * <P>
281+ * The reader/writer facility
282+ * provided by the <code>SyncProvider</code> class is pluggable, allowing for the
283+ * customization of data retrieval and updating. If a different concurrency
284+ * control mechanism is desired, a different implementation of
285+ * <code>SyncProvider</code> can be plugged in using the method
286+ * <code>setSyncProvider</code>.
287+ * <P>
288+ * In order to use the optimistic concurrency control routine, the
289+ * <code>RIOptismisticProvider</code> maintains both its current
290+ * value and its original value (the value it had immediately preceding the
291+ * current value). Note that if no changes have been made to the data in a
292+ * <code>RowSet</code> object, its current values and its original values are the same,
293+ * both being the values with which the <code>RowSet</code> object was initially
294+ * populated. However, once any values in the <code>RowSet</code> object have been
295+ * changed, the current values and the original values will be different, though at
296+ * this stage, the original values are still the initial values. With any subsequent
297+ * changes to data in a <code>RowSet</code> object, its original values and current
298+ * values will still differ, but its original values will be the values that
299+ * were previously the current values.
300+ * <P>
301+ * Keeping track of original values allows the writer to compare the <code>RowSet</code>
302+ * object's original value with the value in the database. If the values in
303+ * the database differ from the <code>RowSet</code> object's original values, which means that
304+ * the values in the database have been changed, there is a conflict.
305+ * Whether a writer checks for conflicts, what degree of checking it does, and how
306+ * it handles conflicts all depend on how it is implemented.
307+ * <P>
308+ * <h3>5.0 Registering and Notifying Listeners</h3>
309+ * Being JavaBeans components, all rowsets participate in the JavaBeans event
310+ * model, inheriting methods for registering listeners and notifying them of
311+ * changes from the <code>BaseRowSet</code> class. A listener for a
312+ * <code>CachedRowSet</code> object is a component that wants to be notified
313+ * whenever there is a change in the rowset. For example, if a
314+ * <code>CachedRowSet</code> object contains the results of a query and
315+ * those
316+ * results are being displayed in, say, a table and a bar graph, the table and
317+ * bar graph could be registered as listeners with the rowset so that they can
318+ * update themselves to reflect changes. To become listeners, the table and
319+ * bar graph classes must implement the <code>RowSetListener</code> interface.
320+ * Then they can be added to the <Code>CachedRowSet</code> object's list of
321+ * listeners, as is illustrated in the following lines of code.
322+ * <PRE>
323+ * crs.addRowSetListener(table);
324+ * crs.addRowSetListener(barGraph);
325+ * </PRE>
326+ * Each <code>CachedRowSet</code> method that moves the cursor or changes
327+ * data also notifies registered listeners of the changes, so
328+ * <code>table</code> and <code>barGraph</code> will be notified when there is
329+ * a change in <code>crs</code>.
330+ * <P>
331+ * <h3>6.0 Passing Data to Thin Clients</h3>
332+ * One of the main reasons to use a <code>CachedRowSet</code> object is to
333+ * pass data between different components of an application. Because it is
334+ * serializable, a <code>CachedRowSet</code> object can be used, for example,
335+ * to send the result of a query executed by an enterprise JavaBeans component
336+ * running in a server environment over a network to a client running in a
337+ * web browser.
338+ * <P>
339+ * While a <code>CachedRowSet</code> object is disconnected, it can be much
340+ * leaner than a <code>ResultSet</code> object with the same data.
341+ * As a result, it can be especially suitable for sending data to a thin client
342+ * such as a PDA, where it would be inappropriate to use a JDBC driver
343+ * due to resource limitations or security considerations.
344+ * Thus, a <code>CachedRowSet</code> object provides a means to "get rows in"
345+ * without the need to implement the full JDBC API.
346+ * <P>
347+ * <h3>7.0 Scrolling and Updating</h3>
348+ * A second major use for <code>CachedRowSet</code> objects is to provide
349+ * scrolling and updating for <code>ResultSet</code> objects that
350+ * do not provide these capabilities themselves. In other words, a
351+ * <code>CachedRowSet</code> object can be used to augment the
352+ * capabilities of a JDBC technology-enabled driver (hereafter called a
353+ * "JDBC driver") when the DBMS does not provide full support for scrolling and
354+ * updating. To achieve the effect of making a non-scrollble and read-only
355+ * <code>ResultSet</code> object scrollable and updatable, a programmer
356+ * simply needs to create a <code>CachedRowSet</code> object populated
357+ * with that <code>ResultSet</code> object's data. This is demonstrated
358+ * in the following code fragment, where <code>stmt</code> is a
359+ * <code>Statement</code> object.
360+ * <PRE>
361+ * ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEES");
362+ * CachedRowSetImpl crs = new CachedRowSetImpl();
363+ * crs.populate(rs);
364+ * </PRE>
365+ * <P>
366+ * The object <code>crs</code> now contains the data from the table
367+ * <code>EMPLOYEES</code>, just as the object <code>rs</code> does.
368+ * The difference is that the cursor for <code>crs</code> can be moved
369+ * forward, backward, or to a particular row even if the cursor for
370+ * <code>rs</code> can move only forward. In addition, <code>crs</code> is
371+ * updatable even if <code>rs</code> is not because by default, a
372+ * <code>CachedRowSet</code> object is both scrollable and updatable.
373+ * <P>
374+ * In summary, a <code>CachedRowSet</code> object can be thought of as simply
375+ * a disconnected set of rows that are being cached outside of a data source.
376+ * Being thin and serializable, it can easily be sent across a wire,
377+ * and it is well suited to sending data to a thin client. However, a
378+ * <code>CachedRowSet</code> object does have a limitation: It is limited in
379+ * size by the amount of data it can store in memory at one time.
380+ * <P>
381+ * <h3>8.0 Getting Universal Data Access</h3>
382+ * Another advantage of the <code>CachedRowSet</code> class is that it makes it
383+ * possible to retrieve and store data from sources other than a relational
384+ * database. The reader for a rowset can be implemented to read and populate
385+ * its rowset with data from any tabular data source, including a spreadsheet
386+ * or flat file.
387+ * Because both a <code>CachedRowSet</code> object and its metadata can be
388+ * created from scratch, a component that acts as a factory for rowsets
389+ * can use this capability to create a rowset containing data from
390+ * non-SQL data sources. Nevertheless, it is expected that most of the time,
391+ * <code>CachedRowSet</code> objects will contain data that was fetched
392+ * from an SQL database using the JDBC API.
393+ * <P>
394+ * <h3>9.0 Setting Properties</h3>
395+ * All rowsets maintain a set of properties, which will usually be set using
396+ * a tool. The number and kinds of properties a rowset has will vary,
397+ * depending on what the rowset does and how it gets its data. For example,
398+ * rowsets that get their data from a <code>ResultSet</code> object need to
399+ * set the properties that are required for making a database connection.
400+ * If a rowset uses the <code>DriverManager</code> facility to make a
401+ * connection, it needs to set a property for the JDBC URL that identifies
402+ * the appropriate driver, and it needs to set the properties that give the
403+ * user name and password.
404+ * If, on the other hand, the rowset uses a <code>DataSource</code> object
405+ * to make the connection, which is the preferred method, it does not need to
406+ * set the property for the JDBC URL. Instead, it needs to set
407+ * properties for the logical name of the data source, for the user name,
408+ * and for the password.
409+ * <P>
410+ * NOTE: In order to use a <code>DataSource</code> object for making a
411+ * connection, the <code>DataSource</code> object must have been registered
412+ * with a naming service that uses the Java Naming and Directory
413+ * Interface<sup><font size=-2>TM</font></sup> (JNDI) API. This registration
414+ * is usually done by a person acting in the capacity of a system
415+ * administrator.
416+ * <P>
417+ * In order to be able to populate itself with data from a database, a rowset
418+ * needs to set a command property. This property is a query that is a
419+ * <code>PreparedStatement</code> object, which allows the query to have
420+ * parameter placeholders that are set at run time, as opposed to design time.
421+ * To set these placeholder parameters with values, a rowset provides
422+ * setter methods for setting values of each data type,
423+ * similar to the setter methods provided by the <code>PreparedStatement</code>
424+ * interface.
425+ * <P>
426+ * The following code fragment illustrates how the <code>CachedRowSet</code>
427+ * object <code>crs</code> might have its command property set. Note that if a
428+ * tool is used to set properties, this is the code that the tool would use.
429+ * <PRE>
430+ * crs.setCommand("SELECT FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS " +
431+ * "WHERE CREDIT_LIMIT > ? AND REGION = ?");
432+ * </PRE>
433+ * <P>
434+ * The values that will be used to set the command's placeholder parameters are
435+ * contained in the <code>RowSet</code> object's <code>params</code> field, which is a
436+ * <code>Vector</code> object.
437+ * The <code>CachedRowSet</code> class provides a set of setter
438+ * methods for setting the elements in its <code>params</code> field. The
439+ * following code fragment demonstrates setting the two parameters in the
440+ * query from the previous example.
441+ * <PRE>
442+ * crs.setInt(1, 5000);
443+ * crs.setString(2, "West");
444+ * </PRE>
445+ * <P>
446+ * The <code>params</code> field now contains two elements, each of which is
447+ * an array two elements long. The first element is the parameter number;
448+ * the second is the value to be set.
449+ * In this case, the first element of <code>params</code> is
450+ * <code>1</code>, <code>5000</code>, and the second element is <code>2</code>,
451+ * <code>"West"</code>. When an application calls the method
452+ * <code>execute</code>, it will in turn call on this <code>RowSet</code> object's reader,
453+ * which will in turn invoke its <code>readData</code> method. As part of
454+ * its implementation, <code>readData</code> will get the values in
455+ * <code>params</code> and use them to set the command's placeholder
456+ * parameters.
457+ * The following code fragment gives an idea of how the reader
458+ * does this, after obtaining the <code>Connection</code> object
459+ * <code>con</code>.
460+ * <PRE>
461+ * PreparedStatement pstmt = con.prepareStatement(crs.getCommand());
462+ * reader.decodeParams();
463+ * // decodeParams figures out which setter methods to use and does something
464+ * // like the following:
465+ * // for (i = 0; i < params.length; i++) {
466+ * // pstmt.setObject(i + 1, params[i]);
467+ * // }
468+ * </PRE>
469+ * <P>
470+ * At this point, the command for <code>crs</code> is the query <code>"SELECT
471+ * FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS WHERE CREDIT_LIMIT > 5000
472+ * AND REGION = "West"</code>. After the <code>readData</code> method executes
473+ * this command with the following line of code, it will have the data from
474+ * <code>rs</code> with which to populate <code>crs</code>.
475+ * <PRE>
476+ * ResultSet rs = pstmt.executeQuery();
477+ * </PRE>
478+ * <P>
479+ * The preceding code fragments give an idea of what goes on behind the
480+ * scenes; they would not appear in an application, which would not invoke
481+ * methods like <code>readData</code> and <code>decodeParams</code>.
482+ * In contrast, the following code fragment shows what an application might do.
483+ * It sets the rowset's command, sets the command's parameters, and executes
484+ * the command. Simply by calling the <code>execute</code> method,
485+ * <code>crs</code> populates itself with the requested data from the
486+ * table <code>CUSTOMERS</code>.
487+ * <PRE>
488+ * crs.setCommand("SELECT FIRST_NAME, LAST_NAME, ADDRESS FROM CUSTOMERS" +
489+ * "WHERE CREDIT_LIMIT > ? AND REGION = ?");
490+ * crs.setInt(1, 5000);
491+ * crs.setString(2, "West");
492+ * crs.execute();
493+ * </PRE>
494+ *
495+ * <h3>10.0 Paging Data</h3>
496+ * Because a <code>CachedRowSet</code> object stores data in memory,
497+ * the amount of data that it can contain at any one
498+ * time is determined by the amount of memory available. To get around this limitation,
499+ * a <code>CachedRowSet</code> object can retrieve data from a <code>ResultSet</code>
500+ * object in chunks of data, called <i>pages</i>. To take advantage of this mechanism,
501+ * an application sets the number of rows to be included in a page using the method
502+ * <code>setPageSize</code>. In other words, if the page size is set to five, a chunk
503+ * of five rows of
504+ * data will be fetched from the data source at one time. An application can also
505+ * optionally set the maximum number of rows that may be fetched at one time. If the
506+ * maximum number of rows is set to zero, or no maximum number of rows is set, there is
507+ * no limit to the number of rows that may be fetched at a time.
508+ * <P>
509+ * After properties have been set,
510+ * the <code>CachedRowSet</code> object must be populated with data
511+ * using either the method <code>populate</code> or the method <code>execute</code>.
512+ * The following lines of code demonstrate using the method <code>populate</code>.
513+ * Note that this version of the method takes two parameters, a <code>ResultSet</code>
514+ * handle and the row in the <code>ResultSet</code> object from which to start
515+ * retrieving rows.
516+ * <PRE>
517+ * CachedRowSet crs = new CachedRowSetImpl();
518+ * crs.setMaxRows(20);
519+ * crs.setPageSize(4);
520+ * crs.populate(rsHandle, 10);
521+ * </PRE>
522+ * When this code runs, <i>crs</i> will be populated with four rows from
523+ * <i>rsHandle</i> starting with the tenth row.
524+ * <P>
525+ * The next code fragment shows populating a <code>CachedRowSet</code> object using the
526+ * method <code>execute</code>, which may or may not take a <code>Connection</code>
527+ * object as a parameter. This code passes <code>execute</code> the <code>Connection</code>
528+ * object <i>conHandle</i>.
529+ * <P>
530+ * Note that there are two differences between the following code
531+ * fragment and the previous one. First, the method <code>setMaxRows</code> is not
532+ * called, so there is no limit set for the number of rows that <i>crs</i> may contain.
533+ * (Remember that <i>crs</i> always has the overriding limit of how much data it can
534+ * store in memory.) The second difference is that the you cannot pass the method
535+ * <code>execute</code> the number of the row in the <code>ResultSet</code> object
536+ * from which to start retrieving rows. This method always starts with the first row.
537+ * <PRE>
538+ * CachedRowSet crs = new CachedRowSetImpl();
539+ * crs.setPageSize(5);
540+ * crs.execute(conHandle);
541+ * </PRE>
542+ * After this code has run, <i>crs</i> will contain five rows of data from the
543+ * <code>ResultSet</code> object produced by the command for <i>crs</i>. The writer
544+ * for <i>crs</i> will use <i>conHandle</i> to connect to the data source and
545+ * execute the command for <i>crs</i>. An application is then able to operate on the
546+ * data in <i>crs</i> in the same way that it would operate on data in any other
547+ * <code>CachedRowSet</code> object.
548+ * <P>
549+ * To access the next page (chunk of data), an application calls the method
550+ * <code>nextPage</code>. This method creates a new <code>CachedRowSet</code> object
551+ * and fills it with the next page of data. For example, assume that the
552+ * <code>CachedRowSet</code> object's command returns a <code>ResultSet</code> object
553+ * <i>rs</i> with 1000 rows of data. If the page size has been set to 100, the first
554+ * call to the method <code>nextPage</code> will create a <code>CachedRowSet</code> object
555+ * containing the first 100 rows of <i>rs</i>. After doing what it needs to do with the
556+ * data in these first 100 rows, the application can again call the method
557+ * <code>nextPage</code> to create another <code>CachedRowSet</code> object
558+ * with the second 100 rows from <i>rs</i>. The data from the first <code>CachedRowSet</code>
559+ * object will no longer be in memory because it is replaced with the data from the
560+ * second <code>CachedRowSet</code> object. After the tenth call to the method <code>nextPage</code>,
561+ * the tenth <code>CachedRowSet</code> object will contain the last 100 rows of data from
562+ * <i>rs</i>, which are stored in memory. At any given time, the data from only one
563+ * <code>CachedRowSet</code> object is stored in memory.
564+ * <P>
565+ * The method <code>nextPage</code> returns <code>true</code> as long as the current
566+ * page is not the last page of rows and <code>false</code> when there are no more pages.
567+ * It can therefore be used in a <code>while</code> loop to retrieve all of the pages,
568+ * as is demonstrated in the following lines of code.
569+ * <PRE>
570+ * CachedRowSet crs = CachedRowSetImpl();
571+ * crs.setPageSize(100);
572+ * crs.execute(conHandle);
573+ *
574+ * while(crs.nextPage()) {
575+ * while(crs.next()) {
576+ * . . . // operate on chunks (of 100 rows each) in crs,
577+ * // row by row
578+ * }
579+ * }
580+ * </PRE>
581+ * After this code fragment has been run, the application will have traversed all
582+ * 1000 rows, but it will have had no more than 100 rows in memory at a time.
583+ * <P>
584+ * The <code>CachedRowSet</code> interface also defines the method <code>previousPage</code>.
585+ * Just as the method <code>nextPage</code> is analogous to the <code>ResultSet</code>
586+ * method <code>next</code>, the method <code>previousPage</code> is analogous to
587+ * the <code>ResultSet</code> method <code>previous</code>. Similar to the method
588+ * <code>nextPage</code>, <code>previousPage</code> creates a <code>CachedRowSet</code>
589+ * object containing the number of rows set as the page size. So, for instance, the
590+ * method <code>previousPage</code> could be used in a <code>while</code> loop at
591+ * the end of the preceding code fragment to navigate back through the pages from the last
592+ * page to the first page.
593+ * The method <code>previousPage</code> is also similar to <code>nextPage</code>
594+ * in that it can be used in a <code>while</code>
595+ * loop, except that it returns <code>true</code> as long as there is another page
596+ * preceding it and <code>false</code> when there are no more pages ahead of it.
597+ * <P>
598+ * By positioning the cursor after the last row for each page,
599+ * as is done in the following code fragment, the method <code>previous</code>
600+ * navigates from the last row to the first row in each page.
601+ * The code could also have left the cursor before the first row on each page and then
602+ * used the method <code>next</code> in a <code>while</code> loop to navigate each page
603+ * from the first row to the last row.
604+ * <P>
605+ * The following code fragment assumes a continuation from the previous code fragment,
606+ * meaning that the cursor for the tenth <code>CachedRowSet</code> object is on the
607+ * last row. The code moves the cursor to after the last row so that the first
608+ * call to the method <code>previous</code> will put the cursor back on the last row.
609+ * After going through all of the rows in the last page (the <code>CachedRowSet</code>
610+ * object <i>crs</i>), the code then enters
611+ * the <code>while</code> loop to get to the ninth page, go through the rows backwards,
612+ * go to the eighth page, go through the rows backwards, and so on to the first row
613+ * of the first page.
614+ *
615+ * <PRE>
616+ * crs.afterLast();
617+ * while(crs.previous()) {
618+ * . . . // navigate through the rows, last to first
619+ * {
620+ * while(crs.previousPage()) {
621+ * crs.afterLast();
622+ * while(crs.previous()) {
623+ * . . . // go from the last row to the first row of each page
624+ * }
625+ * }
626+ * </PRE>
627+ *
628+ * @author Jonathan Bruce
629+ */
630+
631+public interface CachedRowSet extends RowSet, Joinable {
632+
633+ /**
634+ * Populates this <code>CachedRowSet</code> object with data from
635+ * the given <code>ResultSet</code> object.
636+ * <P>
637+ * This method can be used as an alternative to the <code>execute</code> method when an
638+ * application has a connection to an open <code>ResultSet</code> object.
639+ * Using the method <code>populate</code> can be more efficient than using
640+ * the version of the <code>execute</code> method that takes no parameters
641+ * because it does not open a new connection and re-execute this
642+ * <code>CachedRowSet</code> object's command. Using the <code>populate</code>
643+ * method is more a matter of convenience when compared to using the version
644+ * of <code>execute</code> that takes a <code>ResultSet</code> object.
645+ *
646+ * @param data the <code>ResultSet</code> object containing the data
647+ * to be read into this <code>CachedRowSet</code> object
648+ * @throws SQLException if a null <code>ResultSet</code> object is supplied
649+ * or this <code>CachedRowSet</code> object cannot
650+ * retrieve the associated <code>ResultSetMetaData</code> object
651+ * @see #execute
652+ * @see java.sql.ResultSet
653+ * @see java.sql.ResultSetMetaData
654+ */
655+ public void populate(ResultSet data) throws SQLException;
656+
657+ /**
658+ * Populates this <code>CachedRowSet</code> object with data, using the
659+ * given connection to produce the result set from which the data will be read.
660+ * This method should close any database connections that it creates to
661+ * ensure that this <code>CachedRowSet</code> object is disconnected except when
662+ * it is reading data from its data source or writing data to its data source.
663+ * <P>
664+ * The reader for this <code>CachedRowSet</code> object
665+ * will use <i>conn</i> to establish a connection to the data source
666+ * so that it can execute the rowset's command and read data from the
667+ * the resulting <code>ResultSet</code> object into this
668+ * <code>CachedRowSet</code> object. This method also closes <i>conn</i>
669+ * after it has populated this <code>CachedRowSet</code> object.
670+ * <P>
671+ * If this method is called when an implementation has already been
672+ * populated, the contents and the metadata are (re)set. Also, if this method is
673+ * called before the method <code>acceptChanges</code> has been called
674+ * to commit outstanding updates, those updates are lost.
675+ *
676+ * @param conn a standard JDBC <code>Connection</code> object with valid
677+ * properties
678+ * @throws SQLException if an invalid <code>Connection</code> object is supplied
679+ * or an error occurs in establishing the connection to the
680+ * data source
681+ * @see #populate
682+ * @see java.sql.Connection
683+ */
684+ public void execute(Connection conn) throws SQLException;
685+
686+ /**
687+ * Propagates row update, insert and delete changes made to this
688+ * <code>CachedRowSet</code> object to the underlying data source.
689+ * <P>
690+ * This method calls on this <code>CachedRowSet</code> object's writer
691+ * to do the work behind the scenes.
692+ * Standard <code>CachedRowSet</code> implementations should use the
693+ * <code>SyncFactory</code> singleton
694+ * to obtain a <code>SyncProvider</code> instance providing a
695+ * <code>RowSetWriter</code> object (writer). The writer will attempt
696+ * to propagate changes made in this <code>CachedRowSet</code> object
697+ * back to the data source.
698+ * <P>
699+ * When the method <code>acceptChanges</code> executes successfully, in
700+ * addition to writing changes to the data source, it
701+ * makes the values in the current row be the values in the original row.
702+ * <P>
703+ * Depending on the synchronization level of the <code>SyncProvider</code>
704+ * implementation being used, the writer will compare the original values
705+ * with those in the data source to check for conflicts. When there is a conflict,
706+ * the <code>RIOptimisticProvider</code> implementation, for example, throws a
707+ * <code>SyncProviderException</code> and does not write anything to the
708+ * data source.
709+ * <P>
710+ * An application may choose to catch the <code>SyncProviderException</code>
711+ * object and retrieve the <code>SyncResolver</code> object it contains.
712+ * The <code>SyncResolver</code> object lists the conflicts row by row and
713+ * sets a lock on the data source to avoid further conflicts while the
714+ * current conflicts are being resolved.
715+ * Further, for each conflict, it provides methods for examining the conflict
716+ * and setting the value that should be persisted in the data source.
717+ * After all conflicts have been resolved, an application must call the
718+ * <code>acceptChanges</code> method again to write resolved values to the
719+ * data source. If all of the values in the data source are already the
720+ * values to be persisted, the method <code>acceptChanges</code> does nothing.
721+ * <P>
722+ * Some provider implementations may use locks to ensure that there are no
723+ * conflicts. In such cases, it is guaranteed that the writer will succeed in
724+ * writing changes to the data source when the method <code>acceptChanges</code>
725+ * is called. This method may be called immediately after the methods
726+ * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>
727+ * have been called, but it is more efficient to call it only once after
728+ * all changes have been made so that only one connection needs to be
729+ * established.
730+ * <P>
731+ * Note: The <code>acceptChanges()</code> method will determine if the
732+ * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set
733+ * to true, all updates in the synchronization are committed to the data
734+ * source. Otherwise, the application <b>must</b> explicity call the
735+ * <code>commit()</code> or <code>rollback()</code> methods as appropriate.
736+ *
737+ * @throws SQLException if the cursor is on the insert row
738+ * @throws SyncProviderException if the underlying
739+ * synchronization provider's writer fails to write the updates
740+ * back to the data source
741+ * @see #acceptChanges(java.sql.Connection)
742+ * @see javax.sql.RowSetWriter
743+ * @see javax.sql.rowset.spi.SyncFactory
744+ * @see javax.sql.rowset.spi.SyncProvider
745+ * @see javax.sql.rowset.spi.SyncProviderException
746+ * @see javax.sql.rowset.spi.SyncResolver
747+ */
748+ public void acceptChanges() throws SyncProviderException;
749+
750+ /**
751+ * Propagates all row update, insert and delete changes to the
752+ * data source backing this <code>CachedRowSet</code> object
753+ * using the specified <code>Connection</code> object to establish a
754+ * connection to the data source.
755+ * <P>
756+ * The other version of the <code>acceptChanges</code> method is not passed
757+ * a connection because it uses
758+ * the <code>Connection</code> object already defined within the <code>RowSet</code>
759+ * object, which is the connection used for populating it initially.
760+ * <P>
761+ * This form of the method <code>acceptChanges</code> is similar to the
762+ * form that takes no arguments; however, unlike the other form, this form
763+ * can be used only when the underlying data source is a JDBC data source.
764+ * The updated <code>Connection</code> properties must be used by the
765+ * <code>SyncProvider</code> to reset the <code>RowSetWriter</code>
766+ * configuration to ensure that the contents of the <code>CachedRowSet</code>
767+ * object are synchronized correctly.
768+ * <P>
769+ * When the method <code>acceptChanges</code> executes successfully, in
770+ * addition to writing changes to the data source, it
771+ * makes the values in the current row be the values in the original row.
772+ * <P>
773+ * Depending on the synchronization level of the <code>SyncProvider</code>
774+ * implementation being used, the writer will compare the original values
775+ * with those in the data source to check for conflicts. When there is a conflict,
776+ * the <code>RIOptimisticProvider</code> implementation, for example, throws a
777+ * <code>SyncProviderException</code> and does not write anything to the
778+ * data source.
779+ * <P>
780+ * An application may choose to catch the <code>SyncProviderException</code>
781+ * object and retrieve the <code>SyncResolver</code> object it contains.
782+ * The <code>SyncResolver</code> object lists the conflicts row by row and
783+ * sets a lock on the data source to avoid further conflicts while the
784+ * current conflicts are being resolved.
785+ * Further, for each conflict, it provides methods for examining the conflict
786+ * and setting the value that should be persisted in the data source.
787+ * After all conflicts have been resolved, an application must call the
788+ * <code>acceptChanges</code> method again to write resolved values to the
789+ * data source. If all of the values in the data source are already the
790+ * values to be persisted, the method <code>acceptChanges</code> does nothing.
791+ * <P>
792+ * Some provider implementations may use locks to ensure that there are no
793+ * conflicts. In such cases, it is guaranteed that the writer will succeed in
794+ * writing changes to the data source when the method <code>acceptChanges</code>
795+ * is called. This method may be called immediately after the methods
796+ * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>
797+ * have been called, but it is more efficient to call it only once after
798+ * all changes have been made so that only one connection needs to be
799+ * established.
800+ * <P>
801+ * Note: The <code>acceptChanges()</code> method will determine if the
802+ * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set
803+ * to true, all updates in the synchronization are committed to the data
804+ * source. Otherwise, the application <b>must</b> explicity call the
805+ * <code>commit</code> or <code>rollback</code> methods as appropriate.
806+ *
807+ * @param con a standard JDBC <code>Connection</code> object
808+ * @throws SQLException if the cursor is on the insert row
809+ * @throws SyncProviderException if the underlying
810+ * synchronization provider's writer fails to write the updates
811+ * back to the data source
812+ * @see #acceptChanges()
813+ * @see javax.sql.RowSetWriter
814+ * @see javax.sql.rowset.spi.SyncFactory
815+ * @see javax.sql.rowset.spi.SyncProvider
816+ * @see javax.sql.rowset.spi.SyncProviderException
817+ * @see javax.sql.rowset.spi.SyncResolver
818+ */
819+ public void acceptChanges(Connection con) throws SyncProviderException;
820+
821+ /**
822+ * Restores this <code>CachedRowSet</code> object to its original
823+ * value, that is, its value before the last set of changes. If there
824+ * have been no changes to the rowset or only one set of changes,
825+ * the original value is the value with which this <code>CachedRowSet</code> object
826+ * was populated; otherwise, the original value is
827+ * the value it had immediately before its current value.
828+ * <P>
829+ * When this method is called, a <code>CachedRowSet</code> implementation
830+ * must ensure that all updates, inserts, and deletes to the current
831+ * rowset instance are replaced by the previous values. In addition,
832+ * the cursor should be
833+ * reset to the first row and a <code>rowSetChanged</code> event
834+ * should be fired to notify all registered listeners.
835+ *
836+ * @throws SQLException if an error occurs rolling back the current value of
837+ * this <code>CachedRowSet</code> object to its previous value
838+ * @see javax.sql.RowSetListener#rowSetChanged
839+ */
840+ public void restoreOriginal() throws SQLException;
841+
842+ /**
843+ * Releases the current contents of this <code>CachedRowSet</code>
844+ * object and sends a <code>rowSetChanged</code> event to all
845+ * registered listeners. Any outstanding updates are discarded and
846+ * the rowset contains no rows after this method is called. There
847+ * are no interactions with the underlying data source, and any rowset
848+ * content, metadata, and content updates should be non-recoverable.
849+ * <P>
850+ * This <code>CachedRowSet</code> object should lock until its contents and
851+ * associated updates are fully cleared, thus preventing 'dirty' reads by
852+ * other components that hold a reference to this <code>RowSet</code> object.
853+ * In addition, the contents cannot be released
854+ * until all all components reading this <code>CachedRowSet</code> object
855+ * have completed their reads. This <code>CachedRowSet</code> object
856+ * should be returned to normal behavior after firing the
857+ * <code>rowSetChanged</code> event.
858+ * <P>
859+ * The metadata, including JDBC properties and Synchronization SPI
860+ * properties, are maintained for future use. It is important that
861+ * properties such as the <code>command</code> property be
862+ * relevant to the originating data source from which this <code>CachedRowSet</code>
863+ * object was originally established.
864+ * <P>
865+ * This method empties a rowset, as opposed to the <code>close</code> method,
866+ * which marks the entire rowset as recoverable to allow the garbage collector
867+ * the rowset's Java VM resources.
868+ *
869+ * @throws SQLException if an error occurs flushing the contents of this
870+ * <code>CachedRowSet</code> object
871+ * @see javax.sql.RowSetListener#rowSetChanged
872+ * @see java.sql.ResultSet#close
873+ */
874+ public void release() throws SQLException;
875+
876+ /**
877+ * Cancels the deletion of the current row and notifies listeners that
878+ * a row has changed. After this method is called, the current row is
879+ * no longer marked for deletion. This method can be called at any
880+ * time during the lifetime of the rowset.
881+ * <P>
882+ * In addition, multiple cancellations of row deletions can be made
883+ * by adjusting the position of the cursor using any of the cursor
884+ * position control methods such as:
885+ * <ul>
886+ * <li><code>CachedRowSet.absolute</code>
887+ * <li><code>CachedRowSet.first</code>
888+ * <li><code>CachedRowSet.last</code>
889+ * </ul>
890+ *
891+ * @throws SQLException if (1) the current row has not been deleted or
892+ * (2) the cursor is on the insert row, before the first row, or
893+ * after the last row
894+ * @see javax.sql.rowset.CachedRowSet#undoInsert
895+ * @see java.sql.ResultSet#cancelRowUpdates
896+ */
897+ public void undoDelete() throws SQLException;
898+
899+ /**
900+ * Immediately removes the current row from this <code>CachedRowSet</code>
901+ * object if the row has been inserted, and also notifies listeners that a
902+ * row has changed. This method can be called at any time during the
903+ * lifetime of a rowset and assuming the current row is within
904+ * the exception limitations (see below), it cancels the row insertion
905+ * of the current row.
906+ * <P>
907+ * In addition, multiple cancellations of row insertions can be made
908+ * by adjusting the position of the cursor using any of the cursor
909+ * position control methods such as:
910+ * <ul>
911+ * <li><code>CachedRowSet.absolute</code>
912+ * <li><code>CachedRowSet.first</code>
913+ * <li><code>CachedRowSet.last</code>
914+ * </ul>
915+ *
916+ * @throws SQLException if (1) the current row has not been inserted or (2)
917+ * the cursor is before the first row, after the last row, or on the
918+ * insert row
919+ * @see javax.sql.rowset.CachedRowSet#undoDelete
920+ * @see java.sql.ResultSet#cancelRowUpdates
921+ */
922+ public void undoInsert() throws SQLException;
923+
924+
925+ /**
926+ * Immediately reverses the last update operation if the
927+ * row has been modified. This method can be
928+ * called to reverse updates on all columns until all updates in a row have
929+ * been rolled back to their state just prior to the last synchronization
930+ * (<code>acceptChanges</code>) or population. This method may also be called
931+ * while performing updates to the insert row.
932+ * <P>
933+ * <code>undoUpdate</code> may be called at any time during the lifetime of a
934+ * rowset; however, after a synchronization has occurred, this method has no
935+ * effect until further modification to the rowset data has occurred.
936+ *
937+ * @throws SQLException if the cursor is before the first row or after the last
938+ * row in in this <code>CachedRowSet</code> object
939+ * @see #undoDelete
940+ * @see #undoInsert
941+ * @see java.sql.ResultSet#cancelRowUpdates
942+ */
943+ public void undoUpdate() throws SQLException;
944+
945+ /**
946+ * Indicates whether the designated column in the current row of this
947+ * <code>CachedRowSet</code> object has been updated.
948+ *
949+ * @param idx an <code>int</code> identifying the column to be checked for updates
950+ * @return <code>true</code> if the designated column has been visibly updated;
951+ * <code>false</code> otherwise
952+ * @throws SQLException if the cursor is on the insert row, before the first row,
953+ * or after the last row
954+ * @see java.sql.DatabaseMetaData#updatesAreDetected
955+ */
956+ public boolean columnUpdated(int idx) throws SQLException;
957+
958+
959+ /**
960+ * Indicates whether the designated column in the current row of this
961+ * <code>CachedRowSet</code> object has been updated.
962+ *
963+ * @param columnName a <code>String</code> object giving the name of the
964+ * column to be checked for updates
965+ * @return <code>true</code> if the column has been visibly updated;
966+ * <code>false</code> otherwise
967+ * @throws SQLException if the cursor is on the insert row, before the first row,
968+ * or after the last row
969+ * @see java.sql.DatabaseMetaData#updatesAreDetected
970+ */
971+ public boolean columnUpdated(String columnName) throws SQLException;
972+
973+ /**
974+ * Converts this <code>CachedRowSet</code> object to a <code>Collection</code>
975+ * object that contains all of this <code>CachedRowSet</code> object's data.
976+ * Implementations have some latitude in
977+ * how they can represent this <code>Collection</code> object because of the
978+ * abstract nature of the <code>Collection</code> framework.
979+ * Each row must be fully represented in either a
980+ * general purpose <code>Collection</code> implementation or a specialized
981+ * <code>Collection</code> implementation, such as a <code>TreeMap</code>
982+ * object or a <code>Vector</code> object.
983+ * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
984+ * in the Java programming language.
985+ * <P>
986+ * The standard reference implementation for the <code>CachedRowSet</code>
987+ * interface uses a <code>TreeMap</code> object for the rowset, with the
988+ * values in each row being contained in <code>Vector</code> objects. It is
989+ * expected that most implementations will do the same.
990+ * <P>
991+ * The <code>TreeMap</code> type of collection guarantees that the map will be in
992+ * ascending key order, sorted according to the natural order for the
993+ * key's class.
994+ * Each key references a <code>Vector</code> object that corresponds to one
995+ * row of a <code>RowSet</code> object. Therefore, the size of each
996+ * <code>Vector</code> object must be exactly equal to the number of
997+ * columns in the <code>RowSet</code> object.
998+ * The key used by the <code>TreeMap</code> collection is determined by the
999+ * implementation, which may choose to leverage a set key that is
1000+ * available within the internal <code>RowSet</code> tabular structure by
1001+ * virtue of a key already set either on the <code>RowSet</code> object
1002+ * itself or on the underlying SQL data.
1003+ * <P>
1004+ *
1005+ * @return a <code>Collection</code> object that contains the values in
1006+ * each row in this <code>CachedRowSet</code> object
1007+ * @throws SQLException if an error occurs generating the collection
1008+ * @see #toCollection(int)
1009+ * @see #toCollection(String)
1010+ */
1011+ public Collection<?> toCollection() throws SQLException;
1012+
1013+ /**
1014+ * Converts the designated column in this <code>CachedRowSet</code> object
1015+ * to a <code>Collection</code> object. Implementations have some latitude in
1016+ * how they can represent this <code>Collection</code> object because of the
1017+ * abstract nature of the <code>Collection</code> framework.
1018+ * Each column value should be fully represented in either a
1019+ * general purpose <code>Collection</code> implementation or a specialized
1020+ * <code>Collection</code> implementation, such as a <code>Vector</code> object.
1021+ * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
1022+ * in the Java programming language.
1023+ * <P>
1024+ * The standard reference implementation uses a <code>Vector</code> object
1025+ * to contain the column values, and it is expected
1026+ * that most implementations will do the same. If a <code>Vector</code> object
1027+ * is used, it size must be exactly equal to the number of rows
1028+ * in this <code>CachedRowSet</code> object.
1029+ *
1030+ * @param column an <code>int</code> indicating the column whose values
1031+ * are to be represented in a <code>Collection</code> object
1032+ * @return a <code>Collection</code> object that contains the values
1033+ * stored in the specified column of this <code>CachedRowSet</code>
1034+ * object
1035+ * @throws SQLException if an error occurs generating the collection or
1036+ * an invalid column id is provided
1037+ * @see #toCollection
1038+ * @see #toCollection(String)
1039+ */
1040+ public Collection<?> toCollection(int column) throws SQLException;
1041+
1042+ /**
1043+ * Converts the designated column in this <code>CachedRowSet</code> object
1044+ * to a <code>Collection</code> object. Implementations have some latitude in
1045+ * how they can represent this <code>Collection</code> object because of the
1046+ * abstract nature of the <code>Collection</code> framework.
1047+ * Each column value should be fully represented in either a
1048+ * general purpose <code>Collection</code> implementation or a specialized
1049+ * <code>Collection</code> implementation, such as a <code>Vector</code> object.
1050+ * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
1051+ * in the Java programming language.
1052+ * <P>
1053+ * The standard reference implementation uses a <code>Vector</code> object
1054+ * to contain the column values, and it is expected
1055+ * that most implementations will do the same. If a <code>Vector</code> object
1056+ * is used, it size must be exactly equal to the number of rows
1057+ * in this <code>CachedRowSet</code> object.
1058+ *
1059+ * @param column a <code>String</code> object giving the name of the
1060+ * column whose values are to be represented in a collection
1061+ * @return a <code>Collection</code> object that contains the values
1062+ * stored in the specified column of this <code>CachedRowSet</code>
1063+ * object
1064+ * @throws SQLException if an error occurs generating the collection or
1065+ * an invalid column id is provided
1066+ * @see #toCollection
1067+ * @see #toCollection(int)
1068+ */
1069+ public Collection<?> toCollection(String column) throws SQLException;
1070+
1071+ /**
1072+ * Retrieves the <code>SyncProvider</code> implementation for this
1073+ * <code>CachedRowSet</code> object. Internally, this method is used by a rowset
1074+ * to trigger read or write actions between the rowset
1075+ * and the data source. For example, a rowset may need to get a handle
1076+ * on the the rowset reader (<code>RowSetReader</code> object) from the
1077+ * <code>SyncProvider</code> to allow the rowset to be populated.
1078+ * <pre>
1079+ * RowSetReader rowsetReader = null;
1080+ * SyncProvider provider =
1081+ * SyncFactory.getInstance("javax.sql.rowset.provider.RIOptimisticProvider");
1082+ * if (provider instanceof RIOptimisticProvider) {
1083+ * rowsetReader = provider.getRowSetReader();
1084+ * }
1085+ * </pre>
1086+ * Assuming <i>rowsetReader</i> is a private, accessible field within
1087+ * the rowset implementation, when an application calls the <code>execute</code>
1088+ * method, it in turn calls on the reader's <code>readData</code> method
1089+ * to populate the <code>RowSet</code> object.
1090+ *<pre>
1091+ * rowsetReader.readData((RowSetInternal)this);
1092+ * </pre>
1093+ * <P>
1094+ * In addition, an application can use the <code>SyncProvider</code> object
1095+ * returned by this method to call methods that return information about the
1096+ * <code>SyncProvider</code> object, including information about the
1097+ * vendor, version, provider identification, synchronization grade, and locks
1098+ * it currently has set.
1099+ *
1100+ * @return the <code>SyncProvider</code> object that was set when the rowset
1101+ * was instantiated, or if none was was set, the default provider
1102+ * @throws SQLException if an error occurs while returning the
1103+ * <code>SyncProvider</code> object
1104+ * @see #setSyncProvider
1105+ */
1106+ public SyncProvider getSyncProvider() throws SQLException;
1107+
1108+ /**
1109+ * Sets the <code>SyncProvider</code> objec for this <code>CachedRowSet</code>
1110+ * object to the one specified. This method
1111+ * allows the <code>SyncProvider</code> object to be reset.
1112+ * <P>
1113+ * A <code>CachedRowSet</code> implementation should always be instantiated
1114+ * with an available <code>SyncProvider</code> mechanism, but there are
1115+ * cases where resetting the <code>SyncProvider</code> object is desirable
1116+ * or necessary. For example, an application might want to use the default
1117+ * <code>SyncProvider</code> object for a time and then choose to use a provider
1118+ * that has more recently become available and better fits its needs.
1119+ * <P>
1120+ * Resetting the <code>SyncProvider</code> object causes the
1121+ * <code>RowSet</code> object to request a new <code>SyncProvider</code> implementation
1122+ * from the <code>SyncFactory</code>. This has the effect of resetting
1123+ * all previous connections and relationships with the originating
1124+ * data source and can potentially drastically change the synchronization
1125+ * behavior of a disconnected rowset.
1126+ *
1127+ * @param provider a <code>String</code> object giving the fully qualified class
1128+ * name of a <code>SyncProvider</code> implementation
1129+ * @throws SQLException if an error occurs while attempting to reset the
1130+ * <code>SyncProvider</code> implementation
1131+ * @see #getSyncProvider
1132+ */
1133+ public void setSyncProvider(String provider) throws SQLException;
1134+
1135+ /**
1136+ * Returns the number of rows in this <code>CachedRowSet</code>
1137+ * object.
1138+ *
1139+ * @return number of rows in the rowset
1140+ */
1141+ public int size();
1142+
1143+ /**
1144+ * Sets the metadata for this <code>CachedRowSet</code> object with
1145+ * the given <code>RowSetMetaData</code> object. When a
1146+ * <code>RowSetReader</code> object is reading the contents of a rowset,
1147+ * it creates a <code>RowSetMetaData</code> object and initializes
1148+ * it using the methods in the <code>RowSetMetaData</code> implementation.
1149+ * The reference implementation uses the <code>RowSetMetaDataImpl</code>
1150+ * class. When the reader has completed reading the rowset contents,
1151+ * this method is called internally to pass the <code>RowSetMetaData</code>
1152+ * object to the rowset.
1153+ *
1154+ * @param md a <code>RowSetMetaData</code> object containing
1155+ * metadata about the columns in this <code>CachedRowSet</code> object
1156+ * @throws SQLException if invalid metadata is supplied to the
1157+ * rowset
1158+ */
1159+ public void setMetaData(RowSetMetaData md) throws SQLException;
1160+
1161+ /**
1162+ * Returns a <code>ResultSet</code> object containing the original value of this
1163+ * <code>CachedRowSet</code> object.
1164+ * <P>
1165+ * The cursor for the <code>ResultSet</code>
1166+ * object should be positioned before the first row.
1167+ * In addition, the returned <code>ResultSet</code> object should have the following
1168+ * properties:
1169+ * <UL>
1170+ * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE
1171+ * <LI>ResultSet.CONCUR_UPDATABLE
1172+ * </UL>
1173+ * <P>
1174+ * The original value for a <code>RowSet</code> object is the value it had before
1175+ * the last synchronization with the underlying data source. If there have been
1176+ * no synchronizations, the original value will be the value with which the
1177+ * <code>RowSet</code> object was populated. This method is called internally
1178+ * when an aplication calls the method <code>acceptChanges</code> and the
1179+ * <code>SyncProvider</code> object has been implemented to check for conflicts.
1180+ * If this is the case, the writer compares the original value with the value
1181+ * currently in the data source to check for conflicts.
1182+ *
1183+ * @return a <code>ResultSet</code> object that contains the original value for
1184+ * this <code>CachedRowSet</code> object
1185+ * @throws SQLException if an error occurs producing the
1186+ * <code>ResultSet</code> object
1187+ */
1188+ public ResultSet getOriginal() throws SQLException;
1189+
1190+ /**
1191+ * Returns a <code>ResultSet</code> object containing the original value for the
1192+ * current row only of this <code>CachedRowSet</code> object.
1193+ * <P>
1194+ * The cursor for the <code>ResultSet</code>
1195+ * object should be positioned before the first row.
1196+ * In addition, the returned <code>ResultSet</code> object should have the following
1197+ * properties:
1198+ * <UL>
1199+ * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE
1200+ * <LI>ResultSet.CONCUR_UPDATABLE
1201+ * </UL>
1202+ *
1203+ * @return the original result set of the row
1204+ * @throws SQLException if there is no current row
1205+ * @see #setOriginalRow
1206+ */
1207+ public ResultSet getOriginalRow() throws SQLException;
1208+
1209+ /**
1210+ * Sets the current row in this <code>CachedRowSet</code> object as the original
1211+ * row.
1212+ * <P>
1213+ * This method is called internally after the any modified values in the current
1214+ * row have been synchronized with the data source. The current row must be tagged
1215+ * as no longer inserted, deleted or updated.
1216+ * <P>
1217+ * A call to <code>setOriginalRow</code> is irreversible.
1218+ *
1219+ * @throws SQLException if there is no current row or an error is
1220+ * encountered resetting the contents of the original row
1221+ * @see #getOriginalRow
1222+ */
1223+ public void setOriginalRow() throws SQLException;
1224+
1225+ /**
1226+ * Returns an identifier for the object (table) that was used to
1227+ * create this <code>CachedRowSet</code> object. This name may be set on multiple occasions,
1228+ * and the specification imposes no limits on how many times this
1229+ * may occur or whether standard implementations should keep track
1230+ * of previous table names.
1231+ *
1232+ * @return a <code>String</code> object giving the name of the table that is the
1233+ * source of data for this <code>CachedRowSet</code> object or <code>null</code>
1234+ * if no name has been set for the table
1235+ * @throws SQLException if an error is encountered returning the table name
1236+ * @see javax.sql.RowSetMetaData#getTableName
1237+ */
1238+ public String getTableName() throws SQLException;
1239+
1240+ /**
1241+ * Sets the identifier for the table from which this <code>CachedRowSet</code>
1242+ * object was derived to the given table name. The writer uses this name to
1243+ * determine which table to use when comparing the values in the data source with the
1244+ * <code>CachedRowSet</code> object's values during a synchronization attempt.
1245+ * The table identifier also indicates where modified values from this
1246+ * <code>CachedRowSet</code> object should be written.
1247+ * <P>
1248+ * The implementation of this <code>CachedRowSet</code> object may obtain the
1249+ * the name internally from the <code>RowSetMetaDataImpl</code> object.
1250+ *
1251+ * @param tabName a <code>String</code> object identifying the table from which this
1252+ <code>CachedRowSet</code> object was derived; cannot be <code>null</code>
1253+ * but may be an empty string
1254+ * @throws SQLException if an error is encountered naming the table or
1255+ * <i>tabName</i> is <code>null</code>
1256+ * @see javax.sql.RowSetMetaData#setTableName
1257+ * @see javax.sql.RowSetWriter
1258+ * @see javax.sql.rowset.spi.SyncProvider
1259+ */
1260+ public void setTableName(String tabName) throws SQLException;
1261+
1262+ /**
1263+ * Returns an array containing one or more column numbers indicating the columns
1264+ * that form a key that uniquely
1265+ * identifies a row in this <code>CachedRowSet</code> object.
1266+ *
1267+ * @return an array containing the column number or numbers that indicate which columns
1268+ * constitute a primary key
1269+ * for a row in this <code>CachedRowSet</code> object. This array should be
1270+ * empty if no columns are representative of a primary key.
1271+ * @throws SQLException if this <code>CachedRowSet</code> object is empty
1272+ * @see #setKeyColumns
1273+ * @see Joinable#getMatchColumnIndexes
1274+ * @see Joinable#getMatchColumnNames
1275+ */
1276+ public int[] getKeyColumns() throws SQLException;
1277+
1278+ /**
1279+ * Sets this <code>CachedRowSet</code> object's <code>keyCols</code>
1280+ * field with the given array of column numbers, which forms a key
1281+ * for uniquely identifying a row in this <code>CachedRowSet</code> object.
1282+ * <p>
1283+ * If a <code>CachedRowSet</code> object becomes part of a <code>JoinRowSet</code>
1284+ * object, the keys defined by this method and the resulting constraints are
1285+ * maintained if the columns designated as key columns also become match
1286+ * columns.
1287+ *
1288+ * @param keys an array of <code>int</code> indicating the columns that form
1289+ * a primary key for this <code>CachedRowSet</code> object; every
1290+ * element in the array must be greater than <code>0</code> and
1291+ * less than or equal to the number of columns in this rowset
1292+ * @throws SQLException if any of the numbers in the given array
1293+ * are not valid for this rowset
1294+ * @see #getKeyColumns
1295+ * @see Joinable#setMatchColumn(String)
1296+ * @see Joinable#setMatchColumn(int)
1297+
1298+ */
1299+ public void setKeyColumns(int[] keys) throws SQLException;
1300+
1301+
1302+ /**
1303+ * Returns a new <code>RowSet</code> object backed by the same data as
1304+ * that of this <code>CachedRowSet</code> object. In effect, both
1305+ * <code>CachedRowSet</code> objects have a cursor over the same data.
1306+ * As a result, any changes made by a duplicate are visible to the original
1307+ * and to any other duplicates, just as a change made by the original is visible
1308+ * to all of its duplicates. If a duplicate calls a method that changes the
1309+ * underlying data, the method it calls notifies all registered listeners
1310+ * just as it would when it is called by the original <code>CachedRowSet</code>
1311+ * object.
1312+ * <P>
1313+ * In addition, any <code>RowSet</code> object
1314+ * created by this method will have the same properties as this
1315+ * <code>CachedRowSet</code> object. For example, if this <code>CachedRowSet</code>
1316+ * object is read-only, all of its duplicates will also be read-only. If it is
1317+ * changed to be updatable, the duplicates also become updatable.
1318+ * <P>
1319+ * NOTE: If multiple threads access <code>RowSet</code> objects created from
1320+ * the <code>createShared()</code> method, the following behavior is specified
1321+ * to preserve shared data integrity: reads and writes of all
1322+ * shared <code>RowSet</code> objects should be made serially between each
1323+ * object and the single underlying tabular structure.
1324+ *
1325+ * @return a new shared <code>RowSet</code> object that has the same properties
1326+ * as this <code>CachedRowSet</code> object and that has a cursor over
1327+ * the same data
1328+ * @throws SQLException if an error occurs or cloning is not
1329+ * supported in the underlying platform
1330+ * @see javax.sql.RowSetEvent
1331+ * @see javax.sql.RowSetListener
1332+ */
1333+ public RowSet createShared() throws SQLException;
1334+
1335+ /**
1336+ * Creates a <code>RowSet</code> object that is a deep copy of the data in
1337+ * this <code>CachedRowSet</code> object. In contrast to
1338+ * the <code>RowSet</code> object generated from a <code>createShared</code>
1339+ * call, updates made to the copy of the original <code>RowSet</code> object
1340+ * must not be visible to the original <code>RowSet</code> object. Also, any
1341+ * event listeners that are registered with the original
1342+ * <code>RowSet</code> must not have scope over the new
1343+ * <code>RowSet</code> copies. In addition, any constraint restrictions
1344+ * established must be maintained.
1345+ *
1346+ * @return a new <code>RowSet</code> object that is a deep copy
1347+ * of this <code>CachedRowSet</code> object and is
1348+ * completely independent of this <code>CachedRowSet</code> object
1349+ * @throws SQLException if an error occurs in generating the copy of
1350+ * the of this <code>CachedRowSet</code> object
1351+ * @see #createShared
1352+ * @see #createCopySchema
1353+ * @see #createCopyNoConstraints
1354+ * @see javax.sql.RowSetEvent
1355+ * @see javax.sql.RowSetListener
1356+ */
1357+ public CachedRowSet createCopy() throws SQLException;
1358+
1359+ /**
1360+ * Creates a <code>CachedRowSet</code> object that is an empty copy of this
1361+ * <code>CachedRowSet</code> object. The copy
1362+ * must not contain any contents but only represent the table
1363+ * structure of the original <code>CachedRowSet</code> object. In addition, primary
1364+ * or foreign key constraints set in the originating <code>CachedRowSet</code> object must
1365+ * be equally enforced in the new empty <code>CachedRowSet</code> object.
1366+ * In contrast to
1367+ * the <code>RowSet</code> object generated from a <code>createShared</code> method
1368+ * call, updates made to a copy of this <code>CachedRowSet</code> object with the
1369+ * <code>createCopySchema</code> method must not be visible to it.
1370+ * <P>
1371+ * Applications can form a <code>WebRowSet</code> object from the <code>CachedRowSet</code>
1372+ * object returned by this method in order
1373+ * to export the <code>RowSet</code> schema definition to XML for future use.
1374+ *
1375+ * @throws SQLException if an error occurs in cloning the structure of this
1376+ * <code>CachedRowSet</code> object
1377+ * @see #createShared
1378+ * @see #createCopySchema
1379+ * @see #createCopyNoConstraints
1380+ * @see javax.sql.RowSetEvent
1381+ * @see javax.sql.RowSetListener
1382+ */
1383+ public CachedRowSet createCopySchema() throws SQLException;
1384+
1385+ /**
1386+ * Creates a <code>CachedRowSet</code> object that is a deep copy of
1387+ * this <code>CachedRowSet</code> object's data but is independent of it.
1388+ * In contrast to
1389+ * the <code>RowSet</code> object generated from a <code>createShared</code>
1390+ * method call, updates made to a copy of this <code>CachedRowSet</code> object
1391+ * must not be visible to it. Also, any
1392+ * event listeners that are registered with this
1393+ * <code>CachedRowSet</code> object must not have scope over the new
1394+ * <code>RowSet</code> object. In addition, any constraint restrictions
1395+ * established for this <code>CachedRowSet</code> object must <b>not</b> be maintained
1396+ * in the copy.
1397+ *
1398+ * @return a new <code>CachedRowSet</code> object that is a deep copy
1399+ * of this <code>CachedRowSet</code> object and is
1400+ * completely independent of this <code>CachedRowSet</code> object
1401+ * @throws SQLException if an error occurs in generating the copy of
1402+ * the of this <code>CachedRowSet</code> object
1403+ * @see #createCopy
1404+ * @see #createShared
1405+ * @see #createCopySchema
1406+ * @see javax.sql.RowSetEvent
1407+ * @see javax.sql.RowSetListener
1408+ */
1409+ public CachedRowSet createCopyNoConstraints() throws SQLException;
1410+
1411+ /**
1412+ * Retrieves the first warning reported by calls on this <code>RowSet</code> object.
1413+ * Subsequent warnings on this <code>RowSet</code> object will be chained to the
1414+ * <code>RowSetWarning</code> object that this method returns.
1415+ *
1416+ * The warning chain is automatically cleared each time a new row is read.
1417+ * This method may not be called on a RowSet object that has been closed;
1418+ * doing so will cause a <code>SQLException</code> to be thrown.
1419+ *
1420+ * @return RowSetWarning the first <code>RowSetWarning</code>
1421+ * object reported or null if there are none
1422+ * @throws SQLException if this method is called on a closed RowSet
1423+ * @see RowSetWarning
1424+ */
1425+ public RowSetWarning getRowSetWarnings() throws SQLException;
1426+
1427+ /**
1428+ * Retrieves a <code>boolean</code> indicating whether rows marked
1429+ * for deletion appear in the set of current rows. If <code>true</code> is
1430+ * returned, deleted rows are visible with the current rows. If
1431+ * <code>false</code> is returned, rows are not visible with the set of
1432+ * current rows. The default value is <code>false</code>.
1433+ * <P>
1434+ * Standard rowset implementations may choose to restrict this behavior
1435+ * due to security considerations or to better fit certain deployment
1436+ * scenarios. This is left as implementation defined and does not
1437+ * represent standard behavior.
1438+ * <P>
1439+ * Note: Allowing deleted rows to remain visible complicates the behavior
1440+ * of some standard JDBC <code>RowSet</code> Implementations methods.
1441+ * However, most rowset users can simply ignore this extra detail because
1442+ * only very specialized applications will likely want to take advantage of
1443+ * this feature.
1444+ *
1445+ * @return <code>true</code> if deleted rows are visible;
1446+ * <code>false</code> otherwise
1447+ * @throws SQLException if a rowset implementation is unable to
1448+ * to determine whether rows marked for deletion are visible
1449+ * @see #setShowDeleted
1450+ */
1451+ public boolean getShowDeleted() throws SQLException;
1452+
1453+ /**
1454+ * Sets the property <code>showDeleted</code> to the given
1455+ * <code>boolean</code> value, which determines whether
1456+ * rows marked for deletion appear in the set of current rows.
1457+ * If the value is set to <code>true</code>, deleted rows are immediately
1458+ * visible with the set of current rows. If the value is set to
1459+ * <code>false</code>, the deleted rows are set as invisible with the
1460+ * current set of rows.
1461+ * <P>
1462+ * Standard rowset implementations may choose to restrict this behavior
1463+ * due to security considerations or to better fit certain deployment
1464+ * scenarios. This is left as implementations defined and does not
1465+ * represent standard behavior.
1466+ *
1467+ * @param b <code>true</code> if deleted rows should be shown;
1468+ * <code>false</code> otherwise
1469+ * @exception SQLException if a rowset implementation is unable to
1470+ * to reset whether deleted rows should be visible
1471+ * @see #getShowDeleted
1472+ */
1473+ public void setShowDeleted(boolean b) throws SQLException;
1474+
1475+ /**
1476+ * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
1477+ * a <code>Connection</code> object from the <code>ResultSet</code> or JDBC
1478+ * properties passed to it's constructors. This method wraps the
1479+ * <code>Connection</code> commit method to allow flexible
1480+ * auto commit or non auto commit transactional control support.
1481+ * <p>
1482+ * Makes all changes that are performed by the <code>acceptChanges()</code>
1483+ * method since the previous commit/rollback permanent. This method should
1484+ * be used only when auto-commit mode has been disabled.
1485+ *
1486+ * @throws SQLException if a database access error occurs or this
1487+ * Connection object within this <code>CachedRowSet</code> is in auto-commit mode
1488+ * @see java.sql.Connection#setAutoCommit
1489+ */
1490+ public void commit() throws SQLException;
1491+
1492+ /**
1493+ * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
1494+ * a <code>Connection</code> object from the original <code>ResultSet</code>
1495+ * or JDBC properties passed to it.
1496+ * <p>
1497+ * Undoes all changes made in the current transaction. This method
1498+ * should be used only when auto-commit mode has been disabled.
1499+ *
1500+ * @throws SQLException if a database access error occurs or this Connection
1501+ * object within this <code>CachedRowSet</code> is in auto-commit mode.
1502+ */
1503+ public void rollback() throws SQLException;
1504+
1505+ /**
1506+ * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
1507+ * a <code>Connection</code> object from the original <code>ResultSet</code>
1508+ * or JDBC properties passed to it.
1509+ * <p>
1510+ * Undoes all changes made in the current transaction back to the last
1511+ * <code>Savepoint</code> transaction marker. This method should be used only
1512+ * when auto-commit mode has been disabled.
1513+ *
1514+ * @param s A <code>Savepoint</code> transaction marker
1515+ * @throws SQLException if a database access error occurs or this Connection
1516+ * object within this <code>CachedRowSet</code> is in auto-commit mode.
1517+ */
1518+ public void rollback(Savepoint s) throws SQLException;
1519+
1520+ /**
1521+ * Causes the <code>CachedRowSet</code> object's <code>SyncProvider</code>
1522+ * to commit the changes when <code>acceptChanges()</code> is called. If
1523+ * set to false, the changes will <b>not</b> be committed until one of the
1524+ * <code>CachedRowSet</code> interface transaction methods is called.
1525+ *
1526+ * @deprecated Because this field is final (it is part of an interface),
1527+ * its value cannot be changed.
1528+ * @see #commit
1529+ * @see #rollback
1530+ */
1531+ @Deprecated
1532+ public static final boolean COMMIT_ON_ACCEPT_CHANGES = true;
1533+
1534+ /**
1535+ * Notifies registered listeners that a RowSet object in the given RowSetEvent
1536+ * object has populated a number of additional rows. The <code>numRows</code> parameter
1537+ * ensures that this event will only be fired every <code>numRow</code>.
1538+ * <p>
1539+ * The source of the event can be retrieved with the method event.getSource.
1540+ *
1541+ * @param event a <code>RowSetEvent</code> object that contains the
1542+ * <code>RowSet</code> object that is the source of the events
1543+ * @param numRows when populating, the number of rows interval on which the
1544+ * <code>CachedRowSet</code> populated should fire; the default value
1545+ * is zero; cannot be less than <code>fetchSize</code> or zero
1546+ */
1547+ public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException;
1548+
1549+ /**
1550+ * Populates this <code>CachedRowSet</code> object with data from
1551+ * the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code>
1552+ * method, an additional parameter is provided to allow starting position within
1553+ * the <code>ResultSet</code> from where to populate the CachedRowSet
1554+ * instance.
1555+ * <P>
1556+ * This method can be used as an alternative to the <code>execute</code> method when an
1557+ * application has a connection to an open <code>ResultSet</code> object.
1558+ * Using the method <code>populate</code> can be more efficient than using
1559+ * the version of the <code>execute</code> method that takes no parameters
1560+ * because it does not open a new connection and re-execute this
1561+ * <code>CachedRowSet</code> object's command. Using the <code>populate</code>
1562+ * method is more a matter of convenience when compared to using the version
1563+ * of <code>execute</code> that takes a <code>ResultSet</code> object.
1564+ *
1565+ * @param startRow the position in the <code>ResultSet</code> from where to start
1566+ * populating the records in this <code>CachedRowSet</code>
1567+ * @param rs the <code>ResultSet</code> object containing the data
1568+ * to be read into this <code>CachedRowSet</code> object
1569+ * @throws SQLException if a null <code>ResultSet</code> object is supplied
1570+ * or this <code>CachedRowSet</code> object cannot
1571+ * retrieve the associated <code>ResultSetMetaData</code> object
1572+ * @see #execute
1573+ * @see #populate(ResultSet)
1574+ * @see java.sql.ResultSet
1575+ * @see java.sql.ResultSetMetaData
1576+ */
1577+ public void populate(ResultSet rs, int startRow) throws SQLException;
1578+
1579+ /**
1580+ * Sets the <code>CachedRowSet</code> object's page-size. A <code>CachedRowSet</code>
1581+ * may be configured to populate itself in page-size sized batches of rows. When
1582+ * either <code>populate()</code> or <code>execute()</code> are called, the
1583+ * <code>CachedRowSet</code> fetches an additional page according to the
1584+ * original SQL query used to populate the RowSet.
1585+ *
1586+ * @param size the page-size of the <code>CachedRowSet</code>
1587+ * @throws SQLException if an error occurs setting the <code>CachedRowSet</code>
1588+ * page size or if the page size is less than 0.
1589+ */
1590+ public void setPageSize(int size) throws SQLException;
1591+
1592+ /**
1593+ * Returns the page-size for the <code>CachedRowSet</code> object
1594+ *
1595+ * @return an <code>int</code> page size
1596+ */
1597+ public int getPageSize();
1598+
1599+ /**
1600+ * Increments the current page of the <code>CachedRowSet</code>. This causes
1601+ * the <code>CachedRowSet</code> implementation to fetch the next page-size
1602+ * rows and populate the RowSet, if remaining rows remain within scope of the
1603+ * original SQL query used to populated the RowSet.
1604+ *
1605+ * @return true if more pages exist; false if this is the last page
1606+ * @throws SQLException if an error occurs fetching the next page, or if this
1607+ * method is called prematurely before populate or execute.
1608+ */
1609+ public boolean nextPage() throws SQLException;
1610+
1611+ /**
1612+ * Decrements the current page of the <code>CachedRowSet</code>. This causes
1613+ * the <code>CachedRowSet</code> implementation to fetch the previous page-size
1614+ * rows and populate the RowSet. The amount of rows returned in the previous
1615+ * page must always remain within scope of the original SQL query used to
1616+ * populate the RowSet.
1617+ *
1618+ * @return true if the previous page is successfully retrieved; false if this
1619+ * is the first page.
1620+ * @throws SQLException if an error occurs fetching the previous page, or if
1621+ * this method is called prematurely before populate or execute.
1622+ */
1623+ public boolean previousPage() throws SQLException;
1624+
1625+}