1/*
2 * Copyright (c) 2003, 2014, 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
26package javax.sql.rowset;
27
28import java.sql.*;
29import javax.sql.*;
30import javax.naming.*;
31import java.io.*;
32import java.math.*;
33import java.util.*;
34
35import 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&trade; 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 *
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 *
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 *
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 *
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>RIOptimisticProvider</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 *
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 *
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 *
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-scrollable 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 *
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 *
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&trade; (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>{@code
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>{@code
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"}.  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>{@code
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>{@code
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 * @since 1.5
630 */
631
632public interface CachedRowSet extends RowSet, Joinable {
633
634   /**
635    * Populates this <code>CachedRowSet</code> object with data from
636    * the given <code>ResultSet</code> object.
637    * <P>
638    * This method can be used as an alternative to the <code>execute</code> method when an
639    * application has a connection to an open <code>ResultSet</code> object.
640    * Using the method <code>populate</code> can be more efficient than using
641    * the version of the <code>execute</code> method that takes no parameters
642    * because it does not open a new connection and re-execute this
643    * <code>CachedRowSet</code> object's command. Using the <code>populate</code>
644    * method is more a matter of convenience when compared to using the version
645    * of <code>execute</code> that takes a <code>ResultSet</code> object.
646    *
647    * @param data the <code>ResultSet</code> object containing the data
648    * to be read into this <code>CachedRowSet</code> object
649    * @throws SQLException if a null <code>ResultSet</code> object is supplied
650    * or this <code>CachedRowSet</code> object cannot
651    * retrieve the associated <code>ResultSetMetaData</code> object
652    * @see #execute
653    * @see java.sql.ResultSet
654    * @see java.sql.ResultSetMetaData
655    */
656    public void populate(ResultSet data) throws SQLException;
657
658   /**
659    * Populates this <code>CachedRowSet</code> object with data, using the
660    * given connection to produce the result set from which the data will be read.
661    * This method should close any database connections that it creates to
662    * ensure that this <code>CachedRowSet</code> object is disconnected except when
663    * it is reading data from its data source or writing data to its data source.
664    * <P>
665    * The reader for this <code>CachedRowSet</code> object
666    * will use <i>conn</i> to establish a connection to the data source
667    * so that it can execute the rowset's command and read data from the
668    * the resulting <code>ResultSet</code> object into this
669    * <code>CachedRowSet</code> object. This method also closes <i>conn</i>
670    * after it has populated this <code>CachedRowSet</code> object.
671    * <P>
672    * If this method is called when an implementation has already been
673    * populated, the contents and the metadata are (re)set. Also, if this method is
674    * called before the method <code>acceptChanges</code> has been called
675    * to commit outstanding updates, those updates are lost.
676    *
677    * @param conn a standard JDBC <code>Connection</code> object with valid
678    * properties
679    * @throws SQLException if an invalid <code>Connection</code> object is supplied
680    * or an error occurs in establishing the connection to the
681    * data source
682    * @see #populate
683    * @see java.sql.Connection
684    */
685    public void execute(Connection conn) throws SQLException;
686
687   /**
688    * Propagates row update, insert and delete changes made to this
689    * <code>CachedRowSet</code> object to the underlying data source.
690    * <P>
691    * This method calls on this <code>CachedRowSet</code> object's writer
692    * to do the work behind the scenes.
693    * Standard <code>CachedRowSet</code> implementations should use the
694    * <code>SyncFactory</code> singleton
695    * to obtain a <code>SyncProvider</code> instance providing a
696    * <code>RowSetWriter</code> object (writer).  The writer will attempt
697    * to propagate changes made in this <code>CachedRowSet</code> object
698    * back to the data source.
699    * <P>
700    * When the method <code>acceptChanges</code> executes successfully, in
701    * addition to writing changes to the data source, it
702    * makes the values in the current row be the values in the original row.
703    * <P>
704    * Depending on the synchronization level of the <code>SyncProvider</code>
705    * implementation being used, the writer will compare the original values
706    * with those in the data source to check for conflicts. When there is a conflict,
707    * the <code>RIOptimisticProvider</code> implementation, for example, throws a
708    * <code>SyncProviderException</code> and does not write anything to the
709    * data source.
710    * <P>
711    * An application may choose to catch the <code>SyncProviderException</code>
712    * object and retrieve the <code>SyncResolver</code> object it contains.
713    * The <code>SyncResolver</code> object lists the conflicts row by row and
714    * sets a lock on the data source to avoid further conflicts while the
715    * current conflicts are being resolved.
716    * Further, for each conflict, it provides methods for examining the conflict
717    * and setting the value that should be persisted in the data source.
718    * After all conflicts have been resolved, an application must call the
719    * <code>acceptChanges</code> method again to write resolved values to the
720    * data source.  If all of the values in the data source are already the
721    * values to be persisted, the method <code>acceptChanges</code> does nothing.
722    * <P>
723    * Some provider implementations may use locks to ensure that there are no
724    * conflicts.  In such cases, it is guaranteed that the writer will succeed in
725    * writing changes to the data source when the method <code>acceptChanges</code>
726    * is called.  This method may be called immediately after the methods
727    * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>
728    * have been called, but it is more efficient to call it only once after
729    * all changes have been made so that only one connection needs to be
730    * established.
731    * <P>
732    * Note: The <code>acceptChanges()</code> method will determine if the
733    * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set
734    * to true, all updates in the synchronization are committed to the data
735    * source. Otherwise, the application <b>must</b> explicitly call the
736    * <code>commit()</code> or <code>rollback()</code> methods as appropriate.
737    *
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> explicitly 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 SyncProviderException if the underlying
809    * synchronization provider's writer fails to write the updates
810    * back to the data source
811    * @see #acceptChanges()
812    * @see javax.sql.RowSetWriter
813    * @see javax.sql.rowset.spi.SyncFactory
814    * @see javax.sql.rowset.spi.SyncProvider
815    * @see javax.sql.rowset.spi.SyncProviderException
816    * @see javax.sql.rowset.spi.SyncResolver
817    */
818    public void acceptChanges(Connection con) throws SyncProviderException;
819
820   /**
821    * Restores this <code>CachedRowSet</code> object to its original
822    * value, that is, its value before the last set of changes. If there
823    * have been no changes to the rowset or only one set of changes,
824    * the original value is the value with which this <code>CachedRowSet</code> object
825    * was populated; otherwise, the original value is
826    * the value it had immediately before its current value.
827    * <P>
828    * When this method is called, a <code>CachedRowSet</code> implementation
829    * must ensure that all updates, inserts, and deletes to the current
830    * rowset instance are replaced by the previous values. In addition,
831    * the cursor should be
832    * reset to the first row and a <code>rowSetChanged</code> event
833    * should be fired to notify all registered listeners.
834    *
835    * @throws SQLException if an error occurs rolling back the current value of
836    *       this <code>CachedRowSet</code> object to its previous value
837    * @see javax.sql.RowSetListener#rowSetChanged
838    */
839    public void restoreOriginal() throws SQLException;
840
841   /**
842    * Releases the current contents of this <code>CachedRowSet</code>
843    * object and sends a <code>rowSetChanged</code> event to all
844    * registered listeners. Any outstanding updates are discarded and
845    * the rowset contains no rows after this method is called. There
846    * are no interactions with the underlying data source, and any rowset
847    * content, metadata, and content updates should be non-recoverable.
848    * <P>
849    * This <code>CachedRowSet</code> object should lock until its contents and
850    * associated updates are fully cleared, thus preventing 'dirty' reads by
851    * other components that hold a reference to this <code>RowSet</code> object.
852    * In addition, the contents cannot be released
853    * until all components reading this <code>CachedRowSet</code> object
854    * have completed their reads. This <code>CachedRowSet</code> object
855    * should be returned to normal behavior after firing the
856    * <code>rowSetChanged</code> event.
857    * <P>
858    * The metadata, including JDBC properties and Synchronization SPI
859    * properties, are maintained for future use. It is important that
860    * properties such as the <code>command</code> property be
861    * relevant to the originating data source from which this <code>CachedRowSet</code>
862    * object was originally established.
863    * <P>
864    * This method empties a rowset, as opposed to the <code>close</code> method,
865    * which marks the entire rowset as recoverable to allow the garbage collector
866    * the rowset's Java VM resources.
867    *
868    * @throws SQLException if an error occurs flushing the contents of this
869    * <code>CachedRowSet</code> object
870    * @see javax.sql.RowSetListener#rowSetChanged
871    * @see java.sql.ResultSet#close
872    */
873    public void release() throws SQLException;
874
875   /**
876    * Cancels the deletion of the current row and notifies listeners that
877    * a row has changed. After this method is called, the current row is
878    * no longer marked for deletion. This method can be called at any
879    * time during the lifetime of the rowset.
880    * <P>
881    * In addition, multiple cancellations of row deletions can be made
882    * by adjusting the position of the cursor using any of the cursor
883    * position control methods such as:
884    * <ul>
885    * <li><code>CachedRowSet.absolute</code>
886    * <li><code>CachedRowSet.first</code>
887    * <li><code>CachedRowSet.last</code>
888    * </ul>
889    *
890    * @throws SQLException if (1) the current row has not been deleted or
891    * (2) the cursor is on the insert row, before the first row, or
892    * after the last row
893    * @see javax.sql.rowset.CachedRowSet#undoInsert
894    * @see java.sql.ResultSet#cancelRowUpdates
895    */
896    public void undoDelete() throws SQLException;
897
898   /**
899    * Immediately removes the current row from this <code>CachedRowSet</code>
900    * object if the row has been inserted, and also notifies listeners that a
901    * row has changed. This method can be called at any time during the
902    * lifetime of a rowset and assuming the current row is within
903    * the exception limitations (see below), it cancels the row insertion
904    * of the current row.
905    * <P>
906    * In addition, multiple cancellations of row insertions can be made
907    * by adjusting the position of the cursor using any of the cursor
908    * position control methods such as:
909    * <ul>
910    * <li><code>CachedRowSet.absolute</code>
911    * <li><code>CachedRowSet.first</code>
912    * <li><code>CachedRowSet.last</code>
913    * </ul>
914    *
915    * @throws SQLException if (1) the current row has not been inserted or (2)
916    * the cursor is before the first row, after the last row, or on the
917    * insert row
918    * @see javax.sql.rowset.CachedRowSet#undoDelete
919    * @see java.sql.ResultSet#cancelRowUpdates
920    */
921    public void undoInsert() throws SQLException;
922
923
924   /**
925    * Immediately reverses the last update operation if the
926    * row has been modified. This method can be
927    * called to reverse updates on all columns until all updates in a row have
928    * been rolled back to their state just prior to the last synchronization
929    * (<code>acceptChanges</code>) or population. This method may also be called
930    * while performing updates to the insert row.
931    * <P>
932    * <code>undoUpdate</code> may be called at any time during the lifetime of a
933    * rowset; however, after a synchronization has occurred, this method has no
934    * effect until further modification to the rowset data has occurred.
935    *
936    * @throws SQLException if the cursor is before the first row or after the last
937    *     row in this <code>CachedRowSet</code> object
938    * @see #undoDelete
939    * @see #undoInsert
940    * @see java.sql.ResultSet#cancelRowUpdates
941    */
942    public void undoUpdate() throws SQLException;
943
944   /**
945    * Indicates whether the designated column in the current row of this
946    * <code>CachedRowSet</code> object has been updated.
947    *
948    * @param idx an <code>int</code> identifying the column to be checked for updates
949    * @return <code>true</code> if the designated column has been visibly updated;
950    * <code>false</code> otherwise
951    * @throws SQLException if the cursor is on the insert row, before the first row,
952    *     or after the last row
953    * @see java.sql.DatabaseMetaData#updatesAreDetected
954    */
955    public boolean columnUpdated(int idx) throws SQLException;
956
957
958   /**
959    * Indicates whether the designated column in the current row of this
960    * <code>CachedRowSet</code> object has been updated.
961    *
962    * @param columnName a <code>String</code> object giving the name of the
963    *        column to be checked for updates
964    * @return <code>true</code> if the column has been visibly updated;
965    * <code>false</code> otherwise
966    * @throws SQLException if the cursor is on the insert row, before the first row,
967    *      or after the last row
968    * @see java.sql.DatabaseMetaData#updatesAreDetected
969    */
970    public boolean columnUpdated(String columnName) throws SQLException;
971
972   /**
973    * Converts this <code>CachedRowSet</code> object to a <code>Collection</code>
974    * object that contains all of this <code>CachedRowSet</code> object's data.
975    * Implementations have some latitude in
976    * how they can represent this <code>Collection</code> object because of the
977    * abstract nature of the <code>Collection</code> framework.
978    * Each row must be fully represented in either a
979    * general purpose <code>Collection</code> implementation or a specialized
980    * <code>Collection</code> implementation, such as a <code>TreeMap</code>
981    * object or a <code>Vector</code> object.
982    * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
983    * in the Java programming language.
984    * <P>
985    * The standard reference implementation for the <code>CachedRowSet</code>
986    * interface uses a <code>TreeMap</code> object for the rowset, with the
987    * values in each row being contained in  <code>Vector</code> objects. It is
988    * expected that most implementations will do the same.
989    * <P>
990    * The <code>TreeMap</code> type of collection guarantees that the map will be in
991    * ascending key order, sorted according to the natural order for the
992    * key's class.
993    * Each key references a <code>Vector</code> object that corresponds to one
994    * row of a <code>RowSet</code> object. Therefore, the size of each
995    * <code>Vector</code> object  must be exactly equal to the number of
996    * columns in the <code>RowSet</code> object.
997    * The key used by the <code>TreeMap</code> collection is determined by the
998    * implementation, which may choose to leverage a set key that is
999    * available within the internal <code>RowSet</code> tabular structure by
1000    * virtue of a key already set either on the <code>RowSet</code> object
1001    * itself or on the underlying SQL data.
1002    *
1003    * @return a <code>Collection</code> object that contains the values in
1004    * each row in this <code>CachedRowSet</code> object
1005    * @throws SQLException if an error occurs generating the collection
1006    * @see #toCollection(int)
1007    * @see #toCollection(String)
1008    */
1009    public Collection<?> toCollection() throws SQLException;
1010
1011   /**
1012    * Converts the designated column in this <code>CachedRowSet</code> object
1013    * to a <code>Collection</code> object. Implementations have some latitude in
1014    * how they can represent this <code>Collection</code> object because of the
1015    * abstract nature of the <code>Collection</code> framework.
1016    * Each column value should be fully represented in either a
1017    * general purpose <code>Collection</code> implementation or a specialized
1018    * <code>Collection</code> implementation, such as a <code>Vector</code> object.
1019    * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
1020    * in the Java programming language.
1021    * <P>
1022    * The standard reference implementation uses a <code>Vector</code> object
1023    * to contain the column values, and it is expected
1024    * that most implementations will do the same. If a <code>Vector</code> object
1025    * is used, it size must be exactly equal to the number of rows
1026    * in this <code>CachedRowSet</code> object.
1027    *
1028    * @param column an <code>int</code> indicating the column whose values
1029    *        are to be represented in a <code>Collection</code> object
1030    * @return a <code>Collection</code> object that contains the values
1031    * stored in the specified column of this <code>CachedRowSet</code>
1032    * object
1033    * @throws SQLException if an error occurs generating the collection or
1034    * an invalid column id is provided
1035    * @see #toCollection
1036    * @see #toCollection(String)
1037    */
1038    public Collection<?> toCollection(int column) throws SQLException;
1039
1040   /**
1041    * Converts the designated column in this <code>CachedRowSet</code> object
1042    * to a <code>Collection</code> object. Implementations have some latitude in
1043    * how they can represent this <code>Collection</code> object because of the
1044    * abstract nature of the <code>Collection</code> framework.
1045    * Each column value should be fully represented in either a
1046    * general purpose <code>Collection</code> implementation or a specialized
1047    * <code>Collection</code> implementation, such as a <code>Vector</code> object.
1048    * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
1049    * in the Java programming language.
1050    * <P>
1051    * The standard reference implementation uses a <code>Vector</code> object
1052    * to contain the column values, and it is expected
1053    * that most implementations will do the same. If a <code>Vector</code> object
1054    * is used, it size must be exactly equal to the number of rows
1055    * in this <code>CachedRowSet</code> object.
1056    *
1057    * @param column a <code>String</code> object giving the name of the
1058    *        column whose values are to be represented in a collection
1059    * @return a <code>Collection</code> object that contains the values
1060    * stored in the specified column of this <code>CachedRowSet</code>
1061    * object
1062    * @throws SQLException if an error occurs generating the collection or
1063    * an invalid column id is provided
1064    * @see #toCollection
1065    * @see #toCollection(int)
1066    */
1067    public Collection<?> toCollection(String column) throws SQLException;
1068
1069   /**
1070    * Retrieves the <code>SyncProvider</code> implementation for this
1071    * <code>CachedRowSet</code> object. Internally, this method is used by a rowset
1072    * to trigger read or write actions between the rowset
1073    * and the data source. For example, a rowset may need to get a handle
1074    * on the rowset reader (<code>RowSetReader</code> object) from the
1075    * <code>SyncProvider</code> to allow the rowset to be populated.
1076    * <pre>
1077    *     RowSetReader rowsetReader = null;
1078    *     SyncProvider provider =
1079    *         SyncFactory.getInstance("javax.sql.rowset.provider.RIOptimisticProvider");
1080    *         if (provider instanceof RIOptimisticProvider) {
1081    *             rowsetReader = provider.getRowSetReader();
1082    *         }
1083    * </pre>
1084    * Assuming <i>rowsetReader</i> is a private, accessible field within
1085    * the rowset implementation, when an application calls the <code>execute</code>
1086    * method, it in turn calls on the reader's <code>readData</code> method
1087    * to populate the <code>RowSet</code> object.
1088    *<pre>
1089    *     rowsetReader.readData((RowSetInternal)this);
1090    * </pre>
1091    * <P>
1092    * In addition, an application can use the <code>SyncProvider</code> object
1093    * returned by this method to call methods that return information about the
1094    * <code>SyncProvider</code> object, including information about the
1095    * vendor, version, provider identification, synchronization grade, and locks
1096    * it currently has set.
1097    *
1098    * @return the <code>SyncProvider</code> object that was set when the rowset
1099    *      was instantiated, or if none was set, the default provider
1100    * @throws SQLException if an error occurs while returning the
1101    * <code>SyncProvider</code> object
1102    * @see #setSyncProvider
1103    */
1104    public SyncProvider getSyncProvider() throws SQLException;
1105
1106   /**
1107    * Sets the <code>SyncProvider</code> object for this <code>CachedRowSet</code>
1108    * object to the one specified.  This method
1109    * allows the <code>SyncProvider</code> object to be reset.
1110    * <P>
1111    * A <code>CachedRowSet</code> implementation should always be instantiated
1112    * with an available <code>SyncProvider</code> mechanism, but there are
1113    * cases where resetting the <code>SyncProvider</code> object is desirable
1114    * or necessary. For example, an application might want to use the default
1115    * <code>SyncProvider</code> object for a time and then choose to use a provider
1116    * that has more recently become available and better fits its needs.
1117    * <P>
1118    * Resetting the <code>SyncProvider</code> object causes the
1119    * <code>RowSet</code> object to request a new <code>SyncProvider</code> implementation
1120    * from the <code>SyncFactory</code>. This has the effect of resetting
1121    * all previous connections and relationships with the originating
1122    * data source and can potentially drastically change the synchronization
1123    * behavior of a disconnected rowset.
1124    *
1125    * @param provider a <code>String</code> object giving the fully qualified class
1126    *        name of a <code>SyncProvider</code> implementation
1127    * @throws SQLException if an error occurs while attempting to reset the
1128    * <code>SyncProvider</code> implementation
1129    * @see #getSyncProvider
1130    */
1131    public void setSyncProvider(String provider) throws SQLException;
1132
1133   /**
1134    * Returns the number of rows in this <code>CachedRowSet</code>
1135    * object.
1136    *
1137    * @return number of rows in the rowset
1138    */
1139    public int size();
1140
1141   /**
1142    * Sets the metadata for this <code>CachedRowSet</code> object with
1143    * the given <code>RowSetMetaData</code> object. When a
1144    * <code>RowSetReader</code> object is reading the contents of a rowset,
1145    * it creates a <code>RowSetMetaData</code> object and initializes
1146    * it using the methods in the <code>RowSetMetaData</code> implementation.
1147    * The reference implementation uses the <code>RowSetMetaDataImpl</code>
1148    * class. When the reader has completed reading the rowset contents,
1149    * this method is called internally to pass the <code>RowSetMetaData</code>
1150    * object to the rowset.
1151    *
1152    * @param md a <code>RowSetMetaData</code> object containing
1153    * metadata about the columns in this <code>CachedRowSet</code> object
1154    * @throws SQLException if invalid metadata is supplied to the
1155    * rowset
1156    */
1157    public void setMetaData(RowSetMetaData md) throws SQLException;
1158
1159   /**
1160    * Returns a <code>ResultSet</code> object containing the original value of this
1161    * <code>CachedRowSet</code> object.
1162    * <P>
1163    * The cursor for the <code>ResultSet</code>
1164    * object should be positioned before the first row.
1165    * In addition, the returned <code>ResultSet</code> object should have the following
1166    * properties:
1167    * <UL>
1168    * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE
1169    * <LI>ResultSet.CONCUR_UPDATABLE
1170    * </UL>
1171    * <P>
1172    * The original value for a <code>RowSet</code> object is the value it had before
1173    * the last synchronization with the underlying data source.  If there have been
1174    * no synchronizations, the original value will be the value with which the
1175    * <code>RowSet</code> object was populated.  This method is called internally
1176    * when an application calls the method <code>acceptChanges</code> and the
1177    * <code>SyncProvider</code> object has been implemented to check for conflicts.
1178    * If this is the case, the writer compares the original value with the value
1179    * currently in the data source to check for conflicts.
1180    *
1181    * @return a <code>ResultSet</code> object that contains the original value for
1182    *         this <code>CachedRowSet</code> object
1183    * @throws SQLException if an error occurs producing the
1184    * <code>ResultSet</code> object
1185    */
1186   public ResultSet getOriginal() throws SQLException;
1187
1188   /**
1189    * Returns a <code>ResultSet</code> object containing the original value for the
1190    * current row only of this <code>CachedRowSet</code> object.
1191    * <P>
1192    * The cursor for the <code>ResultSet</code>
1193    * object should be positioned before the first row.
1194    * In addition, the returned <code>ResultSet</code> object should have the following
1195    * properties:
1196    * <UL>
1197    * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE
1198    * <LI>ResultSet.CONCUR_UPDATABLE
1199    * </UL>
1200    *
1201    * @return the original result set of the row
1202    * @throws SQLException if there is no current row
1203    * @see #setOriginalRow
1204    */
1205    public ResultSet getOriginalRow() throws SQLException;
1206
1207   /**
1208    * Sets the current row in this <code>CachedRowSet</code> object as the original
1209    * row.
1210    * <P>
1211    * This method is called internally after the any modified values in the current
1212    * row have been synchronized with the data source. The current row must be tagged
1213    * as no longer inserted, deleted or updated.
1214    * <P>
1215    * A call to <code>setOriginalRow</code> is irreversible.
1216    *
1217    * @throws SQLException if there is no current row or an error is
1218    * encountered resetting the contents of the original row
1219    * @see #getOriginalRow
1220    */
1221    public void setOriginalRow() throws SQLException;
1222
1223   /**
1224    * Returns an identifier for the object (table) that was used to
1225    * create this <code>CachedRowSet</code> object. This name may be set on multiple occasions,
1226    * and the specification imposes no limits on how many times this
1227    * may occur or whether standard implementations should keep track
1228    * of previous table names.
1229    *
1230    * @return a <code>String</code> object giving the name of the table that is the
1231    *         source of data for this <code>CachedRowSet</code> object or <code>null</code>
1232    *         if no name has been set for the table
1233    * @throws SQLException if an error is encountered returning the table name
1234    * @see javax.sql.RowSetMetaData#getTableName
1235    */
1236    public String getTableName() throws SQLException;
1237
1238   /**
1239    * Sets the identifier for the table from which this <code>CachedRowSet</code>
1240    * object was derived to the given table name. The writer uses this name to
1241    * determine which table to use when comparing the values in the data source with the
1242    * <code>CachedRowSet</code> object's values during a synchronization attempt.
1243    * The table identifier also indicates where modified values from this
1244    * <code>CachedRowSet</code> object should be written.
1245    * <P>
1246    * The implementation of this <code>CachedRowSet</code> object may obtain the
1247    * the name internally from the <code>RowSetMetaDataImpl</code> object.
1248    *
1249    * @param tabName a <code>String</code> object identifying the table from which this
1250             <code>CachedRowSet</code> object was derived; cannot be <code>null</code>
1251    *         but may be an empty string
1252    * @throws SQLException if an error is encountered naming the table or
1253    *     <i>tabName</i> is <code>null</code>
1254    * @see javax.sql.RowSetMetaData#setTableName
1255    * @see javax.sql.RowSetWriter
1256    * @see javax.sql.rowset.spi.SyncProvider
1257    */
1258   public void setTableName(String tabName) throws SQLException;
1259
1260   /**
1261    * Returns an array containing one or more column numbers indicating the columns
1262    * that form a key that uniquely
1263    * identifies a row in this <code>CachedRowSet</code> object.
1264    *
1265    * @return an array containing the column number or numbers that indicate which columns
1266    *       constitute a primary key
1267    *       for a row in this <code>CachedRowSet</code> object. This array should be
1268    *       empty if no columns are representative of a primary key.
1269    * @throws SQLException if this <code>CachedRowSet</code> object is empty
1270    * @see #setKeyColumns
1271    * @see Joinable#getMatchColumnIndexes
1272    * @see Joinable#getMatchColumnNames
1273    */
1274    public int[] getKeyColumns() throws SQLException;
1275
1276   /**
1277    * Sets this <code>CachedRowSet</code> object's <code>keyCols</code>
1278    * field with the given array of column numbers, which forms a key
1279    * for uniquely identifying a row in this <code>CachedRowSet</code> object.
1280    * <p>
1281    * If a <code>CachedRowSet</code> object becomes part of a <code>JoinRowSet</code>
1282    * object, the keys defined by this method and the resulting constraints are
1283    * maintained if the columns designated as key columns also become match
1284    * columns.
1285    *
1286    * @param keys an array of <code>int</code> indicating the columns that form
1287    *        a primary key for this <code>CachedRowSet</code> object; every
1288    *        element in the array must be greater than <code>0</code> and
1289    *        less than or equal to the number of columns in this rowset
1290    * @throws SQLException if any of the numbers in the given array
1291    *            are not valid for this rowset
1292    * @see #getKeyColumns
1293    * @see Joinable#setMatchColumn(String)
1294    * @see Joinable#setMatchColumn(int)
1295
1296    */
1297    public void setKeyColumns(int[] keys) throws SQLException;
1298
1299
1300   /**
1301    * Returns a new <code>RowSet</code> object backed by the same data as
1302    * that of this <code>CachedRowSet</code> object. In effect, both
1303    * <code>CachedRowSet</code> objects have a cursor over the same data.
1304    * As a result, any changes made by a duplicate are visible to the original
1305    * and to any other duplicates, just as a change made by the original is visible
1306    * to all of its duplicates. If a duplicate calls a method that changes the
1307    * underlying data, the method it calls notifies all registered listeners
1308    * just as it would when it is called by the original <code>CachedRowSet</code>
1309    * object.
1310    * <P>
1311    * In addition, any <code>RowSet</code> object
1312    * created by this method will have the same properties as this
1313    * <code>CachedRowSet</code> object. For example, if this <code>CachedRowSet</code>
1314    * object is read-only, all of its duplicates will also be read-only. If it is
1315    * changed to be updatable, the duplicates also become updatable.
1316    * <P>
1317    * NOTE: If multiple threads access <code>RowSet</code> objects created from
1318    * the <code>createShared()</code> method, the following behavior is specified
1319    * to preserve shared data integrity: reads and writes of all
1320    * shared <code>RowSet</code> objects should be made serially between each
1321    * object and the single underlying tabular structure.
1322    *
1323    * @return a new shared <code>RowSet</code> object that has the same properties
1324    *         as this <code>CachedRowSet</code> object and that has a cursor over
1325    *         the same data
1326    * @throws SQLException if an error occurs or cloning is not
1327    * supported in the underlying platform
1328    * @see javax.sql.RowSetEvent
1329    * @see javax.sql.RowSetListener
1330    */
1331    public RowSet createShared() throws SQLException;
1332
1333   /**
1334    * Creates a <code>RowSet</code> object that is a deep copy of the data in
1335    * this <code>CachedRowSet</code> object. In contrast to
1336    * the <code>RowSet</code> object generated from a <code>createShared</code>
1337    * call, updates made to the copy of the original <code>RowSet</code> object
1338    * must not be visible to the original <code>RowSet</code> object. Also, any
1339    * event listeners that are registered with the original
1340    * <code>RowSet</code> must not have scope over the new
1341    * <code>RowSet</code> copies. In addition, any constraint restrictions
1342    * established must be maintained.
1343    *
1344    * @return a new <code>RowSet</code> object that is a deep copy
1345    * of this <code>CachedRowSet</code> object and is
1346    * completely independent of this <code>CachedRowSet</code> object
1347    * @throws SQLException if an error occurs in generating the copy of
1348    * the of this <code>CachedRowSet</code> object
1349    * @see #createShared
1350    * @see #createCopySchema
1351    * @see #createCopyNoConstraints
1352    * @see javax.sql.RowSetEvent
1353    * @see javax.sql.RowSetListener
1354    */
1355    public CachedRowSet createCopy() throws SQLException;
1356
1357    /**
1358     * Creates a <code>CachedRowSet</code> object that is an empty copy of this
1359     * <code>CachedRowSet</code> object.  The copy
1360     * must not contain any contents but only represent the table
1361     * structure of the original <code>CachedRowSet</code> object. In addition, primary
1362     * or foreign key constraints set in the originating <code>CachedRowSet</code> object must
1363     * be equally enforced in the new empty <code>CachedRowSet</code> object.
1364     * In contrast to
1365     * the <code>RowSet</code> object generated from a <code>createShared</code> method
1366     * call, updates made to a copy of this <code>CachedRowSet</code> object with the
1367     * <code>createCopySchema</code> method must not be visible to it.
1368     * <P>
1369     * Applications can form a <code>WebRowSet</code> object from the <code>CachedRowSet</code>
1370     * object returned by this method in order
1371     * to export the <code>RowSet</code> schema definition to XML for future use.
1372     * @return An empty copy of this {@code CachedRowSet} object
1373     * @throws SQLException if an error occurs in cloning the structure of this
1374     *         <code>CachedRowSet</code> object
1375     * @see #createShared
1376     * @see #createCopySchema
1377     * @see #createCopyNoConstraints
1378     * @see javax.sql.RowSetEvent
1379     * @see javax.sql.RowSetListener
1380     */
1381    public CachedRowSet createCopySchema() throws SQLException;
1382
1383    /**
1384     * Creates a <code>CachedRowSet</code> object that is a deep copy of
1385     * this <code>CachedRowSet</code> object's data but is independent of it.
1386     * In contrast to
1387     * the <code>RowSet</code> object generated from a <code>createShared</code>
1388     * method call, updates made to a copy of this <code>CachedRowSet</code> object
1389     * must not be visible to it. Also, any
1390     * event listeners that are registered with this
1391     * <code>CachedRowSet</code> object must not have scope over the new
1392     * <code>RowSet</code> object. In addition, any constraint restrictions
1393     * established for this <code>CachedRowSet</code> object must <b>not</b> be maintained
1394     * in the copy.
1395     *
1396     * @return a new <code>CachedRowSet</code> object that is a deep copy
1397     *     of this <code>CachedRowSet</code> object and is
1398     *     completely independent of this  <code>CachedRowSet</code> object
1399     * @throws SQLException if an error occurs in generating the copy of
1400     *     the of this <code>CachedRowSet</code> object
1401     * @see #createCopy
1402     * @see #createShared
1403     * @see #createCopySchema
1404     * @see javax.sql.RowSetEvent
1405     * @see javax.sql.RowSetListener
1406     */
1407    public CachedRowSet createCopyNoConstraints() throws SQLException;
1408
1409    /**
1410     * Retrieves the first warning reported by calls on this <code>RowSet</code> object.
1411     * Subsequent warnings on this <code>RowSet</code> object will be chained to the
1412     * <code>RowSetWarning</code> object that this method returns.
1413     *
1414     * The warning chain is automatically cleared each time a new row is read.
1415     * This method may not be called on a RowSet object that has been closed;
1416     * doing so will cause a <code>SQLException</code> to be thrown.
1417     *
1418     * @return RowSetWarning the first <code>RowSetWarning</code>
1419     * object reported or null if there are none
1420     * @throws SQLException if this method is called on a closed RowSet
1421     * @see RowSetWarning
1422     */
1423    public RowSetWarning getRowSetWarnings() throws SQLException;
1424
1425    /**
1426     * Retrieves a <code>boolean</code> indicating whether rows marked
1427     * for deletion appear in the set of current rows. If <code>true</code> is
1428     * returned, deleted rows are visible with the current rows. If
1429     * <code>false</code> is returned, rows are not visible with the set of
1430     * current rows. The default value is <code>false</code>.
1431     * <P>
1432     * Standard rowset implementations may choose to restrict this behavior
1433     * due to security considerations or to better fit certain deployment
1434     * scenarios. This is left as implementation defined and does not
1435     * represent standard behavior.
1436     * <P>
1437     * Note: Allowing deleted rows to remain visible complicates the behavior
1438     * of some standard JDBC <code>RowSet</code> Implementations methods.
1439     * However, most rowset users can simply ignore this extra detail because
1440     * only very specialized applications will likely want to take advantage of
1441     * this feature.
1442     *
1443     * @return <code>true</code> if deleted rows are visible;
1444     *         <code>false</code> otherwise
1445     * @throws SQLException if a rowset implementation is unable to
1446     * to determine whether rows marked for deletion are visible
1447     * @see #setShowDeleted
1448     */
1449    public boolean getShowDeleted() throws SQLException;
1450
1451    /**
1452     * Sets the property <code>showDeleted</code> to the given
1453     * <code>boolean</code> value, which determines whether
1454     * rows marked for deletion appear in the set of current rows.
1455     * If the value is set to <code>true</code>, deleted rows are immediately
1456     * visible with the set of current rows. If the value is set to
1457     * <code>false</code>, the deleted rows are set as invisible with the
1458     * current set of rows.
1459     * <P>
1460     * Standard rowset implementations may choose to restrict this behavior
1461     * due to security considerations or to better fit certain deployment
1462     * scenarios. This is left as implementations defined and does not
1463     * represent standard behavior.
1464     *
1465     * @param b <code>true</code> if deleted rows should be shown;
1466     *              <code>false</code> otherwise
1467     * @exception SQLException if a rowset implementation is unable to
1468     * to reset whether deleted rows should be visible
1469     * @see #getShowDeleted
1470     */
1471    public void setShowDeleted(boolean b) throws SQLException;
1472
1473    /**
1474     * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
1475     * a <code>Connection</code> object from the <code>ResultSet</code> or JDBC
1476     * properties passed to it's constructors. This method wraps the
1477     * <code>Connection</code> commit method to allow flexible
1478     * auto commit or non auto commit transactional control support.
1479     * <p>
1480     * Makes all changes that are performed by the <code>acceptChanges()</code>
1481     * method since the previous commit/rollback permanent. This method should
1482     * be used only when auto-commit mode has been disabled.
1483     *
1484     * @throws SQLException if a database access error occurs or this
1485     * Connection object within this <code>CachedRowSet</code> is in auto-commit mode
1486     * @see java.sql.Connection#setAutoCommit
1487     */
1488    public void commit() throws SQLException;
1489
1490    /**
1491     * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
1492     * a <code>Connection</code> object from the original <code>ResultSet</code>
1493     * or JDBC properties passed to it.
1494     * <p>
1495     * Undoes all changes made in the current transaction.  This method
1496     * should be used only when auto-commit mode has been disabled.
1497     *
1498     * @throws SQLException if a database access error occurs or this Connection
1499     * object within this <code>CachedRowSet</code> is in auto-commit mode.
1500     */
1501    public void rollback() throws SQLException;
1502
1503    /**
1504     * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
1505     * a <code>Connection</code> object from the original <code>ResultSet</code>
1506     * or JDBC properties passed to it.
1507     * <p>
1508     * Undoes all changes made in the current transaction back to the last
1509     * <code>Savepoint</code> transaction marker. This method should be used only
1510     * when auto-commit mode has been disabled.
1511     *
1512     * @param s A <code>Savepoint</code> transaction marker
1513     * @throws SQLException if a database access error occurs or this Connection
1514     * object within this <code>CachedRowSet</code> is in auto-commit mode.
1515     */
1516    public void rollback(Savepoint s) throws SQLException;
1517
1518    /**
1519     * Causes the <code>CachedRowSet</code> object's <code>SyncProvider</code>
1520     * to commit the changes when <code>acceptChanges()</code> is called. If
1521     * set to false, the changes will <b>not</b> be committed until one of the
1522     * <code>CachedRowSet</code> interface transaction methods is called.
1523     *
1524     * @deprecated Because this field is final (it is part of an interface),
1525     *  its value cannot be changed.
1526     * @see #commit
1527     * @see #rollback
1528     */
1529    @Deprecated
1530    public static final boolean COMMIT_ON_ACCEPT_CHANGES = true;
1531
1532    /**
1533     * Notifies registered listeners that a RowSet object in the given RowSetEvent
1534     * object has populated a number of additional rows. The <code>numRows</code> parameter
1535     * ensures that this event will only be fired every <code>numRow</code>.
1536     * <p>
1537     * The source of the event can be retrieved with the method event.getSource.
1538     *
1539     * @param event a <code>RowSetEvent</code> object that contains the
1540     *     <code>RowSet</code> object that is the source of the events
1541     * @param numRows when populating, the number of rows interval on which the
1542     *     <code>CachedRowSet</code> populated should fire; the default value
1543     *     is zero; cannot be less than <code>fetchSize</code> or zero
1544     * @throws SQLException {@code numRows < 0 or numRows < getFetchSize() }
1545     */
1546    public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException;
1547
1548    /**
1549     * Populates this <code>CachedRowSet</code> object with data from
1550     * the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code>
1551     * method, an additional parameter is provided to allow starting position within
1552     * the <code>ResultSet</code> from where to populate the CachedRowSet
1553     * instance.
1554     * <P>
1555     * This method can be used as an alternative to the <code>execute</code> method when an
1556     * application has a connection to an open <code>ResultSet</code> object.
1557     * Using the method <code>populate</code> can be more efficient than using
1558     * the version of the <code>execute</code> method that takes no parameters
1559     * because it does not open a new connection and re-execute this
1560     * <code>CachedRowSet</code> object's command. Using the <code>populate</code>
1561     *  method is more a matter of convenience when compared to using the version
1562     * of <code>execute</code> that takes a <code>ResultSet</code> object.
1563     *
1564     * @param startRow the position in the <code>ResultSet</code> from where to start
1565     *                populating the records in this <code>CachedRowSet</code>
1566     * @param rs the <code>ResultSet</code> object containing the data
1567     * to be read into this <code>CachedRowSet</code> object
1568     * @throws SQLException if a null <code>ResultSet</code> object is supplied
1569     * or this <code>CachedRowSet</code> object cannot
1570     * retrieve the associated <code>ResultSetMetaData</code> object
1571     * @see #execute
1572     * @see #populate(ResultSet)
1573     * @see java.sql.ResultSet
1574     * @see java.sql.ResultSetMetaData
1575    */
1576    public void populate(ResultSet rs, int startRow) throws SQLException;
1577
1578    /**
1579     * Sets the <code>CachedRowSet</code> object's page-size. A <code>CachedRowSet</code>
1580     * may be configured to populate itself in page-size sized batches of rows. When
1581     * either <code>populate()</code> or <code>execute()</code> are called, the
1582     * <code>CachedRowSet</code> fetches an additional page according to the
1583     * original SQL query used to populate the RowSet.
1584     *
1585     * @param size the page-size of the <code>CachedRowSet</code>
1586     * @throws SQLException if an error occurs setting the <code>CachedRowSet</code>
1587     *      page size or if the page size is less than 0.
1588     */
1589    public void setPageSize(int size) throws SQLException;
1590
1591    /**
1592     * Returns the page-size for the <code>CachedRowSet</code> object
1593     *
1594     * @return an <code>int</code> page size
1595     */
1596    public int getPageSize();
1597
1598    /**
1599     * Increments the current page of the <code>CachedRowSet</code>. This causes
1600     * the <code>CachedRowSet</code> implementation to fetch the next page-size
1601     * rows and populate the RowSet, if remaining rows remain within scope of the
1602     * original SQL query used to populated the RowSet.
1603     *
1604     * @return true if more pages exist; false if this is the last page
1605     * @throws SQLException if an error occurs fetching the next page, or if this
1606     *     method is called prematurely before populate or execute.
1607     */
1608    public boolean nextPage() throws SQLException;
1609
1610    /**
1611     * Decrements the current page of the <code>CachedRowSet</code>. This causes
1612     * the <code>CachedRowSet</code> implementation to fetch the previous page-size
1613     * rows and populate the RowSet. The amount of rows returned in the previous
1614     * page must always remain within scope of the original SQL query used to
1615     * populate the RowSet.
1616     *
1617     * @return true if the previous page is successfully retrieved; false if this
1618     *     is the first page.
1619     * @throws SQLException if an error occurs fetching the previous page, or if
1620     *     this method is called prematurely before populate or execute.
1621     */
1622    public boolean previousPage() throws SQLException;
1623
1624}
1625