1625 lines · 82.4 KB · Java
RawDownload
 * an application sets the number of rows to be included in a page using the method * <code>setPageSize</code>. In other words, if the page size is set to five, a chunk * of five rows of * data will be fetched from the data source at one time. An application can also * optionally set the maximum number of rows that may be fetched at one time.  If the * maximum number of rows is set to zero, or no maximum number of rows is set, there is * no limit to the number of rows that may be fetched at a time. * <P> * After properties have been set, * the <code>CachedRowSet</code> object must be populated with data * using either the method <code>populate</code> or the method <code>execute</code>. * The following lines of code demonstrate using the method <code>populate</code>. * Note that this version of the method takes two parameters, a <code>ResultSet</code> * handle and the row in the <code>ResultSet</code> object from which to start * retrieving rows. * <PRE> *     CachedRowSet crs = new CachedRowSetImpl(); *     crs.setMaxRows(20); *     crs.setPageSize(4); *     crs.populate(rsHandle, 10); * </PRE> * When this code runs, <i>crs</i> will be populated with four rows from * <i>rsHandle</i> starting with the tenth row. * <P> * The next code fragment shows populating a <code>CachedRowSet</code> object using the * method <code>execute</code>, which may or may not take a <code>Connection</code> * object as a parameter.  This code passes <code>execute</code> the <code>Connection</code> * object <i>conHandle</i>. * <P> * Note that there are two differences between the following code * fragment and the previous one. First, the method <code>setMaxRows</code> is not * called, so there is no limit set for the number of rows that <i>crs</i> may contain. * (Remember that <i>crs</i> always has the overriding limit of how much data it can * store in memory.) The second difference is that the you cannot pass the method * <code>execute</code> the number of the row in the <code>ResultSet</code> object * from which to start retrieving rows. This method always starts with the first row. * <PRE> *     CachedRowSet crs = new CachedRowSetImpl(); *     crs.setPageSize(5); *     crs.execute(conHandle); * </PRE> * After this code has run, <i>crs</i> will contain five rows of data from the * <code>ResultSet</code> object produced by the command for <i>crs</i>. The writer * for <i>crs</i> will use <i>conHandle</i> to connect to the data source and * execute the command for <i>crs</i>. An application is then able to operate on the * data in <i>crs</i> in the same way that it would operate on data in any other * <code>CachedRowSet</code> object. * <P> * To access the next page (chunk of data), an application calls the method * <code>nextPage</code>.  This method creates a new <code>CachedRowSet</code> object * and fills it with the next page of data.  For example, assume that the * <code>CachedRowSet</code> object's command returns a <code>ResultSet</code> object * <i>rs</i> with 1000 rows of data.  If the page size has been set to 100, the first *  call to the method <code>nextPage</code> will create a <code>CachedRowSet</code> object * containing the first 100 rows of <i>rs</i>. After doing what it needs to do with the * data in these first 100 rows, the application can again call the method * <code>nextPage</code> to create another <code>CachedRowSet</code> object * with the second 100 rows from <i>rs</i>. The data from the first <code>CachedRowSet</code> * object will no longer be in memory because it is replaced with the data from the * second <code>CachedRowSet</code> object. After the tenth call to the method <code>nextPage</code>, * the tenth <code>CachedRowSet</code> object will contain the last 100 rows of data from * <i>rs</i>, which are stored in memory. At any given time, the data from only one * <code>CachedRowSet</code> object is stored in memory. * <P> * The method <code>nextPage</code> returns <code>true</code> as long as the current * page is not the last page of rows and <code>false</code> when there are no more pages. * It can therefore be used in a <code>while</code> loop to retrieve all of the pages, * as is demonstrated in the following lines of code. * <PRE> *     CachedRowSet crs = CachedRowSetImpl(); *     crs.setPageSize(100); *     crs.execute(conHandle); * *     while(crs.nextPage()) { *         while(crs.next()) { *             . . . // operate on chunks (of 100 rows each) in crs, *                   // row by row *         } *     } * </PRE> * After this code fragment has been run, the application will have traversed all * 1000 rows, but it will have had no more than 100 rows in memory at a time. * <P> * The <code>CachedRowSet</code> interface also defines the method <code>previousPage</code>. * Just as the method <code>nextPage</code> is analogous to the <code>ResultSet</code> * method <code>next</code>, the method <code>previousPage</code> is analogous to * the <code>ResultSet</code> method <code>previous</code>.  Similar to the method * <code>nextPage</code>, <code>previousPage</code> creates a <code>CachedRowSet</code> * object containing the number of rows set as the page size.  So, for instance, the * method <code>previousPage</code> could be used in a <code>while</code> loop at * the end of the preceding code fragment to navigate back through the pages from the last * page to the first page. * The method <code>previousPage</code> is also similar to <code>nextPage</code> * in that it can be used in a <code>while</code> * loop, except that it returns <code>true</code> as long as there is another page * preceding it and <code>false</code> when there are no more pages ahead of it. * <P> * By positioning the cursor after the last row for each page, * as is done in the following code fragment, the method <code>previous</code> * navigates from the last row to the first row in each page. * The code could also have left the cursor before the first row on each page and then * used the method <code>next</code> in a <code>while</code> loop to navigate each page * from the first row to the last row. * <P> * The following code fragment assumes a continuation from the previous code fragment, * meaning that the cursor for the tenth <code>CachedRowSet</code> object is on the * last row.  The code moves the cursor to after the last row so that the first * call to the method <code>previous</code> will put the cursor back on the last row. * After going through all of the rows in the last page (the <code>CachedRowSet</code> * object <i>crs</i>), the code then enters * the <code>while</code> loop to get to the ninth page, go through the rows backwards, * go to the eighth page, go through the rows backwards, and so on to the first row * of the first page. * * <PRE> *     crs.afterLast(); *     while(crs.previous())  { *         . . . // navigate through the rows, last to first *     { *     while(crs.previousPage())  { *         crs.afterLast(); *         while(crs.previous())  { *             . . . // go from the last row to the first row of each page *         } *     } * </PRE> * * @author Jonathan Bruce */ public interface CachedRowSet extends RowSet, Joinable {    /**    * Populates this <code>CachedRowSet</code> object with data from    * the given <code>ResultSet</code> object.    * <P>    * This method can be used as an alternative to the <code>execute</code> method when an    * application has a connection to an open <code>ResultSet</code> object.    * Using the method <code>populate</code> can be more efficient than using    * the version of the <code>execute</code> method that takes no parameters    * because it does not open a new connection and re-execute this    * <code>CachedRowSet</code> object's command. Using the <code>populate</code>    * method is more a matter of convenience when compared to using the version    * of <code>execute</code> that takes a <code>ResultSet</code> object.    *    * @param data the <code>ResultSet</code> object containing the data    * to be read into this <code>CachedRowSet</code> object    * @throws SQLException if a null <code>ResultSet</code> object is supplied    * or this <code>CachedRowSet</code> object cannot    * retrieve the associated <code>ResultSetMetaData</code> object    * @see #execute    * @see java.sql.ResultSet    * @see java.sql.ResultSetMetaData    */    public void populate(ResultSet data) throws SQLException;    /**    * Populates this <code>CachedRowSet</code> object with data, using the    * given connection to produce the result set from which the data will be read.    * This method should close any database connections that it creates to    * ensure that this <code>CachedRowSet</code> object is disconnected except when    * it is reading data from its data source or writing data to its data source.    * <P>    * The reader for this <code>CachedRowSet</code> object    * will use <i>conn</i> to establish a connection to the data source    * so that it can execute the rowset's command and read data from the    * the resulting <code>ResultSet</code> object into this    * <code>CachedRowSet</code> object. This method also closes <i>conn</i>    * after it has populated this <code>CachedRowSet</code> object.    * <P>    * If this method is called when an implementation has already been    * populated, the contents and the metadata are (re)set. Also, if this method is    * called before the method <code>acceptChanges</code> has been called    * to commit outstanding updates, those updates are lost.    *    * @param conn a standard JDBC <code>Connection</code> object with valid    * properties    * @throws SQLException if an invalid <code>Connection</code> object is supplied    * or an error occurs in establishing the connection to the    * data source    * @see #populate    * @see java.sql.Connection    */    public void execute(Connection conn) throws SQLException;    /**    * Propagates row update, insert and delete changes made to this    * <code>CachedRowSet</code> object to the underlying data source.    * <P>    * This method calls on this <code>CachedRowSet</code> object's writer    * to do the work behind the scenes.    * Standard <code>CachedRowSet</code> implementations should use the    * <code>SyncFactory</code> singleton    * to obtain a <code>SyncProvider</code> instance providing a    * <code>RowSetWriter</code> object (writer).  The writer will attempt    * to propagate changes made in this <code>CachedRowSet</code> object    * back to the data source.    * <P>    * When the method <code>acceptChanges</code> executes successfully, in    * addition to writing changes to the data source, it    * makes the values in the current row be the values in the original row.    * <P>    * Depending on the synchronization level of the <code>SyncProvider</code>    * implementation being used, the writer will compare the original values    * with those in the data source to check for conflicts. When there is a conflict,    * the <code>RIOptimisticProvider</code> implementation, for example, throws a    * <code>SyncProviderException</code> and does not write anything to the    * data source.    * <P>    * An application may choose to catch the <code>SyncProviderException</code>    * object and retrieve the <code>SyncResolver</code> object it contains.    * The <code>SyncResolver</code> object lists the conflicts row by row and    * sets a lock on the data source to avoid further conflicts while the    * current conflicts are being resolved.    * Further, for each conflict, it provides methods for examining the conflict    * and setting the value that should be persisted in the data source.    * After all conflicts have been resolved, an application must call the    * <code>acceptChanges</code> method again to write resolved values to the    * data source.  If all of the values in the data source are already the    * values to be persisted, the method <code>acceptChanges</code> does nothing.    * <P>    * Some provider implementations may use locks to ensure that there are no    * conflicts.  In such cases, it is guaranteed that the writer will succeed in    * writing changes to the data source when the method <code>acceptChanges</code>    * is called.  This method may be called immediately after the methods    * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>    * have been called, but it is more efficient to call it only once after    * all changes have been made so that only one connection needs to be    * established.    * <P>    * Note: The <code>acceptChanges()</code> method will determine if the    * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set    * to true, all updates in the synchronization are committed to the data    * source. Otherwise, the application <b>must</b> explicity call the    * <code>commit()</code> or <code>rollback()</code> methods as appropriate.    *    * @throws SQLException if the cursor is on the insert row    * @throws SyncProviderException if the underlying    * synchronization provider's writer fails to write the updates    * back to the data source    * @see #acceptChanges(java.sql.Connection)    * @see javax.sql.RowSetWriter    * @see javax.sql.rowset.spi.SyncFactory    * @see javax.sql.rowset.spi.SyncProvider    * @see javax.sql.rowset.spi.SyncProviderException    * @see javax.sql.rowset.spi.SyncResolver    */    public void acceptChanges() throws SyncProviderException;    /**    * Propagates all row update, insert and delete changes to the    * data source backing this <code>CachedRowSet</code> object    * using the specified <code>Connection</code> object to establish a    * connection to the data source.    * <P>    * The other version of the <code>acceptChanges</code> method is not passed    * a connection because it uses    * the <code>Connection</code> object already defined within the <code>RowSet</code>    * object, which is the connection used for populating it initially.    * <P>    * This form of the method <code>acceptChanges</code> is similar to the    * form that takes no arguments; however, unlike the other form, this form    * can be used only when the underlying data source is a JDBC data source.    * The updated <code>Connection</code> properties must be used by the    * <code>SyncProvider</code> to reset the <code>RowSetWriter</code>    * configuration to ensure that the contents of the <code>CachedRowSet</code>    * object are synchronized correctly.    * <P>    * When the method <code>acceptChanges</code> executes successfully, in    * addition to writing changes to the data source, it    * makes the values in the current row be the values in the original row.    * <P>    * Depending on the synchronization level of the <code>SyncProvider</code>    * implementation being used, the writer will compare the original values    * with those in the data source to check for conflicts. When there is a conflict,    * the <code>RIOptimisticProvider</code> implementation, for example, throws a    * <code>SyncProviderException</code> and does not write anything to the    * data source.    * <P>    * An application may choose to catch the <code>SyncProviderException</code>    * object and retrieve the <code>SyncResolver</code> object it contains.    * The <code>SyncResolver</code> object lists the conflicts row by row and    * sets a lock on the data source to avoid further conflicts while the    * current conflicts are being resolved.    * Further, for each conflict, it provides methods for examining the conflict    * and setting the value that should be persisted in the data source.    * After all conflicts have been resolved, an application must call the    * <code>acceptChanges</code> method again to write resolved values to the    * data source.  If all of the values in the data source are already the    * values to be persisted, the method <code>acceptChanges</code> does nothing.    * <P>    * Some provider implementations may use locks to ensure that there are no    * conflicts.  In such cases, it is guaranteed that the writer will succeed in    * writing changes to the data source when the method <code>acceptChanges</code>    * is called.  This method may be called immediately after the methods    * <code>updateRow</code>, <code>insertRow</code>, or <code>deleteRow</code>    * have been called, but it is more efficient to call it only once after    * all changes have been made so that only one connection needs to be    * established.    * <P>    * Note: The <code>acceptChanges()</code> method will determine if the    * <code>COMMIT_ON_ACCEPT_CHANGES</code> is set to true or not. If it is set    * to true, all updates in the synchronization are committed to the data    * source. Otherwise, the application <b>must</b> explicity call the    * <code>commit</code> or <code>rollback</code> methods as appropriate.    *    * @param con a standard JDBC <code>Connection</code> object    * @throws SQLException if the cursor is on the insert row    * @throws SyncProviderException if the underlying    * synchronization provider's writer fails to write the updates    * back to the data source    * @see #acceptChanges()    * @see javax.sql.RowSetWriter    * @see javax.sql.rowset.spi.SyncFactory    * @see javax.sql.rowset.spi.SyncProvider    * @see javax.sql.rowset.spi.SyncProviderException    * @see javax.sql.rowset.spi.SyncResolver    */    public void acceptChanges(Connection con) throws SyncProviderException;    /**    * Restores this <code>CachedRowSet</code> object to its original    * value, that is, its value before the last set of changes. If there    * have been no changes to the rowset or only one set of changes,    * the original value is the value with which this <code>CachedRowSet</code> object    * was populated; otherwise, the original value is    * the value it had immediately before its current value.    * <P>    * When this method is called, a <code>CachedRowSet</code> implementation    * must ensure that all updates, inserts, and deletes to the current    * rowset instance are replaced by the previous values. In addition,    * the cursor should be    * reset to the first row and a <code>rowSetChanged</code> event    * should be fired to notify all registered listeners.    *    * @throws SQLException if an error occurs rolling back the current value of    *       this <code>CachedRowSet</code> object to its previous value    * @see javax.sql.RowSetListener#rowSetChanged    */    public void restoreOriginal() throws SQLException;    /**    * Releases the current contents of this <code>CachedRowSet</code>    * object and sends a <code>rowSetChanged</code> event to all    * registered listeners. Any outstanding updates are discarded and    * the rowset contains no rows after this method is called. There    * are no interactions with the underlying data source, and any rowset    * content, metadata, and content updates should be non-recoverable.    * <P>    * This <code>CachedRowSet</code> object should lock until its contents and    * associated updates are fully cleared, thus preventing 'dirty' reads by    * other components that hold a reference to this <code>RowSet</code> object.    * In addition, the contents cannot be released    * until all all components reading this <code>CachedRowSet</code> object    * have completed their reads. This <code>CachedRowSet</code> object    * should be returned to normal behavior after firing the    * <code>rowSetChanged</code> event.    * <P>    * The metadata, including JDBC properties and Synchronization SPI    * properties, are maintained for future use. It is important that    * properties such as the <code>command</code> property be    * relevant to the originating data source from which this <code>CachedRowSet</code>    * object was originally established.    * <P>    * This method empties a rowset, as opposed to the <code>close</code> method,    * which marks the entire rowset as recoverable to allow the garbage collector    * the rowset's Java VM resources.    *    * @throws SQLException if an error occurs flushing the contents of this    * <code>CachedRowSet</code> object    * @see javax.sql.RowSetListener#rowSetChanged    * @see java.sql.ResultSet#close    */    public void release() throws SQLException;    /**    * Cancels the deletion of the current row and notifies listeners that    * a row has changed. After this method is called, the current row is    * no longer marked for deletion. This method can be called at any    * time during the lifetime of the rowset.    * <P>    * In addition, multiple cancellations of row deletions can be made    * by adjusting the position of the cursor using any of the cursor    * position control methods such as:    * <ul>    * <li><code>CachedRowSet.absolute</code>    * <li><code>CachedRowSet.first</code>    * <li><code>CachedRowSet.last</code>    * </ul>    *    * @throws SQLException if (1) the current row has not been deleted or    * (2) the cursor is on the insert row, before the first row, or    * after the last row    * @see javax.sql.rowset.CachedRowSet#undoInsert    * @see java.sql.ResultSet#cancelRowUpdates    */    public void undoDelete() throws SQLException;    /**    * Immediately removes the current row from this <code>CachedRowSet</code>    * object if the row has been inserted, and also notifies listeners that a    * row has changed. This method can be called at any time during the    * lifetime of a rowset and assuming the current row is within    * the exception limitations (see below), it cancels the row insertion    * of the current row.    * <P>    * In addition, multiple cancellations of row insertions can be made    * by adjusting the position of the cursor using any of the cursor    * position control methods such as:    * <ul>    * <li><code>CachedRowSet.absolute</code>    * <li><code>CachedRowSet.first</code>    * <li><code>CachedRowSet.last</code>    * </ul>    *    * @throws SQLException if (1) the current row has not been inserted or (2)    * the cursor is before the first row, after the last row, or on the    * insert row    * @see javax.sql.rowset.CachedRowSet#undoDelete    * @see java.sql.ResultSet#cancelRowUpdates    */    public void undoInsert() throws SQLException;     /**    * Immediately reverses the last update operation if the    * row has been modified. This method can be    * called to reverse updates on all columns until all updates in a row have    * been rolled back to their state just prior to the last synchronization    * (<code>acceptChanges</code>) or population. This method may also be called    * while performing updates to the insert row.    * <P>    * <code>undoUpdate</code> may be called at any time during the lifetime of a    * rowset; however, after a synchronization has occurred, this method has no    * effect until further modification to the rowset data has occurred.    *    * @throws SQLException if the cursor is before the first row or after the last    *     row in in this <code>CachedRowSet</code> object    * @see #undoDelete    * @see #undoInsert    * @see java.sql.ResultSet#cancelRowUpdates    */    public void undoUpdate() throws SQLException;    /**    * Indicates whether the designated column in the current row of this    * <code>CachedRowSet</code> object has been updated.    *    * @param idx an <code>int</code> identifying the column to be checked for updates    * @return <code>true</code> if the designated column has been visibly updated;    * <code>false</code> otherwise    * @throws SQLException if the cursor is on the insert row, before the first row,    *     or after the last row    * @see java.sql.DatabaseMetaData#updatesAreDetected    */    public boolean columnUpdated(int idx) throws SQLException;     /**    * Indicates whether the designated column in the current row of this    * <code>CachedRowSet</code> object has been updated.    *    * @param columnName a <code>String</code> object giving the name of the    *        column to be checked for updates    * @return <code>true</code> if the column has been visibly updated;    * <code>false</code> otherwise    * @throws SQLException if the cursor is on the insert row, before the first row,    *      or after the last row    * @see java.sql.DatabaseMetaData#updatesAreDetected    */    public boolean columnUpdated(String columnName) throws SQLException;    /**    * Converts this <code>CachedRowSet</code> object to a <code>Collection</code>    * object that contains all of this <code>CachedRowSet</code> object's data.    * Implementations have some latitude in    * how they can represent this <code>Collection</code> object because of the    * abstract nature of the <code>Collection</code> framework.    * Each row must be fully represented in either a    * general purpose <code>Collection</code> implementation or a specialized    * <code>Collection</code> implementation, such as a <code>TreeMap</code>    * object or a <code>Vector</code> object.    * An SQL <code>NULL</code> column value must be represented as a <code>null</code>    * in the Java programming language.    * <P>    * The standard reference implementation for the <code>CachedRowSet</code>    * interface uses a <code>TreeMap</code> object for the rowset, with the    * values in each row being contained in  <code>Vector</code> objects. It is    * expected that most implementations will do the same.    * <P>    * The <code>TreeMap</code> type of collection guarantees that the map will be in    * ascending key order, sorted according to the natural order for the    * key's class.    * Each key references a <code>Vector</code> object that corresponds to one    * row of a <code>RowSet</code> object. Therefore, the size of each    * <code>Vector</code> object  must be exactly equal to the number of    * columns in the <code>RowSet</code> object.    * The key used by the <code>TreeMap</code> collection is determined by the    * implementation, which may choose to leverage a set key that is    * available within the internal <code>RowSet</code> tabular structure by

Lines 501–1000 of 1625. Previous lines