Added: 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=165178&view=auto ============================================================================== --- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java (added) +++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ResultSet.java Thu Apr 28 12:05:42 2005 @@ -0,0 +1,3543 @@ +/* + + Derby - Class org.apache.derby.client.am.ResultSet + + Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +package org.apache.derby.client.am; + +import org.apache.derby.client.am.Section; + +public abstract class ResultSet implements java.sql.ResultSet, + 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------------------------------------------ + + 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 +// 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 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; + } + } + + // 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 { + 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++; + } + } + if (count == statement_.resultSetList_.length) { + if (connection_.autoCommit_ && !autoCommitted_) { + connection_.flowAutoCommit(); + markAutoCommitted(); + } + } + } + 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)) { + 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_; + } + } + + 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_; + } + + if (rowIsInCurrentRowset (currentAbsoluteRowNumber+rows, scrollOrientation_relative__)) { + currentRowInRowset_ += rows; + isValidCursorPosition_ = true; + } + else { + checkAndThrowReceivedQueryTerminatingException(); + long rowNumber = + (sensitivity_ == sensitivity_sensitive_dynamic__) ? currentRowInRowset_+rows : + currentAbsoluteRowNumber+rows-absolutePosition_; + isValidCursorPosition_ = getRelativeRowset (rowNumber); + } + + if (isValidCursorPosition_) { + updateColumnInfoFromCache (); + // check if there is a non-null SQLCA for the row for rowset cursors + checkRowsetSqlca (); + } + + return isValidCursorPosition_; + } + + public boolean previous () throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "previous"); + boolean isValidCursorPosition = previousX(); + if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "previous", isValidCursorPosition); + return isValidCursorPosition; + } + } + + private boolean previousX () throws SqlException + { + checkForClosedResultSet (); + checkThatResultSetTypeIsScrollable(); + clearWarningsX (); + + wasNull_ = ResultSet.WAS_NULL_UNSET; + + // discard all previous updates when moving the cursor. + resetUpdatedColumns (); + + isBeforeFirst_ = false; + isFirst_ = false; + + if (rowIsInCurrentRowset (firstRowInRowset_+currentRowInRowset_-1, scrollOrientation_prior__)) { + isValidCursorPosition_ = true; + currentRowInRowset_--; + } + else { + checkAndThrowReceivedQueryTerminatingException(); + isValidCursorPosition_ = getPreviousRowset (); + } + + if (isValidCursorPosition_) { + updateColumnInfoFromCache (); + // check if there is a non-null SQLCA for the row for rowset cursors + checkRowsetSqlca (); + if (isAfterLast_) isLast_ = true; + isAfterLast_ = false; + } + else { + return isValidCursorPosition_; + } + + if (sensitivity_ != sensitivity_sensitive_dynamic__ && statement_.maxRows_ > 0 && + (firstRowInRowset_+currentRowInRowset_ > statement_.maxRows_)) + isValidCursorPosition_ = false; + // auto-close result set if this is the last row from server and return false + return isValidCursorPosition_; + } + + public void setFetchDirection (int direction) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "setFetchDirection", direction); + checkForClosedResultSet (); + checkThatResultSetTypeIsScrollable(); + + switch (direction) { + case java.sql.ResultSet.FETCH_FORWARD: + case java.sql.ResultSet.FETCH_REVERSE: + case java.sql.ResultSet.FETCH_UNKNOWN: + fetchDirection_ = direction; + break; + default: + throw new SqlException (agent_.logWriter_, "Invalid fetch direction " + direction); + } + } + } + + public int getFetchDirection () throws SqlException + { + checkForClosedResultSet (); + if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getFetchDirection", fetchDirection_); + return fetchDirection_; + } + + public void setFetchSize (int rows) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "setFetchSize", rows); + checkForClosedResultSet (); + if (rows < 0 || (statement_.maxRows_ != 0 && rows > statement_.maxRows_)) + throw new SqlException (agent_.logWriter_, "Invalid fetch size " + rows); + setFetchSize_ (rows); + } + } + + public int getFetchSize () throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getFetchSize", fetchSize_); + checkForClosedResultSet (); + return fetchSize_; + } + + public int getType () throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getType", resultSetType_); + checkForClosedResultSet (); + return resultSetType_; + } + + public int getConcurrency () throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "getConcurrency", resultSetConcurrency_); + checkForClosedResultSet (); + return resultSetConcurrency_; + } + + //----------------------------- Updates -------------------------------------- + + public boolean rowUpdated () throws SqlException + { + // we cannot tell whether the ResultSet has been updated, so always return false here. + boolean rowUpdated = false; + checkForClosedResultSet (); + if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "rowUpdated", rowUpdated); + return rowUpdated; + } + + public boolean rowInserted () throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "rowInserted"); + checkForClosedResultSet (); + if (true) throw new SqlException (agent_.logWriter_, "under construction"); + boolean rowInserted = false; + if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "rowInserted", rowInserted); + return rowInserted; + } + + public boolean rowDeleted () throws SqlException + { + // rowDeleted is visible through a delete hole, (sqlcode +222). + // Always return false and do not check the return code for now. + boolean rowDeleted = false; + checkForClosedResultSet (); + if (agent_.loggingEnabled()) agent_.logWriter_.traceExit (this, "rowDeleted", rowDeleted); + return rowDeleted; + } + + // --------------------------- update column methods ------------------------- + + public void updateNull (int column) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateNull", column); + checkUpdatePreconditions (column); + if (!resultSetMetaData_.nullable_[column-1]) + throw new SqlException (agent_.logWriter_, "Invalid operation to update a non-nullable column to null."); + updateColumn (column, null); + } + } + + public void updateBoolean (int column, boolean x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBoolean", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateByte (int column, byte x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateByte", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateShort (int column, short x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateShort", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateInt (int column, int x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateInt", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateLong (int column, long x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateLong", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateFloat (int column, float x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateFloat", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateDouble (int column, double x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateDouble", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateBigDecimal (int column, java.math.BigDecimal x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBigDecimal", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateDate (int column, java.sql.Date x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateDate", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateTime (int column, java.sql.Time x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateTime", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateTimestamp (int column, java.sql.Timestamp x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateTimestamp", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateString (int column, String x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateString", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateBytes (int column, byte x[]) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBytes", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateBinaryStream (int column, + java.io.InputStream x, + int length) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBinaryStream", column, x, length); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObjectFromBinaryStream (resultSetMetaData_.types_[column-1], x, length)); + } + } + + public void updateAsciiStream (int column, + java.io.InputStream x, + int length) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateAsciiStream", column, x, length); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObjectFromCharacterStream (resultSetMetaData_.types_[column-1], x, "US-ASCII", length)); + } + } + + public void updateCharacterStream (int column, + java.io.Reader x, + int length) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateCharacterStream", column, x, length); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x, length)); + } + } + + public void updateObject (int column, Object x, int scale) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateObject", column, x, scale); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + public void updateObject (int column, Object x) throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateObject", column, x); + checkUpdatePreconditions (column); + updateColumn (column, agent_.crossConverters_.setObject (resultSetMetaData_.types_[column-1], x)); + } + } + + // ---------------------- update on column name methods ---------------------- + + public void updateNull (String columnName) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateNull", columnName); + updateNull (findColumnX (columnName)); + } + + public void updateBoolean (String columnName, boolean x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBoolean", columnName, x); + updateBoolean (findColumnX (columnName), x); + } + + public void updateByte (String columnName, byte x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateByte", columnName, x); + updateByte (findColumnX (columnName), x); + } + + public void updateShort (String columnName, short x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateShort", columnName, x); + updateShort (findColumnX (columnName), x); + } + + public void updateInt (String columnName, int x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateInt", columnName, x); + updateInt (findColumnX (columnName), x); + } + + public void updateLong (String columnName, long x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateLong", columnName, x); + updateLong (findColumnX (columnName), x); + } + + public void updateFloat (String columnName, float x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateFloat", columnName, x); + updateFloat (findColumnX (columnName), x); + } + + public void updateDouble (String columnName, double x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateDouble", columnName, x); + updateDouble (findColumnX (columnName), x); + } + + public void updateBigDecimal (String columnName, java.math.BigDecimal x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBigDecimal", columnName, x); + updateBigDecimal (findColumnX (columnName), x); + } + + public void updateDate (String columnName, java.sql.Date x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateDate", columnName, x); + updateDate (findColumnX (columnName), x); + } + + public void updateTime (String columnName, java.sql.Time x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateTime", columnName, x); + updateTime (findColumnX (columnName), x); + } + + public void updateTimestamp (String columnName, java.sql.Timestamp x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateTimestamp", columnName, x); + updateTimestamp (findColumnX (columnName), x); + } + + public void updateString (String columnName, String x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateString", columnName, x); + updateString (findColumnX (columnName), x); + } + + public void updateBytes (String columnName, byte x[]) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBytes", columnName, x); + updateBytes (findColumnX (columnName), x); + } + + public void updateBinaryStream (String columnName, + java.io.InputStream x, + int length) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateBinaryStream", columnName, x, length); + updateBinaryStream (findColumnX (columnName), x, length); + } + + public void updateAsciiStream (String columnName, + java.io.InputStream x, + int length) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateAsciiStream", columnName, x, length); + updateAsciiStream (findColumnX (columnName), x, length); + } + + public void updateCharacterStream (String columnName, + java.io.Reader x, + int length) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateCharacterStream", columnName, x, length); + updateCharacterStream (findColumnX (columnName), x, length); + } + + public void updateObject (String columnName, Object x, int scale) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateObject", columnName, x, scale); + updateObject (findColumnX (columnName), x, scale); + } + + public void updateObject (String columnName, Object x) throws SqlException + { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateObject", columnName, x); + updateObject (findColumnX (columnName), x); + } + + // --------------------------------------------------------------------------- + + public void insertRow () throws SqlException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "insertRow"); + checkForClosedResultSet (); + throw new SqlException (agent_.logWriter_, "Driver not capable: insertRow"); + } + } + + public void updateRow () throws java.sql.SQLException + { + synchronized (connection_) { + if (agent_.loggingEnabled()) agent_.logWriter_.traceEntry (this, "updateRow"); + updateRowX(); + } + } + + private void updateRowX () throws java.sql.SQLException + { + checkForClosedResultSet (); + if (isOnInsertRow_ || resultSetConcurrency_ == java.sql.ResultSet.CONCUR_READ_ONLY)
[... 1407 lines stripped ...]