📄 jdbcresultset.java
字号:
* HSQLDB 2.x series, but no decisions have been made at this point.<p> * * <b>JRE 1.1.x Notes:</b> <p> * * In general, JDBC 2 support requires Java 1.2 and above, and JDBC 3 requires * Java 1.4 and above. In HSQLDB, support for methods introduced in different * versions of JDBC depends on the JDK version used for compiling and building * HSQLDB.<p> * * Since 1.7.0, it is possible to build the product so that * all JDBC 2 methods can be called while executing under the version 1.1.x * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>. * However, some of these method calls require <code>int</code> values that * are defined only in the JDBC 2 or greater version of the * <a href="http://java.sun.com/j2se/1.4/docs/api/java/sql/ResultSet.html"> * <CODE>ResultSet</CODE></a> interface. For this reason, when the * product is compiled under JDK 1.1.x, these values are defined in * here, in this class. <p> * * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the * JDBC2-only <CODE>ResultSet</CODE> values can be achieved by referring * to them in parameter specifications and return value comparisons, * respectively, as follows: <p> * * <CODE class="JavaCodeExample"> * jdbcResultSet.FETCH_FORWARD<br> * jdbcResultSet.TYPE_FORWARD_ONLY<br> * jdbcResultSet.TYPE_SCROLL_INSENSITIVE<br> * jdbcResultSet.CONCUR_READ_ONLY<br> * </CODE> <p> * * However, please note that code written in such a manner will not be * compatible for use with other JDBC 2 drivers, since they expect and use * <code>ResultSet</code>, rather than <code>jdbcResultSet</code>. Also * note, this feature is offered solely as a convenience to developers * who must work under JDK 1.1.x due to operating constraints, yet wish to * use some of the more advanced features available under the JDBC 2 * specification.<p> * * <b>ResultSetMetaData Implementation Notes:</b> <p> * * HSQLDB supports a subset of <code>ResultSetMetaData</code> interface. * The JDBC specification for <code>ResultSetMetaData</code> is in part very * vague. Several methods are exclusively for columns that are database * table columns. There is a complete lack of specification on how these * methods are supposed to distinguish between updatable and non-updatable * <code>ResultSet</code> objects or between columns that are database * table columns and those that are results of calculations or functions. * This causes potential incompatibility between interpretations of the * specifications in different JDBC drivers.<p> * * As such, <code>DatabaseMetadata</code> reporting will be enhanced * in future 1.7.x and greater versions, but enhancements to reporting * <code>ResultSetMetaData</code> have to be considered carefully as they * impose a performance penalty on all <code>ResultSet</code> objects * returned from HSQLDB, whether or not the <code>ResultSetMetaData</code> * methods are used.<p> * * (fredt@users) <br> * (boucherb@users)<p> * * </span> * @see jdbcStatement#executeQuery * @see jdbcStatement#getResultSet * @see <a href= * "http://java.sun.com/j2se/1.4/docs/api/java/sql/ResultSetMetaData.html"> * <CODE>ResultSetMetaData</CODE></a> */public class jdbcResultSet implements ResultSet, ResultSetMetaData {// fredt@users 20020320 - patch 497714 by lakuhns@users - scrollable ResultSet// variable values in different states// Condition definitions// bInit iCurrentRow nCurrent nCurrent.next// ----- ----------- -------- -------------// beforeFirst false 0 N/A N/A// first true 1 !null next or null// last true last row # !null null// afterLast true 0 !null N/A //------------------------ Private Attributes --------------------------/* * Future Development Information for Developers and Contributors<p> * Providing a * full and robust implementation guaranteeing consistently accurate * results and behaviour depends upon introducing several new engine * features for which the internals of the product currently have no * infrastructure: <p> * * <OL> * <LI>a unique rowid for each row in the database which lasts the life * of a row, independent of any updates made to that row</LI> * <LI>the ability to explicitly lock either the tables or the * individual rows of an updateable result, for the duration that * the result is open</LI> * <LI>the ability to choose between transactions supporting repeatable * reads, committed reads, and uncommitted reads * <LI>the ability to map an updated result row's columns back to * specific updateable objects on the database.<p> * * <B>Note:</B> Typically, it is easy to do this mapping if all the * rows of a result consist of columns from a single table. And it * is especially easy if the result's columns are a superset of the * primary key columns of that table. The ability to * update a result consisting of any combintation of join, union, * intersect, difference and grouping operations, however, is much more * complex to implement and often impossible, especially under * grouping and non-natural joins. Also, it is not even guaranteed * that the columns of a result map back to *any* updateable object * on the database, for instance in the cases where the * result's column values are general expressions or the result * comes from a stored procedure where the data may not even come, * directly or indirectly, from updateable database objects such as * columns in table rows. * </OL> * * For developers working under a JDBC3 environment, * it is gently recommended to take a look at Sun's early access * <a href="http://developer.java.sun.com/developer/earlyAccess/crs/"> * <CODE>RowSet</CODE></a> implementation, as this can be used to add * JDBC driver independent scrollablility and updateability. * However, as a driver independent implementation, it obviously cannot * guarantee to use the traditional table and/or row locking features * that many DBMS make available to ensure the success of all * valid updates against updateable results sets. As such, performing * updates through Sun's early access <CODE>RowSet</CODE> implementation * may not always succeed, even when it is generally expected that they * should. This is because the condition used to find the original row * on the database to update (which, for a driver independent * implementation, would have to be equality on all columns values of * the originally retrieved row) can become invalid if another * transaction modifies or deletes that row on the database at some * point between the time the row was last retrieved or refreshed in * the RowSet and the time the RowSet attempts to make its next * update to that row. Also, any driver independent implementation * of RowSet is still dependent on each driver guaranteeing that its * <CODE>ResultSet</CODE> objects return completely accurate * <CODE>ResultSetMetaData</CODE> that fulfills all of the * JDBC <CODE>ResultSetMetaData</CODE> contracts under all circumstances. * However, up to and including 1.7.1, HSQLDB does not make such guarantees * under all conditions. See the discussion at {@link #getMetaData}. * (boucherb@users)<p>*/ /** * The internal representation. Basically, a linked list of records, * each containing an Object[] payload representing the data for a row, * plus some metadata. */ private Result rResult; /** * The record containing the data for the row, if any, * currently positioned on. */ private Record nCurrent; /** * The offset of the row, if any, currently positioned on. */ private int iCurrentRow; /** * If a result of updating the database, then this is the number of rows * updated. */ private int iUpdateCount; /** * Is current row before the first row? */ private boolean bInit; // false if before first row /** * How many columns does this <code>ResultSet</code> have? */ private int iColumnCount; /** * Did the last getXXX method encounter a null value? <p> * * This is important for methods that return primitive values, since * there is no other way to check for this condition in those cases. */ private boolean bWasNull;// fredt@users 20020222 - patch 489917 by jytou@users - made optional// see setGetColumnName in package private internal implementation// methods section /** * Does {@link #getColumnName(int) getColumnName} return the * column name (true) or label (false)? */ private boolean getColumnName = true; /** * if false, various unsupported ResultSetMetaData methods return the * true/false values they used to return in version 1.61. * if true they throw an SQLException */ private boolean strictMetaData = false; /** * Properties for the connectin * */ private HsqlProperties connProperties; //------------------------ Package Attributes -------------------------- /** * The Statement that generated this result. */ Statement sqlStatement; /** * The direction of this result. */ int rsType = TYPE_FORWARD_ONLY; /** * <!-- start generic documentation --> * Moves the cursor down one row from its current position. * A <code>ResultSet</code> cursor is initially positioned * before the first row; the first call to the method * <code>next</code> makes the first row the current row; the * second call makes the second row the current row, and so on. * * <P>If an input stream is open for the current row, a call * to the method <code>next</code> will * implicitly close it. A <code>ResultSet</code> object's * warning chain is cleared when a new row is read. <p> * * <!-- end generic documentation --> * * <!-- start release-specific documentation --> * <span class="ReleaseSpecificDocumentation"> * </span> * <!-- end release-specific documentation --> * * * @return <code>true</code> if the new current row is valid; * <code>false</code> if there are no more rows * @exception SQLException if a database access error occurs */ public boolean next() throws SQLException { bWasNull = false; // Have an empty resultset so exit with false if (rResult == null) { return false; } if (rResult.rRoot == null) { return false; } if (!bInit) { // The resultset has not been traversed, so set the cursor // to the first row (1) nCurrent = rResult.rRoot; bInit = true; iCurrentRow = 1; } else { // The resultset has been traversed, if afterLast, retrun false if (nCurrent == null) { return false; } // On a valid row so go to next nCurrent = nCurrent.next; iCurrentRow++; } // finally test to see if we are in an afterLast situation if (nCurrent == null) { // Yes, set the current row to 0 and exit with false iCurrentRow = 0; return false; } else { // Not afterLast, so success return true; } } /** * <!-- start generic documentation --> * Releases this <code>ResultSet</code> object's database and * JDBC resources immediately instead of waiting for * this to happen when it is automatically closed. * * <P><B>Note:</B> A <code>ResultSet</code> object * is automatically closed by the * <code>Statement</code> object that generated it when * that <code>Statement</code> object is closed, * re-executed, or is used to retrieve the next result from a * sequence of multiple results. A <code>ResultSet</code> object * is also automatically closed when it is garbage collected. <p> * <!-- end generic documentation --> * * <!-- start release-specific documentation --> * <span class="ReleaseSpecificDocumentation"> * </span> * <!-- end release-specific documentation --> * * @exception SQLException if a database access error occurs */ public void close() throws SQLException { iUpdateCount = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -