You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by jb...@apache.org on 2005/05/02 08:26:03 UTC
svn commit: r165585 [19/42] - in
/incubator/derby/code/trunk/java/client/org/apache/derby: client/
client/am/ client/net/ client/resources/ jdbc/
Modified: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java?rev=165585&r1=165584&r2=165585&view=diff
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Sun May 1 23:25:59 2005
@@ -20,3512 +20,3778 @@
package org.apache.derby.client.am;
-import org.apache.derby.client.am.Section;
+
public abstract class ResultSet implements java.sql.ResultSet,
- ResultSetCallbackInterface,
- UnitOfWorkListener
+ ResultSetCallbackInterface,
+ UnitOfWorkListener {
+ //---------------------navigational members-----------------------------------
+
+ public Statement statement_;
+ public ColumnMetaData resultSetMetaData_; // As obtained from the SQLDA
+ private SqlWarning warnings_;
+ public Cursor cursor_;
+ protected Agent agent_;
+
+ public Section generatedSection_ = null;
+
+ //---------------------navigational cheat-links-------------------------------
+ // Cheat-links are for convenience only, and are not part of the conceptual model.
+ // Warning:
+ // Cheat-links should only be defined for invariant state data.
+ // That is, the state data is set by the constructor and never changes.
+
+ // Alias for statement_.connection
+ public final Connection connection_;
+
+ //----------------------------- constants ------------------------------------
+
+ public final static int scrollOrientation_relative__ = 1;
+ public final static int scrollOrientation_absolute__ = 2;
+ public final static int scrollOrientation_after__ = 3;
+ public final static int scrollOrientation_before__ = 4;
+ public final static int scrollOrientation_prior__ = 5;
+ public final static int scrollOrientation_first__ = 6;
+ public final static int scrollOrientation_last__ = 7;
+ public final static int scrollOrientation_current__ = 8;
+ public final static int scrollOrientation_next__ = 0;
+
+ public final static int updatability_unknown__ = 0;
+ public final static int updatability_readOnly__ = 1;
+ public final static int updatability_delete__ = 2;
+ public final static int updatability_update__ = 4;
+
+ public final static int sensitivity_unknown__ = 0;
+ public final static int sensitivity_insensitive__ = 1;
+ public final static int sensitivity_sensitive_static__ = 2;
+ public final static int sensitivity_sensitive_dynamic__ = 3;
+
+ static final private int WAS_NULL = 1;
+ static final private int WAS_NOT_NULL = 2;
+ static final private int WAS_NULL_UNSET = 0;
+
+ static final public int NEXT_ROWSET = 1;
+ static final public int PREVIOUS_ROWSET = 2;
+ static final public int ABSOLUTE_ROWSET = 3;
+ static final public int FIRST_ROWSET = 4;
+ static final public int LAST_ROWSET = 5;
+ static final public int RELATIVE_ROWSET = 6;
+ static final public int REFRESH_ROWSET = 7;
+ // determines if a cursor is a:
+ // Return to Client - not to be read by the stored procedure only by client
+ // Return to Caller
+ public static final byte DDM_RETURN_CALLER = 0x01;
+ public static final byte DDM_RETURN_CLIENT = 0x02;
+
+ //-----------------------------state------------------------------------------
+
+ // Note:
+ // Result set meta data as described by the SQLDA is described in ColumnMetaData.
+
+ private int wasNull_ = WAS_NULL_UNSET;
+
+ // ResultSet returnability for Stored Procedure cursors
+ // determines if a cursor is a:
+ // Return to Client - not to be read by the stored procedure only by client
+ // Return to Caller - only calling JSP can read it, not the client
+ protected byte rsReturnability_ = DDM_RETURN_CLIENT;
+
+ // This means the client-side jdbc result set object is open.
+ boolean openOnClient_ = true;
+ // This means a server-side DERBY query section (cursor) for this result set is in the open state.
+ // A jdbc result set may remain open even after the server has closed its cursor
+ // (openOnClient=true, openOnServer=false); this is known as the "close-only" state.
+ public boolean openOnServer_ = true;
+
+ // there is a query terminating sqlca returned from the server when the server closes
+ // it's cursor and the client moves to the close-only state.
+ public Sqlca queryTerminatingSqlca_;
+
+ // Only true for forward cursors after next() returns false (+100).
+ // Used to prevent multiple commits for subsequent next() calls.
+ boolean autoCommitted_ = false;
+
+ // Before the first call to next() or any cursor positioning method, the cursor position is invalid
+ // and getter methods cannot be called.
+ // Also, if a cursor is exhausted (+100), the cursor position is invalid.
+ public boolean isValidCursorPosition_ = false;
+
+ public boolean cursorHold_;
+
+ // query instance identifier returned on open by uplevel servers.
+ // this value plus the package information uniquely identifies a query.
+ // it is 64 bits long and it's value is unarchitected.
+ public long queryInstanceIdentifier_ = 0;
+
+ public int resultSetType_;
+ public int resultSetConcurrency_;
+ public int resultSetHoldability_;
+ public boolean scrollable_ = false;
+ public int sensitivity_;
+ public boolean isRowsetCursor_ = false;
+ public boolean isBeforeFirst_ = true;
+ public boolean isAfterLast_ = false;
+ public boolean isFirst_ = false;
+ public boolean isLast_ = false;
+ public boolean rowsetContainsLastRow_ = false;
+ public Sqlca[] rowsetSqlca_;
+ public int fetchSize_;
+ public int fetchDirection_;
+
+ public long rowCount_ = -1;
+
+ protected long absolutePosition_ = 0; // absolute position of the current row
+ protected long firstRowInRowset_ = 0; // absolute position of the first row in the current rowset
+ protected long lastRowInRowset_ = 0; // absolute position of the last row in the current rowset
+ protected long currentRowInRowset_ = -1; // relative position to the first row in the current rowsetwel
+
+ protected long absoluteRowNumberForTheIntendedRow_;
+
+ // This variable helps keep track of whether cancelRowUpdates() should have any effect.
+ protected boolean updateRowCalled_ = false;
+ private boolean isOnInsertRow_ = false; // reserved for later
+ protected boolean isOnCurrentRow_ = true;
+ public int rowsReceivedInCurrentRowset_ = 0; // keep track of the number of rows received in the
+ // current rowset so far
+
+ // maybe be able to consolidate with rowsReceivedInCurrentRowset_
+ // Could use the rowsReceivedInCurrentRowset_ flag. But since we are going to set it to the
+ // fetchSize and decrement it each time we successfully receiveds a row, the name will be confusing.
+ // Fetch size can be changed in the middle of a rowset, and since we don't pre-parse all the rows \
+ // for forward-only cursors like we do for scrollable cursors, we will lose the original fetchSize
+ // when it's reset. By decrementing rowsYetToBeReceivedInRowset_, when we come across a fetch
+ // request, if rowsYetToBeReceivedInRowset_ is 0, then we can fetch using the "new" fetchSize,
+ // otherwise, we will use rowsYetToBeReceivedInRowset_ to complete the rowset.
+ public int rowsYetToBeReceivedForRowset_ = 0; // keep track of the number of rows still need to
+ // be received to complete the rowset
+
+ private Object updatedColumns_[];
+
+ // Keeps track of whether a column has been updated. If a column is updated to null,
+ // the object array updatedColumns_ entry is null, and we will use this array to distinguish
+ // between column not updated and column updated to null.
+ private boolean columnUpdated_[];
+
+ public PreparedStatement preparedStatementForUpdate_;
+ public PreparedStatement preparedStatementForDelete_;
+
+ // Nesting level of the result set in a stored procedure
+ public int nestingLevel_ = -1;
+
+ // Whenever a commit occurs, it unpositions the cursor on the server. We need to
+ // reposition the cursor before updating/deleting again. This flag will be set to true
+ // whenever a commit happens, and reset to false again after we repositoin the cursor.
+ public boolean cursorUnpositionedOnServer_ = false;
+
+ //---------------------constructors/finalizer---------------------------------
+
+ protected ResultSet(Agent agent,
+ Statement statement,
+ Cursor cursor,
+ int resultSetType,
+ int resultSetConcurrency,
+ int resultSetHoldability) {
+ agent_ = agent;
+ statement_ = statement;
+ connection_ = statement_.connection_;
+ cursor_ = cursor;
+ if (cursor_ != null) {
+ cursor_.maxFieldSize_ = statement_.maxFieldSize_;
+ }
+ resultSetType_ = resultSetType;
+ resultSetConcurrency_ = resultSetConcurrency;
+ resultSetHoldability_ = resultSetHoldability;
+ fetchDirection_ = statement_.fetchDirection_;
+ fetchSize_ = statement_.fetchSize_;
+
+ // Only set the warning if actual resultSetType returned by the server is less
+ // than the application requested resultSetType.
+ // TYPE_FORWARD_ONLY = 1003
+ // TYPE_SCROLL_INSENSITIVE = 1004
+ // TYPE_SCROLL_SENSITIVE = 1005
+ if (resultSetType_ < statement_.resultSetType_) {
+ statement_.accumulateWarning
+ (new SqlWarning(agent_.logWriter_, "Unable to open resultSet type " +
+ statement_.resultSetType_ + "." +
+ " ResultSet type " + resultSetType_ + " opened."));
+ }
+
+ // Only set the warning if actual resultSetConcurrency returned by the server is
+ // less than the application requested resultSetConcurrency.
+ // CONCUR_READ_ONLY = 1007
+ // CONCUR_UPDATABLE = 1008
+ if (resultSetConcurrency_ < statement_.resultSetConcurrency_) {
+ statement_.accumulateWarning
+ (new SqlWarning(agent_.logWriter_, "Unable to open ResultSet with concurrency " +
+ statement_.resultSetConcurrency_ + "." +
+ " ResultSet concurrency " + resultSetConcurrency_ + " is used."));
+ }
+
+ listenToUnitOfWork();
+ }
+
+ // ---------------------------jdbc 1------------------------------------------
-{
- //---------------------navigational members-----------------------------------
+ public final boolean next() throws SqlException {
+ synchronized (connection_) {
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceEntry(this, "next");
+ }
+ boolean isValidCursorPosition = nextX();
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceExit(this, "next", isValidCursorPosition);
+ }
+ return isValidCursorPosition;
+ }
+ }
- public Statement statement_;
- public ColumnMetaData resultSetMetaData_; // As obtained from the SQLDA
- private SqlWarning warnings_;
- public Cursor cursor_;
- protected Agent agent_;
-
- public Section generatedSection_ = null;
-
- //---------------------navigational cheat-links-------------------------------
- // Cheat-links are for convenience only, and are not part of the conceptual model.
- // Warning:
- // Cheat-links should only be defined for invariant state data.
- // That is, the state data is set by the constructor and never changes.
-
- // Alias for statement_.connection
- public final Connection connection_;
-
- //----------------------------- constants ------------------------------------
-
- public final static int scrollOrientation_relative__ = 1;
- public final static int scrollOrientation_absolute__ = 2;
- public final static int scrollOrientation_after__ = 3;
- public final static int scrollOrientation_before__ = 4;
- public final static int scrollOrientation_prior__ = 5;
- public final static int scrollOrientation_first__ = 6;
- public final static int scrollOrientation_last__ = 7;
- public final static int scrollOrientation_current__ = 8;
- public final static int scrollOrientation_next__ = 0;
-
- public final static int updatability_unknown__ = 0;
- public final static int updatability_readOnly__ = 1;
- public final static int updatability_delete__ = 2;
- public final static int updatability_update__ = 4;
-
- public final static int sensitivity_unknown__ = 0;
- public final static int sensitivity_insensitive__ = 1;
- public final static int sensitivity_sensitive_static__ = 2;
- public final static int sensitivity_sensitive_dynamic__ = 3;
-
- static final private int WAS_NULL = 1;
- static final private int WAS_NOT_NULL = 2;
- static final private int WAS_NULL_UNSET = 0;
-
- static final public int NEXT_ROWSET = 1;
- static final public int PREVIOUS_ROWSET = 2;
- static final public int ABSOLUTE_ROWSET = 3;
- static final public int FIRST_ROWSET = 4;
- static final public int LAST_ROWSET = 5;
- static final public int RELATIVE_ROWSET = 6;
- static final public int REFRESH_ROWSET = 7;
- // determines if a cursor is a:
- // Return to Client - not to be read by the stored procedure only by client
- // Return to Caller
- public static final byte DDM_RETURN_CALLER = 0x01;
- public static final byte DDM_RETURN_CLIENT = 0x02;
-
- //-----------------------------state------------------------------------------
-
- // Note:
- // Result set meta data as described by the SQLDA is described in ColumnMetaData.
-
- private int wasNull_ = WAS_NULL_UNSET;
-
- // ResultSet returnability for Stored Procedure cursors
- // determines if a cursor is a:
- // Return to Client - not to be read by the stored procedure only by client
- // Return to Caller - only calling JSP can read it, not the client
- protected byte rsReturnability_ = DDM_RETURN_CLIENT;
-
- // This means the client-side jdbc result set object is open.
- boolean openOnClient_ = true;
- // This means a server-side DERBY query section (cursor) for this result set is in the open state.
- // A jdbc result set may remain open even after the server has closed its cursor
- // (openOnClient=true, openOnServer=false); this is known as the "close-only" state.
- public boolean openOnServer_ = true;
-
- // there is a query terminating sqlca returned from the server when the server closes
- // it's cursor and the client moves to the close-only state.
- public Sqlca queryTerminatingSqlca_;
-
- // Only true for forward cursors after next() returns false (+100).
- // Used to prevent multiple commits for subsequent next() calls.
- boolean autoCommitted_ = false;
-
- // Before the first call to next() or any cursor positioning method, the cursor position is invalid
- // and getter methods cannot be called.
- // Also, if a cursor is exhausted (+100), the cursor position is invalid.
- public boolean isValidCursorPosition_ = false;
-
- public boolean cursorHold_;
-
- // query instance identifier returned on open by uplevel servers.
- // this value plus the package information uniquely identifies a query.
- // it is 64 bits long and it's value is unarchitected.
- public long queryInstanceIdentifier_ = 0;
-
- public int resultSetType_;
- public int resultSetConcurrency_;
- public int resultSetHoldability_;
- public boolean scrollable_ = false;
- public int sensitivity_;
- public boolean isRowsetCursor_ = false;
- public boolean isBeforeFirst_ = true;
- public boolean isAfterLast_ = false;
- public boolean isFirst_ = false;
- public boolean isLast_ = false;
- public boolean rowsetContainsLastRow_ = false;
- public Sqlca[] rowsetSqlca_;
- public int fetchSize_;
- public int fetchDirection_;
-
- public long rowCount_ = -1;
-
- protected long absolutePosition_ = 0; // absolute position of the current row
- protected long firstRowInRowset_ = 0; // absolute position of the first row in the current rowset
- protected long lastRowInRowset_ = 0; // absolute position of the last row in the current rowset
- protected long currentRowInRowset_ = -1; // relative position to the first row in the current rowsetwel
-
- protected long absoluteRowNumberForTheIntendedRow_;
-
- // This variable helps keep track of whether cancelRowUpdates() should have any effect.
- protected boolean updateRowCalled_ = false;
- private boolean isOnInsertRow_ = false; // reserved for later
- protected boolean isOnCurrentRow_ = true;
- public int rowsReceivedInCurrentRowset_ = 0; // keep track of the number of rows received in the
- // current rowset so far
-
- // maybe be able to consolidate with rowsReceivedInCurrentRowset_
- // Could use the rowsReceivedInCurrentRowset_ flag. But since we are going to set it to the
- // fetchSize and decrement it each time we successfully receiveds a row, the name will be confusing.
- // Fetch size can be changed in the middle of a rowset, and since we don't pre-parse all the rows \
- // for forward-only cursors like we do for scrollable cursors, we will lose the original fetchSize
- // when it's reset. By decrementing rowsYetToBeReceivedInRowset_, when we come across a fetch
- // request, if rowsYetToBeReceivedInRowset_ is 0, then we can fetch using the "new" fetchSize,
- // otherwise, we will use rowsYetToBeReceivedInRowset_ to complete the rowset.
- public int rowsYetToBeReceivedForRowset_ = 0; // keep track of the number of rows still need to
- // be received to complete the rowset
-
- private Object updatedColumns_[];
-
- // Keeps track of whether a column has been updated. If a column is updated to null,
- // the object array updatedColumns_ entry is null, and we will use this array to distinguish
- // between column not updated and column updated to null.
- private boolean columnUpdated_[];
-
- public PreparedStatement preparedStatementForUpdate_;
- public PreparedStatement preparedStatementForDelete_;
-
- // Nesting level of the result set in a stored procedure
- public int nestingLevel_ = -1;
-
- // Whenever a commit occurs, it unpositions the cursor on the server. We need to
- // reposition the cursor before updating/deleting again. This flag will be set to true
- // whenever a commit happens, and reset to false again after we repositoin the cursor.
- public boolean cursorUnpositionedOnServer_ = false;
-
- //---------------------constructors/finalizer---------------------------------
-
- protected ResultSet (Agent agent,
- Statement statement,
- Cursor cursor,
- int resultSetType,
- int resultSetConcurrency,
- int resultSetHoldability)
- {
- agent_ = agent;
- statement_ = statement;
- connection_ = statement_.connection_;
- cursor_ = cursor;
- if (cursor_ != null) cursor_.maxFieldSize_ = statement_.maxFieldSize_;
- resultSetType_ = resultSetType;
- resultSetConcurrency_ = resultSetConcurrency;
- resultSetHoldability_ = resultSetHoldability;
- fetchDirection_ = statement_.fetchDirection_;
- fetchSize_ = statement_.fetchSize_;
-
- // Only set the warning if actual resultSetType returned by the server is less
- // than the application requested resultSetType.
- // TYPE_FORWARD_ONLY = 1003
- // TYPE_SCROLL_INSENSITIVE = 1004
- // TYPE_SCROLL_SENSITIVE = 1005
- if (resultSetType_ < statement_.resultSetType_)
- statement_.accumulateWarning
- (new SqlWarning (agent_.logWriter_, "Unable to open resultSet type " +
- statement_.resultSetType_ + "." +
- " ResultSet type " + resultSetType_ + " opened."));
-
- // Only set the warning if actual resultSetConcurrency returned by the server is
- // less than the application requested resultSetConcurrency.
- // CONCUR_READ_ONLY = 1007
- // CONCUR_UPDATABLE = 1008
- if (resultSetConcurrency_ < statement_.resultSetConcurrency_)
- statement_.accumulateWarning
- (new SqlWarning (agent_.logWriter_, "Unable to open ResultSet with concurrency " +
- statement_.resultSetConcurrency_ + "." +
- " ResultSet concurrency " + resultSetConcurrency_ + " is used."));
-
- listenToUnitOfWork();
- }
-
- // ---------------------------jdbc 1------------------------------------------
-
- public final boolean next () throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "next");
- boolean isValidCursorPosition = nextX();
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "next", isValidCursorPosition);
- return isValidCursorPosition;
- }
- }
-
- // used by DBMD
- boolean nextX () throws SqlException
- {
- checkForClosedResultSet ();
- clearWarningsX ();
-
- wasNull_ = ResultSet.WAS_NULL_UNSET;
-
- // discard all previous updates when moving the cursor
- resetUpdatedColumns ();
-
- // for TYPE_FORWARD_ONLY ResultSet, just call cursor.next()
- if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
- // cursor is null for singleton selects that do not return data.
- isValidCursorPosition_ = (cursor_ == null) ? false : cursor_.next ();
-
- // for forward-only cursors, if qryrowset was specificed on OPNQRY or EXCSQLSTT,
- // then we must count the rows returned in the rowset to make sure we received a
- // complete rowset. if not, we need to complete the rowset on the next fetch.
- if (fetchSize_ != 0) {
- if (rowsYetToBeReceivedForRowset_ == 0) rowsYetToBeReceivedForRowset_ = fetchSize_;
- if (isValidCursorPosition_) rowsYetToBeReceivedForRowset_--;
- }
-
- // Auto-commit semantics for exhausted cursors follows.
- // From Connection.setAutoCommit() javadoc:
- // The commit occurs when the statement completes or the next execute occurs, whichever comes first.
- // In the case of statements returning a ResultSet object, the statement completes when the
- // last row of the ResultSet object has been retrieved or the ResultSet object has been closed.
- // In advanced cases, a single statement may return multiple results as well as output parameter values.
- // In these cases, the commit occurs when all results and output parameter values have been retrieved.
- // we will check to see if the forward only result set has gone past the end,
- // we will close the result set, the autocommit logic is in the closeX() method
+ // used by DBMD
+ boolean nextX() throws SqlException {
+ checkForClosedResultSet();
+ clearWarningsX();
+
+ wasNull_ = ResultSet.WAS_NULL_UNSET;
+
+ // discard all previous updates when moving the cursor
+ resetUpdatedColumns();
+
+ // for TYPE_FORWARD_ONLY ResultSet, just call cursor.next()
+ if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
+ // cursor is null for singleton selects that do not return data.
+ isValidCursorPosition_ = (cursor_ == null) ? false : cursor_.next();
+
+ // for forward-only cursors, if qryrowset was specificed on OPNQRY or EXCSQLSTT,
+ // then we must count the rows returned in the rowset to make sure we received a
+ // complete rowset. if not, we need to complete the rowset on the next fetch.
+ if (fetchSize_ != 0) {
+ if (rowsYetToBeReceivedForRowset_ == 0) {
+ rowsYetToBeReceivedForRowset_ = fetchSize_;
+ }
+ if (isValidCursorPosition_) {
+ rowsYetToBeReceivedForRowset_--;
+ }
+ }
+
+ // Auto-commit semantics for exhausted cursors follows.
+ // From Connection.setAutoCommit() javadoc:
+ // The commit occurs when the statement completes or the next execute occurs, whichever comes first.
+ // In the case of statements returning a ResultSet object, the statement completes when the
+ // last row of the ResultSet object has been retrieved or the ResultSet object has been closed.
+ // In advanced cases, a single statement may return multiple results as well as output parameter values.
+ // In these cases, the commit occurs when all results and output parameter values have been retrieved.
+ // we will check to see if the forward only result set has gone past the end,
+ // we will close the result set, the autocommit logic is in the closeX() method
// if (!isValidCursorPosition_ && // We've gone past the end (+100)
// cursor_ != null) {
- if ((!isValidCursorPosition_ && cursor_ != null) ||
- (statement_.maxRows_ > 0 && cursor_.rowsRead_ > statement_.maxRows_)) {
- isValidCursorPosition_ = false;
+ if ((!isValidCursorPosition_ && cursor_ != null) ||
+ (statement_.maxRows_ > 0 && cursor_.rowsRead_ > statement_.maxRows_)) {
+ isValidCursorPosition_ = false;
+
+ // if not on a valid row and the query is closed at the server.
+ // check for an error which may have caused the cursor to terminate.
+ // if there were no more rows because of an error, then this method
+ // should throw an SqlException rather than just returning false.
+ // note: closeX is still called and this will cause the
+ // result set to be closed on the client. any additional calls to
+ // next() will fail checkForClosedResultSet(), the query terminating exception is
+ // only thrown once.
+ // depending on how this works with scrollable cursors, there may be
+ // a better way/more common place for this logic.
+ SqlException sqlException = null;
+ if (!openOnServer_) {
+ int sqlcode = Utils.getSqlcodeFromSqlca(queryTerminatingSqlca_);
+ if (sqlcode > 0 && sqlcode != 100) {
+ accumulateWarning(new SqlWarning(agent_.logWriter_, queryTerminatingSqlca_));
+ } else if (sqlcode < 0) {
+ sqlException = new SqlException(agent_.logWriter_, queryTerminatingSqlca_);
+ }
+ }
+ try {
+ closeX(); // the auto commit logic is in closeX()
+ } catch (SqlException sqle) {
+ sqlException = Utils.accumulateSQLException(sqle, sqlException);
+ }
+ if (sqlException != null) {
+ throw sqlException;
+ }
+ }
+ }
- // if not on a valid row and the query is closed at the server.
- // check for an error which may have caused the cursor to terminate.
- // if there were no more rows because of an error, then this method
- // should throw an SqlException rather than just returning false.
- // note: closeX is still called and this will cause the
- // result set to be closed on the client. any additional calls to
- // next() will fail checkForClosedResultSet(), the query terminating exception is
- // only thrown once.
- // depending on how this works with scrollable cursors, there may be
- // a better way/more common place for this logic.
- SqlException sqlException = null;
- if (!openOnServer_) {
- int sqlcode = Utils.getSqlcodeFromSqlca (queryTerminatingSqlca_);
- if (sqlcode > 0 && sqlcode != 100) {
- accumulateWarning(new SqlWarning (agent_.logWriter_, queryTerminatingSqlca_));
- }
- else if (sqlcode < 0)
- sqlException = new SqlException (agent_.logWriter_, queryTerminatingSqlca_);
+ // for scrollable ResultSet's,
+ // if the "next" request is still fetching within the current rowset,
+ // update column info from cache and increment the current row index
+ // else
+ // fetch the next rowset from the server
+ else {
+
+ // These flags will only be used for dynamic cursors where we don't know the row count
+ // and can't keep track of the absolute position of the cursor.
+ isAfterLast_ = false;
+ isLast_ = false;
+
+ // if the next row is still within the current rowset
+ if (rowIsInCurrentRowset(firstRowInRowset_ + currentRowInRowset_ + 1, scrollOrientation_next__)) {
+ isValidCursorPosition_ = true;
+ currentRowInRowset_++;
+ } else {
+ checkAndThrowReceivedQueryTerminatingException();
+ isValidCursorPosition_ = getNextRowset();
+ }
+
+ if (isValidCursorPosition_) {
+ updateColumnInfoFromCache();
+ // check if there is a non-null SQLCA for the current row for rowset cursors
+ checkRowsetSqlca();
+ if (isBeforeFirst_) {
+ isFirst_ = true;
+ }
+ isBeforeFirst_ = false;
+ } else {
+ isFirst_ = false;
+ return isValidCursorPosition_;
+ }
+ }
+
+ // for forward-only cursors, check if rowsRead_ > maxRows_.
+ // for scrollable cursors, check if absolute row number > maxRows_.
+ // maxRows_ will be ignored by sensitive dynamic cursors since we don't know the rowCount
+ if (!openOnClient_) {
+ isValidCursorPosition_ = false;
+ } else if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0 &&
+ (firstRowInRowset_ + currentRowInRowset_ > statement_.maxRows_)) {
+ isValidCursorPosition_ = false;
+ }
+ return isValidCursorPosition_;
+ }
+
+
+ public void close() throws SqlException {
+ synchronized (connection_) {
+ if (agent_.loggingEnabled()) {
+ agent_.logWriter_.traceEntry(this, "close");
+ }
+ closeX();
+ }
+ }
+
+ // TO DO: when parseEndqryrm() notifies common w/ endQueryCloseOnlyEvent() we need to mark something
+ // that we later check to drive a commit.
+ // An untraced version of close()
+ public final void closeX() throws SqlException {
+ if (!openOnClient_) {
+ return;
}
try {
- closeX(); // the auto commit logic is in closeX()
+ if (openOnServer_) {
+ flowCloseAndAutoCommitIfNotAutoCommitted();
+ } else {
+ flowAutoCommitIfNotAutoCommitted(); // in case of early close
+ }
+ } finally {
+ markClosed();
+ connection_.CommitAndRollbackListeners_.remove(this);
}
- catch (SqlException sqle) {
- sqlException = Utils.accumulateSQLException (sqle, sqlException);
+
+ flowAutoCommitIfLastOpenMultipleResultSetWasJustClosed();
+ if (statement_.openOnClient_ && statement_.isCatalogQuery_) {
+ statement_.closeX();
}
- if (sqlException != null)
- throw sqlException;
- }
- }
-
- // for scrollable ResultSet's,
- // if the "next" request is still fetching within the current rowset,
- // update column info from cache and increment the current row index
- // else
- // fetch the next rowset from the server
- else {
-
- // These flags will only be used for dynamic cursors where we don't know the row count
- // and can't keep track of the absolute position of the cursor.
- isAfterLast_ = false;
- isLast_ = false;
-
- // if the next row is still within the current rowset
- if (rowIsInCurrentRowset (firstRowInRowset_+currentRowInRowset_+1, scrollOrientation_next__)) {
- isValidCursorPosition_ = true;
- currentRowInRowset_++;
- }
- else {
- checkAndThrowReceivedQueryTerminatingException();
- isValidCursorPosition_ = getNextRowset ();
- }
- if (isValidCursorPosition_) {
- updateColumnInfoFromCache ();
- // check if there is a non-null SQLCA for the current row for rowset cursors
- checkRowsetSqlca ();
- if (isBeforeFirst_) isFirst_ = true;
- isBeforeFirst_ = false;
- }
- else {
- isFirst_ = false;
- return isValidCursorPosition_;
- }
+ nullDataForGC();
}
- // for forward-only cursors, check if rowsRead_ > maxRows_.
- // for scrollable cursors, check if absolute row number > maxRows_.
- // maxRows_ will be ignored by sensitive dynamic cursors since we don't know the rowCount
- if (!openOnClient_) {
- isValidCursorPosition_ = false;
- }
- else if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0 &&
- (firstRowInRowset_+currentRowInRowset_ > statement_.maxRows_)) {
- isValidCursorPosition_ = false;
- }
- return isValidCursorPosition_;
- }
-
-
- public void close () throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "close");
- closeX();
- }
- }
-
- // TO DO: when parseEndqryrm() notifies common w/ endQueryCloseOnlyEvent() we need to mark something
- // that we later check to drive a commit.
- // An untraced version of close()
- public final void closeX () throws SqlException
- {
- if (!openOnClient_) return;
- try {
- if (openOnServer_) flowCloseAndAutoCommitIfNotAutoCommitted();
- else flowAutoCommitIfNotAutoCommitted(); // in case of early close
- }
- finally {
- markClosed();
- connection_.CommitAndRollbackListeners_.remove (this);
- }
-
- flowAutoCommitIfLastOpenMultipleResultSetWasJustClosed ();
- if (statement_.openOnClient_ && statement_.isCatalogQuery_) statement_.closeX();
-
- nullDataForGC();
- }
-
- public void nullDataForGC()
- {
- // This method is called by closeX(). We cannot call this if cursor is cached,
- // otherwise it will cause NullPointerException's when cursor is reused.
- // Cursor is only cached for PreparedStatement's.
- if (cursor_ != null && !statement_.isPreparedStatement_)
- cursor_.nullDataForGC();
- cursor_ = null;
- resultSetMetaData_ = null;
- }
-
- void flowCloseAndAutoCommitIfNotAutoCommitted() throws SqlException
- {
- agent_.beginWriteChain (statement_);
- writeCloseAndAutoCommitIfNotAutoCommitted();
- agent_.flow (statement_);
- readCloseAndAutoCommitIfNotAutoCommitted();
- agent_.endReadChain();
- }
-
- private void writeCloseAndAutoCommitIfNotAutoCommitted() throws SqlException
- {
- // set autoCommitted_ to false so commit will flow following
- // close cursor if autoCommit is true.
- autoCommitted_ = false;
- if (generatedSection_ == null) { // none call statement result set case
- writeCursorClose_ (statement_.section_);
- writeAutoCommitIfNotAutoCommitted();
- }
- else { // call statement result set(s) case
- writeCursorClose_ (generatedSection_);
- }
- }
-
- private void readCloseAndAutoCommitIfNotAutoCommitted() throws SqlException
- {
- if (generatedSection_ == null) { // none call statement result set case
- readCursorClose_ ();
- readAutoCommitIfNotAutoCommitted();
- }
- else { // call statement result set(s) case
- readCursorClose_ ();
- }
- }
-
- void writeClose() throws SqlException
- {
- // set autoCommitted_ to false so commit will flow following
- // close cursor if autoCommit is true.
- autoCommitted_ = false;
- if (generatedSection_ == null) { // none call statement result set case
- writeCursorClose_ (statement_.section_);
- }
- else { // call statement result set(s) case
- writeCursorClose_ (generatedSection_);
- }
- }
-
- void readClose() throws SqlException
- {
- try {
- if (generatedSection_ == null) { // none call statement result set case
- readCursorClose_ ();
- }
- else { // call statement result set(s) case
- readCursorClose_ ();
- }
- }
- finally {
- markClosed();
- }
- }
-
- void flowAutoCommitIfNotAutoCommitted () throws SqlException
- {
- if (generatedSection_ == null && connection_.autoCommit_ && !autoCommitted_) {
- connection_.flowAutoCommit ();
- markAutoCommitted();
- }
- }
-
- // precondition: transaction state allows for auto commit to generate flow
- private void writeAutoCommitIfNotAutoCommitted () throws SqlException
- {
- if (connection_.autoCommit_ && !autoCommitted_) connection_.writeAutoCommit ();
- }
-
- private void readAutoCommitIfNotAutoCommitted () throws SqlException
- {
- if (connection_.autoCommit_ && !autoCommitted_) {
- connection_.readAutoCommit ();
- markAutoCommitted();
- }
- }
-
- private void flowAutoCommitIfLastOpenMultipleResultSetWasJustClosed () throws SqlException
- {
- // After this call, the generatedSection_ is reset to null to avoid repeating the commit.
- if (generatedSection_ != null && statement_ != null && statement_.resultSetList_ != null ) {
- int count = 0;
- for (int i = 0; i < statement_.resultSetList_.length; i++) {
- if (statement_.resultSetList_[i] == null) {
- count++;
+ public void nullDataForGC() {
+ // This method is called by closeX(). We cannot call this if cursor is cached,
+ // otherwise it will cause NullPointerException's when cursor is reused.
+ // Cursor is only cached for PreparedStatement's.
+ if (cursor_ != null && !statement_.isPreparedStatement_) {
+ cursor_.nullDataForGC();
}
- }
- if (count == statement_.resultSetList_.length) {
- if (connection_.autoCommit_ && !autoCommitted_) {
- connection_.flowAutoCommit();
- markAutoCommitted();
+ cursor_ = null;
+ resultSetMetaData_ = null;
+ }
+
+ void flowCloseAndAutoCommitIfNotAutoCommitted() throws SqlException {
+ agent_.beginWriteChain(statement_);
+ writeCloseAndAutoCommitIfNotAutoCommitted();
+ agent_.flow(statement_);
+ readCloseAndAutoCommitIfNotAutoCommitted();
+ agent_.endReadChain();
+ }
+
+ private void writeCloseAndAutoCommitIfNotAutoCommitted() throws SqlException {
+ // set autoCommitted_ to false so commit will flow following
+ // close cursor if autoCommit is true.
+ autoCommitted_ = false;
+ if (generatedSection_ == null) { // none call statement result set case
+ writeCursorClose_(statement_.section_);
+ writeAutoCommitIfNotAutoCommitted();
+ } else { // call statement result set(s) case
+ writeCursorClose_(generatedSection_);
}
- }
}
- generatedSection_ = null; // this is prevent a subsequent close() call from doing another autocommit.
- }
- public boolean wasNull () throws SqlException
- {
-
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "wasNull");
- checkForClosedResultSet ();
-
- if (wasNull_ == ResultSet.WAS_NULL_UNSET)
- throw new SqlException (agent_.logWriter_, "Invalid operation: wasNull() called with no data retrieved");
-
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "wasNull", wasNull_ == ResultSet.WAS_NULL);
- return wasNull_ == ResultSet.WAS_NULL;
- }
-
- //------------------- getters on column index --------------------------------
-
- // Live life on the edge and run unsynchronized
- public boolean getBoolean (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBoolean", column);
- checkGetterPreconditions (column);
- boolean result = false;
- if (wasNonNullSensitiveUpdate (column))
- result = agent_.crossConverters_.setBooleanFromObject (updatedColumns_[column-1],
- resultSetMetaData_.types_[column-1]);
- else
- result = isNull (column) ? false : cursor_.getBoolean (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBoolean", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public byte getByte (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getByte", column);
- checkGetterPreconditions (column);
- byte result = 0;
- if (wasNonNullSensitiveUpdate (column))
- result = agent_.crossConverters_.setByteFromObject (updatedColumns_[column-1],
- resultSetMetaData_.types_[column-1]);
- else
- result = isNull (column) ? 0 : cursor_.getByte (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getByte", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public short getShort (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getShort", column);
- checkGetterPreconditions (column);
- short result = 0;
- if (wasNonNullSensitiveUpdate (column))
- result = ((Short) agent_.crossConverters_.setObject (java.sql.Types.SMALLINT,
- updatedColumns_[column-1])).shortValue();
- else
- result = isNull (column) ? 0 : cursor_.getShort (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getShort", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public int getInt (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getInt", column);
- checkGetterPreconditions (column);
- int result = 0;
- if (wasNonNullSensitiveUpdate (column))
- result = ((Integer) agent_.crossConverters_.setObject (java.sql.Types.INTEGER,
- updatedColumns_[column-1])).intValue();
- else
- result = isNull (column) ? 0 : cursor_.getInt (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getInt", result);
- setWasNull (column); // this is placed here close to the return to minimize risk of race condition.
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public long getLong (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getLong", column);
- checkGetterPreconditions (column);
- long result = 0;
- if (wasNonNullSensitiveUpdate (column))
- result = ((Long) agent_.crossConverters_.setObject (java.sql.Types.BIGINT,
- updatedColumns_[column-1])).longValue();
- else
- result = isNull (column) ? 0 : cursor_.getLong (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getLong", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public float getFloat (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getFloat", column);
- checkGetterPreconditions (column);
- float result = 0;
- if (wasNonNullSensitiveUpdate (column))
- result = ((Float) agent_.crossConverters_.setObject (java.sql.Types.REAL,
- updatedColumns_[column-1])).floatValue();
- else
- result = isNull (column) ? 0 : cursor_.getFloat (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getFloat", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public double getDouble (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDouble", column);
- checkGetterPreconditions (column);
- double result = 0;
- if (wasNonNullSensitiveUpdate (column))
- result = ((Double) agent_.crossConverters_.setObject (java.sql.Types.DOUBLE,
- updatedColumns_[column-1])).doubleValue();
- else
- result = isNull (column) ? 0 : cursor_.getDouble (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getDouble", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.math.BigDecimal getBigDecimal (int column, int scale) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedEntry (this, "getBigDecimal", column, scale);
- checkGetterPreconditions (column);
- java.math.BigDecimal result = null;
- if (wasNonNullSensitiveUpdate (column))
- result =
- ((java.math.BigDecimal)agent_.crossConverters_.setObject (java.sql.Types.DECIMAL,
- updatedColumns_[column-1])).setScale (scale, java.math.BigDecimal.ROUND_DOWN);
- else
- result =
- isNull (column) ? null : cursor_.getBigDecimal (column).setScale (scale, java.math.BigDecimal.ROUND_DOWN);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedExit (this, "getBigDecimal", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.math.BigDecimal getBigDecimal (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBigDecimal", column);
- checkGetterPreconditions (column);
- java.math.BigDecimal result = null;
- if (wasNonNullSensitiveUpdate (column))
- result =
- (java.math.BigDecimal)agent_.crossConverters_.setObject (java.sql.Types.DECIMAL,
- updatedColumns_[column-1]);
- else
- result = isNull (column) ? null : cursor_.getBigDecimal (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBigDecimal", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Date getDate (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDate", column);
- checkGetterPreconditions (column);
- java.sql.Date result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = (java.sql.Date) agent_.crossConverters_.setObject (java.sql.Types.DATE, updatedColumns_[column-1]);
- else
- result = isNull (column) ? null : cursor_.getDate (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getDate", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Date getDate (int column, java.util.Calendar calendar) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDate", column, calendar);
- if (calendar == null) throw new SqlException (agent_.logWriter_, "Invalid parameter: calendar is null");
- java.sql.Date date = getDate (column);
- if (date != null) {
- java.util.Calendar targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
- targetCalendar.clear();
- targetCalendar.setTime(date);
- java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
- defaultCalendar.clear();
- defaultCalendar.setTime(date);
- long timeZoneOffset =
- targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET) +
- targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
- date.setTime (date.getTime() - timeZoneOffset);
- }
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getDate", date);
- return date;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Time getTime (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTime", column);
- checkGetterPreconditions (column);
- java.sql.Time result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = (java.sql.Time) agent_.crossConverters_.setObject (java.sql.Types.TIME, updatedColumns_[column-1]);
- else
- result = isNull (column) ? null : cursor_.getTime (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getTime", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Time getTime (int column, java.util.Calendar calendar) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTime", column, calendar);
- if (calendar == null) throw new SqlException (agent_.logWriter_, "Invalid parameter: calendar is null");
- java.sql.Time time = getTime (column);
- if (time != null) {
- java.util.Calendar targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
- targetCalendar.clear();
- targetCalendar.setTime(time);
- java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
- defaultCalendar.clear();
- defaultCalendar.setTime(time);
- long timeZoneOffset =
- targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET) +
- targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
- time.setTime (time.getTime() - timeZoneOffset);
- }
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getTime", time);
- return time;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Timestamp getTimestamp (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTimestamp", column);
- checkGetterPreconditions (column);
- java.sql.Timestamp result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = (java.sql.Timestamp) agent_.crossConverters_.setObject (java.sql.Types.TIMESTAMP, updatedColumns_[column-1]);
- else
- result = isNull (column) ? null : cursor_.getTimestamp (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getTimestamp", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Timestamp getTimestamp (int column, java.util.Calendar calendar) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTimestamp", column, calendar);
- if (calendar == null) throw new SqlException (agent_.logWriter_, "Invalid parameter: calendar is null");
- java.sql.Timestamp timestamp = getTimestamp (column);
- if (timestamp != null) {
- int nano = timestamp.getNanos();
- java.util.Calendar targetCalendar = java.util.Calendar.getInstance(calendar.getTimeZone());
- targetCalendar.clear();
- targetCalendar.setTime(timestamp);
- java.util.Calendar defaultCalendar = java.util.Calendar.getInstance();
- defaultCalendar.clear();
- defaultCalendar.setTime(timestamp);
- long timeZoneOffset =
- targetCalendar.get(java.util.Calendar.ZONE_OFFSET) - defaultCalendar.get(java.util.Calendar.ZONE_OFFSET) +
- targetCalendar.get(java.util.Calendar.DST_OFFSET) - defaultCalendar.get(java.util.Calendar.DST_OFFSET);
- timestamp.setTime (timestamp.getTime() - timeZoneOffset);
- timestamp.setNanos (nano);
- }
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getTimestamp", timestamp);
- return timestamp;
- }
-
- // Live life on the edge and run unsynchronized
- public String getString (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getString", column);
- checkGetterPreconditions (column);
- String result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = (String) agent_.crossConverters_.setObject (java.sql.Types.CHAR, updatedColumns_[column-1]);
- else
- result = isNull (column) ? null : cursor_.getString (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getString", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public byte[] getBytes (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBytes", column);
- checkGetterPreconditions (column);
- byte[] result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = (byte[]) agent_.crossConverters_.setObject (java.sql.Types.BINARY, updatedColumns_[column-1]);
- else
- result = isNull (column) ? null : cursor_.getBytes (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBytes", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.io.InputStream getBinaryStream (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBinaryStream", column);
- checkGetterPreconditions (column);
- java.io.InputStream result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = new java.io.ByteArrayInputStream (
- (byte[]) agent_.crossConverters_.setObject (java.sql.Types.BINARY, updatedColumns_[column-1]));
- else
- result = isNull (column) ? null : cursor_.getBinaryStream (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBinaryStream", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.io.InputStream getAsciiStream (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getAsciiStream", column);
- checkGetterPreconditions (column);
- java.io.InputStream result = null;
- if (wasNonNullSensitiveUpdate (column)) {
- try {
- result = new java.io.ByteArrayInputStream
- (((String) agent_.crossConverters_.setObject (java.sql.Types.CHAR,
- updatedColumns_[column-1])).getBytes ("US-ASCII"));
- }
- catch (java.io.UnsupportedEncodingException e) {
- throw new SqlException (agent_.logWriter_, e, e.getMessage());
- }
- }
- else
- result = isNull (column) ? null : cursor_.getAsciiStream (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getAsciiStream", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.io.InputStream getUnicodeStream (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedEntry (this, "getUnicodeStream", column);
- checkGetterPreconditions (column);
- java.io.InputStream result = null;
- if (wasNonNullSensitiveUpdate (column)) {
+ private void readCloseAndAutoCommitIfNotAutoCommitted() throws SqlException {
+ if (generatedSection_ == null) { // none call statement result set case
+ readCursorClose_();
+ readAutoCommitIfNotAutoCommitted();
+ } else { // call statement result set(s) case
+ readCursorClose_();
+ }
+ }
+
+ void writeClose() throws SqlException {
+ // set autoCommitted_ to false so commit will flow following
+ // close cursor if autoCommit is true.
+ autoCommitted_ = false;
+ if (generatedSection_ == null) { // none call statement result set case
+ writeCursorClose_(statement_.section_);
+ } else { // call statement result set(s) case
+ writeCursorClose_(generatedSection_);
+ }
+ }
+
+ void readClose() throws SqlException {
try {
- result = new java.io.ByteArrayInputStream
- (((String)agent_.crossConverters_.setObject (java.sql.Types.CHAR,
- updatedColumns_[column-1])).getBytes("UTF-8"));
- }
- catch (java.io.UnsupportedEncodingException e) {
- throw new SqlException (agent_.logWriter_, e, e.getMessage());
- }
- }
- else
- result = isNull (column) ? null : cursor_.getUnicodeStream (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedExit (this, "getUnicodeStream", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.io.Reader getCharacterStream (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getCharacterStream", column);
- checkGetterPreconditions (column);
- java.io.Reader result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = new java.io.StringReader
- ((String)agent_.crossConverters_.setObject (java.sql.Types.CHAR, updatedColumns_[column-1]));
- else
- result = isNull (column) ? null : cursor_.getCharacterStream (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getCharacterStream", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Blob getBlob (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBlob", column);
- checkGetterPreconditions (column);
- java.sql.Blob result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = (java.sql.Blob)agent_.crossConverters_.setObject (java.sql.Types.BLOB,
- updatedColumns_[column-1]);
- else
- result = isNull (column) ? null : cursor_.getBlob (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getBlob", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Clob getClob (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getClob", column);
- checkGetterPreconditions (column);
- java.sql.Clob result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = (java.sql.Clob) agent_.crossConverters_.setObject (java.sql.Types.CLOB,
- updatedColumns_[column-1]);
- else
- result = isNull (column) ? null : cursor_.getClob (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getClob", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Ref getRef (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getRef", column);
- checkGetterPreconditions (column);
- java.sql.Ref result = isNull (column) ? null : cursor_.getRef (column);
- if (true) throw new SqlException (agent_.logWriter_, "jdbc 2 method not yet implemented");
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getRef", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public java.sql.Array getArray (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getArray", column);
- checkGetterPreconditions (column);
- java.sql.Array result = isNull (column) ? null : cursor_.getArray (column);
- if (true) throw new SqlException (agent_.logWriter_, "jdbc 2 method not yet implemented");
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getArray", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public Object getObject (int column) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getObject", column);
- Object result = getObjectX (column);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getObject", result);
- return result;
- }
-
- // used by DBMD
- Object getObjectX (int column) throws SqlException
- {
- checkGetterPreconditions (column);
- Object result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = updatedColumns_[column-1];
- else
- result = isNull (column) ? null : cursor_.getObject (column);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- // Live life on the edge and run unsynchronized
- public Object getObject (int column, java.util.Map map) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getObject", column, map);
- checkGetterPreconditions (column);
- Object result = null;
- if (wasNonNullSensitiveUpdate (column))
- result = updatedColumns_[column-1];
- else
- result = isNull (column) ? null : cursor_.getObject (column);
- if (true) throw new SqlException (agent_.logWriter_, "jdbc 2 method not yet implemented");
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getObject", result);
- setWasNull (column); // Placed close to the return to minimize risk of thread interference
- return result;
- }
-
- //----------------------------------------------------------------------------
-
- // This method only returns true if there is a new non-null updated value.
- // If the resultset is updatable, sensitive, and updated, return the new non-null updated value.
- // Otherwise this method will return false.
- // If the column is updated to null, or if the column has not been update but is null,
- // a null will be returned by isNull(), which first calls wasNullSensitiveUpdate() to check for a column
- // that is updated to null, and columnUpdated_ is checked there.
- private boolean wasNonNullSensitiveUpdate (int column)
- {
- return
- updatedColumns_ != null &&
- updatedColumns_[column-1] != null;
- }
-
- // if updatedColumns_ entry is null, but columnUpdated_ entry
- // indicates column has been updated, then column is updated to null.
- private boolean wasNullSensitiveUpdate (int column)
- {
- return
- resultSetType_ == java.sql.ResultSet.TYPE_SCROLL_SENSITIVE &&
- updatedColumns_ != null &&
- updatedColumns_[column-1] == null &&
- columnUpdated_[column-1];
- }
-
- private void setWasNull (int column)
- {
- if (wasNullSensitiveUpdate (column))
- wasNull_ = WAS_NULL;
- else
- wasNull_ = (cursor_.isNull_ == null || cursor_.isNull_[column-1]) ? WAS_NULL : WAS_NOT_NULL ;
- }
-
- private boolean isNull (int column)
- {
- if (wasNullSensitiveUpdate (column))
- return true;
- else
- return (cursor_.isUpdateDeleteHole_ == true || cursor_.isNull_[column-1]);
- }
-
- // ------------- Methods for accessing results by column name ----------------
-
- public final boolean getBoolean (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBoolean", columnName);
- return getBoolean (findColumnX (columnName));
- }
-
- public final byte getByte (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getByte", columnName);
- return getByte (findColumnX (columnName));
- }
-
- public final short getShort (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getShort", columnName);
- return getShort (findColumnX (columnName));
- }
-
- public final int getInt (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getInt", columnName);
- return getInt (findColumnX (columnName));
- }
-
- public final long getLong (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getLong", columnName);
- return getLong (findColumnX (columnName));
- }
-
- public final float getFloat (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getFloat", columnName);
- return getFloat (findColumnX (columnName));
- }
-
- public final double getDouble (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDouble", columnName);
- return getDouble (findColumnX (columnName));
- }
-
- public final java.math.BigDecimal getBigDecimal (String columnName, int scale) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedEntry (this, "getBigDecimal", columnName, scale);
- return getBigDecimal (findColumnX (columnName), scale);
- }
-
- public final java.math.BigDecimal getBigDecimal (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBigDecimal", columnName);
- return getBigDecimal (findColumnX (columnName));
- }
-
- public final java.sql.Date getDate (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDate", columnName);
- return getDate (findColumnX (columnName));
- }
-
- public final java.sql.Date getDate (String columnName, java.util.Calendar cal) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getDate", columnName, cal);
- return getDate (findColumnX (columnName), cal);
- }
-
- public final java.sql.Time getTime (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTime", columnName);
- return getTime (findColumnX (columnName));
- }
-
- public final java.sql.Time getTime (String columnName, java.util.Calendar cal) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTime", columnName, cal);
- return getTime (findColumnX (columnName), cal);
- }
-
- public final java.sql.Timestamp getTimestamp (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTimestamp", columnName);
- return getTimestamp (findColumnX (columnName));
- }
-
- public final java.sql.Timestamp getTimestamp (String columnName, java.util.Calendar cal) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getTimestamp", columnName, cal);
- return getTimestamp (findColumnX (columnName), cal);
- }
-
- public final String getString (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getString", columnName);
- return getString (findColumnX (columnName));
- }
-
- public final byte[] getBytes (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBytes", columnName);
- return getBytes (findColumnX (columnName));
- }
-
- public final java.io.InputStream getBinaryStream (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBinaryStream", columnName);
- return getBinaryStream (findColumnX (columnName));
- }
-
- public final java.io.InputStream getAsciiStream (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getAsciiStream", columnName);
- return getAsciiStream (findColumnX (columnName));
- }
-
- public final java.io.InputStream getUnicodeStream (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceDeprecatedEntry (this, "getUnicodeStream", columnName);
- return getUnicodeStream (findColumnX (columnName));
- }
-
- public final java.io.Reader getCharacterStream (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getCharacterStream", columnName);
- return getCharacterStream (findColumnX (columnName));
- }
-
- public final java.sql.Blob getBlob (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getBlob", columnName);
- return getBlob (findColumnX (columnName));
- }
-
- public final java.sql.Clob getClob (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getClob", columnName);
- return getClob (findColumnX (columnName));
- }
-
- public final java.sql.Array getArray (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getArray", columnName);
- return getArray (findColumnX (columnName));
- }
-
- public final java.sql.Ref getRef (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getRef", columnName);
- return getRef (findColumnX (columnName));
- }
-
- public final Object getObject (String columnName) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getObject", columnName);
- return getObject (findColumnX (columnName));
- }
-
- public final Object getObject (String columnName, java.util.Map map) throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getObject", columnName, map);
- return getObject (findColumnX (columnName), map);
- }
-
- // ----------------Advanced features -----------------------------------------
-
- public final java.sql.SQLWarning getWarnings ()
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getWarnings", warnings_);
- return warnings_;
- }
-
- public final void clearWarnings () throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "clearWarnings");
- warnings_ = null;
- }
- }
-
- // An untraced version of clearWarnings()
- public final void clearWarningsX ()
- {
- warnings_ = null;
- }
-
- public String getCursorName () throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getCursorName");
- checkForClosedResultSet();
- if (generatedSection_ != null)
- return "stored procedure generated cursor:" + generatedSection_.getServerCursorName();
- if (statement_.cursorName_ == null) {// cursor name is not in the maps yet.
- statement_.cursorName_ = statement_.section_.getServerCursorName ();
- if (statement_.section_ instanceof Section)
- agent_.sectionManager_.mapCursorNameToQuerySection (statement_.cursorName_,
- (Section) statement_.section_);
- }
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getCursorName", statement_.cursorName_);
- return statement_.cursorName_;
- }
- }
-
- public java.sql.ResultSetMetaData getMetaData () throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getMetaData");
- java.sql.ResultSetMetaData resultSetMetaData = getMetaDataX();
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getMetaData", resultSetMetaData);
- return resultSetMetaData;
- }
-
- // used by DBMD
- ColumnMetaData getMetaDataX () throws SqlException
- {
- checkForClosedResultSet ();
- return resultSetMetaData_;
- }
-
-
- public final int findColumn (String columnName) throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "findColumn", columnName);
- int column = findColumnX (columnName);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "findColumn", column);
- return column;
- }
- }
-
- // An untraced version of findColumn()
- private final int findColumnX (String columnName) throws SqlException
- {
- checkForClosedResultSet ();
- return resultSetMetaData_.findColumnX(columnName);
- }
-
- //-------------------------- Traversal/Positioning ---------------------------
-
- public boolean isBeforeFirst () throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "isBeforeFirst");
- checkForClosedResultSet ();
- checkThatResultSetTypeIsScrollable();
- // Returns false if the ResultSet contains no rows.
- boolean isBeforeFirst = isBeforeFirstX ();
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "isBeforeFirst", isBeforeFirst);
- return isBeforeFirst;
- }
-
- private boolean isBeforeFirstX () throws SqlException
- {
- if (sensitivity_ == sensitivity_sensitive_dynamic__)
- return isBeforeFirst_;
- else
- //return ((resultSetContainsNoRows()) ? false : (currentRowInRowset_ == -1));
- return ((currentRowInRowset_ == -1) && !resultSetContainsNoRows());
- }
-
- public boolean isAfterLast () throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "isAfterLast");
- checkForClosedResultSet ();
- checkThatResultSetTypeIsScrollable();
- // Returns false if the ResultSet contains no rows.
- boolean isAfterLast = isAfterLastX ();
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "isAfterLast", isAfterLast);
- return isAfterLast;
- }
-
- private boolean isAfterLastX () throws SqlException
- {
- if (sensitivity_ == sensitivity_sensitive_dynamic__)
- return isAfterLast_;
- else
- return (resultSetContainsNoRows() ? false :
- (firstRowInRowset_ == currentRowInRowset_ &&
- currentRowInRowset_ == lastRowInRowset_ &&
- lastRowInRowset_ == 0 &&
- absolutePosition_ == rowCount_ + 1));
- }
-
- public boolean isFirst () throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "isFirst");
- checkForClosedResultSet ();
- checkThatResultSetTypeIsScrollable();
- // Not necessary to get the rowCount_ since currentRowInRowset_ is initialized to -1,
- // and it will not be changed if there is no rows in the ResultSet.
- boolean isFirst = isFirstX ();
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "isFirst", isFirst);
- return isFirst;
- }
-
- private boolean isFirstX ()
- {
- if (sensitivity_ == sensitivity_sensitive_dynamic__) return isFirst_;
- return (firstRowInRowset_ == 1 && currentRowInRowset_ == 0);
- }
-
- public boolean isLast () throws SqlException
- {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "isLast");
- checkForClosedResultSet ();
- checkThatResultSetTypeIsScrollable();
- // Returns false if the ResultSet contains no rows.
- boolean isLast = isLastX ();
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "isLast", isLast);
- return isLast;
- }
-
- private boolean isLastX () throws SqlException
- {
- if (sensitivity_ == sensitivity_sensitive_dynamic__)
- return isLast_;
- else
- return (resultSetContainsNoRows() ? false :
- (firstRowInRowset_ + currentRowInRowset_) == rowCount_);
- }
-
- public void beforeFirst () throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "beforeFirst");
- checkForClosedResultSet();
- checkThatResultSetTypeIsScrollable();
- clearWarningsX();
- beforeFirstX();
- }
- }
-
- private void beforeFirstX () throws SqlException
- {
- resetRowsetFlags ();
-
- // this method has no effect if the result set has no rows.
- // only send cntqry to position the cursor before first if
- // resultset contains rows and it is not already before first, or
- // if the cursor is a dynamic cursor.
- if (sensitivity_ == sensitivity_sensitive_dynamic__ ||
- (!resultSetContainsNoRows() && !isServersCursorPositionBeforeFirst())) {
- moveToBeforeFirst();
- }
- isBeforeFirst_ = true;
- setRowsetBeforeFirstEvent();
- cursor_.resetDataBuffer();
- resetRowsetSqlca();
- isValidCursorPosition_ = false;
- }
-
- public void afterLast () throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "afterLast");
- checkForClosedResultSet ();
- checkThatResultSetTypeIsScrollable();
- clearWarningsX ();
- afterLastX();
- }
- }
-
- private void afterLastX () throws SqlException
- {
- resetRowsetFlags ();
-
- // this method has no effect if the result set has no rows.
- // only send cntqry to position the cursor after last if
- // resultset contains rows and it is not already after last, or
- // if the cursor is a dynamic cursor.
- if (sensitivity_ == sensitivity_sensitive_dynamic__ ||
- (!resultSetContainsNoRows() && !isServerCursorPositionAfterLast())) {
- moveToAfterLast();
- }
- isAfterLast_ = true;
- setRowsetAfterLastEvent();
- cursor_.resetDataBuffer();
- resetRowsetSqlca();
- isValidCursorPosition_ = false;
- }
-
- public boolean first () throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "first");
- boolean isValidCursorPosition = firstX();
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "first", isValidCursorPosition);
- return isValidCursorPosition;
- }
- }
-
- private boolean firstX () throws SqlException
- {
- checkForClosedResultSet ();
- checkThatResultSetTypeIsScrollable();
- clearWarningsX ();
-
- wasNull_ = ResultSet.WAS_NULL_UNSET;
-
- // discard all previous updates when moving the cursor
- resetUpdatedColumns ();
-
- resetRowsetFlags ();
-
- // if first row is not in the current rowset, fetch the first rowset from the server.
- // rowIsInCurrentRowset with orientation first will always return false for dynamic cursors.
- if (rowIsInCurrentRowset(1, scrollOrientation_first__)) {
- isValidCursorPosition_ = true;
- currentRowInRowset_ = 0;
- }
- else {
- checkAndThrowReceivedQueryTerminatingException();
- isValidCursorPosition_ = getFirstRowset ();
- }
-
- if (isValidCursorPosition_) {
- updateColumnInfoFromCache ();
- isFirst_ = true;
- // check if there is a non-null SQLCA for the row for rowset cursors
- checkRowsetSqlca ();
- }
-
- return isValidCursorPosition_;
- }
-
- public boolean last () throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "last");
- boolean isValidCursorPosition = lastX();
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "last", isValidCursorPosition);
- return isValidCursorPosition;
- }
- }
-
- private boolean lastX () throws SqlException
- {
- checkForClosedResultSet ();
- checkThatResultSetTypeIsScrollable();
- clearWarningsX ();
-
- wasNull_ = ResultSet.WAS_NULL_UNSET;
-
- // discard all previous updates when moving the cursor
- resetUpdatedColumns ();
-
- resetRowsetFlags();
-
- // only get the rowCount for static cursors.
- if (rowCountIsUnknown()) getRowCount();
- long row = rowCount_;
- if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0) {
- if (rowCount_ > statement_.maxRows_)
- row = statement_.maxRows_;
- }
-
- // rowIsInCurrentRowset with orientation last will always return false for dynamic cursors.
- if (rowIsInCurrentRowset (row, scrollOrientation_last__)) {
- isValidCursorPosition_ = true;
- currentRowInRowset_ = row - firstRowInRowset_;
- }
- else {
- checkAndThrowReceivedQueryTerminatingException();
- isValidCursorPosition_ = getLastRowset (row);
- }
-
- if (isValidCursorPosition_) {
- updateColumnInfoFromCache ();
- isLast_ = true;
- // check if there is a non-null SQLCA for the current row for rowset cursors
- checkRowsetSqlca ();
- }
-
- return isValidCursorPosition_;
- }
-
- public int getRow () throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "getRow");
- int row = getRowX();
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getRow", row);
- return row;
- }
- }
-
- private int getRowX () throws SqlException
- {
- checkForClosedResultSet ();
- long row;
- checkThatResultSetIsNotDynamic ();
- if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY)
- // for forward-only cursors, getRow() should return 0 if cursor is not on a valid row,
- // i.e. afterlast.
- row = (cursor_.allRowsReceivedFromServer_ &&
- cursor_.currentRowPositionIsEqualToNextRowPosition ()) ? 0 : cursor_.rowsRead_;
- else {
- if (rowCountIsUnknown()) {
- // commented out here because the following method is called the first thing
- // inside getRowCount();
- //checkAndThrowReceivedQueryTerminatingException();
- getRowCount();
- }
- if (rowCount_ == 0 || currentRowInRowset_ < 0) // || currentRowInRowset_ > rowCount_)
- row = 0;
- else
- row = firstRowInRowset_ + currentRowInRowset_;
- }
- if (row > Integer.MAX_VALUE)
- this.accumulateWarning (new SqlWarning (agent_.logWriter_, "Value too large to fit in an int."));
- return (int)row;
- }
-
- public boolean absolute (int row) throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "absolute", row);
- boolean isValidCursorPosition = absoluteX (row);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "absolute", isValidCursorPosition);
- return isValidCursorPosition;
- }
- }
-
- public boolean absoluteX (int row) throws SqlException
- {
- checkForClosedResultSet();
- checkThatResultSetTypeIsScrollable();
- clearWarningsX();
-
- wasNull_ = ResultSet.WAS_NULL_UNSET;
-
- // discard all previous updates when moving the cursor.
- resetUpdatedColumns ();
-
- resetRowsetFlags ();
-
- if (statement_.maxRows_ > 0) {
- // if "row" is positive and > maxRows, fetch afterLast
- // else if "row" is negative, and abs(row) > maxRows, fetch beforeFirst
- if (row > 0 && row > statement_.maxRows_) {
- afterLastX();
- isValidCursorPosition_ = false;
- return isValidCursorPosition_;
- }
- else if (row <= 0 && java.lang.Math.abs(row) > statement_.maxRows_) {
- beforeFirstX();
- isValidCursorPosition_ = false;
- return isValidCursorPosition_;
- }
+ if (generatedSection_ == null) { // none call statement result set case
+ readCursorClose_();
+ } else { // call statement result set(s) case
+ readCursorClose_();
+ }
+ } finally {
+ markClosed();
+ }
}
- int fetchAbsoluteRow = 0;
- if (rowCountIsUnknown()) getRowCount();
- if (sensitivity_ == sensitivity_sensitive_dynamic__)
- fetchAbsoluteRow = row;
- else
- // calculate the positive absolute row number based on rowCount for static or insensitive cursors.
- fetchAbsoluteRow = (row >= 0) ? row : (int)(rowCount_ + row + 1);
-
- // rowIsInCurrentRowset with orientation absolute will always return false for dynamic cursors.
- if (rowIsInCurrentRowset (fetchAbsoluteRow, scrollOrientation_absolute__)) {
- isValidCursorPosition_ = true;
- currentRowInRowset_ = fetchAbsoluteRow - firstRowInRowset_;
- }
- else {
- checkAndThrowReceivedQueryTerminatingException();
- isValidCursorPosition_ = getAbsoluteRowset (fetchAbsoluteRow);
- }
-
- if (isValidCursorPosition_) {
- updateColumnInfoFromCache ();
- if (row == 1) isFirst_ = true;
- if (row == -1) isLast_ = true;
- // check if there is a non-null SQLCA for the row for rowset cursors
- checkRowsetSqlca ();
- }
-
- return isValidCursorPosition_;
- }
-
- public boolean relative (int rows) throws SqlException
- {
- synchronized (connection_) {
- if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "relative", rows);
- boolean isValidCursorPosition = relativeX (rows);
- if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "relative", isValidCursorPosition);
- return isValidCursorPosition;
- }
- }
-
- private boolean relativeX (int rows) throws SqlException
- {
- checkForClosedResultSet ();
- checkThatResultSetTypeIsScrollable();
- clearWarningsX ();
- wasNull_ = ResultSet.WAS_NULL_UNSET;
-
- // discard all previous updates when moving the cursor.
- resetUpdatedColumns ();
-
- // this method may only be called when the cursor on a valid row,
- // not after the last row, before the first row, or on the insert row.
- // throw exception if result set contains no rows, because there is no current row.
- if (isBeforeFirstX() || isAfterLastX() || isOnInsertRow_ || resultSetContainsNoRows())
- throw new SqlException (agent_.logWriter_, "Cursor is Not on a Valid Row");
-
- if (rows == 0) {
- isValidCursorPosition_ = true;
- return isValidCursorPosition_;
- }
-
- resetRowsetFlags ();
-
- // currentAbsoluteRowNumber is used for static cursors only.
- long currentAbsoluteRowNumber = firstRowInRowset_ + currentRowInRowset_;
-
- // if "rows" is positive, and currentRow+rows > maxRows, fetch afterLast.
- // if "rows" is negative, and if the absolute value of "rows" is greater than
- // the currentrow number, will fetch beforeFirst anyways. do not need to check
- // for maxRows.
- if (sensitivity_ != sensitivity_sensitive_dynamic__ &&
- statement_.maxRows_ > 0 && rows > 0 && currentAbsoluteRowNumber+rows > statement_.maxRows_) {
- afterLastX();
- isValidCursorPosition_ = false;
- return isValidCursorPosition_;
- }
[... 5197 lines stripped ...]