1 /*
   2  * Copyright (c) 2003, 2013, 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&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>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  *
 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-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  *
 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  */
 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 SyncProviderException if the underlying
 738     * synchronization provider's writer fails to write the updates
 739     * back to the data source
 740     * @see #acceptChanges(java.sql.Connection)
 741     * @see javax.sql.RowSetWriter
 742     * @see javax.sql.rowset.spi.SyncFactory
 743     * @see javax.sql.rowset.spi.SyncProvider
 744     * @see javax.sql.rowset.spi.SyncProviderException
 745     * @see javax.sql.rowset.spi.SyncResolver
 746     */
 747     public void acceptChanges() throws SyncProviderException;
 748 
 749    /**
 750     * Propagates all row update, insert and delete changes to the
 751     * data source backing this <code>CachedRowSet</code> object
 752     * using the specified <code>Connection</code> object to establish a
 753     * connection to the data source.
 754     * <P>
 755     * The other version of the <code>acceptChanges</code> method is not passed
 756     * a connection because it uses
 757     * the <code>Connection</code> object already defined within the <code>RowSet</code>
 758     * object, which is the connection used for populating it initially.
 759     * <P>
 760     * This form of the method <code>acceptChanges</code> is similar to the
 761     * form that takes no arguments; however, unlike the other form, this form
 762     * can be used only when the underlying data source is a JDBC data source.
 763     * The updated <code>Connection</code> properties must be used by the
 764     * <code>SyncProvider</code> to reset the <code>RowSetWriter</code>
 765     * configuration to ensure that the contents of the <code>CachedRowSet</code>
 766     * object are synchronized correctly.
 767     * <P>
 768     * When the method <code>acceptChanges</code> executes successfully, in
 769     * addition to writing changes to the data source, it
 770     * makes the values in the current row be the values in the original row.
 771     * <P>
 772     * Depending on the synchronization level of the <code>SyncProvider</code>
 773     * implementation being used, the writer will compare the original values
 774     * with those in the data source to check for conflicts. When there is a conflict,
 775     * the <code>RIOptimisticProvider</code> implementation, for example, throws a
 776     * <code>SyncProviderException</code> and does not write anything to the
 777     * data source.
 778     * <P>
 779     * An application may choose to catch the <code>SyncProviderException</code>
 780     * object and retrieve the <code>SyncResolver</code> object it contains.
 781     * The <code>SyncResolver</code> object lists the conflicts row by row and
 782     * sets a lock on the data source to avoid further conflicts while the
 783     * current conflicts are being resolved.
 784     * Further, for each conflict, it provides methods for examining the conflict
 785     * and setting the value that should be persisted in the data source.
 786     * After all conflicts have been resolved, an application must call the
 787     * <code>acceptChanges</code> method again to write resolved values to the
 788     * data source.  If all of the values in the data source are already the
 789     * values to be persisted, the method <code>acceptChanges</code> does nothing.
 790     * <P>
 791     * Some provider implementations may use locks to ensure that there are no
 792     * conflicts.  In such cases, it is guaranteed that the writer will succeed in
 793     * writing changes to the data source when the method <code>acceptChanges</code>
 794     * is called.  This method may be called immediately after the methods
 795     * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>
 796     * have been called, but it is more efficient to call it only once after
 797     * all changes have been made so that only one connection needs to be
 798     * established.
 799     * <P>
 800     * Note: The <code>acceptChanges()</code> method will determine if the
 801     * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set
 802     * to true, all updates in the synchronization are committed to the data
 803     * source. Otherwise, the application <b>must</b> explicity call the
 804     * <code>commit</code> or <code>rollback</code> methods as appropriate.
 805     *
 806     * @param con a standard JDBC <code>Connection</code> object
 807     * @throws SyncProviderException if the underlying
 808     * synchronization provider's writer fails to write the updates
 809     * back to the data source
 810     * @see #acceptChanges()
 811     * @see javax.sql.RowSetWriter
 812     * @see javax.sql.rowset.spi.SyncFactory
 813     * @see javax.sql.rowset.spi.SyncProvider
 814     * @see javax.sql.rowset.spi.SyncProviderException
 815     * @see javax.sql.rowset.spi.SyncResolver
 816     */
 817     public void acceptChanges(Connection con) throws SyncProviderException;
 818 
 819    /**
 820     * Restores this <code>CachedRowSet</code> object to its original
 821     * value, that is, its value before the last set of changes. If there
 822     * have been no changes to the rowset or only one set of changes,
 823     * the original value is the value with which this <code>CachedRowSet</code> object
 824     * was populated; otherwise, the original value is
 825     * the value it had immediately before its current value.
 826     * <P>
 827     * When this method is called, a <code>CachedRowSet</code> implementation
 828     * must ensure that all updates, inserts, and deletes to the current
 829     * rowset instance are replaced by the previous values. In addition,
 830     * the cursor should be
 831     * reset to the first row and a <code>rowSetChanged</code> event
 832     * should be fired to notify all registered listeners.
 833     *
 834     * @throws SQLException if an error occurs rolling back the current value of
 835     *       this <code>CachedRowSet</code> object to its previous value
 836     * @see javax.sql.RowSetListener#rowSetChanged
 837     */
 838     public void restoreOriginal() throws SQLException;
 839 
 840    /**
 841     * Releases the current contents of this <code>CachedRowSet</code>
 842     * object and sends a <code>rowSetChanged</code> event to all
 843     * registered listeners. Any outstanding updates are discarded and
 844     * the rowset contains no rows after this method is called. There
 845     * are no interactions with the underlying data source, and any rowset
 846     * content, metadata, and content updates should be non-recoverable.
 847     * <P>
 848     * This <code>CachedRowSet</code> object should lock until its contents and
 849     * associated updates are fully cleared, thus preventing 'dirty' reads by
 850     * other components that hold a reference to this <code>RowSet</code> object.
 851     * In addition, the contents cannot be released
 852     * until all all components reading this <code>CachedRowSet</code> object
 853     * have completed their reads. This <code>CachedRowSet</code> object
 854     * should be returned to normal behavior after firing the
 855     * <code>rowSetChanged</code> event.
 856     * <P>
 857     * The metadata, including JDBC properties and Synchronization SPI
 858     * properties, are maintained for future use. It is important that
 859     * properties such as the <code>command</code> property be
 860     * relevant to the originating data source from which this <code>CachedRowSet</code>
 861     * object was originally established.
 862     * <P>
 863     * This method empties a rowset, as opposed to the <code>close</code> method,
 864     * which marks the entire rowset as recoverable to allow the garbage collector
 865     * the rowset's Java VM resources.
 866     *
 867     * @throws SQLException if an error occurs flushing the contents of this
 868     * <code>CachedRowSet</code> object
 869     * @see javax.sql.RowSetListener#rowSetChanged
 870     * @see java.sql.ResultSet#close
 871     */
 872     public void release() throws SQLException;
 873 
 874    /**
 875     * Cancels the deletion of the current row and notifies listeners that
 876     * a row has changed. After this method is called, the current row is
 877     * no longer marked for deletion. This method can be called at any
 878     * time during the lifetime of the rowset.
 879     * <P>
 880     * In addition, multiple cancellations of row deletions can be made
 881     * by adjusting the position of the cursor using any of the cursor
 882     * position control methods such as:
 883     * <ul>
 884     * <li><code>CachedRowSet.absolute</code>
 885     * <li><code>CachedRowSet.first</code>
 886     * <li><code>CachedRowSet.last</code>
 887     * </ul>
 888     *
 889     * @throws SQLException if (1) the current row has not been deleted or
 890     * (2) the cursor is on the insert row, before the first row, or
 891     * after the last row
 892     * @see javax.sql.rowset.CachedRowSet#undoInsert
 893     * @see java.sql.ResultSet#cancelRowUpdates
 894     */
 895     public void undoDelete() throws SQLException;
 896 
 897    /**
 898     * Immediately removes the current row from this <code>CachedRowSet</code>
 899     * object if the row has been inserted, and also notifies listeners that a
 900     * row has changed. This method can be called at any time during the
 901     * lifetime of a rowset and assuming the current row is within
 902     * the exception limitations (see below), it cancels the row insertion
 903     * of the current row.
 904     * <P>
 905     * In addition, multiple cancellations of row insertions can be made
 906     * by adjusting the position of the cursor using any of the cursor
 907     * position control methods such as:
 908     * <ul>
 909     * <li><code>CachedRowSet.absolute</code>
 910     * <li><code>CachedRowSet.first</code>
 911     * <li><code>CachedRowSet.last</code>
 912     * </ul>
 913     *
 914     * @throws SQLException if (1) the current row has not been inserted or (2)
 915     * the cursor is before the first row, after the last row, or on the
 916     * insert row
 917     * @see javax.sql.rowset.CachedRowSet#undoDelete
 918     * @see java.sql.ResultSet#cancelRowUpdates
 919     */
 920     public void undoInsert() throws SQLException;
 921 
 922 
 923    /**
 924     * Immediately reverses the last update operation if the
 925     * row has been modified. This method can be
 926     * called to reverse updates on all columns until all updates in a row have
 927     * been rolled back to their state just prior to the last synchronization
 928     * (<code>acceptChanges</code>) or population. This method may also be called
 929     * while performing updates to the insert row.
 930     * <P>
 931     * <code>undoUpdate</code> may be called at any time during the lifetime of a
 932     * rowset; however, after a synchronization has occurred, this method has no
 933     * effect until further modification to the rowset data has occurred.
 934     *
 935     * @throws SQLException if the cursor is before the first row or after the last
 936     *     row in in this <code>CachedRowSet</code> object
 937     * @see #undoDelete
 938     * @see #undoInsert
 939     * @see java.sql.ResultSet#cancelRowUpdates
 940     */
 941     public void undoUpdate() throws SQLException;
 942 
 943    /**
 944     * Indicates whether the designated column in the current row of this
 945     * <code>CachedRowSet</code> object has been updated.
 946     *
 947     * @param idx an <code>int</code> identifying the column to be checked for updates
 948     * @return <code>true</code> if the designated column has been visibly updated;
 949     * <code>false</code> otherwise
 950     * @throws SQLException if the cursor is on the insert row, before the first row,
 951     *     or after the last row
 952     * @see java.sql.DatabaseMetaData#updatesAreDetected
 953     */
 954     public boolean columnUpdated(int idx) throws SQLException;
 955 
 956 
 957    /**
 958     * Indicates whether the designated column in the current row of this
 959     * <code>CachedRowSet</code> object has been updated.
 960     *
 961     * @param columnName a <code>String</code> object giving the name of the
 962     *        column to be checked for updates
 963     * @return <code>true</code> if the column has been visibly updated;
 964     * <code>false</code> otherwise
 965     * @throws SQLException if the cursor is on the insert row, before the first row,
 966     *      or after the last row
 967     * @see java.sql.DatabaseMetaData#updatesAreDetected
 968     */
 969     public boolean columnUpdated(String columnName) throws SQLException;
 970 
 971    /**
 972     * Converts this <code>CachedRowSet</code> object to a <code>Collection</code>
 973     * object that contains all of this <code>CachedRowSet</code> object's data.
 974     * Implementations have some latitude in
 975     * how they can represent this <code>Collection</code> object because of the
 976     * abstract nature of the <code>Collection</code> framework.
 977     * Each row must be fully represented in either a
 978     * general purpose <code>Collection</code> implementation or a specialized
 979     * <code>Collection</code> implementation, such as a <code>TreeMap</code>
 980     * object or a <code>Vector</code> object.
 981     * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
 982     * in the Java programming language.
 983     * <P>
 984     * The standard reference implementation for the <code>CachedRowSet</code>
 985     * interface uses a <code>TreeMap</code> object for the rowset, with the
 986     * values in each row being contained in  <code>Vector</code> objects. It is
 987     * expected that most implementations will do the same.
 988     * <P>
 989     * The <code>TreeMap</code> type of collection guarantees that the map will be in
 990     * ascending key order, sorted according to the natural order for the
 991     * key's class.
 992     * Each key references a <code>Vector</code> object that corresponds to one
 993     * row of a <code>RowSet</code> object. Therefore, the size of each
 994     * <code>Vector</code> object  must be exactly equal to the number of
 995     * columns in the <code>RowSet</code> object.
 996     * The key used by the <code>TreeMap</code> collection is determined by the
 997     * implementation, which may choose to leverage a set key that is
 998     * available within the internal <code>RowSet</code> tabular structure by
 999     * virtue of a key already set either on the <code>RowSet</code> object
1000     * itself or on the underlying SQL data.

1001     *
1002     * @return a <code>Collection</code> object that contains the values in
1003     * each row in this <code>CachedRowSet</code> object
1004     * @throws SQLException if an error occurs generating the collection
1005     * @see #toCollection(int)
1006     * @see #toCollection(String)
1007     */
1008     public Collection<?> toCollection() throws SQLException;
1009 
1010    /**
1011     * Converts the designated column in this <code>CachedRowSet</code> object
1012     * to a <code>Collection</code> object. Implementations have some latitude in
1013     * how they can represent this <code>Collection</code> object because of the
1014     * abstract nature of the <code>Collection</code> framework.
1015     * Each column value should be fully represented in either a
1016     * general purpose <code>Collection</code> implementation or a specialized
1017     * <code>Collection</code> implementation, such as a <code>Vector</code> object.
1018     * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
1019     * in the Java programming language.
1020     * <P>
1021     * The standard reference implementation uses a <code>Vector</code> object
1022     * to contain the column values, and it is expected
1023     * that most implementations will do the same. If a <code>Vector</code> object
1024     * is used, it size must be exactly equal to the number of rows
1025     * in this <code>CachedRowSet</code> object.
1026     *
1027     * @param column an <code>int</code> indicating the column whose values
1028     *        are to be represented in a <code>Collection</code> object
1029     * @return a <code>Collection</code> object that contains the values
1030     * stored in the specified column of this <code>CachedRowSet</code>
1031     * object
1032     * @throws SQLException if an error occurs generating the collection or
1033     * an invalid column id is provided
1034     * @see #toCollection
1035     * @see #toCollection(String)
1036     */
1037     public Collection<?> toCollection(int column) throws SQLException;
1038 
1039    /**
1040     * Converts the designated column in this <code>CachedRowSet</code> object
1041     * to a <code>Collection</code> object. Implementations have some latitude in
1042     * how they can represent this <code>Collection</code> object because of the
1043     * abstract nature of the <code>Collection</code> framework.
1044     * Each column value should be fully represented in either a
1045     * general purpose <code>Collection</code> implementation or a specialized
1046     * <code>Collection</code> implementation, such as a <code>Vector</code> object.
1047     * An SQL <code>NULL</code> column value must be represented as a <code>null</code>
1048     * in the Java programming language.
1049     * <P>
1050     * The standard reference implementation uses a <code>Vector</code> object
1051     * to contain the column values, and it is expected
1052     * that most implementations will do the same. If a <code>Vector</code> object
1053     * is used, it size must be exactly equal to the number of rows
1054     * in this <code>CachedRowSet</code> object.
1055     *
1056     * @param column a <code>String</code> object giving the name of the
1057     *        column whose values are to be represented in a collection
1058     * @return a <code>Collection</code> object that contains the values
1059     * stored in the specified column of this <code>CachedRowSet</code>
1060     * object
1061     * @throws SQLException if an error occurs generating the collection or
1062     * an invalid column id is provided
1063     * @see #toCollection
1064     * @see #toCollection(int)
1065     */
1066     public Collection<?> toCollection(String column) throws SQLException;
1067 
1068    /**
1069     * Retrieves the <code>SyncProvider</code> implementation for this
1070     * <code>CachedRowSet</code> object. Internally, this method is used by a rowset
1071     * to trigger read or write actions between the rowset
1072     * and the data source. For example, a rowset may need to get a handle
1073     * on the the rowset reader (<code>RowSetReader</code> object) from the
1074     * <code>SyncProvider</code> to allow the rowset to be populated.
1075     * <pre>
1076     *     RowSetReader rowsetReader = null;
1077     *     SyncProvider provider =
1078     *         SyncFactory.getInstance("javax.sql.rowset.provider.RIOptimisticProvider");
1079     *         if (provider instanceof RIOptimisticProvider) {
1080     *             rowsetReader = provider.getRowSetReader();
1081     *         }
1082     * </pre>
1083     * Assuming <i>rowsetReader</i> is a private, accessible field within
1084     * the rowset implementation, when an application calls the <code>execute</code>
1085     * method, it in turn calls on the reader's <code>readData</code> method
1086     * to populate the <code>RowSet</code> object.
1087     *<pre>
1088     *     rowsetReader.readData((RowSetInternal)this);
1089     * </pre>
1090     * <P>
1091     * In addition, an application can use the <code>SyncProvider</code> object
1092     * returned by this method to call methods that return information about the
1093     * <code>SyncProvider</code> object, including information about the
1094     * vendor, version, provider identification, synchronization grade, and locks
1095     * it currently has set.
1096     *
1097     * @return the <code>SyncProvider</code> object that was set when the rowset
1098     *      was instantiated, or if none was was set, the default provider
1099     * @throws SQLException if an error occurs while returning the
1100     * <code>SyncProvider</code> object
1101     * @see #setSyncProvider
1102     */
1103     public SyncProvider getSyncProvider() throws SQLException;
1104 
1105    /**
1106     * Sets the <code>SyncProvider</code> object for this <code>CachedRowSet</code>
1107     * object to the one specified.  This method
1108     * allows the <code>SyncProvider</code> object to be reset.
1109     * <P>
1110     * A <code>CachedRowSet</code> implementation should always be instantiated
1111     * with an available <code>SyncProvider</code> mechanism, but there are
1112     * cases where resetting the <code>SyncProvider</code> object is desirable
1113     * or necessary. For example, an application might want to use the default
1114     * <code>SyncProvider</code> object for a time and then choose to use a provider
1115     * that has more recently become available and better fits its needs.
1116     * <P>
1117     * Resetting the <code>SyncProvider</code> object causes the
1118     * <code>RowSet</code> object to request a new <code>SyncProvider</code> implementation
1119     * from the <code>SyncFactory</code>. This has the effect of resetting
1120     * all previous connections and relationships with the originating
1121     * data source and can potentially drastically change the synchronization
1122     * behavior of a disconnected rowset.
1123     *
1124     * @param provider a <code>String</code> object giving the fully qualified class
1125     *        name of a <code>SyncProvider</code> implementation
1126     * @throws SQLException if an error occurs while attempting to reset the
1127     * <code>SyncProvider</code> implementation
1128     * @see #getSyncProvider
1129     */
1130     public void setSyncProvider(String provider) throws SQLException;
1131 
1132    /**
1133     * Returns the number of rows in this <code>CachedRowSet</code>
1134     * object.
1135     *
1136     * @return number of rows in the rowset
1137     */
1138     public int size();
1139 
1140    /**
1141     * Sets the metadata for this <code>CachedRowSet</code> object with
1142     * the given <code>RowSetMetaData</code> object. When a
1143     * <code>RowSetReader</code> object is reading the contents of a rowset,
1144     * it creates a <code>RowSetMetaData</code> object and initializes
1145     * it using the methods in the <code>RowSetMetaData</code> implementation.
1146     * The reference implementation uses the <code>RowSetMetaDataImpl</code>
1147     * class. When the reader has completed reading the rowset contents,
1148     * this method is called internally to pass the <code>RowSetMetaData</code>
1149     * object to the rowset.
1150     *
1151     * @param md a <code>RowSetMetaData</code> object containing
1152     * metadata about the columns in this <code>CachedRowSet</code> object
1153     * @throws SQLException if invalid metadata is supplied to the
1154     * rowset
1155     */
1156     public void setMetaData(RowSetMetaData md) throws SQLException;
1157 
1158    /**
1159     * Returns a <code>ResultSet</code> object containing the original value of this
1160     * <code>CachedRowSet</code> object.
1161     * <P>
1162     * The cursor for the <code>ResultSet</code>
1163     * object should be positioned before the first row.
1164     * In addition, the returned <code>ResultSet</code> object should have the following
1165     * properties:
1166     * <UL>
1167     * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE
1168     * <LI>ResultSet.CONCUR_UPDATABLE
1169     * </UL>
1170     * <P>
1171     * The original value for a <code>RowSet</code> object is the value it had before
1172     * the last synchronization with the underlying data source.  If there have been
1173     * no synchronizations, the original value will be the value with which the
1174     * <code>RowSet</code> object was populated.  This method is called internally
1175     * when an application calls the method <code>acceptChanges</code> and the
1176     * <code>SyncProvider</code> object has been implemented to check for conflicts.
1177     * If this is the case, the writer compares the original value with the value
1178     * currently in the data source to check for conflicts.
1179     *
1180     * @return a <code>ResultSet</code> object that contains the original value for
1181     *         this <code>CachedRowSet</code> object
1182     * @throws SQLException if an error occurs producing the
1183     * <code>ResultSet</code> object
1184     */
1185    public ResultSet getOriginal() throws SQLException;
1186 
1187    /**
1188     * Returns a <code>ResultSet</code> object containing the original value for the
1189     * current row only of this <code>CachedRowSet</code> object.
1190     * <P>
1191     * The cursor for the <code>ResultSet</code>
1192     * object should be positioned before the first row.
1193     * In addition, the returned <code>ResultSet</code> object should have the following
1194     * properties:
1195     * <UL>
1196     * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE
1197     * <LI>ResultSet.CONCUR_UPDATABLE
1198     * </UL>
1199     *
1200     * @return the original result set of the row
1201     * @throws SQLException if there is no current row
1202     * @see #setOriginalRow
1203     */
1204     public ResultSet getOriginalRow() throws SQLException;
1205 
1206    /**
1207     * Sets the current row in this <code>CachedRowSet</code> object as the original
1208     * row.
1209     * <P>
1210     * This method is called internally after the any modified values in the current
1211     * row have been synchronized with the data source. The current row must be tagged
1212     * as no longer inserted, deleted or updated.
1213     * <P>
1214     * A call to <code>setOriginalRow</code> is irreversible.
1215     *
1216     * @throws SQLException if there is no current row or an error is
1217     * encountered resetting the contents of the original row
1218     * @see #getOriginalRow
1219     */
1220     public void setOriginalRow() throws SQLException;
1221 
1222    /**
1223     * Returns an identifier for the object (table) that was used to
1224     * create this <code>CachedRowSet</code> object. This name may be set on multiple occasions,
1225     * and the specification imposes no limits on how many times this
1226     * may occur or whether standard implementations should keep track
1227     * of previous table names.
1228     *
1229     * @return a <code>String</code> object giving the name of the table that is the
1230     *         source of data for this <code>CachedRowSet</code> object or <code>null</code>
1231     *         if no name has been set for the table
1232     * @throws SQLException if an error is encountered returning the table name
1233     * @see javax.sql.RowSetMetaData#getTableName
1234     */
1235     public String getTableName() throws SQLException;
1236 
1237    /**
1238     * Sets the identifier for the table from which this <code>CachedRowSet</code>
1239     * object was derived to the given table name. The writer uses this name to
1240     * determine which table to use when comparing the values in the data source with the
1241     * <code>CachedRowSet</code> object's values during a synchronization attempt.
1242     * The table identifier also indicates where modified values from this
1243     * <code>CachedRowSet</code> object should be written.
1244     * <P>
1245     * The implementation of this <code>CachedRowSet</code> object may obtain the
1246     * the name internally from the <code>RowSetMetaDataImpl</code> object.
1247     *
1248     * @param tabName a <code>String</code> object identifying the table from which this
1249              <code>CachedRowSet</code> object was derived; cannot be <code>null</code>
1250     *         but may be an empty string
1251     * @throws SQLException if an error is encountered naming the table or
1252     *     <i>tabName</i> is <code>null</code>
1253     * @see javax.sql.RowSetMetaData#setTableName
1254     * @see javax.sql.RowSetWriter
1255     * @see javax.sql.rowset.spi.SyncProvider
1256     */
1257    public void setTableName(String tabName) throws SQLException;
1258 
1259    /**
1260     * Returns an array containing one or more column numbers indicating the columns
1261     * that form a key that uniquely
1262     * identifies a row in this <code>CachedRowSet</code> object.
1263     *
1264     * @return an array containing the column number or numbers that indicate which columns
1265     *       constitute a primary key
1266     *       for a row in this <code>CachedRowSet</code> object. This array should be
1267     *       empty if no columns are representative of a primary key.
1268     * @throws SQLException if this <code>CachedRowSet</code> object is empty
1269     * @see #setKeyColumns
1270     * @see Joinable#getMatchColumnIndexes
1271     * @see Joinable#getMatchColumnNames
1272     */
1273     public int[] getKeyColumns() throws SQLException;
1274 
1275    /**
1276     * Sets this <code>CachedRowSet</code> object's <code>keyCols</code>
1277     * field with the given array of column numbers, which forms a key
1278     * for uniquely identifying a row in this <code>CachedRowSet</code> object.
1279     * <p>
1280     * If a <code>CachedRowSet</code> object becomes part of a <code>JoinRowSet</code>
1281     * object, the keys defined by this method and the resulting constraints are
1282     * maintained if the columns designated as key columns also become match
1283     * columns.
1284     *
1285     * @param keys an array of <code>int</code> indicating the columns that form
1286     *        a primary key for this <code>CachedRowSet</code> object; every
1287     *        element in the array must be greater than <code>0</code> and
1288     *        less than or equal to the number of columns in this rowset
1289     * @throws SQLException if any of the numbers in the given array
1290     *            are not valid for this rowset
1291     * @see #getKeyColumns
1292     * @see Joinable#setMatchColumn(String)
1293     * @see Joinable#setMatchColumn(int)
1294 
1295     */
1296     public void setKeyColumns(int[] keys) throws SQLException;
1297 
1298 
1299    /**
1300     * Returns a new <code>RowSet</code> object backed by the same data as
1301     * that of this <code>CachedRowSet</code> object. In effect, both
1302     * <code>CachedRowSet</code> objects have a cursor over the same data.
1303     * As a result, any changes made by a duplicate are visible to the original
1304     * and to any other duplicates, just as a change made by the original is visible
1305     * to all of its duplicates. If a duplicate calls a method that changes the
1306     * underlying data, the method it calls notifies all registered listeners
1307     * just as it would when it is called by the original <code>CachedRowSet</code>
1308     * object.
1309     * <P>
1310     * In addition, any <code>RowSet</code> object
1311     * created by this method will have the same properties as this
1312     * <code>CachedRowSet</code> object. For example, if this <code>CachedRowSet</code>
1313     * object is read-only, all of its duplicates will also be read-only. If it is
1314     * changed to be updatable, the duplicates also become updatable.
1315     * <P>
1316     * NOTE: If multiple threads access <code>RowSet</code> objects created from
1317     * the <code>createShared()</code> method, the following behavior is specified
1318     * to preserve shared data integrity: reads and writes of all
1319     * shared <code>RowSet</code> objects should be made serially between each
1320     * object and the single underlying tabular structure.
1321     *
1322     * @return a new shared <code>RowSet</code> object that has the same properties
1323     *         as this <code>CachedRowSet</code> object and that has a cursor over
1324     *         the same data
1325     * @throws SQLException if an error occurs or cloning is not
1326     * supported in the underlying platform
1327     * @see javax.sql.RowSetEvent
1328     * @see javax.sql.RowSetListener
1329     */
1330     public RowSet createShared() throws SQLException;
1331 
1332    /**
1333     * Creates a <code>RowSet</code> object that is a deep copy of the data in
1334     * this <code>CachedRowSet</code> object. In contrast to
1335     * the <code>RowSet</code> object generated from a <code>createShared</code>
1336     * call, updates made to the copy of the original <code>RowSet</code> object
1337     * must not be visible to the original <code>RowSet</code> object. Also, any
1338     * event listeners that are registered with the original
1339     * <code>RowSet</code> must not have scope over the new
1340     * <code>RowSet</code> copies. In addition, any constraint restrictions
1341     * established must be maintained.
1342     *
1343     * @return a new <code>RowSet</code> object that is a deep copy
1344     * of this <code>CachedRowSet</code> object and is
1345     * completely independent of this <code>CachedRowSet</code> object
1346     * @throws SQLException if an error occurs in generating the copy of
1347     * the of this <code>CachedRowSet</code> object
1348     * @see #createShared
1349     * @see #createCopySchema
1350     * @see #createCopyNoConstraints
1351     * @see javax.sql.RowSetEvent
1352     * @see javax.sql.RowSetListener
1353     */
1354     public CachedRowSet createCopy() throws SQLException;
1355 
1356     /**
1357      * Creates a <code>CachedRowSet</code> object that is an empty copy of this
1358      * <code>CachedRowSet</code> object.  The copy
1359      * must not contain any contents but only represent the table
1360      * structure of the original <code>CachedRowSet</code> object. In addition, primary
1361      * or foreign key constraints set in the originating <code>CachedRowSet</code> object must
1362      * be equally enforced in the new empty <code>CachedRowSet</code> object.
1363      * In contrast to
1364      * the <code>RowSet</code> object generated from a <code>createShared</code> method
1365      * call, updates made to a copy of this <code>CachedRowSet</code> object with the
1366      * <code>createCopySchema</code> method must not be visible to it.
1367      * <P>
1368      * Applications can form a <code>WebRowSet</code> object from the <code>CachedRowSet</code>
1369      * object returned by this method in order
1370      * to export the <code>RowSet</code> schema definition to XML for future use.
1371      * @return An empty copy of this {@code CachedRowSet} object
1372      * @throws SQLException if an error occurs in cloning the structure of this
1373      *         <code>CachedRowSet</code> object
1374      * @see #createShared
1375      * @see #createCopySchema
1376      * @see #createCopyNoConstraints
1377      * @see javax.sql.RowSetEvent
1378      * @see javax.sql.RowSetListener
1379      */
1380     public CachedRowSet createCopySchema() throws SQLException;
1381 
1382     /**
1383      * Creates a <code>CachedRowSet</code> object that is a deep copy of
1384      * this <code>CachedRowSet</code> object's data but is independent of it.
1385      * In contrast to
1386      * the <code>RowSet</code> object generated from a <code>createShared</code>
1387      * method call, updates made to a copy of this <code>CachedRowSet</code> object
1388      * must not be visible to it. Also, any
1389      * event listeners that are registered with this
1390      * <code>CachedRowSet</code> object must not have scope over the new
1391      * <code>RowSet</code> object. In addition, any constraint restrictions
1392      * established for this <code>CachedRowSet</code> object must <b>not</b> be maintained
1393      * in the copy.
1394      *
1395      * @return a new <code>CachedRowSet</code> object that is a deep copy
1396      *     of this <code>CachedRowSet</code> object and is
1397      *     completely independent of this  <code>CachedRowSet</code> object
1398      * @throws SQLException if an error occurs in generating the copy of
1399      *     the of this <code>CachedRowSet</code> object
1400      * @see #createCopy
1401      * @see #createShared
1402      * @see #createCopySchema
1403      * @see javax.sql.RowSetEvent
1404      * @see javax.sql.RowSetListener
1405      */
1406     public CachedRowSet createCopyNoConstraints() throws SQLException;
1407 
1408     /**
1409      * Retrieves the first warning reported by calls on this <code>RowSet</code> object.
1410      * Subsequent warnings on this <code>RowSet</code> object will be chained to the
1411      * <code>RowSetWarning</code> object that this method returns.
1412      *
1413      * The warning chain is automatically cleared each time a new row is read.
1414      * This method may not be called on a RowSet object that has been closed;
1415      * doing so will cause a <code>SQLException</code> to be thrown.
1416      *
1417      * @return RowSetWarning the first <code>RowSetWarning</code>
1418      * object reported or null if there are none
1419      * @throws SQLException if this method is called on a closed RowSet
1420      * @see RowSetWarning
1421      */
1422     public RowSetWarning getRowSetWarnings() throws SQLException;
1423 
1424     /**
1425      * Retrieves a <code>boolean</code> indicating whether rows marked
1426      * for deletion appear in the set of current rows. If <code>true</code> is
1427      * returned, deleted rows are visible with the current rows. If
1428      * <code>false</code> is returned, rows are not visible with the set of
1429      * current rows. The default value is <code>false</code>.
1430      * <P>
1431      * Standard rowset implementations may choose to restrict this behavior
1432      * due to security considerations or to better fit certain deployment
1433      * scenarios. This is left as implementation defined and does not
1434      * represent standard behavior.
1435      * <P>
1436      * Note: Allowing deleted rows to remain visible complicates the behavior
1437      * of some standard JDBC <code>RowSet</code> Implementations methods.
1438      * However, most rowset users can simply ignore this extra detail because
1439      * only very specialized applications will likely want to take advantage of
1440      * this feature.
1441      *
1442      * @return <code>true</code> if deleted rows are visible;
1443      *         <code>false</code> otherwise
1444      * @throws SQLException if a rowset implementation is unable to
1445      * to determine whether rows marked for deletion are visible
1446      * @see #setShowDeleted
1447      */
1448     public boolean getShowDeleted() throws SQLException;
1449 
1450     /**
1451      * Sets the property <code>showDeleted</code> to the given
1452      * <code>boolean</code> value, which determines whether
1453      * rows marked for deletion appear in the set of current rows.
1454      * If the value is set to <code>true</code>, deleted rows are immediately
1455      * visible with the set of current rows. If the value is set to
1456      * <code>false</code>, the deleted rows are set as invisible with the
1457      * current set of rows.
1458      * <P>
1459      * Standard rowset implementations may choose to restrict this behavior
1460      * due to security considerations or to better fit certain deployment
1461      * scenarios. This is left as implementations defined and does not
1462      * represent standard behavior.
1463      *
1464      * @param b <code>true</code> if deleted rows should be shown;
1465      *              <code>false</code> otherwise
1466      * @exception SQLException if a rowset implementation is unable to
1467      * to reset whether deleted rows should be visible
1468      * @see #getShowDeleted
1469      */
1470     public void setShowDeleted(boolean b) throws SQLException;
1471 
1472     /**
1473      * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
1474      * a <code>Connection</code> object from the <code>ResultSet</code> or JDBC
1475      * properties passed to it's constructors. This method wraps the
1476      * <code>Connection</code> commit method to allow flexible
1477      * auto commit or non auto commit transactional control support.
1478      * <p>
1479      * Makes all changes that are performed by the <code>acceptChanges()</code>
1480      * method since the previous commit/rollback permanent. This method should
1481      * be used only when auto-commit mode has been disabled.
1482      *
1483      * @throws SQLException if a database access error occurs or this
1484      * Connection object within this <code>CachedRowSet</code> is in auto-commit mode
1485      * @see java.sql.Connection#setAutoCommit
1486      */
1487     public void commit() throws SQLException;
1488 
1489     /**
1490      * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
1491      * a <code>Connection</code> object from the original <code>ResultSet</code>
1492      * or JDBC properties passed to it.
1493      * <p>
1494      * Undoes all changes made in the current transaction.  This method
1495      * should be used only when auto-commit mode has been disabled.
1496      *
1497      * @throws SQLException if a database access error occurs or this Connection
1498      * object within this <code>CachedRowSet</code> is in auto-commit mode.
1499      */
1500     public void rollback() throws SQLException;
1501 
1502     /**
1503      * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains
1504      * a <code>Connection</code> object from the original <code>ResultSet</code>
1505      * or JDBC properties passed to it.
1506      * <p>
1507      * Undoes all changes made in the current transaction back to the last
1508      * <code>Savepoint</code> transaction marker. This method should be used only
1509      * when auto-commit mode has been disabled.
1510      *
1511      * @param s A <code>Savepoint</code> transaction marker
1512      * @throws SQLException if a database access error occurs or this Connection
1513      * object within this <code>CachedRowSet</code> is in auto-commit mode.
1514      */
1515     public void rollback(Savepoint s) throws SQLException;
1516 
1517     /**
1518      * Causes the <code>CachedRowSet</code> object's <code>SyncProvider</code>
1519      * to commit the changes when <code>acceptChanges()</code> is called. If
1520      * set to false, the changes will <b>not</b> be committed until one of the
1521      * <code>CachedRowSet</code> interface transaction methods is called.
1522      *
1523      * @deprecated Because this field is final (it is part of an interface),
1524      *  its value cannot be changed.
1525      * @see #commit
1526      * @see #rollback
1527      */
1528     @Deprecated
1529     public static final boolean COMMIT_ON_ACCEPT_CHANGES = true;
1530 
1531     /**
1532      * Notifies registered listeners that a RowSet object in the given RowSetEvent
1533      * object has populated a number of additional rows. The <code>numRows</code> parameter
1534      * ensures that this event will only be fired every <code>numRow</code>.
1535      * <p>
1536      * The source of the event can be retrieved with the method event.getSource.
1537      *
1538      * @param event a <code>RowSetEvent</code> object that contains the
1539      *     <code>RowSet</code> object that is the source of the events
1540      * @param numRows when populating, the number of rows interval on which the
1541      *     <code>CachedRowSet</code> populated should fire; the default value
1542      *     is zero; cannot be less than <code>fetchSize</code> or zero
1543      * @throws SQLException {@code numRows < 0 or numRows < getFetchSize() }
1544      */
1545     public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException;
1546 
1547     /**
1548      * Populates this <code>CachedRowSet</code> object with data from
1549      * the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code>
1550      * method, an additional parameter is provided to allow starting position within
1551      * the <code>ResultSet</code> from where to populate the CachedRowSet
1552      * instance.
1553      * <P>
1554      * This method can be used as an alternative to the <code>execute</code> method when an
1555      * application has a connection to an open <code>ResultSet</code> object.
1556      * Using the method <code>populate</code> can be more efficient than using
1557      * the version of the <code>execute</code> method that takes no parameters
1558      * because it does not open a new connection and re-execute this
1559      * <code>CachedRowSet</code> object's command. Using the <code>populate</code>
1560      *  method is more a matter of convenience when compared to using the version
1561      * of <code>execute</code> that takes a <code>ResultSet</code> object.
1562      *
1563      * @param startRow the position in the <code>ResultSet</code> from where to start
1564      *                populating the records in this <code>CachedRowSet</code>
1565      * @param rs the <code>ResultSet</code> object containing the data
1566      * to be read into this <code>CachedRowSet</code> object
1567      * @throws SQLException if a null <code>ResultSet</code> object is supplied
1568      * or this <code>CachedRowSet</code> object cannot
1569      * retrieve the associated <code>ResultSetMetaData</code> object
1570      * @see #execute
1571      * @see #populate(ResultSet)
1572      * @see java.sql.ResultSet
1573      * @see java.sql.ResultSetMetaData
1574     */
1575     public void populate(ResultSet rs, int startRow) throws SQLException;
1576 
1577     /**
1578      * Sets the <code>CachedRowSet</code> object's page-size. A <code>CachedRowSet</code>
1579      * may be configured to populate itself in page-size sized batches of rows. When
1580      * either <code>populate()</code> or <code>execute()</code> are called, the
1581      * <code>CachedRowSet</code> fetches an additional page according to the
1582      * original SQL query used to populate the RowSet.
1583      *
1584      * @param size the page-size of the <code>CachedRowSet</code>
1585      * @throws SQLException if an error occurs setting the <code>CachedRowSet</code>
1586      *      page size or if the page size is less than 0.
1587      */
1588     public void setPageSize(int size) throws SQLException;
1589 
1590     /**
1591      * Returns the page-size for the <code>CachedRowSet</code> object
1592      *
1593      * @return an <code>int</code> page size
1594      */
1595     public int getPageSize();
1596 
1597     /**
1598      * Increments the current page of the <code>CachedRowSet</code>. This causes
1599      * the <code>CachedRowSet</code> implementation to fetch the next page-size
1600      * rows and populate the RowSet, if remaining rows remain within scope of the
1601      * original SQL query used to populated the RowSet.
1602      *
1603      * @return true if more pages exist; false if this is the last page
1604      * @throws SQLException if an error occurs fetching the next page, or if this
1605      *     method is called prematurely before populate or execute.
1606      */
1607     public boolean nextPage() throws SQLException;
1608 
1609     /**
1610      * Decrements the current page of the <code>CachedRowSet</code>. This causes
1611      * the <code>CachedRowSet</code> implementation to fetch the previous page-size
1612      * rows and populate the RowSet. The amount of rows returned in the previous
1613      * page must always remain within scope of the original SQL query used to
1614      * populate the RowSet.
1615      *
1616      * @return true if the previous page is successfully retrieved; false if this
1617      *     is the first page.
1618      * @throws SQLException if an error occurs fetching the previous page, or if
1619      *     this method is called prematurely before populate or execute.
1620      */
1621     public boolean previousPage() throws SQLException;
1622 
1623 }
--- EOF ---