📄 jdbcresultset.java
字号:
*
* (fredt@users) <br>
* (boucherb@users)<p>
*
* </div>
* @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>
*
* Extensively rewritten and extended in successive versions of HSQLDB.
*
* @author Thomas Mueller (Hypersonic SQL Group)
* @version 1.8.0
* @since Hypersonic SQL
*/
public class jdbcResultSet implements ResultSet {
// 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 last row + 1 N/A N/A
//------------------------ Private Attributes --------------------------
/*
* Campbell's comments
* 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.0, HSQLDB does not make such guarantees
* under all conditions. See the discussion at {@link #getMetaData}.
* (boucherb@users) (version 1.7.0)<p>
*/
// boucherb@users/hiep256@users 20010829 - patch 1.7.2 - allow expression to
// return Results as Object, where object is Result or jdbcResultSet.
// - rResult access changed to allow getting internal result object
// from Parser.processCall()
/** Statement is closed when its result set is closed */
boolean autoClose;
/** The internal representation. */
public Result rResult;
/**
* The current record containing the data for the row
*/
private Record nCurrent;
/** The row upon which this ResultSet is currently positioned. */
private int iCurrentRow;
/** When the result of updating the database, the number of updated rows. */
private int iUpdateCount;
/** Is current row before the first row? */
private boolean bInit; // false if before first row
/** How many columns does this ResultSet have? */
int iColumnCount;
/** Did the last getXXX method encounter a null value? */
private boolean bWasNull;
/** The ResultSetMetaData object for this ResultSet */
private ResultSetMetaData rsmd;
/** Properties of this ResultSet's parent Connection. */
private HsqlProperties connProperties;
/** is the connection via network */
private boolean isNetConn;
/**
* The Statement that generated this result. Null if the result is
* from DatabaseMetaData<p>
*/
jdbcStatement sqlStatement;
//------------------------ Package Attributes --------------------------
/**
* The scrollability / scroll sensitivity type 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 -->
*
* @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 || rResult.isEmpty()) {
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 after last and exit with false
iCurrentRow = rResult.getSize() + 1;
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 -->
*
* @exception SQLException if a database access error occurs
*/
public void close() throws SQLException {
iUpdateCount = -1;
rResult = null;
if (autoClose) {
sqlStatement.close();
}
}
/**
* <!-- start generic documentation -->
* Reports whether
* the last column read had a value of SQL <code>NULL</code>.
* Note that you must first call one of the getter methods
* on a column to try to read its value and then call
* the method <code>wasNull</code> to see if the value read was
* SQL <code>NULL</code>. <p>
* <!-- end generic documentation -->
*
* @return <code>true</code> if the last column value read was SQL
* <code>NULL</code> and <code>false</code> otherwise
* @exception SQLException if a database access error occurs
*/
public boolean wasNull() throws SQLException {
return bWasNull;
}
//======================================================================
// Methods for accessing results by column index
//======================================================================
/**
* <!-- start generic documentation -->
* Retrieves the value of the designated column in the current row
* of this <code>ResultSet</code> object as
* a <code>String</code> in the Java programming language. <p>
* <!-- end generic documentation -->
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return the column value; if the value is SQL <code>NULL</code>, the
* value returned is <code>null</code>
* @exception SQLException if a database access error occurs
*/
public String getString(int columnIndex) throws SQLException {
return (String) getColumnInType(columnIndex, Types.CHAR);
}
/**
* <!-- start generic documentation -->
* Retrieves the value of the designated column in the current row
* of this <code>ResultSet</code> object as
* a <code>boolean</code> in the Java programming language. <p>
* <!-- end generic documentation -->
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return the column value; if the value is SQL <code>NULL</code>, the
* value returned is <code>false</code>
* @exception SQLException if a database access error occurs
*/
public boolean getBoolean(int columnIndex) throws SQLException {
Object o = getColumnInType(columnIndex, Types.BOOLEAN);
return o == null ? false
: ((Boolean) o).booleanValue();
}
/**
* <!-- start generic documentation -->
* Retrieves the value of the designated column in the current row
* of this <code>ResultSet</code> object as
* a <code>byte</code> in the Java programming language. <p>
* <!-- end generic documentation -->
*
* @param columnIndex the first column is 1, the second is 2, ...
* @return the column value; if the value is SQL <code>NULL</code>, the
* value returned is <code>0</code>
* @exception SQLException if a database access error occurs
*/
public byte getByte(int columnIndex) throws SQLException {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -