1 /* 2 * Copyright (c) 2003, 2019, 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 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 * <h2>1.0 Creating a <code>CachedRowSet</code> Object</h2> 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 * <h2>2.0 Retrieving Data from a <code>CachedRowSet</code> Object</h2> 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 * <h3>2.1 Retrieving <code>RowSetMetaData</code></h3> 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 * <h2>3.0 Updating a <code>CachedRowSet</code> Object</h2> 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 * <h2>4.0 Updating the Underlying Data Source</h2> 265 * When the method <code>acceptChanges</code> is executed, the 266 * <code>CachedRowSet</code> object's writer, a <code>RowSetWriterImpl</code> 267 * object, is called behind the scenes to write the changes made to the 268 * rowset to the underlying data source. The writer is implemented to make a 269 * connection to the data source and write updates to it. 270 * <P> 271 * A writer is made available through an implementation of the 272 * <code>SyncProvider</code> interface, as discussed in section 1, 273 * "Creating a <code>CachedRowSet</code> Object." 274 * The default reference implementation provider, <code>RIOptimisticProvider</code>, 275 * has its writer implemented to use an optimistic concurrency control 276 * mechanism. That is, it maintains no locks in the underlying database while 277 * the rowset is disconnected from the database and simply checks to see if there 278 * are any conflicts before writing data to the data source. If there are any 279 * conflicts, it does not write anything to the data source. 280 * <P> 281 * The reader/writer facility 282 * provided by the <code>SyncProvider</code> class is pluggable, allowing for the 283 * customization of data retrieval and updating. If a different concurrency 284 * control mechanism is desired, a different implementation of 285 * <code>SyncProvider</code> can be plugged in using the method 286 * <code>setSyncProvider</code>. 287 * <P> 288 * In order to use the optimistic concurrency control routine, the 289 * <code>RIOptimisticProvider</code> maintains both its current 290 * value and its original value (the value it had immediately preceding the 291 * current value). Note that if no changes have been made to the data in a 292 * <code>RowSet</code> object, its current values and its original values are the same, 293 * both being the values with which the <code>RowSet</code> object was initially 294 * populated. However, once any values in the <code>RowSet</code> object have been 295 * changed, the current values and the original values will be different, though at 296 * this stage, the original values are still the initial values. With any subsequent 297 * changes to data in a <code>RowSet</code> object, its original values and current 298 * values will still differ, but its original values will be the values that 299 * were previously the current values. 300 * <P> 301 * Keeping track of original values allows the writer to compare the <code>RowSet</code> 302 * object's original value with the value in the database. If the values in 303 * the database differ from the <code>RowSet</code> object's original values, which means that 304 * the values in the database have been changed, there is a conflict. 305 * Whether a writer checks for conflicts, what degree of checking it does, and how 306 * it handles conflicts all depend on how it is implemented. 307 * 308 * <h2>5.0 Registering and Notifying Listeners</h2> 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 * <h2>6.0 Passing Data to Thin Clients</h2> 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 * <h2>7.0 Scrolling and Updating</h2> 348 * A second major use for <code>CachedRowSet</code> objects is to provide 349 * scrolling and updating for <code>ResultSet</code> objects that 350 * do not provide these capabilities themselves. In other words, a 351 * <code>CachedRowSet</code> object can be used to augment the 352 * capabilities of a JDBC technology-enabled driver (hereafter called a 353 * "JDBC driver") when the DBMS does not provide full support for scrolling and 354 * updating. To achieve the effect of making a non-scrollable and read-only 355 * <code>ResultSet</code> object scrollable and updatable, a programmer 356 * simply needs to create a <code>CachedRowSet</code> object populated 357 * with that <code>ResultSet</code> object's data. This is demonstrated 358 * in the following code fragment, where <code>stmt</code> is a 359 * <code>Statement</code> object. 360 * <PRE> 361 * ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEES"); 362 * CachedRowSetImpl crs = new CachedRowSetImpl(); 363 * crs.populate(rs); 364 * </PRE> 365 * <P> 366 * The object <code>crs</code> now contains the data from the table 367 * <code>EMPLOYEES</code>, just as the object <code>rs</code> does. 368 * The difference is that the cursor for <code>crs</code> can be moved 369 * forward, backward, or to a particular row even if the cursor for 370 * <code>rs</code> can move only forward. In addition, <code>crs</code> is 371 * updatable even if <code>rs</code> is not because by default, a 372 * <code>CachedRowSet</code> object is both scrollable and updatable. 373 * <P> 374 * In summary, a <code>CachedRowSet</code> object can be thought of as simply 375 * a disconnected set of rows that are being cached outside of a data source. 376 * Being thin and serializable, it can easily be sent across a wire, 377 * and it is well suited to sending data to a thin client. However, a 378 * <code>CachedRowSet</code> object does have a limitation: It is limited in 379 * size by the amount of data it can store in memory at one time. 380 * 381 * <h2>8.0 Getting Universal Data Access</h2> 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 * <h2>9.0 Setting Properties</h2> 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 (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 * <h2>10.0 Paging Data</h2> 496 * Because a <code>CachedRowSet</code> object stores data in memory, 497 * the amount of data that it can contain at any one 498 * time is determined by the amount of memory available. To get around this limitation, 499 * a <code>CachedRowSet</code> object can retrieve data from a <code>ResultSet</code> 500 * object in chunks of data, called <i>pages</i>. To take advantage of this mechanism, 501 * an application sets the number of rows to be included in a page using the method 502 * <code>setPageSize</code>. In other words, if the page size is set to five, a chunk 503 * of five rows of 504 * data will be fetched from the data source at one time. An application can also 505 * optionally set the maximum number of rows that may be fetched at one time. If the 506 * maximum number of rows is set to zero, or no maximum number of rows is set, there is 507 * no limit to the number of rows that may be fetched at a time. 508 * <P> 509 * After properties have been set, 510 * the <code>CachedRowSet</code> object must be populated with data 511 * using either the method <code>populate</code> or the method <code>execute</code>. 512 * The following lines of code demonstrate using the method <code>populate</code>. 513 * Note that this version of the method takes two parameters, a <code>ResultSet</code> 514 * handle and the row in the <code>ResultSet</code> object from which to start 515 * retrieving rows. 516 * <PRE> 517 * CachedRowSet crs = new CachedRowSetImpl(); 518 * crs.setMaxRows(20); 519 * crs.setPageSize(4); 520 * crs.populate(rsHandle, 10); 521 * </PRE> 522 * When this code runs, <i>crs</i> will be populated with four rows from 523 * <i>rsHandle</i> starting with the tenth row. 524 * <P> 525 * The next code fragment shows populating a <code>CachedRowSet</code> object using the 526 * method <code>execute</code>, which may or may not take a <code>Connection</code> 527 * object as a parameter. This code passes <code>execute</code> the <code>Connection</code> 528 * object <i>conHandle</i>. 529 * <P> 530 * Note that there are two differences between the following code 531 * fragment and the previous one. First, the method <code>setMaxRows</code> is not 532 * called, so there is no limit set for the number of rows that <i>crs</i> may contain. 533 * (Remember that <i>crs</i> always has the overriding limit of how much data it can 534 * store in memory.) The second difference is that the you cannot pass the method 535 * <code>execute</code> the number of the row in the <code>ResultSet</code> object 536 * from which to start retrieving rows. This method always starts with the first row. 537 * <PRE> 538 * CachedRowSet crs = new CachedRowSetImpl(); 539 * crs.setPageSize(5); 540 * crs.execute(conHandle); 541 * </PRE> 542 * After this code has run, <i>crs</i> will contain five rows of data from the 543 * <code>ResultSet</code> object produced by the command for <i>crs</i>. The writer 544 * for <i>crs</i> will use <i>conHandle</i> to connect to the data source and 545 * execute the command for <i>crs</i>. An application is then able to operate on the 546 * data in <i>crs</i> in the same way that it would operate on data in any other 547 * <code>CachedRowSet</code> object. 548 * <P> 549 * To access the next page (chunk of data), an application calls the method 550 * <code>nextPage</code>. This method creates a new <code>CachedRowSet</code> object 551 * and fills it with the next page of data. For example, assume that the 552 * <code>CachedRowSet</code> object's command returns a <code>ResultSet</code> object 553 * <i>rs</i> with 1000 rows of data. If the page size has been set to 100, the first 554 * call to the method <code>nextPage</code> will create a <code>CachedRowSet</code> object 555 * containing the first 100 rows of <i>rs</i>. After doing what it needs to do with the 556 * data in these first 100 rows, the application can again call the method 557 * <code>nextPage</code> to create another <code>CachedRowSet</code> object 558 * with the second 100 rows from <i>rs</i>. The data from the first <code>CachedRowSet</code> 559 * object will no longer be in memory because it is replaced with the data from the 560 * second <code>CachedRowSet</code> object. After the tenth call to the method <code>nextPage</code>, 561 * the tenth <code>CachedRowSet</code> object will contain the last 100 rows of data from 562 * <i>rs</i>, which are stored in memory. At any given time, the data from only one 563 * <code>CachedRowSet</code> object is stored in memory. 564 * <P> 565 * The method <code>nextPage</code> returns <code>true</code> as long as the current 566 * page is not the last page of rows and <code>false</code> when there are no more pages. 567 * It can therefore be used in a <code>while</code> loop to retrieve all of the pages, 568 * as is demonstrated in the following lines of code. 569 * <PRE> 570 * CachedRowSet crs = CachedRowSetImpl(); 571 * crs.setPageSize(100); 572 * crs.execute(conHandle); 573 * 574 * while(crs.nextPage()) { 575 * while(crs.next()) { 576 * . . . // operate on chunks (of 100 rows each) in crs, 577 * // row by row 578 * } 579 * } 580 * </PRE> 581 * After this code fragment has been run, the application will have traversed all 582 * 1000 rows, but it will have had no more than 100 rows in memory at a time. 583 * <P> 584 * The <code>CachedRowSet</code> interface also defines the method <code>previousPage</code>. 585 * Just as the method <code>nextPage</code> is analogous to the <code>ResultSet</code> 586 * method <code>next</code>, the method <code>previousPage</code> is analogous to 587 * the <code>ResultSet</code> method <code>previous</code>. Similar to the method 588 * <code>nextPage</code>, <code>previousPage</code> creates a <code>CachedRowSet</code> 589 * object containing the number of rows set as the page size. So, for instance, the 590 * method <code>previousPage</code> could be used in a <code>while</code> loop at 591 * the end of the preceding code fragment to navigate back through the pages from the last 592 * page to the first page. 593 * The method <code>previousPage</code> is also similar to <code>nextPage</code> 594 * in that it can be used in a <code>while</code> 595 * loop, except that it returns <code>true</code> as long as there is another page 596 * preceding it and <code>false</code> when there are no more pages ahead of it. 597 * <P> 598 * By positioning the cursor after the last row for each page, 599 * as is done in the following code fragment, the method <code>previous</code> 600 * navigates from the last row to the first row in each page. 601 * The code could also have left the cursor before the first row on each page and then 602 * used the method <code>next</code> in a <code>while</code> loop to navigate each page 603 * from the first row to the last row. 604 * <P> 605 * The following code fragment assumes a continuation from the previous code fragment, 606 * meaning that the cursor for the tenth <code>CachedRowSet</code> object is on the 607 * last row. The code moves the cursor to after the last row so that the first 608 * call to the method <code>previous</code> will put the cursor back on the last row. 609 * After going through all of the rows in the last page (the <code>CachedRowSet</code> 610 * object <i>crs</i>), the code then enters 611 * the <code>while</code> loop to get to the ninth page, go through the rows backwards, 612 * go to the eighth page, go through the rows backwards, and so on to the first row 613 * of the first page. 614 * 615 * <PRE> 616 * crs.afterLast(); 617 * while(crs.previous()) { 618 * . . . // navigate through the rows, last to first 619 * { 620 * while(crs.previousPage()) { 621 * crs.afterLast(); 622 * while(crs.previous()) { 623 * . . . // go from the last row to the first row of each page 624 * } 625 * } 626 * </PRE> 627 * 628 * @author Jonathan Bruce 629 * @since 1.5 630 */ 631 632 public interface CachedRowSet extends RowSet, Joinable { 633 634 /** 635 * Populates this <code>CachedRowSet</code> object with data from 636 * the given <code>ResultSet</code> object. 637 * <P> 638 * This method can be used as an alternative to the <code>execute</code> method when an 639 * application has a connection to an open <code>ResultSet</code> object. 640 * Using the method <code>populate</code> can be more efficient than using 641 * the version of the <code>execute</code> method that takes no parameters 642 * because it does not open a new connection and re-execute this 643 * <code>CachedRowSet</code> object's command. Using the <code>populate</code> 644 * method is more a matter of convenience when compared to using the version 645 * of <code>execute</code> that takes a <code>ResultSet</code> object. 646 * 647 * @param data the <code>ResultSet</code> object containing the data 648 * to be read into this <code>CachedRowSet</code> object 649 * @throws SQLException if a null <code>ResultSet</code> object is supplied 650 * or this <code>CachedRowSet</code> object cannot 651 * retrieve the associated <code>ResultSetMetaData</code> object 652 * @see #execute 653 * @see java.sql.ResultSet 654 * @see java.sql.ResultSetMetaData 655 */ 656 public void populate(ResultSet data) throws SQLException; 657 658 /** 659 * Populates this <code>CachedRowSet</code> object with data, using the 660 * given connection to produce the result set from which the data will be read. 661 * This method should close any database connections that it creates to 662 * ensure that this <code>CachedRowSet</code> object is disconnected except when 663 * it is reading data from its data source or writing data to its data source. 664 * <P> 665 * The reader for this <code>CachedRowSet</code> object 666 * will use <i>conn</i> to establish a connection to the data source 667 * so that it can execute the rowset's command and read data from the 668 * the resulting <code>ResultSet</code> object into this 669 * <code>CachedRowSet</code> object. This method also closes <i>conn</i> 670 * after it has populated this <code>CachedRowSet</code> object. 671 * <P> 672 * If this method is called when an implementation has already been 673 * populated, the contents and the metadata are (re)set. Also, if this method is 674 * called before the method <code>acceptChanges</code> has been called 675 * to commit outstanding updates, those updates are lost. 676 * 677 * @param conn a standard JDBC <code>Connection</code> object with valid 678 * properties 679 * @throws SQLException if an invalid <code>Connection</code> object is supplied 680 * or an error occurs in establishing the connection to the 681 * data source 682 * @see #populate 683 * @see java.sql.Connection 684 */ 685 public void execute(Connection conn) throws SQLException; 686 687 /** 688 * Propagates row update, insert and delete changes made to this 689 * <code>CachedRowSet</code> object to the underlying data source. 690 * <P> 691 * This method calls on this <code>CachedRowSet</code> object's writer 692 * to do the work behind the scenes. 693 * Standard <code>CachedRowSet</code> implementations should use the 694 * <code>SyncFactory</code> singleton 695 * to obtain a <code>SyncProvider</code> instance providing a 696 * <code>RowSetWriter</code> object (writer). The writer will attempt 697 * to propagate changes made in this <code>CachedRowSet</code> object 698 * back to the data source. 699 * <P> 700 * When the method <code>acceptChanges</code> executes successfully, in 701 * addition to writing changes to the data source, it 702 * makes the values in the current row be the values in the original row. 703 * <P> 704 * Depending on the synchronization level of the <code>SyncProvider</code> 705 * implementation being used, the writer will compare the original values 706 * with those in the data source to check for conflicts. When there is a conflict, 707 * the <code>RIOptimisticProvider</code> implementation, for example, throws a 708 * <code>SyncProviderException</code> and does not write anything to the 709 * data source. 710 * <P> 711 * An application may choose to catch the <code>SyncProviderException</code> 712 * object and retrieve the <code>SyncResolver</code> object it contains. 713 * The <code>SyncResolver</code> object lists the conflicts row by row and 714 * sets a lock on the data source to avoid further conflicts while the 715 * current conflicts are being resolved. 716 * Further, for each conflict, it provides methods for examining the conflict 717 * and setting the value that should be persisted in the data source. 718 * After all conflicts have been resolved, an application must call the 719 * <code>acceptChanges</code> method again to write resolved values to the 720 * data source. If all of the values in the data source are already the 721 * values to be persisted, the method <code>acceptChanges</code> does nothing. 722 * <P> 723 * Some provider implementations may use locks to ensure that there are no 724 * conflicts. In such cases, it is guaranteed that the writer will succeed in 725 * writing changes to the data source when the method <code>acceptChanges</code> 726 * is called. This method may be called immediately after the methods 727 * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code> 728 * have been called, but it is more efficient to call it only once after 729 * all changes have been made so that only one connection needs to be 730 * established. 731 * <P> 732 * Note: The <code>acceptChanges()</code> method will determine if the 733 * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set 734 * to true, all updates in the synchronization are committed to the data 735 * source. Otherwise, the application <b>must</b> explicitly call the 736 * <code>commit()</code> or <code>rollback()</code> methods as appropriate. 737 * 738 * @throws SyncProviderException if the underlying 739 * synchronization provider's writer fails to write the updates 740 * back to the data source 741 * @see #acceptChanges(java.sql.Connection) 742 * @see javax.sql.RowSetWriter 743 * @see javax.sql.rowset.spi.SyncFactory 744 * @see javax.sql.rowset.spi.SyncProvider 745 * @see javax.sql.rowset.spi.SyncProviderException 746 * @see javax.sql.rowset.spi.SyncResolver 747 */ 748 public void acceptChanges() throws SyncProviderException; 749 750 /** 751 * Propagates all row update, insert and delete changes to the 752 * data source backing this <code>CachedRowSet</code> object 753 * using the specified <code>Connection</code> object to establish a 754 * connection to the data source. 755 * <P> 756 * The other version of the <code>acceptChanges</code> method is not passed 757 * a connection because it uses 758 * the <code>Connection</code> object already defined within the <code>RowSet</code> 759 * object, which is the connection used for populating it initially. 760 * <P> 761 * This form of the method <code>acceptChanges</code> is similar to the 762 * form that takes no arguments; however, unlike the other form, this form 763 * can be used only when the underlying data source is a JDBC data source. 764 * The updated <code>Connection</code> properties must be used by the 765 * <code>SyncProvider</code> to reset the <code>RowSetWriter</code> 766 * configuration to ensure that the contents of the <code>CachedRowSet</code> 767 * object are synchronized correctly. 768 * <P> 769 * When the method <code>acceptChanges</code> executes successfully, in 770 * addition to writing changes to the data source, it 771 * makes the values in the current row be the values in the original row. 772 * <P> 773 * Depending on the synchronization level of the <code>SyncProvider</code> 774 * implementation being used, the writer will compare the original values 775 * with those in the data source to check for conflicts. When there is a conflict, 776 * the <code>RIOptimisticProvider</code> implementation, for example, throws a 777 * <code>SyncProviderException</code> and does not write anything to the 778 * data source. 779 * <P> 780 * An application may choose to catch the <code>SyncProviderException</code> 781 * object and retrieve the <code>SyncResolver</code> object it contains. 782 * The <code>SyncResolver</code> object lists the conflicts row by row and 783 * sets a lock on the data source to avoid further conflicts while the 784 * current conflicts are being resolved. 785 * Further, for each conflict, it provides methods for examining the conflict 786 * and setting the value that should be persisted in the data source. 787 * After all conflicts have been resolved, an application must call the 788 * <code>acceptChanges</code> method again to write resolved values to the 789 * data source. If all of the values in the data source are already the 790 * values to be persisted, the method <code>acceptChanges</code> does nothing. 791 * <P> 792 * Some provider implementations may use locks to ensure that there are no 793 * conflicts. In such cases, it is guaranteed that the writer will succeed in 794 * writing changes to the data source when the method <code>acceptChanges</code> 795 * is called. This method may be called immediately after the methods 796 * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code> 797 * have been called, but it is more efficient to call it only once after 798 * all changes have been made so that only one connection needs to be 799 * established. 800 * <P> 801 * Note: The <code>acceptChanges()</code> method will determine if the 802 * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set 803 * to true, all updates in the synchronization are committed to the data 804 * source. Otherwise, the application <b>must</b> explicitly call the 805 * <code>commit</code> or <code>rollback</code> methods as appropriate. 806 * 807 * @param con a standard JDBC <code>Connection</code> object 808 * @throws SyncProviderException if the underlying 809 * synchronization provider's writer fails to write the updates 810 * back to the data source 811 * @see #acceptChanges() 812 * @see javax.sql.RowSetWriter 813 * @see javax.sql.rowset.spi.SyncFactory 814 * @see javax.sql.rowset.spi.SyncProvider 815 * @see javax.sql.rowset.spi.SyncProviderException 816 * @see javax.sql.rowset.spi.SyncResolver 817 */ 818 public void acceptChanges(Connection con) throws SyncProviderException; 819 820 /** 821 * Restores this <code>CachedRowSet</code> object to its original 822 * value, that is, its value before the last set of changes. If there 823 * have been no changes to the rowset or only one set of changes, 824 * the original value is the value with which this <code>CachedRowSet</code> object 825 * was populated; otherwise, the original value is 826 * the value it had immediately before its current value. 827 * <P> 828 * When this method is called, a <code>CachedRowSet</code> implementation 829 * must ensure that all updates, inserts, and deletes to the current 830 * rowset instance are replaced by the previous values. In addition, 831 * the cursor should be 832 * reset to the first row and a <code>rowSetChanged</code> event 833 * should be fired to notify all registered listeners. 834 * 835 * @throws SQLException if an error occurs rolling back the current value of 836 * this <code>CachedRowSet</code> object to its previous value 837 * @see javax.sql.RowSetListener#rowSetChanged 838 */ 839 public void restoreOriginal() throws SQLException; 840 841 /** 842 * Releases the current contents of this <code>CachedRowSet</code> 843 * object and sends a <code>rowSetChanged</code> event to all 844 * registered listeners. Any outstanding updates are discarded and 845 * the rowset contains no rows after this method is called. There 846 * are no interactions with the underlying data source, and any rowset 847 * content, metadata, and content updates should be non-recoverable. 848 * <P> 849 * This <code>CachedRowSet</code> object should lock until its contents and 850 * associated updates are fully cleared, thus preventing 'dirty' reads by 851 * other components that hold a reference to this <code>RowSet</code> object. 852 * In addition, the contents cannot be released 853 * until all components reading this <code>CachedRowSet</code> object 854 * have completed their reads. This <code>CachedRowSet</code> object 855 * should be returned to normal behavior after firing the 856 * <code>rowSetChanged</code> event. 857 * <P> 858 * The metadata, including JDBC properties and Synchronization SPI 859 * properties, are maintained for future use. It is important that 860 * properties such as the <code>command</code> property be 861 * relevant to the originating data source from which this <code>CachedRowSet</code> 862 * object was originally established. 863 * <P> 864 * This method empties a rowset, as opposed to the <code>close</code> method, 865 * which marks the entire rowset as recoverable to allow the garbage collector 866 * the rowset's Java VM resources. 867 * 868 * @throws SQLException if an error occurs flushing the contents of this 869 * <code>CachedRowSet</code> object 870 * @see javax.sql.RowSetListener#rowSetChanged 871 * @see java.sql.ResultSet#close 872 */ 873 public void release() throws SQLException; 874 875 /** 876 * Cancels the deletion of the current row and notifies listeners that 877 * a row has changed. After this method is called, the current row is 878 * no longer marked for deletion. This method can be called at any 879 * time during the lifetime of the rowset. 880 * <P> 881 * In addition, multiple cancellations of row deletions can be made 882 * by adjusting the position of the cursor using any of the cursor 883 * position control methods such as: 884 * <ul> 885 * <li><code>CachedRowSet.absolute</code> 886 * <li><code>CachedRowSet.first</code> 887 * <li><code>CachedRowSet.last</code> 888 * </ul> 889 * 890 * @throws SQLException if (1) the current row has not been deleted or 891 * (2) the cursor is on the insert row, before the first row, or 892 * after the last row 893 * @see javax.sql.rowset.CachedRowSet#undoInsert 894 * @see java.sql.ResultSet#cancelRowUpdates 895 */ 896 public void undoDelete() throws SQLException; 897 898 /** 899 * Immediately removes the current row from this <code>CachedRowSet</code> 900 * object if the row has been inserted, and also notifies listeners that a 901 * row has changed. This method can be called at any time during the 902 * lifetime of a rowset and assuming the current row is within 903 * the exception limitations (see below), it cancels the row insertion 904 * of the current row. 905 * <P> 906 * In addition, multiple cancellations of row insertions can be made 907 * by adjusting the position of the cursor using any of the cursor 908 * position control methods such as: 909 * <ul> 910 * <li><code>CachedRowSet.absolute</code> 911 * <li><code>CachedRowSet.first</code> 912 * <li><code>CachedRowSet.last</code> 913 * </ul> 914 * 915 * @throws SQLException if (1) the current row has not been inserted or (2) 916 * the cursor is before the first row, after the last row, or on the 917 * insert row 918 * @see javax.sql.rowset.CachedRowSet#undoDelete 919 * @see java.sql.ResultSet#cancelRowUpdates 920 */ 921 public void undoInsert() throws SQLException; 922 923 924 /** 925 * Immediately reverses the last update operation if the 926 * row has been modified. This method can be 927 * called to reverse updates on all columns until all updates in a row have 928 * been rolled back to their state just prior to the last synchronization 929 * (<code>acceptChanges</code>) or population. This method may also be called 930 * while performing updates to the insert row. 931 * <P> 932 * <code>undoUpdate</code> may be called at any time during the lifetime of a 933 * rowset; however, after a synchronization has occurred, this method has no 934 * effect until further modification to the rowset data has occurred. 935 * 936 * @throws SQLException if the cursor is before the first row or after the last 937 * row in this <code>CachedRowSet</code> object 938 * @see #undoDelete 939 * @see #undoInsert 940 * @see java.sql.ResultSet#cancelRowUpdates 941 */ 942 public void undoUpdate() throws SQLException; 943 944 /** 945 * Indicates whether the designated column in the current row of this 946 * <code>CachedRowSet</code> object has been updated. 947 * 948 * @param idx an <code>int</code> identifying the column to be checked for updates 949 * @return <code>true</code> if the designated column has been visibly updated; 950 * <code>false</code> otherwise 951 * @throws SQLException if the cursor is on the insert row, before the first row, 952 * or after the last row 953 * @see java.sql.DatabaseMetaData#updatesAreDetected 954 */ 955 public boolean columnUpdated(int idx) throws SQLException; 956 957 958 /** 959 * Indicates whether the designated column in the current row of this 960 * <code>CachedRowSet</code> object has been updated. 961 * 962 * @param columnName a <code>String</code> object giving the name of the 963 * column to be checked for updates 964 * @return <code>true</code> if the column has been visibly updated; 965 * <code>false</code> otherwise 966 * @throws SQLException if the cursor is on the insert row, before the first row, 967 * or after the last row 968 * @see java.sql.DatabaseMetaData#updatesAreDetected 969 */ 970 public boolean columnUpdated(String columnName) throws SQLException; 971 972 /** 973 * Converts this <code>CachedRowSet</code> object to a <code>Collection</code> 974 * object that contains all of this <code>CachedRowSet</code> object's data. 975 * Implementations have some latitude in 976 * how they can represent this <code>Collection</code> object because of the 977 * abstract nature of the <code>Collection</code> framework. 978 * Each row must be fully represented in either a 979 * general purpose <code>Collection</code> implementation or a specialized 980 * <code>Collection</code> implementation, such as a <code>TreeMap</code> 981 * object or a <code>Vector</code> object. 982 * An SQL <code>NULL</code> column value must be represented as a <code>null</code> 983 * in the Java programming language. 984 * <P> 985 * The standard reference implementation for the <code>CachedRowSet</code> 986 * interface uses a <code>TreeMap</code> object for the rowset, with the 987 * values in each row being contained in <code>Vector</code> objects. It is 988 * expected that most implementations will do the same. 989 * <P> 990 * The <code>TreeMap</code> type of collection guarantees that the map will be in 991 * ascending key order, sorted according to the natural order for the 992 * key's class. 993 * Each key references a <code>Vector</code> object that corresponds to one 994 * row of a <code>RowSet</code> object. Therefore, the size of each 995 * <code>Vector</code> object must be exactly equal to the number of 996 * columns in the <code>RowSet</code> object. 997 * The key used by the <code>TreeMap</code> collection is determined by the 998 * implementation, which may choose to leverage a set key that is 999 * available within the internal <code>RowSet</code> tabular structure by 1000 * virtue of a key already set either on the <code>RowSet</code> object 1001 * itself or on the underlying SQL data. 1002 * 1003 * @return a <code>Collection</code> object that contains the values in 1004 * each row in this <code>CachedRowSet</code> object 1005 * @throws SQLException if an error occurs generating the collection 1006 * @see #toCollection(int) 1007 * @see #toCollection(String) 1008 */ 1009 public Collection<?> toCollection() throws SQLException; 1010 1011 /** 1012 * Converts the designated column in this <code>CachedRowSet</code> object 1013 * to a <code>Collection</code> object. Implementations have some latitude in 1014 * how they can represent this <code>Collection</code> object because of the 1015 * abstract nature of the <code>Collection</code> framework. 1016 * Each column value should be fully represented in either a 1017 * general purpose <code>Collection</code> implementation or a specialized 1018 * <code>Collection</code> implementation, such as a <code>Vector</code> object. 1019 * An SQL <code>NULL</code> column value must be represented as a <code>null</code> 1020 * in the Java programming language. 1021 * <P> 1022 * The standard reference implementation uses a <code>Vector</code> object 1023 * to contain the column values, and it is expected 1024 * that most implementations will do the same. If a <code>Vector</code> object 1025 * is used, it size must be exactly equal to the number of rows 1026 * in this <code>CachedRowSet</code> object. 1027 * 1028 * @param column an <code>int</code> indicating the column whose values 1029 * are to be represented in a <code>Collection</code> object 1030 * @return a <code>Collection</code> object that contains the values 1031 * stored in the specified column of this <code>CachedRowSet</code> 1032 * object 1033 * @throws SQLException if an error occurs generating the collection or 1034 * an invalid column id is provided 1035 * @see #toCollection 1036 * @see #toCollection(String) 1037 */ 1038 public Collection<?> toCollection(int column) throws SQLException; 1039 1040 /** 1041 * Converts the designated column in this <code>CachedRowSet</code> object 1042 * to a <code>Collection</code> object. Implementations have some latitude in 1043 * how they can represent this <code>Collection</code> object because of the 1044 * abstract nature of the <code>Collection</code> framework. 1045 * Each column value should be fully represented in either a 1046 * general purpose <code>Collection</code> implementation or a specialized 1047 * <code>Collection</code> implementation, such as a <code>Vector</code> object. 1048 * An SQL <code>NULL</code> column value must be represented as a <code>null</code> 1049 * in the Java programming language. 1050 * <P> 1051 * The standard reference implementation uses a <code>Vector</code> object 1052 * to contain the column values, and it is expected 1053 * that most implementations will do the same. If a <code>Vector</code> object 1054 * is used, it size must be exactly equal to the number of rows 1055 * in this <code>CachedRowSet</code> object. 1056 * 1057 * @param column a <code>String</code> object giving the name of the 1058 * column whose values are to be represented in a collection 1059 * @return a <code>Collection</code> object that contains the values 1060 * stored in the specified column of this <code>CachedRowSet</code> 1061 * object 1062 * @throws SQLException if an error occurs generating the collection or 1063 * an invalid column id is provided 1064 * @see #toCollection 1065 * @see #toCollection(int) 1066 */ 1067 public Collection<?> toCollection(String column) throws SQLException; 1068 1069 /** 1070 * Retrieves the <code>SyncProvider</code> implementation for this 1071 * <code>CachedRowSet</code> object. Internally, this method is used by a rowset 1072 * to trigger read or write actions between the rowset 1073 * and the data source. For example, a rowset may need to get a handle 1074 * on the rowset reader (<code>RowSetReader</code> object) from the 1075 * <code>SyncProvider</code> to allow the rowset to be populated. 1076 * <pre> 1077 * RowSetReader rowsetReader = null; 1078 * SyncProvider provider = 1079 * SyncFactory.getInstance("javax.sql.rowset.provider.RIOptimisticProvider"); 1080 * if (provider instanceof RIOptimisticProvider) { 1081 * rowsetReader = provider.getRowSetReader(); 1082 * } 1083 * </pre> 1084 * Assuming <i>rowsetReader</i> is a private, accessible field within 1085 * the rowset implementation, when an application calls the <code>execute</code> 1086 * method, it in turn calls on the reader's <code>readData</code> method 1087 * to populate the <code>RowSet</code> object. 1088 *<pre> 1089 * rowsetReader.readData((RowSetInternal)this); 1090 * </pre> 1091 * <P> 1092 * In addition, an application can use the <code>SyncProvider</code> object 1093 * returned by this method to call methods that return information about the 1094 * <code>SyncProvider</code> object, including information about the 1095 * vendor, version, provider identification, synchronization grade, and locks 1096 * it currently has set. 1097 * 1098 * @return the <code>SyncProvider</code> object that was set when the rowset 1099 * was instantiated, or if none was set, the default provider 1100 * @throws SQLException if an error occurs while returning the 1101 * <code>SyncProvider</code> object 1102 * @see #setSyncProvider 1103 */ 1104 public SyncProvider getSyncProvider() throws SQLException; 1105 1106 /** 1107 * Sets the <code>SyncProvider</code> object for this <code>CachedRowSet</code> 1108 * object to the one specified. This method 1109 * allows the <code>SyncProvider</code> object to be reset. 1110 * <P> 1111 * A <code>CachedRowSet</code> implementation should always be instantiated 1112 * with an available <code>SyncProvider</code> mechanism, but there are 1113 * cases where resetting the <code>SyncProvider</code> object is desirable 1114 * or necessary. For example, an application might want to use the default 1115 * <code>SyncProvider</code> object for a time and then choose to use a provider 1116 * that has more recently become available and better fits its needs. 1117 * <P> 1118 * Resetting the <code>SyncProvider</code> object causes the 1119 * <code>RowSet</code> object to request a new <code>SyncProvider</code> implementation 1120 * from the <code>SyncFactory</code>. This has the effect of resetting 1121 * all previous connections and relationships with the originating 1122 * data source and can potentially drastically change the synchronization 1123 * behavior of a disconnected rowset. 1124 * 1125 * @param provider a <code>String</code> object giving the fully qualified class 1126 * name of a <code>SyncProvider</code> implementation 1127 * @throws SQLException if an error occurs while attempting to reset the 1128 * <code>SyncProvider</code> implementation 1129 * @see #getSyncProvider 1130 */ 1131 public void setSyncProvider(String provider) throws SQLException; 1132 1133 /** 1134 * Returns the number of rows in this <code>CachedRowSet</code> 1135 * object. 1136 * 1137 * @return number of rows in the rowset 1138 */ 1139 public int size(); 1140 1141 /** 1142 * Sets the metadata for this <code>CachedRowSet</code> object with 1143 * the given <code>RowSetMetaData</code> object. When a 1144 * <code>RowSetReader</code> object is reading the contents of a rowset, 1145 * it creates a <code>RowSetMetaData</code> object and initializes 1146 * it using the methods in the <code>RowSetMetaData</code> implementation. 1147 * The reference implementation uses the <code>RowSetMetaDataImpl</code> 1148 * class. When the reader has completed reading the rowset contents, 1149 * this method is called internally to pass the <code>RowSetMetaData</code> 1150 * object to the rowset. 1151 * 1152 * @param md a <code>RowSetMetaData</code> object containing 1153 * metadata about the columns in this <code>CachedRowSet</code> object 1154 * @throws SQLException if invalid metadata is supplied to the 1155 * rowset 1156 */ 1157 public void setMetaData(RowSetMetaData md) throws SQLException; 1158 1159 /** 1160 * Returns a <code>ResultSet</code> object containing the original value of this 1161 * <code>CachedRowSet</code> object. 1162 * <P> 1163 * The cursor for the <code>ResultSet</code> 1164 * object should be positioned before the first row. 1165 * In addition, the returned <code>ResultSet</code> object should have the following 1166 * properties: 1167 * <UL> 1168 * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE 1169 * <LI>ResultSet.CONCUR_UPDATABLE 1170 * </UL> 1171 * <P> 1172 * The original value for a <code>RowSet</code> object is the value it had before 1173 * the last synchronization with the underlying data source. If there have been 1174 * no synchronizations, the original value will be the value with which the 1175 * <code>RowSet</code> object was populated. This method is called internally 1176 * when an application calls the method <code>acceptChanges</code> and the 1177 * <code>SyncProvider</code> object has been implemented to check for conflicts. 1178 * If this is the case, the writer compares the original value with the value 1179 * currently in the data source to check for conflicts. 1180 * 1181 * @return a <code>ResultSet</code> object that contains the original value for 1182 * this <code>CachedRowSet</code> object 1183 * @throws SQLException if an error occurs producing the 1184 * <code>ResultSet</code> object 1185 */ 1186 public ResultSet getOriginal() throws SQLException; 1187 1188 /** 1189 * Returns a <code>ResultSet</code> object containing the original value for the 1190 * current row only of this <code>CachedRowSet</code> object. 1191 * <P> 1192 * The cursor for the <code>ResultSet</code> 1193 * object should be positioned before the first row. 1194 * In addition, the returned <code>ResultSet</code> object should have the following 1195 * properties: 1196 * <UL> 1197 * <LI>ResultSet.TYPE_SCROLL_INSENSITIVE 1198 * <LI>ResultSet.CONCUR_UPDATABLE 1199 * </UL> 1200 * 1201 * @return the original result set of the row 1202 * @throws SQLException if there is no current row 1203 * @see #setOriginalRow 1204 */ 1205 public ResultSet getOriginalRow() throws SQLException; 1206 1207 /** 1208 * Sets the current row in this <code>CachedRowSet</code> object as the original 1209 * row. 1210 * <P> 1211 * This method is called internally after the any modified values in the current 1212 * row have been synchronized with the data source. The current row must be tagged 1213 * as no longer inserted, deleted or updated. 1214 * <P> 1215 * A call to <code>setOriginalRow</code> is irreversible. 1216 * 1217 * @throws SQLException if there is no current row or an error is 1218 * encountered resetting the contents of the original row 1219 * @see #getOriginalRow 1220 */ 1221 public void setOriginalRow() throws SQLException; 1222 1223 /** 1224 * Returns an identifier for the object (table) that was used to 1225 * create this <code>CachedRowSet</code> object. This name may be set on multiple occasions, 1226 * and the specification imposes no limits on how many times this 1227 * may occur or whether standard implementations should keep track 1228 * of previous table names. 1229 * 1230 * @return a <code>String</code> object giving the name of the table that is the 1231 * source of data for this <code>CachedRowSet</code> object or <code>null</code> 1232 * if no name has been set for the table 1233 * @throws SQLException if an error is encountered returning the table name 1234 * @see javax.sql.RowSetMetaData#getTableName 1235 */ 1236 public String getTableName() throws SQLException; 1237 1238 /** 1239 * Sets the identifier for the table from which this <code>CachedRowSet</code> 1240 * object was derived to the given table name. The writer uses this name to 1241 * determine which table to use when comparing the values in the data source with the 1242 * <code>CachedRowSet</code> object's values during a synchronization attempt. 1243 * The table identifier also indicates where modified values from this 1244 * <code>CachedRowSet</code> object should be written. 1245 * <P> 1246 * The implementation of this <code>CachedRowSet</code> object may obtain the 1247 * the name internally from the <code>RowSetMetaDataImpl</code> object. 1248 * 1249 * @param tabName a <code>String</code> object identifying the table from which this 1250 <code>CachedRowSet</code> object was derived; cannot be <code>null</code> 1251 * but may be an empty string 1252 * @throws SQLException if an error is encountered naming the table or 1253 * <i>tabName</i> is <code>null</code> 1254 * @see javax.sql.RowSetMetaData#setTableName 1255 * @see javax.sql.RowSetWriter 1256 * @see javax.sql.rowset.spi.SyncProvider 1257 */ 1258 public void setTableName(String tabName) throws SQLException; 1259 1260 /** 1261 * Returns an array containing one or more column numbers indicating the columns 1262 * that form a key that uniquely 1263 * identifies a row in this <code>CachedRowSet</code> object. 1264 * 1265 * @return an array containing the column number or numbers that indicate which columns 1266 * constitute a primary key 1267 * for a row in this <code>CachedRowSet</code> object. This array should be 1268 * empty if no columns are representative of a primary key. 1269 * @throws SQLException if this <code>CachedRowSet</code> object is empty 1270 * @see #setKeyColumns 1271 * @see Joinable#getMatchColumnIndexes 1272 * @see Joinable#getMatchColumnNames 1273 */ 1274 public int[] getKeyColumns() throws SQLException; 1275 1276 /** 1277 * Sets this <code>CachedRowSet</code> object's <code>keyCols</code> 1278 * field with the given array of column numbers, which forms a key 1279 * for uniquely identifying a row in this <code>CachedRowSet</code> object. 1280 * <p> 1281 * If a <code>CachedRowSet</code> object becomes part of a <code>JoinRowSet</code> 1282 * object, the keys defined by this method and the resulting constraints are 1283 * maintained if the columns designated as key columns also become match 1284 * columns. 1285 * 1286 * @param keys an array of <code>int</code> indicating the columns that form 1287 * a primary key for this <code>CachedRowSet</code> object; every 1288 * element in the array must be greater than <code>0</code> and 1289 * less than or equal to the number of columns in this rowset 1290 * @throws SQLException if any of the numbers in the given array 1291 * are not valid for this rowset 1292 * @see #getKeyColumns 1293 * @see Joinable#setMatchColumn(String) 1294 * @see Joinable#setMatchColumn(int) 1295 1296 */ 1297 public void setKeyColumns(int[] keys) throws SQLException; 1298 1299 1300 /** 1301 * Returns a new <code>RowSet</code> object backed by the same data as 1302 * that of this <code>CachedRowSet</code> object. In effect, both 1303 * <code>CachedRowSet</code> objects have a cursor over the same data. 1304 * As a result, any changes made by a duplicate are visible to the original 1305 * and to any other duplicates, just as a change made by the original is visible 1306 * to all of its duplicates. If a duplicate calls a method that changes the 1307 * underlying data, the method it calls notifies all registered listeners 1308 * just as it would when it is called by the original <code>CachedRowSet</code> 1309 * object. 1310 * <P> 1311 * In addition, any <code>RowSet</code> object 1312 * created by this method will have the same properties as this 1313 * <code>CachedRowSet</code> object. For example, if this <code>CachedRowSet</code> 1314 * object is read-only, all of its duplicates will also be read-only. If it is 1315 * changed to be updatable, the duplicates also become updatable. 1316 * <P> 1317 * NOTE: If multiple threads access <code>RowSet</code> objects created from 1318 * the <code>createShared()</code> method, the following behavior is specified 1319 * to preserve shared data integrity: reads and writes of all 1320 * shared <code>RowSet</code> objects should be made serially between each 1321 * object and the single underlying tabular structure. 1322 * 1323 * @return a new shared <code>RowSet</code> object that has the same properties 1324 * as this <code>CachedRowSet</code> object and that has a cursor over 1325 * the same data 1326 * @throws SQLException if an error occurs or cloning is not 1327 * supported in the underlying platform 1328 * @see javax.sql.RowSetEvent 1329 * @see javax.sql.RowSetListener 1330 */ 1331 public RowSet createShared() throws SQLException; 1332 1333 /** 1334 * Creates a <code>RowSet</code> object that is a deep copy of the data in 1335 * this <code>CachedRowSet</code> object. In contrast to 1336 * the <code>RowSet</code> object generated from a <code>createShared</code> 1337 * call, updates made to the copy of the original <code>RowSet</code> object 1338 * must not be visible to the original <code>RowSet</code> object. Also, any 1339 * event listeners that are registered with the original 1340 * <code>RowSet</code> must not have scope over the new 1341 * <code>RowSet</code> copies. In addition, any constraint restrictions 1342 * established must be maintained. 1343 * 1344 * @return a new <code>RowSet</code> object that is a deep copy 1345 * of this <code>CachedRowSet</code> object and is 1346 * completely independent of this <code>CachedRowSet</code> object 1347 * @throws SQLException if an error occurs in generating the copy of 1348 * the of this <code>CachedRowSet</code> object 1349 * @see #createShared 1350 * @see #createCopySchema 1351 * @see #createCopyNoConstraints 1352 * @see javax.sql.RowSetEvent 1353 * @see javax.sql.RowSetListener 1354 */ 1355 public CachedRowSet createCopy() throws SQLException; 1356 1357 /** 1358 * Creates a <code>CachedRowSet</code> object that is an empty copy of this 1359 * <code>CachedRowSet</code> object. The copy 1360 * must not contain any contents but only represent the table 1361 * structure of the original <code>CachedRowSet</code> object. In addition, primary 1362 * or foreign key constraints set in the originating <code>CachedRowSet</code> object must 1363 * be equally enforced in the new empty <code>CachedRowSet</code> object. 1364 * In contrast to 1365 * the <code>RowSet</code> object generated from a <code>createShared</code> method 1366 * call, updates made to a copy of this <code>CachedRowSet</code> object with the 1367 * <code>createCopySchema</code> method must not be visible to it. 1368 * <P> 1369 * Applications can form a <code>WebRowSet</code> object from the <code>CachedRowSet</code> 1370 * object returned by this method in order 1371 * to export the <code>RowSet</code> schema definition to XML for future use. 1372 * @return An empty copy of this {@code CachedRowSet} object 1373 * @throws SQLException if an error occurs in cloning the structure of this 1374 * <code>CachedRowSet</code> object 1375 * @see #createShared 1376 * @see #createCopySchema 1377 * @see #createCopyNoConstraints 1378 * @see javax.sql.RowSetEvent 1379 * @see javax.sql.RowSetListener 1380 */ 1381 public CachedRowSet createCopySchema() throws SQLException; 1382 1383 /** 1384 * Creates a <code>CachedRowSet</code> object that is a deep copy of 1385 * this <code>CachedRowSet</code> object's data but is independent of it. 1386 * In contrast to 1387 * the <code>RowSet</code> object generated from a <code>createShared</code> 1388 * method call, updates made to a copy of this <code>CachedRowSet</code> object 1389 * must not be visible to it. Also, any 1390 * event listeners that are registered with this 1391 * <code>CachedRowSet</code> object must not have scope over the new 1392 * <code>RowSet</code> object. In addition, any constraint restrictions 1393 * established for this <code>CachedRowSet</code> object must <b>not</b> be maintained 1394 * in the copy. 1395 * 1396 * @return a new <code>CachedRowSet</code> object that is a deep copy 1397 * of this <code>CachedRowSet</code> object and is 1398 * completely independent of this <code>CachedRowSet</code> object 1399 * @throws SQLException if an error occurs in generating the copy of 1400 * the of this <code>CachedRowSet</code> object 1401 * @see #createCopy 1402 * @see #createShared 1403 * @see #createCopySchema 1404 * @see javax.sql.RowSetEvent 1405 * @see javax.sql.RowSetListener 1406 */ 1407 public CachedRowSet createCopyNoConstraints() throws SQLException; 1408 1409 /** 1410 * Retrieves the first warning reported by calls on this <code>RowSet</code> object. 1411 * Subsequent warnings on this <code>RowSet</code> object will be chained to the 1412 * <code>RowSetWarning</code> object that this method returns. 1413 * 1414 * The warning chain is automatically cleared each time a new row is read. 1415 * This method may not be called on a RowSet object that has been closed; 1416 * doing so will cause a <code>SQLException</code> to be thrown. 1417 * 1418 * @return RowSetWarning the first <code>RowSetWarning</code> 1419 * object reported or null if there are none 1420 * @throws SQLException if this method is called on a closed RowSet 1421 * @see RowSetWarning 1422 */ 1423 public RowSetWarning getRowSetWarnings() throws SQLException; 1424 1425 /** 1426 * Retrieves a <code>boolean</code> indicating whether rows marked 1427 * for deletion appear in the set of current rows. If <code>true</code> is 1428 * returned, deleted rows are visible with the current rows. If 1429 * <code>false</code> is returned, rows are not visible with the set of 1430 * current rows. The default value is <code>false</code>. 1431 * <P> 1432 * Standard rowset implementations may choose to restrict this behavior 1433 * due to security considerations or to better fit certain deployment 1434 * scenarios. This is left as implementation defined and does not 1435 * represent standard behavior. 1436 * <P> 1437 * Note: Allowing deleted rows to remain visible complicates the behavior 1438 * of some standard JDBC <code>RowSet</code> Implementations methods. 1439 * However, most rowset users can simply ignore this extra detail because 1440 * only very specialized applications will likely want to take advantage of 1441 * this feature. 1442 * 1443 * @return <code>true</code> if deleted rows are visible; 1444 * <code>false</code> otherwise 1445 * @throws SQLException if a rowset implementation is unable to 1446 * to determine whether rows marked for deletion are visible 1447 * @see #setShowDeleted 1448 */ 1449 public boolean getShowDeleted() throws SQLException; 1450 1451 /** 1452 * Sets the property <code>showDeleted</code> to the given 1453 * <code>boolean</code> value, which determines whether 1454 * rows marked for deletion appear in the set of current rows. 1455 * If the value is set to <code>true</code>, deleted rows are immediately 1456 * visible with the set of current rows. If the value is set to 1457 * <code>false</code>, the deleted rows are set as invisible with the 1458 * current set of rows. 1459 * <P> 1460 * Standard rowset implementations may choose to restrict this behavior 1461 * due to security considerations or to better fit certain deployment 1462 * scenarios. This is left as implementations defined and does not 1463 * represent standard behavior. 1464 * 1465 * @param b <code>true</code> if deleted rows should be shown; 1466 * <code>false</code> otherwise 1467 * @exception SQLException if a rowset implementation is unable to 1468 * to reset whether deleted rows should be visible 1469 * @see #getShowDeleted 1470 */ 1471 public void setShowDeleted(boolean b) throws SQLException; 1472 1473 /** 1474 * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains 1475 * a <code>Connection</code> object from the <code>ResultSet</code> or JDBC 1476 * properties passed to it's constructors. This method wraps the 1477 * <code>Connection</code> commit method to allow flexible 1478 * auto commit or non auto commit transactional control support. 1479 * <p> 1480 * Makes all changes that are performed by the <code>acceptChanges()</code> 1481 * method since the previous commit/rollback permanent. This method should 1482 * be used only when auto-commit mode has been disabled. 1483 * 1484 * @throws SQLException if a database access error occurs or this 1485 * Connection object within this <code>CachedRowSet</code> is in auto-commit mode 1486 * @see java.sql.Connection#setAutoCommit 1487 */ 1488 public void commit() throws SQLException; 1489 1490 /** 1491 * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains 1492 * a <code>Connection</code> object from the original <code>ResultSet</code> 1493 * or JDBC properties passed to it. 1494 * <p> 1495 * Undoes all changes made in the current transaction. This method 1496 * should be used only when auto-commit mode has been disabled. 1497 * 1498 * @throws SQLException if a database access error occurs or this Connection 1499 * object within this <code>CachedRowSet</code> is in auto-commit mode. 1500 */ 1501 public void rollback() throws SQLException; 1502 1503 /** 1504 * Each <code>CachedRowSet</code> object's <code>SyncProvider</code> contains 1505 * a <code>Connection</code> object from the original <code>ResultSet</code> 1506 * or JDBC properties passed to it. 1507 * <p> 1508 * Undoes all changes made in the current transaction back to the last 1509 * <code>Savepoint</code> transaction marker. This method should be used only 1510 * when auto-commit mode has been disabled. 1511 * 1512 * @param s A <code>Savepoint</code> transaction marker 1513 * @throws SQLException if a database access error occurs or this Connection 1514 * object within this <code>CachedRowSet</code> is in auto-commit mode. 1515 */ 1516 public void rollback(Savepoint s) throws SQLException; 1517 1518 /** 1519 * Causes the <code>CachedRowSet</code> object's <code>SyncProvider</code> 1520 * to commit the changes when <code>acceptChanges()</code> is called. If 1521 * set to false, the changes will <b>not</b> be committed until one of the 1522 * <code>CachedRowSet</code> interface transaction methods is called. 1523 * 1524 * @deprecated Because this field is final (it is part of an interface), 1525 * its value cannot be changed. 1526 * @see #commit 1527 * @see #rollback 1528 */ 1529 @Deprecated 1530 public static final boolean COMMIT_ON_ACCEPT_CHANGES = true; 1531 1532 /** 1533 * Notifies registered listeners that a RowSet object in the given RowSetEvent 1534 * object has populated a number of additional rows. The <code>numRows</code> parameter 1535 * ensures that this event will only be fired every <code>numRow</code>. 1536 * <p> 1537 * The source of the event can be retrieved with the method event.getSource. 1538 * 1539 * @param event a <code>RowSetEvent</code> object that contains the 1540 * <code>RowSet</code> object that is the source of the events 1541 * @param numRows when populating, the number of rows interval on which the 1542 * <code>CachedRowSet</code> populated should fire; the default value 1543 * is zero; cannot be less than <code>fetchSize</code> or zero 1544 * @throws SQLException {@code numRows < 0 or numRows < getFetchSize() } 1545 */ 1546 public void rowSetPopulated(RowSetEvent event, int numRows) throws SQLException; 1547 1548 /** 1549 * Populates this <code>CachedRowSet</code> object with data from 1550 * the given <code>ResultSet</code> object. While related to the <code>populate(ResultSet)</code> 1551 * method, an additional parameter is provided to allow starting position within 1552 * the <code>ResultSet</code> from where to populate the CachedRowSet 1553 * instance. 1554 * <P> 1555 * This method can be used as an alternative to the <code>execute</code> method when an 1556 * application has a connection to an open <code>ResultSet</code> object. 1557 * Using the method <code>populate</code> can be more efficient than using 1558 * the version of the <code>execute</code> method that takes no parameters 1559 * because it does not open a new connection and re-execute this 1560 * <code>CachedRowSet</code> object's command. Using the <code>populate</code> 1561 * method is more a matter of convenience when compared to using the version 1562 * of <code>execute</code> that takes a <code>ResultSet</code> object. 1563 * 1564 * @param startRow the position in the <code>ResultSet</code> from where to start 1565 * populating the records in this <code>CachedRowSet</code> 1566 * @param rs the <code>ResultSet</code> object containing the data 1567 * to be read into this <code>CachedRowSet</code> object 1568 * @throws SQLException if a null <code>ResultSet</code> object is supplied 1569 * or this <code>CachedRowSet</code> object cannot 1570 * retrieve the associated <code>ResultSetMetaData</code> object 1571 * @see #execute 1572 * @see #populate(ResultSet) 1573 * @see java.sql.ResultSet 1574 * @see java.sql.ResultSetMetaData 1575 */ 1576 public void populate(ResultSet rs, int startRow) throws SQLException; 1577 1578 /** 1579 * Sets the <code>CachedRowSet</code> object's page-size. A <code>CachedRowSet</code> 1580 * may be configured to populate itself in page-size sized batches of rows. When 1581 * either <code>populate()</code> or <code>execute()</code> are called, the 1582 * <code>CachedRowSet</code> fetches an additional page according to the 1583 * original SQL query used to populate the RowSet. 1584 * 1585 * @param size the page-size of the <code>CachedRowSet</code> 1586 * @throws SQLException if an error occurs setting the <code>CachedRowSet</code> 1587 * page size or if the page size is less than 0. 1588 */ 1589 public void setPageSize(int size) throws SQLException; 1590 1591 /** 1592 * Returns the page-size for the <code>CachedRowSet</code> object 1593 * 1594 * @return an <code>int</code> page size 1595 */ 1596 public int getPageSize(); 1597 1598 /** 1599 * Increments the current page of the <code>CachedRowSet</code>. This causes 1600 * the <code>CachedRowSet</code> implementation to fetch the next page-size 1601 * rows and populate the RowSet, if remaining rows remain within scope of the 1602 * original SQL query used to populated the RowSet. 1603 * 1604 * @return true if more pages exist; false if this is the last page 1605 * @throws SQLException if an error occurs fetching the next page, or if this 1606 * method is called prematurely before populate or execute. 1607 */ 1608 public boolean nextPage() throws SQLException; 1609 1610 /** 1611 * Decrements the current page of the <code>CachedRowSet</code>. This causes 1612 * the <code>CachedRowSet</code> implementation to fetch the previous page-size 1613 * rows and populate the RowSet. The amount of rows returned in the previous 1614 * page must always remain within scope of the original SQL query used to 1615 * populate the RowSet. 1616 * 1617 * @return true if the previous page is successfully retrieved; false if this 1618 * is the first page. 1619 * @throws SQLException if an error occurs fetching the previous page, or if 1620 * this method is called prematurely before populate or execute. 1621 */ 1622 public boolean previousPage() throws SQLException; 1623 1624 }