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